Skip to content

Agent and non-interactive mode: --no-input, --json everywhere, exit codes - #37

Open
Interlap01 wants to merge 8 commits into
mainfrom
agent-mode
Open

Interlap01 wants to merge 8 commits into
mainfrom
agent-mode

Conversation

@Interlap01

Copy link
Copy Markdown
Collaborator

What

Agent / non-interactive mode across the CLI.

  • Exit codes in one place (internal/exitcode): 0 ok, 1 failure, 2 usage, 3 auth, 4 CI run failed, 5 timeout, 130 interrupted. Errors are tagged where they arise (exitcode.With, or an ExitCode() method on github.RunFailedError, github.APIError/asc.Error for 401). Cobra flag/argument errors and unknown subcommands of a group (builder ios nope, which used to print help and exit 0) exit 2.
  • No hidden prompts: global --no-input (also BUILDER_NO_INPUT=1, CI=true, or --json). Every question goes through one helper. With --yes it takes the default. In a terminal it prompts. Otherwise it fails at once with exit 2 and names the flag to pass.
    • init: --project, --ios-path, --flutter-version, --jdk-version, --commit, --build, --yes. --yes takes the detected values but never commits or builds. Missing answers fail before any file is written.
    • signing csr / p12 / setup (manual mode): flags named. csr --yes replaces an existing key.
    • dev flutter|rn|kmp: --device or --yes (first device), --resign/--apple-id with BUILDER_APPLE_ID_PASSWORD, --bundle-id. Without a terminal it takes the newest IPA.
    • auth codemagic|bitrise|apple fail fast off a terminal.
  • auth github --token-stdin checks the token with GET /user. A classic token missing repo, workflow or gist is refused (exit 3, not saved, missing scopes named). Fine-grained tokens report no scopes, so they are saved without the check. Off a terminal, the browser flow needs --device-flow.
  • --json on auth github|status|logout|apple|codemagic|bitrise, init, ios build (build ID, IPA path/size, run URL, duration; progress on stderr), ios share, ios cancel, signing csr|p12|setup --certificate, mobai ping|install|forward. dev * prints NDJSON session events (device, installed, launched, vm_service/metro) on stdout, and everything else goes to stderr.
  • Docs: README section "Using Builder from agents and CI" (flags per command, JSON shapes, exit-code table). CLAUDE.md patterns updated.

Why

Cloud coding agents and CI drive Builder without a TTY. Before this change, init and the dev sessions could hang on promptui, auth github had no token path, and every failure exited 1.

How tested

  • go test -race ./... and golangci-lint v2.12.2 (the CI version): clean.
  • New tests run each command that used to prompt with stdin not a terminal and a 10s guard against blocking: init, signing csr|p12|setup, auth github|codemagic|apple, dev --skip-install. They also cover the --no-input/BUILDER_NO_INPUT/CI switches with a terminal, the dev device/re-sign/IPA choices against a fake MobAI, auth github --token-stdin with stubbed GitHub checks (plus an httptest test of the scope parsing), JSON shapes (ios build, ios share, init, mobai ping), and exit-code mapping on a test tree and the real command tree.
  • No live runs against GitHub, CI providers or devices.

Left out

  • update and mobai run-debug have no --json: update prints one line, and run-debug streams app output.
  • Failures go to stderr as Error: .... There is no JSON error object on stdout; the exit code carries the category.
  • No GH_TOKEN environment fallback for the stored GitHub login. Pipe it with --token-stdin instead.
  • ios build on GitHub still installs no signal handler, so Ctrl-C ends the process by signal (shells report 130).

…d usage errors

0 ok, 1 failure, 2 usage, 3 auth missing or rejected, 4 CI run failed,
5 timeout, 130 interrupted. Errors are tagged where they arise
(exitcode.With, or an ExitCode method on github/asc error types) and
main maps them; cobra's flag and argument errors and an unknown
subcommand of a group exit 2.
A global --no-input (also BUILDER_NO_INPUT=1, CI=true, or --json) turns
every prompt off. Each question then takes its default with --yes or
fails with exit 2 naming the flag that answers it. signing csr, p12 and
setup (both modes) go through it; csr gains --yes for replacing an
existing key and --json, p12 and manual setup gain --json.
…ommand

auth github --token-stdin validates the token against GET /user and
refuses one whose X-OAuth-Scopes lacks repo, workflow or gist (exit 3,
nothing saved); fine-grained tokens report no scopes and are saved
unchecked. Without a terminal the browser flow needs --device-flow,
which prints the code (as a JSON line with --json) and waits.
auth codemagic/bitrise/apple fail fast with exit 2 off a terminal,
and status, logout, apple and the provider logins take --json.
init asks through the shared asker: --project, --ios-path,
--flutter-version and --jdk-version answer the questions, --commit and
--build the two confirmations, and --yes takes every detected value
(without committing or building). Off a terminal a missing answer fails
with exit 2 before any file is written. ios build --json prints build
ID, IPA path and size, run URL and duration, with progress on stderr;
ios share, ios cancel and the provider init print their results too.
The device, IPA, re-sign and bundle ID questions take --device, --ipa,
--resign/--apple-id (password from BUILDER_APPLE_ID_PASSWORD) and
--bundle-id. Without a terminal the IPA is the newest, re-signing is
off, the bundle ID is MobAI's or the IPA's, and several devices need
--device or --yes (exit 2 otherwise). --json prints device, installed,
launched and vm_service/metro events as JSON lines on stdout and sends
all other output, flutter attach and Metro included, to stderr.
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