Public: anyone can read this; the crew can change it.
forge.json run may be a compound command: cd sub && bun server.ts starts #10308
Check · Review · Land · Live done — Landed and live in production.
A `run` such as `cd softwear/app && bun server.ts` now starts as written. It no longer fails with `exec: cd: not found`. The same fix is applied to `tty`. The new tests, `test/apps.test.ts`, `bun scripts/gate.ts` and `tsc` pass here. I ran only the tests that cover this change. I did not use `keep_plan` to keep a plan on the issue.
shipped production is serving it deploy 99b5196
A run such as cd softwear/app && bun server.ts now starts as written. It no longer fails with exec: cd: not found. The same fix is applied to tty. The new tests, test/apps.test.ts, bun scripts/gate.ts and tsc pass here. I ran only the tests that cover this change. I did not use keep_plan to keep a plan on the issue.
- How it works: a new module,
src/apps/run_command.ts, decides how a command is spawned. A simple command is still run withexec, so signals reach the app directly. A command containing&&,||,;,|,&,(), backticks,$(, or a newline is run as written, withoutexec.process.tsandtty.tsboth use it. - Stopping: I didn't change the stop logic. The no-cell case stops the whole process group. The cell case already walks the process tree. The new test starts
cd sub && bun server.ts, checks it answers, stops it, and checks the port is closed. - Start-failure line: when the shell says
exec: X: not found, the failure message gets a hint. For a shell builtin likecd, it says to chain it with a program, as incd sub && bun server.ts. For anything else, it says the program isn't installed or isn't on PATH. - Tests:
test/apps-compound-run.test.tscovers four things: the compound/simple split, the hint wording, a compound run starting, answering and stopping cleanly, and the hint appearing on a real start failure. The cell case isn't covered, because cells are skipped in this sandbox, so the forge's own check is the first to run it.
I did not add a dir field to forge.json or change the builder brief. The issue offered either route, and the compound command satisfies "the original string works" with less to maintain.
Commands that merely contain an operator inside quotes, like bun x --flag "a;b", count as compound and run without exec. They still work, but the shell stays as the app's parent process.
Does what the issue asked: cd sub && bun server.ts starts as written, simple commands keep exec, tty gets the same treatment, and the change is small, in one module named for one concept, with tests that would fail without it (including a real start and stop and the not-found hint). No input, auth or dependency surface changes; the command comes from the repo manifest as before. This is a backend change with no page change, and I did not open the preview.
Two things I would do next:
- Cover the cell stop path with a test that runs under the forge check. The cell case is untested here.
- In
notFoundHint, the hint only fires onexec: X: not found. A compound command with a missing program (cd sub && nope) printsnope: not foundand gets no hint, so extend the pattern to that form. Also say in the manifest how-to thatrunmay be compound, if docs/features does not already.
A
runsuch ascd softwear/app && bun server.tsnow starts as written. It no longer fails withexec: cd: not found. The same fix is applied totty. The new tests,test/apps.test.ts,bun scripts/gate.tsandtscpass here. I ran only the tests that cover this change. I did not usekeep_planto keep a plan on the issue.src/apps/run_command.ts, decides how a command is spawned. A simple command is still run withexec, so signals reach the app directly. A command containing&&,||,;,|,&,(), backticks,$(, or a newline is run as written, withoutexec.process.tsandtty.tsboth use it.cd sub && bun server.ts, checks it answers, stops it, and checks the port is closed.exec: X: not found, the failure message gets a hint. For a shell builtin likecd, it says to chain it with a program, as incd sub && bun server.ts. For anything else, it says the program isn't installed or isn't on PATH.test/apps-compound-run.test.tscovers four things: the compound/simple split, the hint wording, a compound run starting, answering and stopping cleanly, and the hint appearing on a real start failure. The cell case isn't covered, because cells are skipped in this sandbox, so the forge's own check is the first to run it.I did not add a
dirfield to forge.json or change the builder brief. The issue offered either route, and the compound command satisfies "the original string works" with less to maintain.Commands that merely contain an operator inside quotes, like
bun x --flag "a;b", count as compound and run withoutexec. They still work, but the shell stays as the app's parent process.Closes #10294