-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Description
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
- Remove or conditionalize
.macOS(.v13)inPackage.swift(shared with Linux issue)
Shell Execution Abstraction
- Hardcoded POSIX paths in
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 -Command
-
ShellRunner.shell()(ShellRunner.swift:82-95) — runs commands via/bin/bash -c. Needs Windows shell equivalent -
Environment.resolveCommand()(Environment.swift:112-137) — uses/usr/bin/whichviaProcess. Needswhere.exeon Windows -
ClaudeIntegration(ClaudeIntegration.swift:47-49) — invokesclaudevia/usr/bin/env. Needs direct PATH resolution on Windows -
ScriptRunner.runCommand()(ScriptRunner.swift:97-122) — executes fix commands via/bin/bash -c
Terminal I/O
-
Darwin.read()inCLIOutput.swift:523— no Darwin/Glibc on Windows. Use_read()from CRT orReadConsoleInput -
termios/tcgetattr/tcsetattrinCLIOutput.swift:232-245, 378-392— no POSIX terminal on Windows. UseSetConsoleModewithENABLE_LINE_INPUT/ENABLE_ECHO_INPUTflags -
ioctl(TIOCGWINSZ)inCLIOutput.swift:52-53— useGetConsoleScreenBufferInfofor terminal width -
isatty(STDOUT_FILENO)inCLIOutput.swift:11,205,219— use_isatty(_fileno(stdout))on Windows - ANSI escape codes — Windows Terminal supports them natively, but legacy
cmd.exerequiresSetConsoleModewithENABLE_VIRTUAL_TERMINAL_PROCESSINGflag. Consider adding an initialization step
File Locking
- POSIX
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/_close -
strerror/errnoinFileLock.swift:14— available via CRT but error codes may differ
Apple-Only APIs
-
CryptoKit— add#if canImport(CryptoKit)/import Cryptofallback (shared with Linux issue) in 4 files -
OSAllocatedUnfairLockinScriptRunner.swift:174— replace with Swift 6MutexorNSLock(shared with Linux issue)
File Permissions
-
.posixPermissions: 0o755used in:CoreDoctorChecks.swift:223ScriptRunner.swift:131ComponentExecutor.swift:157, 182, 262
POSIX permissions are meaningless on Windows. Guard with
#if !os(Windows)or use Windows ACL equivalent
Path Handling
- Raw
/path splits — e.g.Homebrew.swift:58:resolved.split(separator: "/"). Windows paths use\. Use Foundation URL APIs instead of raw string splitting where possible - PATH separator —
Environment.swift:107:"\(brewBin):\(currentPath)"uses:as PATH separator. Windows uses;
Package Management
- Homebrew does not exist on Windows — the entire
Homebrewstruct andComponentExecutor.installBrewPackage()need a platform guard - Consider abstracting package management behind a protocol to support alternatives (Scoop, Chocolatey, winget) in the future, or simply skip brew components on Windows with a warning
-
ClaudePrerequisite.swift— brew-based Claude CLI installation fallback won't work
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
Processsupport 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
mcsto be useful - The fallback (non-TTY) multi-select in
CLIOutputalready works without raw mode — this could be the initial Windows path while terminal support matures
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels