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:
- Use
process.argv[1] (the entry script), then shebang-resolve back to the bin wrapper — hacky.
- Resolve
which gbrain at install time and use that path. Simple, platform-agnostic.
- Prefer
$HOME/.bun/bin/gbrain when the running process is bun and that file exists; fall back to process.execPath otherwise.
- 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.
Summary
gbrain autopilot --installgenerates~/.gbrain/autopilot-run.shthat cannot execute. The daemon is installed as a launchd service but immediately fails witherror: Script not found "autopilot"on every invocation.Environment
git clone+bun install)Repro
The launchd service keeps respawning because
KeepAlive=truewhile the wrapper script exits non-zero immediately.Root cause
src/commands/autopilot.ts:180:When
gbrainis invoked via a bun-managed symlink (e.g.~/.bun/bin/gbrain → ../install/global/node_modules/gbrain/src/cli.ts),process.execPathis the bun runtime binary (/Users/me/.bun/bin/bun), not the gbrain CLI. The generated script becomes:...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.shmanually to use the gbrain bin symlink:Working correctly since.
Suggested fix
Change the installer to locate the gbrain CLI deterministically. A few options:
process.argv[1](the entry script), then shebang-resolve back to the bin wrapper — hacky.which gbrainat install time and use that path. Simple, platform-agnostic.$HOME/.bun/bin/gbrainwhen the running process is bun and that file exists; fall back toprocess.execPathotherwise.gbrainbare in the wrapper and letsource ~/.zshrcput it on PATH — already done via the shell profile sourcing above, so this is the cleanest IMO:Since the wrapper already sources
~/.zshrc/~/.bashrcabove theexec, PATH will include~/.bun/bin. This is robust to install-path changes and bun-vs-node runtimes.Notes
gbrainis resolved through bun's global bin symlink — which is the documented install path (bun install && bun link).KeepAlive=trueon the plist means the failure is silent unless the user checks~/.gbrain/autopilot.err.--help(or a--noopflag), verify exit 0 before returning success.