Skip to content

autopilot --install generates broken wrapper: execPath resolves to bun runtime, not gbrain CLI #136

@notjbg

Description

@notjbg

Summary

gbrain autopilot --install generates ~/.gbrain/autopilot-run.sh that cannot execute. The daemon is installed as a launchd service but immediately fails with error: Script not found "autopilot" on every invocation.

Environment

  • macOS
  • gbrain 0.10.1 (installed via git clone + bun install)
  • bun 1.3.12

Repro

gbrain autopilot --install --repo ~/brain
# ...claims success...
tail ~/.gbrain/autopilot.err
# error: Script not found "autopilot"
# error: Script not found "autopilot"
# ...

The launchd service keeps respawning because KeepAlive=true while the wrapper script exits non-zero immediately.

Root cause

src/commands/autopilot.ts:180:

const gbrainPath = process.execPath;

When gbrain is invoked via a bun-managed symlink (e.g. ~/.bun/bin/gbrain → ../install/global/node_modules/gbrain/src/cli.ts), process.execPath is the bun runtime binary (/Users/me/.bun/bin/bun), not the gbrain CLI. The generated script becomes:

exec '/Users/me/.bun/bin/bun' autopilot --repo '/Users/me/brain'

...which tells bun to look for a script/package called autopilot, which doesn't exist → error: Script not found "autopilot".

Fix I applied locally

Edited ~/.gbrain/autopilot-run.sh manually to use the gbrain bin symlink:

# before
exec '/Users/me/.bun/bin/bun' autopilot --repo '/Users/me/brain'
# after
exec '/Users/me/.bun/bin/gbrain' autopilot --repo '/Users/me/brain'

Working correctly since.

Suggested fix

Change the installer to locate the gbrain CLI deterministically. A few options:

  1. Use process.argv[1] (the entry script), then shebang-resolve back to the bin wrapper — hacky.
  2. Resolve which gbrain at install time and use that path. Simple, platform-agnostic.
  3. Prefer $HOME/.bun/bin/gbrain when the running process is bun and that file exists; fall back to process.execPath otherwise.
  4. Emit gbrain bare in the wrapper and let source ~/.zshrc put it on PATH — already done via the shell profile sourcing above, so this is the cleanest IMO:
- exec '${safeGbrainPath}' autopilot --repo '${safeRepoPath}'
+ exec gbrain autopilot --repo '${safeRepoPath}'

Since the wrapper already sources ~/.zshrc / ~/.bashrc above the exec, PATH will include ~/.bun/bin. This is robust to install-path changes and bun-vs-node runtimes.

Notes

  • Affects any install where gbrain is resolved through bun's global bin symlink — which is the documented install path (bun install && bun link).
  • KeepAlive=true on the plist means the failure is silent unless the user checks ~/.gbrain/autopilot.err.
  • Consider adding an install-time smoke test: generate the wrapper, run it with --help (or a --noop flag), verify exit 0 before returning success.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions