Summary
Make mcs build and run on Windows. This requires deeper changes than Linux due to fundamental platform differences in shell execution, terminal handling, file locking, and the absence of Homebrew. The existing Environment and ShellRunner abstractions are natural extension points for a platform abstraction layer.
Effort Estimate
High — requires a platform abstraction layer across shell execution, terminal I/O, file locking, and package management. No full rewrite, but significant targeted work.
Required Changes
Build Configuration
Shell Execution Abstraction
Terminal I/O
File Locking
Apple-Only APIs
File Permissions
Path Handling
Package Management
Suggested Architecture
Platform (protocol)
├── macOS: DarwinPlatform
├── Linux: LinuxPlatform
└── Windows: WindowsPlatform
Abstracts:
- shellCommand(_ command: String) -> ShellResult // bash vs cmd/powershell
- resolveCommand(_ name: String) -> String? // which vs where
- terminalWidth() -> Int // ioctl vs GetConsoleScreenBufferInfo
- withFileLock(at: URL, body:) throws -> T // flock vs LockFileEx
- pathSeparator: Character // : vs ;
- isPackageManagerAvailable: Bool
- installPackage(_ name: String) -> Bool
Files Affected
| File |
Change |
Package.swift |
Platform restriction |
Sources/mcs/Core/Constants.swift |
Platform-conditional shell paths |
Sources/mcs/Core/Environment.swift |
Command resolution, PATH separator, brew prefix |
Sources/mcs/Core/ShellRunner.swift |
Shell execution abstraction |
Sources/mcs/Core/CLIOutput.swift |
Terminal I/O (raw mode, read, width, isatty) |
Sources/mcs/Core/FileLock.swift |
File locking mechanism |
Sources/mcs/Core/Homebrew.swift |
Platform guard or abstraction |
Sources/mcs/Core/ClaudePrerequisite.swift |
Brew install fallback |
Sources/mcs/Core/FileHasher.swift |
CryptoKit import |
Sources/mcs/Core/SettingsHasher.swift |
CryptoKit import |
Sources/mcs/Doctor/SectionValidator.swift |
CryptoKit import |
Sources/mcs/Doctor/CoreDoctorChecks.swift |
POSIX permissions guard |
Sources/mcs/ExternalPack/PackTrustManager.swift |
CryptoKit import |
Sources/mcs/ExternalPack/ScriptRunner.swift |
OSAllocatedUnfairLock, bash execution |
Sources/mcs/Install/ComponentExecutor.swift |
POSIX permissions guard, brew abstraction |
Sources/mcs/Core/ClaudeIntegration.swift |
/usr/bin/env usage |
Dependencies
- Linux support issue should be completed first — several fixes are shared (CryptoKit, OSAllocatedUnfairLock, Package.swift)
- Swift for Windows toolchain maturity should be evaluated at implementation time (swift-corelibs-foundation
Process support on Windows is still evolving)
Notes
- Distribution: Homebrew is not available on Windows. Future distribution TBD (direct download, Scoop, Chocolatey, winget)
- Claude Code CLI must also be available on Windows for
mcs to be useful
- The fallback (non-TTY) multi-select in
CLIOutput already works without raw mode — this could be the initial Windows path while terminal support matures
Summary
Make
mcsbuild and run on Windows. This requires deeper changes than Linux due to fundamental platform differences in shell execution, terminal handling, file locking, and the absence of Homebrew. The existingEnvironmentandShellRunnerabstractions are natural extension points for a platform abstraction layer.Effort Estimate
High — requires a platform abstraction layer across shell execution, terminal I/O, file locking, and package management. No full rewrite, but significant targeted work.
Required Changes
Build Configuration
.macOS(.v13)inPackage.swift(shared with Linux issue)Shell Execution Abstraction
Constants.swift:36-42:/usr/bin/env→ no equivalent on Windows (not needed if using absolute paths)/usr/bin/which→where.exeon Windows/bin/bash→cmd.exe /corpowershell.exe -CommandShellRunner.shell()(ShellRunner.swift:82-95) — runs commands via/bin/bash -c. Needs Windows shell equivalentEnvironment.resolveCommand()(Environment.swift:112-137) — uses/usr/bin/whichviaProcess. Needswhere.exeon WindowsClaudeIntegration(ClaudeIntegration.swift:47-49) — invokesclaudevia/usr/bin/env. Needs direct PATH resolution on WindowsScriptRunner.runCommand()(ScriptRunner.swift:97-122) — executes fix commands via/bin/bash -cTerminal I/O
Darwin.read()inCLIOutput.swift:523— no Darwin/Glibc on Windows. Use_read()from CRT orReadConsoleInputtermios/tcgetattr/tcsetattrinCLIOutput.swift:232-245, 378-392— no POSIX terminal on Windows. UseSetConsoleModewithENABLE_LINE_INPUT/ENABLE_ECHO_INPUTflagsioctl(TIOCGWINSZ)inCLIOutput.swift:52-53— useGetConsoleScreenBufferInfofor terminal widthisatty(STDOUT_FILENO)inCLIOutput.swift:11,205,219— use_isatty(_fileno(stdout))on Windowscmd.exerequiresSetConsoleModewithENABLE_VIRTUAL_TERMINAL_PROCESSINGflag. Consider adding an initialization stepFile Locking
flock()inFileLock.swift:76-82— does not exist on Windows. Replace withLockFileEx/UnlockFileEx(Win32 API)open()/close()inFileLock.swift:76,80— useCreateFileW/CloseHandleor CRT_open/_closestrerror/errnoinFileLock.swift:14— available via CRT but error codes may differApple-Only APIs
CryptoKit— add#if canImport(CryptoKit)/import Cryptofallback (shared with Linux issue) in 4 filesOSAllocatedUnfairLockinScriptRunner.swift:174— replace with Swift 6MutexorNSLock(shared with Linux issue)File Permissions
.posixPermissions: 0o755used in:CoreDoctorChecks.swift:223ScriptRunner.swift:131ComponentExecutor.swift:157, 182, 262POSIX permissions are meaningless on Windows. Guard with
#if !os(Windows)or use Windows ACL equivalentPath Handling
/path splits — e.g.Homebrew.swift:58:resolved.split(separator: "/"). Windows paths use\. Use Foundation URL APIs instead of raw string splitting where possibleEnvironment.swift:107:"\(brewBin):\(currentPath)"uses:as PATH separator. Windows uses;Package Management
Homebrewstruct andComponentExecutor.installBrewPackage()need a platform guardClaudePrerequisite.swift— brew-based Claude CLI installation fallback won't workSuggested Architecture
Files Affected
Package.swiftSources/mcs/Core/Constants.swiftSources/mcs/Core/Environment.swiftSources/mcs/Core/ShellRunner.swiftSources/mcs/Core/CLIOutput.swiftSources/mcs/Core/FileLock.swiftSources/mcs/Core/Homebrew.swiftSources/mcs/Core/ClaudePrerequisite.swiftSources/mcs/Core/FileHasher.swiftSources/mcs/Core/SettingsHasher.swiftSources/mcs/Doctor/SectionValidator.swiftSources/mcs/Doctor/CoreDoctorChecks.swiftSources/mcs/ExternalPack/PackTrustManager.swiftSources/mcs/ExternalPack/ScriptRunner.swiftOSAllocatedUnfairLock, bash executionSources/mcs/Install/ComponentExecutor.swiftSources/mcs/Core/ClaudeIntegration.swift/usr/bin/envusageDependencies
Processsupport on Windows is still evolving)Notes
mcsto be usefulCLIOutputalready works without raw mode — this could be the initial Windows path while terminal support matures