llm-cli-gateway 1.13.0 → 1.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,93 @@
2
2
 
3
3
  All notable changes to the llm-cli-gateway project.
4
4
 
5
+ ## [1.13.2] - 2026-05-27 — Claude stream-json regression fix (--verbose now required)
6
+
7
+ Patch release. Single user-facing fix to `claude_request` /
8
+ `claude_request_async` when called with `outputFormat: "stream-json"`.
9
+
10
+ ### Fixed
11
+
12
+ - Claude CLI 2.x rejects `--print --output-format=stream-json` without
13
+ `--verbose` ("When using --print, --output-format=stream-json requires
14
+ --verbose"). The gateway was emitting `--output-format stream-json
15
+ --include-partial-messages` without `--verbose`, so every claude
16
+ request configured for stream-json (sync or async) was exiting 1.
17
+ - `prepareClaudeRequest` now pushes `--verbose` as part of the
18
+ stream-json arg group. `--verbose` only affects what claude writes to
19
+ stderr; the stream-json stdout payload is unchanged, so the existing
20
+ NDJSON parser in `src/stream-json-parser.ts` needs no changes.
21
+ - This was the practical reason the flight recorder's
22
+ `cache_read_tokens` / `cache_creation_tokens` columns stayed NULL for
23
+ claude rows — token capture is gated on a successful stream-json run.
24
+ With this fix, callers who opt into `outputFormat: "stream-json"` get
25
+ Anthropic cache_read_input_tokens / cache_creation_input_tokens
26
+ recorded in the FR for the first time since the CLI started enforcing
27
+ `--verbose`.
28
+ - Direct CLI verification: `claude -p ... --output-format stream-json
29
+ --verbose --include-partial-messages` returned a clean NDJSON stream
30
+ with `cache_read_input_tokens: 17978` and
31
+ `cache_creation_input_tokens: 17435` on a 1-hour-cache-enabled
32
+ account. The parser path is correct; only the missing flag was
33
+ blocking it.
34
+
35
+ ### Tests
36
+
37
+ - New regression: `prepareClaudeRequest` emits `--verbose` when
38
+ `outputFormat: "stream-json"` and does NOT emit it for `text` / `json`
39
+ (src/__tests__/claude-handler.test.ts).
40
+ - Updated `upstream-contracts.test.ts` "accepts a valid Claude argv
41
+ emitted by the gateway" to pin the three-flag combo so a future
42
+ removal of `--verbose` fails at the contract gate.
43
+ - New conformance fixture `claude-stream-json-requires-verbose` in
44
+ `src/upstream-contracts.ts` registering `--verbose` and asserting the
45
+ combo is accepted.
46
+ - 886 tests pass (884 prior + 2 new). Build clean.
47
+
48
+ ### Why a patch release
49
+
50
+ The regression silently broke a documented MCP API surface; users
51
+ explicitly opting into stream-json (for token observability or
52
+ upcoming cache_control work in slice κ) were getting exit-1 errors
53
+ with no obvious gateway-side cause. Same shape as v1.13.1 (single
54
+ focused fix, no behaviour change for callers using `text` / `json`).
55
+
56
+ ## [1.13.1] - 2026-05-27 — Installer Windows build fix (no code changes)
57
+
58
+ Patch release. **No changes to the gateway, MCP tools, or any provider
59
+ wiring.** npm + PyPI 1.13.1 packages are functionally identical to 1.13.0.
60
+
61
+ ### Fixed
62
+
63
+ - `installer/build-release.sh` registered a function-scoped EXIT trap
64
+ that referenced a `local` variable (`staging`). When something inside
65
+ the function failed, `set -e` + `set -u` made the trap die with
66
+ `staging: unbound variable` AFTER the function had already returned
67
+ and its locals had gone out of scope — masking the real failure.
68
+ - This first surfaced on the v1.13.0 release-installer.yml Windows job
69
+ when GitHub started redirecting `windows-latest` to the new
70
+ `windows-2025-vs2026` image (rollout completes 2026-06-15). Linux
71
+ and both macOS targets still built clean.
72
+ - The fix lifts the staging path to a script-level `RVWR_STAGING_DIR`
73
+ variable, registers a single idempotent `cleanup_staging` helper
74
+ with `|| true` so the EXIT trap can't fail itself under `set -e`,
75
+ and defensively cleans up between iterations of the
76
+ `for target in TARGETS` loop.
77
+ - Smoke-tested locally on linux/amd64 (`npm ci` + `cp -R` + `tar` ran
78
+ clean; bundle produced; staging dir cleaned up). Once this reaches
79
+ the new tag, release-installer.yml either succeeds (the trap bug
80
+ WAS the whole problem) or fails with a clearer message we can
81
+ chase as a follow-up patch.
82
+
83
+ ### Why a patch release for an installer-only fix
84
+
85
+ The `release-installer.yml` workflow checks out the tag it builds for
86
+ (`needs.resolve-tag.outputs.tag`) and re-running it against the
87
+ existing `v1.13.0` tag would pick up the broken script. A new tag is
88
+ the simplest way to get the fix onto CI without force-pushing
89
+ `v1.13.0`. npm + PyPI 1.13.1 are republished as a side-effect; this
90
+ matches the precedent of `v1.6.1` (docs-only follow-up to 1.6.0).
91
+
5
92
  ## [1.13.0] - 2026-05-27 — Phase 4 slice θ (Grok HIGH parity)
6
93
 
7
94
  Ships the eighth Phase 4 slice: five HIGH-impact Grok CLI flags are now
package/dist/index.js CHANGED
@@ -957,7 +957,12 @@ export function prepareClaudeRequest(params, runtime = resolveGatewayServerRunti
957
957
  args.push("--output-format", "json");
958
958
  }
959
959
  else if (params.outputFormat === "stream-json") {
960
- args.push("--output-format", "stream-json", "--include-partial-messages");
960
+ // Claude CLI 2.x rejects `--print --output-format stream-json` without
961
+ // `--verbose`: "When using --print, --output-format=stream-json requires
962
+ // --verbose". --verbose only affects what claude logs to stderr; the
963
+ // stream-json stdout payload is unchanged, so the gateway's NDJSON
964
+ // parser is unaffected.
965
+ args.push("--output-format", "stream-json", "--include-partial-messages", "--verbose");
961
966
  }
962
967
  if (params.allowedTools && params.allowedTools.length > 0) {
963
968
  sanitizeCliArgValues(params.allowedTools, "allowedTools");
@@ -57,6 +57,10 @@ export const UPSTREAM_CLI_CONTRACTS = {
57
57
  arity: "none",
58
58
  description: "Include partial messages in stream-json output",
59
59
  },
60
+ "--verbose": {
61
+ arity: "none",
62
+ description: "Claude CLI 2.x: required alongside --print + --output-format=stream-json; affects stderr only, stream-json stdout shape unchanged",
63
+ },
60
64
  "--allowed-tools": { arity: "variadic", description: "Allowed tool names/patterns" },
61
65
  "--disallowed-tools": { arity: "variadic", description: "Disallowed tool names/patterns" },
62
66
  "--permission-mode": {
@@ -142,6 +146,23 @@ export const UPSTREAM_CLI_CONTRACTS = {
142
146
  args: ["-p", "hello", "--add-dir", "/tmp/a", "--add-dir", "/tmp/b"],
143
147
  expect: "pass",
144
148
  },
149
+ {
150
+ // Claude CLI 2.x: stream-json requires --verbose alongside --print.
151
+ // The gateway emits all three together; this fixture pins the combo
152
+ // so a future removal of --verbose breaks loudly here instead of
153
+ // silently at runtime against the upstream CLI.
154
+ id: "claude-stream-json-requires-verbose",
155
+ description: "Claude CLI 2.x: --output-format stream-json + --include-partial-messages + --verbose accepted together",
156
+ args: [
157
+ "-p",
158
+ "hello",
159
+ "--output-format",
160
+ "stream-json",
161
+ "--include-partial-messages",
162
+ "--verbose",
163
+ ],
164
+ expect: "pass",
165
+ },
145
166
  ],
146
167
  },
147
168
  codex: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-cli-gateway",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
4
4
  "mcpName": "io.github.verivus-oss/llm-cli-gateway",
5
5
  "description": "MCP server providing unified access to Claude Code, Codex, Gemini, Grok, and Mistral Vibe CLIs with session management, retry logic, async job orchestration, durable job results, and cross-LLM validation.",
6
6
  "license": "MIT",