Skip to content

Add WitcherScriptMerger.Headless: a Linux-capable CLI/MCP-only host - #8

Merged
TheValiantOne merged 1 commit into
mainfrom
feature/linux-headless-host
Aug 7, 2026
Merged

Add WitcherScriptMerger.Headless: a Linux-capable CLI/MCP-only host#8
TheValiantOne merged 1 commit into
mainfrom
feature/linux-headless-host

Conversation

@TheValiantOne

Copy link
Copy Markdown
Owner

Re-opened against the correct repo (the original PR was mistakenly opened against upstream AnotherSymbiote/WitcherScriptMerger and has been closed there).

See the branch's commits for full details: adds WitcherScriptMerger.Headless, a slim GUI-free host (net10.0, no WinForms) wiring up just the merge CLI verb and mcp server mode via DiffPlexMergeEngine, plus Core changes so bundle-category conflicts degrade gracefully without QuickBMS/wcc_lite. Verified via actual runtime execution on Linux (WSL2), not just cross-compilation — this caught and fixed two real hardcoded-backslash path-separator bugs that only manifest on Linux. Full verification details are in the commit messages.

AI-assisted (Claude Code) per this repo's CONTRIBUTING.md disclosure convention.

New project (net10.0, no -windows suffix, references Core only) that wires
up just the merge CLI verb and mcp server mode - no WinForms, no GUI
fallback. Always uses DiffPlexMergeEngine (Core, no external binary), since
KDiff3MergeEngine needs Win32 P/Invoke that stays host-only.

Getting this actually working on Linux (verified via WSL2, not just a
cross-compile check) surfaced and fixed real bugs in shared Core code:
- ModFile.GetModNameFromPath hardcoded '\' to find a path segment, crashing
  every flat-file merge on Linux (Path.Combine uses '/' there). Fixed to use
  Path.DirectorySeparatorChar.
- WsmMcpTools.MergeConflicts normalized client-supplied paths toward a
  hardcoded '\' too, silently breaking relativePaths/orderOverrides
  matching on Linux. Same fix.
- QuickBms.GetBundleContentPaths returned null when QuickBMS wasn't found,
  which ModFileIndex.BuildAsync and FileMerger.GetUnpackedFiles both
  enumerated directly - unreachable on the WinForms host (always gated
  behind the combined Paths.ValidateDependencyPaths()) but a real
  NullReferenceException once WitcherScriptMerger.Headless legitimately
  scans without QuickBMS/wcc_lite configured. Returns Array.Empty<string>()
  instead now.
- FileMerger.GetUnpackedFiles's vanilla-bundle search also threw
  DirectoryNotFoundException on a missing content/DLC folder (a scratch/
  incomplete game tree) - now degrades to "no vanilla bundle found" instead.

Split Paths.ValidateDependencyPaths() into ValidateTextMergeDependencies()
and ValidateBundleDependencies() so a host without QuickBMS/wcc_lite can
still scan/merge flat-file conflicts; bundle-category conflicts fail
gracefully per-conflict instead (ModFileIndex.BuildAsync prints one clear
message per scan and skips bundle checking rather than crashing or being
noisy per-bundle). This also relaxes WsmMcpTools's MCP-tool gating for the
WinForms host's own mcp verb, not just the new host - documented in
CLAUDE.md.

Verified: full build, existing test suite, and dotnet format whitespace all
pass. Self-contained single-file win-x64 and linux-x64 publishes both
succeed. Actually ran the published linux-x64 binary under WSL2 (real Linux
kernel) for both the merge and mcp verbs against synthetic scratch mods,
including the bundle-graceful-degradation path - not just a cross-compile
check. Added matching win-x64/linux-x64 publish commands to CLAUDE.md (no
existing .pubxml convention to follow).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXAuGMLB44T5Zv5o5ZzKah
@TheValiantOne
TheValiantOne merged commit e64e16b into main Aug 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant