Skip to content

fix(cli): switch copilot and amp providers to stdin prompt delivery - #76

Open
Caldalis wants to merge 2 commits into
onevcat:masterfrom
Caldalis:fix/copilot-amp-stdin-prompt
Open

fix(cli): switch copilot and amp providers to stdin prompt delivery#76
Caldalis wants to merge 2 commits into
onevcat:masterfrom
Caldalis:fix/copilot-amp-stdin-prompt

Conversation

@Caldalis

Copy link
Copy Markdown

copilot and amp were the last two CLI providers passing the prompt through argv (copilot -p "<prompt>", amp -x "<prompt>"). The prompt carries the full task context JSON and the output JSON schema — peer context alone can reach
60 KB — so it can exceed the OS per-argument limit (128 KB on Linux). Same class of failure as the opencode fix in #65.

Both CLIs accept the prompt on stdin, so this routes it there.

The two subtleties

copilot: -p has to be removed entirely, not emptied. Copilot resolves the prompt as opts.prompt ? opts.prompt : readStdin(), so any -p short-circuits the stdin path. Its own error text names both sources:

No prompt provided. Run in an interactive terminal or provide a prompt with
-p or via standard in.

amp: -x stays. It selects execute mode rather than being a prompt flag — bare -x reads the prompt from stdin. -x, --execute [message] takes an optional value, so I checked that it does not swallow the following --flag as its message (see verification below).

With that, no provider puts the prompt in argv, so usesStdinPrompt and the now-unused prompt parameter of buildBaseArgs are removed — the invariant is enforced by the signature instead of by convention.

Why the EPIPE fix is in this PR

Sending a large prompt to these two providers exposed a latent crash in runCommand. A CLI that exits before draining stdin — failing auth is the common case — makes the write fail with EPIPE, which Node raises as an 'error' event on child.stdin that is fatal when unhandled.

Empty stdin never opened that window, so copilot and amp were previously immune while the other seven providers were not:

stdin result
"" (copilot/amp before) clean rejection
10 KB clean rejection
200 KB (typical prompt) EPIPE crash
2 MB EPIPE crash

Without it, this PR would turn a clear No authentication information found into a process crash for any misconfigured copilot user. Ignoring the write error preserves the diagnostic from the close handler and turns a whole-run crash back into a single failed agent. It also fixes the pre-existing exposure for the other seven providers.

Happy to split this into its own commit or PR if you'd prefer — the only constraint is that it must not land after the stdin switch.

Tests

  • copilot and amp prompt-delivery tests now assert stdin rather than argv
  • new: walks every cliType derived from CliProviderSchema and fails if the task payload appears in argv, so a newly added provider has to decide its prompt delivery deliberately rather than inheriting a default
  • new: drives a CLI that exits without reading a 200 KB prompt and expects a clean rejection
    Both new tests were confirmed to fail when their fix is reverted — the argv one reports expected [ 'copilot' ] to deeply equal [], and the EPIPE one surfaces Unhandled Errors: write EPIPE with a non-zero exit.

Verification

Both CLIs were installed locally and probed directly:

  • amp — its own --help documents stdin prompts ("either as argument, or via stdin"); amp -x --definitely-not-a-flag still reports unknown option, proving -x does not consume the following --flag as its value; and --dangerously-allow-all passes argument parsing (it is accepted although not listed in --help).
  • copilot 1.0.81 — the prompt resolution shown above is from the shipped bundle; piped stdin with no -p was also confirmed to stay non-interactive and exit rather than opening a TUI.
  • 200 KB, 2 MB, and 450 KB CJK payloads round-trip through stdin/stdout intact.

Checks

npm run format:check, npm run lint, npm run ci, and npm run smoke:pack
all pass. 352 tests (+2).

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.

1 participant