Skip to content

fix(#1938): add the builds read path, and stop flags from eating positionals - #4

Merged
ryanlitalien merged 1 commit into
mainfrom
fix/1938-builds-read-path
Sep 18, 2026
Merged

ryanlitalien merged 1 commit into
mainfrom
fix/1938-builds-read-path

Conversation

@ryanlitalien

Copy link
Copy Markdown
Member

Client side of ButterStack/butter_stack#1938. The server side is ButterStack/butter_stack#1942; this PR degrades gracefully against a server that does not have it yet, so the two can land in either order.

Does not close #1938 on its own - that issue also covers the API and MCP work in the other PR.

Three defects, all of which made data look absent rather than unreachable

butter builds show <id> printed nothing and exited 0. The subcommand was never wired into the dispatcher, so it fell through the switch and out of main(). An exit 0 with no output reads as "this build has no data", which is why it was filed as a backend problem - the endpoint existed and worked the whole time. Unknown subcommands now fail loudly instead of returning 0.

butter builds investigate --json <id> appeared to print nothing while the plain form rendered fine. parseArgs treated every --flag as taking a value whenever the next argv entry did not start with -, so --json before a positional parsed as json: "<build id>" and left no build id behind; the command printed its usage error and exited 1. Position in the command line must not change what a boolean flag means, so switches are now declared explicitly, and --key=value is honored for any key.

There was no GET counterpart to investigate. Checking whether an investigation had finished meant POSTing again, and each POST is a paid AI call. butter builds investigation <id> reads the result for free, builds show embeds it, and investigate now points at the read path rather than letting callers poll by re-POSTing.

Two smaller things

builds show distinguishes three cases a single falsy check used to collapse: an investigation exists, none has been run, and the server predates the read path. Reporting an old server as "no investigation" is the exact false negative that sent people back to POSTing to find out.

Attribution prints unattributed when the investigation made none, rather than omitting the line. A failure caused by a file that was never submitted has no offending changelist and no culpable author, and that is a real answer worth showing.

Verification

14 tests, 0 failures (8 new). The new cases drive the real binary against a throwaway listener and assert on the HTTP method, so "reading a result must not be a POST" is pinned rather than assumed.

builds show and --json in either position were also confirmed against production, since both fixes are client-side.

Version

Bumped to 0.2.0 - four new behaviours, no breaking changes. The publish workflow requires the tag to match package.json, so tag v0.2.0 after merge.

🤖 Generated with Claude Code

…tionals

Three defects, all of which made a build's data look absent rather than
unreachable.

`butter builds show <id>` printed nothing and exited 0. The subcommand was
never wired into the dispatcher, so it fell through the switch and out of
main(). An exit 0 with no output reads as "this build has no data", which is
why it was reported as a backend problem - the endpoint existed and worked
the whole time. Unknown subcommands now fail loudly instead of returning 0.

`butter builds investigate --json <id>` appeared to print nothing while the
plain form rendered fine. parseArgs treated every `--flag` as taking a value
whenever the next argv entry did not start with `-`, so `--json` before a
positional parsed as `json: "<build id>"` and left no build id behind; the
command printed its usage error and exited 1. Position in the command line
must not change what a boolean flag means, so switches are now declared, and
`--key=value` is honored for any key.

There was no GET counterpart to `investigate`. Checking whether an
investigation had finished meant POSTing again, and each POST is a paid AI
call. `butter builds investigation <id>` reads the result for free, `builds
show` embeds it, and `investigate` now points at the read path rather than
letting callers poll by re-POSTing.

`builds show` also distinguishes three cases a single falsy check used to
collapse: an investigation exists, none has been run, and the server predates
the read path. Reporting an old server as "no investigation" is the exact
false negative that sent people back to POSTing to find out.

Attribution prints "unattributed" when the investigation made none, rather
than omitting the line. A failure caused by a file that was never submitted
has no offending changelist and no culpable author, and that is a real answer.

Minor version: four new behaviours, no breaking changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ryanlitalien
ryanlitalien merged commit 92a09f9 into main Sep 18, 2026
1 check passed
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