fix(cli): write an artifact --out path exactly as given
AS
8h ago+318+318+012345678901234567890123456789-116-116-012345678901234567890123456789
Why
Artifact commands (image, audio and video outputs) chose the file extension from the returned MIME type and changed the caller's --out path to match:
--out photo.pngwith a JPEG response wrotephoto.jpg. A script that then openedphoto.pngfound nothing. In agent mode nothing said so: the only signal was a differentpathin the result.- Any dot suffix counted as an extension, so
--out render.v1wroterender.pngand lost the.v1.
--out is the caller's choice of destination, so the CLI should write there.
What changed
artifact.go.stmpl:- An explicit
--outfile path that ends in a recognized media extension (png,jpg,wav,mp4, …) is written exactly as given, even if the returned MIME type implies another extension. - A mismatch is reported instead of corrected. Human output gets one stderr line,
Note: photo.png contains image/jpeg content; its extension does not match. The result envelope getsextension_mismatch: true, so machine modes keep stderr silent and still get a signal. - A path without a recognized media extension still gets the returned extension appended:
photo→photo.jpg, andrender.v1→render.v1.png(the suffix is kept). - Unchanged: matching extensions,
--outpointing at a directory, and the default file name.
- An explicit
artifact_test.go.stmpl: the rename test is nowTestArtifact_OutKeepsRequestedExtension. The agent-mode test checks the path is kept, stderr is silent and the envelope carriesextension_mismatch. The append test coversphoto,photo.v1andrelease-1.2.- CLI README updated; review CLI SDK regenerated.
This changes documented behavior for a mismatched --out extension. Callers that read the result's path are unaffected; only a caller relying on the renamed file sees a difference.
Testing
TARGET=review make build-cli, then inzSDKs/sdk-cli:go test ./tests/ -run 'TestArtifact|TestAsync',go test ./internal/...,go vet ./internal/output/: pass.make lint: pass.- Not run: the full primary CLI suite.
Public-safety check
- This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
- Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (
.claude/skills/public-repo-communication/SKILL.md). - Generated fixtures and review SDK changes are public-safe.
- I reviewed
git diff --check.