Skip to content

fix: detect Claude/Codex when launched from GUI (stripped PATH)#263

Merged
vakovalskii merged 2 commits into
vakovalskii:mainfrom
NovakPAai:fix/gui-path-agent-detection
Jul 21, 2026
Merged

fix: detect Claude/Codex when launched from GUI (stripped PATH)#263
vakovalskii merged 2 commits into
vakovalskii:mainfrom
NovakPAai:fix/gui-path-agent-detection

Conversation

@NovakPAai

@NovakPAai NovakPAai commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Problem

When the desktop app is launched from Finder/Dock/Spotlight on macOS, the process inherits a minimal PATH (/usr/bin:/bin:/usr/sbin:/sbin) that omits user bin dirs like ~/.local/bin, ~/.npm-global/bin, nvm/fnm shims, and Homebrew — where CLIs such as claude and codex are installed.

src/agents-detect.js resolves claude/codex purely via which() over process.env.PATH. So a GUI launch detects only agents that ship as a .app bundle (Cursor via appBundle) and misses Claude Code and Codex entirely — even though their history is present and the terminal-launched CLI (codbash run) detects all of them.

Reproduced on a real machine:

# GUI-stripped PATH:
detected: cursor
# after fix:
detected: claude(path), codex(path), cursor(app-bundle)

Fix

New src/shell-path.js: at startup, when process.env.PATH contains no bin/shims directory under the user's home (the tell-tale of a Finder-stripped PATH), probe the user's login shell ($SHELL -i -l -c) for its real PATH and merge in the missing directories. Wired into bin/cli.js before any command runs.

  • No-op when launched from a terminal — if PATH already has user bin dirs, no shell is spawned (zero added latency for CLI use).
  • Opt-out: CODBASH_NO_PATH_REPAIR=1 skips the probe entirely. CODBASH_DEBUG=1 logs decisions.
  • Sentinel-delimited capture so shell-integration banners can't corrupt the PATH; control-char entries (incl. TAB/DEL) are filtered; existing entries keep priority (new dirs appended, never shadowing system binaries).
  • Time-boxed probe (4s, killSignal: SIGKILL) so a slow/SIGTERM-ignoring rc file can't wedge startup.
  • Fixes both detection and in-process agent launching, generically for every PATH-detected agent (qwen, opencode, kilo, …).
  • Windows is skipped (its GUI PATH isn't stripped this way). Zero new dependencies.

Acceptance criteria

  • Happy path — GUI-stripped PATH, claude/codex in ~/.local/bin & ~/.npm-global/bin → both detected after startup.
  • Terminal no-op — PATH already contains user bin dirs → no shell spawned, PATH unchanged.
  • Negative — login-shell probe fails (bad $SHELL / hung rc / no sentinel) → error logged, existing PATH preserved, startup continues.
  • Edge — captured entries with control chars / duplicate whitespace variants are dropped; append-after-system precedence preserved.
  • SafetyCODBASH_NO_PATH_REPAIR=1 and win32 short-circuit before any spawn.

Test plan

  • test/shell-path.test.js — 15 cases (gate logic incl. false-negative guard, merge/dedup, control-char + TAB/DEL filtering, whitespace dedup, precedence assertion, idempotency, win32 skip, opt-out, capture-failure, empty capture, process.env mutation)
  • Full suite green: 202 passed / 0 failed / 1 pre-existing skip (node --test test/*.test.js)
  • E2E: agents-detect under PATH=/usr/bin:/bin:/usr/sbin:/sbin goes cursorclaude, codex, cursor
  • node -c syntax check on all touched files
  • Passed code-review + security-review (no CRITICAL/HIGH remaining; all MEDIUM/LOW findings addressed)

Review notes

Went through a code review and a security review. No injection vector (fixed printf script, args array, no shell:true); the probe mirrors the same trust surface as opening a terminal (a compromised rc file already runs on any terminal open) and is now opt-out-able. All MEDIUM/LOW findings from both reviews are fixed in the second commit.

macOS/Linux GUI launches (Finder/Dock/Spotlight) inherit a minimal PATH
(/usr/bin:/bin:/usr/sbin:/sbin) that omits user bin dirs such as
~/.local/bin and ~/.npm-global/bin where CLIs like claude and codex are
installed. agents-detect.js resolves those agents purely via which() on
process.env.PATH, so a GUI-launched app detected only agents shipping as a
.app bundle (Cursor) and missed Claude Code / Codex — even though their
history is present and the terminal-launched CLI detects them fine.

Add src/shell-path.js: on startup, when PATH lacks any user-home dir, probe
the login shell (SHELL -ilc) for its PATH and merge in the missing dirs.
No-op (no shell spawn) when already launched from a terminal. Fixes both
detection and in-process agent launching, generically for all agents.
Code review + security review of the shell-path module:

- HIGH: add test/shell-path.test.js (15 cases) — gate logic, merge/dedup,
  control-char filtering, idempotency, win32 skip, opt-out, capture failure.
- MEDIUM: pass killSignal:SIGKILL so a shell ignoring SIGTERM can't outlive
  the 4s timeout and hang startup.
- MEDIUM: add CODBASH_NO_PATH_REPAIR=1 opt-out (login shell / rc files no
  longer run unconditionally with no escape hatch).
- MEDIUM: log login-shell probe failures (was silently swallowed) and the
  bin/cli.js catch now logs, matching the repo-refresh convention.
- MEDIUM: replace the startsWith($HOME) gate with hasUserBinPaths — a lone
  unrelated ~/Library entry no longer false-negatives and suppresses repair.
- LOW: block TAB (\x09) and DEL (\x7f) too (full \x00-\x1f,\x7f), keeping
  non-ASCII/Unicode dirs valid.
- LOW: unbundle -ilc into -i -l -c for shell-getopt portability.
- LOW: validate $SHELL is absolute before exec; document the zsh fallback.
- LOW: trim existing PATH entries before dedup to avoid whitespace dupes.
- LOW: document the intentional append-after-system precedence + assert it
  in a test; note case-insensitive-FS dupes are an accepted no-op.
- CODBASH_DEBUG=1 logs skip/augment decisions for field diagnosis.
@vakovalskii

Copy link
Copy Markdown
Owner

Thanks for the thorough PR — the diagnosis is spot on: the desktop app spawns the server child inheriting the stripped GUI PATH (desktop/main.js), and agents-detect.js resolves CLIs by walking process.env.PATH, so Claude/Codex were being missed. Repairing PATH in bin/cli.js before detection is the right layer. I like that it's a true no-op from a terminal, opt-out-able (CODBASH_NO_PATH_REPAIR), and injection-free (args array, fixed script, no shell:true). Tests cover the tricky branches and pass against current main. LGTM — merging!

@vakovalskii
vakovalskii merged commit 7042cf8 into vakovalskii:main Jul 21, 2026
6 checks passed
vakovalskii added a commit that referenced this pull request Jul 21, 2026
…it (#265)

Ships #263 (repair stripped GUI PATH so agents are detected when launched
from Finder/Dock) and #264 (Kiro maxBuffer + ToolUse; robust Workspace
terminal fit for large/hi-DPI displays, #259).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants