feat(flow): stream run progress as NDJSON - #855
Conversation
…nd keep export errors propagating
hubgan
left a comment
There was a problem hiding this comment.
Thank you for this contribution. The new --json-stream flag fills a real gap. --json writes nothing until the run stops, so a program could not read step data while a run is in progress.
I tested the flag against a real iOS simulator with a local tool-server. The records stay valid JSON on stdout in each condition that I tested, and the envelope agrees with the NDJSON format of the tool-server.
I found two possible problems with the new flag. Both comments are on the lines below.
| const onStepReport = (event: unknown): void => { | ||
| const s = event as StepReport; | ||
| if (args.jsonStream) { | ||
| writeJsonStreamRecord({ event: "progress", data: s }); |
There was a problem hiding this comment.
This record contains the step report before the artifact fields get their final form.
exportAndResolveArtifacts changes each artifact to a path string. It operates only on the final report at line 1558. As a result, artifacts.current is an object in this record and a string in the result record. A program cannot use one accessor for the field.
The object also contains a hostPath. This path points to the temporary cache of the tool-server. If the user gives --output, only the result record contains the durable copy. A program that acts on the progress records can get a path to a file that the server deletes.
The comment at line 1088 says that every output mode must show the durable location. renderArtifactLines keeps only string values for the same reason.
One snapshot step on an iOS simulator gives these two values:
progress artifacts.current -> object /var/folders/.../simserver-nHC8GF/media/99374000-....png
result artifacts.current -> string /.../out/snap/home__ios-1206x2622-current.png
| // --output copies are fetched, below. | ||
| report = resp.data as FlowReport; | ||
| } catch (err) { | ||
| if (args.jsonStream) writeJsonStreamError(err); |
There was a problem hiding this comment.
The error record covers three failures only. They are this failure, the invalid report at line 1552, and the artifact export failure at line 1565.
Thirteen other failures write text to stderr and write no record. They are at lines 1263, 1272, 1317, 1334, 1340, 1351, 1384, 1416, 1424, 1432, 1452, 1497 and 1500. A wrong subcommand at line 1243 does the same.
These failures include a wrong flow name, a missing file, a directory path, a bad file extension, and the refusal of remote routing. The combination of --json and --json-stream also does this.
A program that reads the NDJSON output sees an empty stream for these failures. The program must read the text on stderr to find the cause.
Reconciles the branch's NDJSON streaming draft with the version that landed as software-mansion#855: requireLocalToolServer now returns the refusal (with the external registry hint appended) and the --tool-registry pre-flight errors go through fail() so --json-stream emits a structured error event.
Bumps every workspace package, `package-lock.json`, and both `server.json` version fields from 0.21.0 to 0.22.0 (18 files). Lockfile regenerated on Node 24 / npm 11 so the diff is version-only; `npm run check:versions` passes. Covers everything on main since `v0.21.0`: `paste` tool (#879), rotation-aware Android capture (#693), 0.25 default screenshot scale (#878), no-reboot describe on externally booted sims (#583/#877), NDJSON flow progress (#855), OTLP telemetry (#570), native-devtools restart_required derivation (#560), Android profiler empty-CPU explanation (#669), plus test/CI fixes. Full-surface live QA of this main (tgz vs npm 0.21.0) on iOS, Android, tvOS, Electron, CLI and Linux/remote found zero regressions. Two release notes: the published artifact must be built with `ARGENT_OTEL_INGEST_TOKEN` set (a local tgz without it compiles `readIngestToken()` to an empty string, making telemetry a silent no-op), and remember to push the `v0.22.0` git tag so online `init` skills installs resolve. No docs update needed: version-only change.
Summary
argent flow run --json-streamWhy
--jsonprints only after a flow finishes.--json-streamlets scripts and CI see live progress.Why this is a separate PR
This is useful without the custom-tools feature in #856.
Validation
npm test -w @argent/cli -- flow.test.ts— 106 tests passednpm run typecheck:tests -w @argent/clinpm run build -w @argent/cli