fix: resolve three macOS startup issues (posix_spawnp, nvm PATH, session restore overlay)#67
Open
buallen wants to merge 1 commit intovultuk:mainfrom
Open
Conversation
1. spawn-helper missing execute permission (posix_spawnp failed) node-pty's spawn-helper binary loses its execute bit after npm install on macOS. Added a postinstall script that detects and repairs the permission, fixing the "posix_spawnp failed" error that affects all macOS users on a fresh install. 2. nvm-installed claude not found under launchd/systemd When cc-web runs as a background service (launchd on macOS, systemd on Linux) PATH does not include nvm's bin directory. findClaudeCommand() now dynamically discovers all nvm node versions and probes their bin dirs before falling back to short-name lookup, so the absolute path is always returned and node-pty can spawn it correctly. 3. node-pty cannot posix_spawnp a JS script (nvm installs) The claude binary installed via nvm is a symlink to cli.js. node-pty's posix_spawnp cannot exec a bare JS file. startSession() now resolves symlinks and, when the target is a .js file, spawns `process.execPath cli.js [args]` instead of the script directly. 4. Restored sessions hide "Start Claude" overlay on page reload init() was calling hideOverlay() unconditionally after switchToTab(), racing with and overriding the startPrompt overlay that session_joined correctly shows for inactive sessions. Removed the redundant hideOverlay() call so the session_joined handler remains authoritative over overlay state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes three issues discovered while running
claude-code-webas a persistent macOS launchd service accessed via ngrok. All three prevent the interface from working on a fresh macOS install with nvm.Bug 1 —
spawn-helpermissing execute permission →posix_spawnp failedRoot cause: npm does not guarantee that executable bits are preserved when installing from the registry.
node-pty'sspawn-helperbinary lands as-rw-r--r--instead of-rwxr-xr-x, causing every singlepty.spawn()call to throwposix_spawnp failed.Fix: Added
scripts/postinstall.js(invoked via"postinstall"inpackage.json) that walks allnode_modules/node-pty/prebuilds/*/spawn-helperfiles and restores the execute bit if missing.Bug 2 — nvm-installed
claudenot found when running as a serviceRoot cause: When
cc-webruns under launchd (macOS) or systemd (Linux),PATHdoes not include nvm's per-versionbin/directory.findClaudeCommand()fell back to the short name"claude", whichwhichfound at runtime butnode-pty's nativeposix_spawnpcould not resolve later.Fix:
findClaudeCommand()now dynamically reads~/.nvm/versions/node/and prepends all discoveredbin/claudeabsolute paths to the search list, ensuring an absolute path is always returned.Bug 3 —
posix_spawnpcannot exec a bare JS script (nvm symlink)Root cause: The
claudebinary installed via nvm is a symlink →cli.js.node-ptypasses the path directly toposix_spawnp, which on some macOS configurations fails to exec a script file even when the shebang is valid.Fix:
startSession()resolves symlinks before spawning. When the resolved target ends in.js, it spawnsprocess.execPath <cli.js> [args]instead of the script directly.Bug 4 — "Start Claude" overlay hidden on page reload for inactive sessions
Root cause:
init()calledthis.hideOverlay()unconditionally afterawait switchToTab(). BecauseswitchToTabawaitsjoinSession(which resolves whensession_joinedis received), the overlay state set by thesession_joinedhandler (showOverlay('startPrompt')for inactive sessions) was immediately overridden by the subsequenthideOverlay()microtask continuation — leaving users with a blank terminal and no way to start Claude.Fix: Removed the unconditional
hideOverlay()frominit(). Thesession_joinedhandler is already authoritative over overlay state and handles both the active (hide) and inactive (show startPrompt) cases correctly.Test plan
npm install -g claude-code-webon macOS —cc-webstarts withoutposix_spawnp failednode cli.js🤖 Generated with Claude Code