fix: inline --json-schema file paths so structured output works on CLI 2.1.160 (#3) #4
Reference in New Issue
Block a user
Delete Branch "fix/json-schema-inline-file"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #3.
Problem
The README,
examples/gitea-structured-output.yml, and theclaude_argsinput description all present the file-path form
--json-schema /path/to/schema.jsonas the primary way to getschema-validated output. But the CLI this action installs by default
(2.1.160) only accepts an inline JSON schema string — a file path makes
the CLI exit 0 with empty output. The action then finds no
structured_outputand hits its fail-loud branch, so a consumer who follows the documented recipe
gets a step that fails closed on every run, with no useful diagnostic.
Fix
This implements the issue's proposed solution #2 (auto-inline the file),
plus the doc clarification from #1. I chose #2 because it dominates the
alternatives:
reintroducing the exact shell
$-expansion hazard the file-path form existsto avoid for schemas with
$ref/$defs.consumer.
prepareRunConfignow resolves each--json-schemavalue (both--json-schema <v>and--json-schema=<v>) before spawning the CLI:{/[) is leftexactly as supplied.
compact JSON string. Because the value reaches the CLI as an argv element
(never through a shell), a schema containing
$ref/$defsround-tripsintact — and it works on any CLI, including the default 2.1.160.
instead of the CLI's silent empty output.
Docs (README structured-output notes, the example workflow, and the
action.ymlclaude_argsdescription) are corrected to explain the file-pathform is auto-inlined and works on the default CLI. The narrowed CLI-version
caveat is kept (a pinned/pre-baked CLI must still support the
--json-schemaflag itself).
Tests
Added an
inlineJsonSchemaArgssuite (real temp files): inline passthrough,file-path inlining for the space and equals forms, the
$ref/$defsfromfile round-trips intact case, missing-file and invalid-JSON error paths, plus
an end-to-end
prepareRunConfigtest.bun testonrun-claude.test.ts:45 pass / 0 fail.
tsc --noEmitclean (base-action + root).If you'd actually prefer solution #1 or #3 instead, happy to redirect.