Skip to content

feat: agent-guide for AI agents and scripts; machine-readable output and exit-code fixes - #177

Open
omattsson wants to merge 4 commits into
mainfrom
feat/agent-guide
Open

omattsson wants to merge 4 commits into
mainfrom
feat/agent-guide

Conversation

@omattsson

Copy link
Copy Markdown
Owner

Summary

Adds stackctl agent-guide, a Markdown guide for AI agents and scripts that is built into the binary. While writing the guide, three behaviours turned up that would mislead an agent or a script. This PR fixes them.

New: stackctl agent-guide

  • Prints cli/cmd/agent_guide.md (embedded with go:embed; {{VERSION}} becomes the build version). It works without a config, like version.
  • The guide covers: machine-readable output, -q, exit codes, authentication without a prompt, confirmations, --dry-run limits, waiting for long-running operations, errors, and common tasks.
  • stackctl --help points to it; the README has a section "Use with AI agents and scripts".
  • TestAgentGuide_CommandsExist checks every stackctl … invocation in the guide against the command tree: subcommands, flags and the number of positional arguments.

Fixes

  • A declined confirmation exits 1 (was: Aborted. on stdout, exit 0). The message is now aborted: not confirmed, nothing changed on stderr. confirmAction returns errAborted itself, which removes 17 copies of the check.
  • --follow after a normal server close (code 1000, for example a restart): it reads the instance. A final status counts as before; otherwise it exits 1 and says that the operation continues on the server (was: exit 0).
  • stdout holds only data with -o json, -o yaml and -q. Printer.MachineReadable() sends PrintMessage text to Printer.ErrWriter (stderr). The table format and custom formats are unchanged.
    • stack deploy, stop, clean and rollback print the 202 response (log_id, message) with -o json|yaml and the log ID with -q (printOperation).
    • With --follow in those modes, the log goes to stderr and stdout gets the instance after the operation (-q: the log ID). stack logs -f prints the log as it does without --follow.
    • cluster shared-values list and config list print [] for an empty list.
  • Refactor: config-free commands are marked with an annotation (skipsConfig) instead of matched by name.

Behaviour changes for scripts

  • A declined prompt now exits 1 (was 0).
  • With -o json, -o yaml or -q, messages such as Deleted stack …, --dry-run text and Aborted. moved from stdout to stderr.
  • stack deploy|stop|clean -o json|yaml print JSON or YAML instead of a text line.
  • --follow with -o json|yaml|-q writes the log to stderr instead of stdout.

Not changed (documented in the guide)

  • bulk commands exit 0 even when some items fail (check failed in -o json).
  • Ctrl-C during --follow exits 0.

Test plan

  • make test: all packages pass, including e2e and integration
  • make lint (go vet, staticcheck)
  • New tests: guide drift (verified it catches a wrong subcommand, flag and argument count), output modes of deploy/stop/clean/rollback, --follow -o json|yaml|-q, stack logs -f -o json, --dry-run in json and quiet mode, empty lists as [], normal close during --follow, the e2e exit code of a declined prompt, MachineReadable, skipsConfig
  • Ran the built binary: agent-guide with a missing config; stack delete --dry-run -o json (stdout empty, message on stderr)

🤖 Generated with Claude Code

omattsson and others added 4 commits October 27, 2026 21:15
`stackctl agent-guide` prints a Markdown guide for agents and scripts:
machine-readable output and where it is not JSON, -q IDs, exit codes,
authentication without a prompt, confirmations (Aborted. exits 0,
< /dev/null), --dry-run limits, waiting for long-running operations and
checking the status after --follow, and common tasks. The guide is
embedded in the binary, so it matches the installed version, and the
command works without a config. `stackctl --help` points to it.

TestAgentGuide_CommandsExist checks every stackctl invocation in the
guide against the command tree and the flags of each command.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atus

A normal WebSocket close (code 1000, for example on a server restart)
ended `--follow` with status "unknown" and exit code 0, although the
operation was still running. After such a close, --follow now reads the
instance: a final status counts (error and partial still exit 1), else
it exits 1 and says that the operation continues on the server.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A declined confirmation prompt printed "Aborted." to stdout and exited 0,
so a script could not tell a declined delete from a done one. It now
returns errAborted: exit code 1 and "aborted: not confirmed, nothing
changed" on stderr. This covers every command with a confirmation
(confirmAction), including bulk, override, chart and action commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Messages for people (PrintMessage: "Deleted ...", --dry-run text,
"Deploying stack ...") went to stdout in every mode, so `-o json | jq`
and `$(... -q)` got text. Printer.MachineReadable() (-o json|yaml, -q)
now sends them to Printer.ErrWriter (stderr); the table format and
custom formats keep them on stdout.

- stack deploy, stop, clean and rollback share printOperation: -o
  json|yaml prints the 202 response (log_id, message), -q the log ID.
  With --follow in those modes the log goes to stderr and stdout gets
  the instance after the operation (-q: the log ID). `stack logs -f`
  prints the log as without --follow. followHelp describes it.
- cluster shared-values list and config list print [] for an empty
  list with -o json|yaml instead of a message.
- confirmAction returns errAborted itself (callers only pass the error
  on), and the skip-config check uses an annotation (skipsConfig)
  instead of command names.
- agent-guide: rules for the new output, login needs a context, bulk
  commands exit 0 with failed items, draft after a clean, quick-deploy
  and bulk are asynchronous, SIGINT exits 0, no fixed --stop-at date.
  The guide test now also checks positional argument counts and quoted
  arguments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 27, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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