MARSOHS-915 emit JSON ack on stdout for agents destroy/pause/resume/download/approve under -o json - #1909
Open
sdharavath wants to merge 1 commit into
Conversation
…ownload/approve under -o json These 5 commands have no resource body to render through the Displayable interface, so -o json left stdout completely empty on success (the human notice() sentence was already correctly on stderr, not stdout - verified against the unmodified binary). Empty stdout still breaks `-o json | jq .`-style consumption, just via "unexpected end of JSON input" rather than a parse error from leaked prose. Emit a minimal JSON acknowledgement object on stdout in json mode (session_id/status, or session_id/path/bytes_written for download, or session_id/request_id/outcome for approve) and skip the stderr notice in that mode. Text mode is unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MARSOHS-915: found during the black-box JSON-purity audit for MARSOHS-887/#1908. Initial diagnosis was that the shared
notice()helper (commands/errors.go) leaked a human-readable banner onto stdout for 5 commands that have no resource body to render through theDisplayableinterface —agents destroy,agents pause,agents resume,agents download,agents approve.That diagnosis was wrong and got corrected before this PR was opened (see the ticket comments):
commands/errors.gohas a package-wideinit()that redirectsnotice()'s writer toos.Stderrunconditionally, for every call site in the codebase,-o jsonor not:Verified directly against the unmodified binary + a mock API server:
doctl agents destroy <id> -o jsonalready hasstdout=""/stderr="Notice: Session <id> destroyed\n". Stdout was already clean — nothing was leaking.The real (smaller) gap: these 5 commands left stdout completely empty on success under
-o json, instead of emitting any document at all.doctl agents destroy <id> -o json | jq .still breaks (Unexpected end of JSON inputon empty stdin), just not for the reason originally suspected. This is inconsistent with every other-o jsoncommand inagents.go(list/get/create), which always emit a parseable document.Change
For
RunAgentsDestroy/RunAgentsPause/RunAgentsResume/RunAgentsDownload/RunAgentsApprove: emit a small JSON acknowledgement object on stdout whenOutput == "json", and skip the stderrnotice()sentence in that mode. Text mode is unchanged (notice() still fires on stderr as before).destroy/pause/resume→{"session_id": "...", "status": "destroyed|paused|resumed"}download→{"session_id": "...", "path": "...", "bytes_written": N}approve→{"session_id": "...", "request_id": "...", "outcome": "HITL_OUTCOME_APPROVE|..."}Test plan
gofmt -l commands/agents.go commands/agents_test.go— cleango vet ./commands/...— cleango test ./commands/... -run Agent— all pass, including 5 new_JSONModeregression tests (destroy/pause/resume/approve/download) assertingjson.Valid, absence of"Notice", and the exact JSON shapeagents destroy -o json→ clean JSON ack on stdout, empty stderragents pause -o json→ clean JSON ack on stdout, empty stderragents destroy(text mode) → notice still on stderr, as before (no regression)Full audit trail (including the self-correction) posted on MARSOHS-915.
Made with Cursor
Made with Cursor