@sagentlab/navarch-runtime 0.1.87 → 0.1.88
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/README.md +7 -6
- package/dist/adapters/claude.cjs +14 -10
- package/dist/exit-conditions.cjs +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -751,7 +751,7 @@ cli.cts
|
|
|
751
751
|
into Docker when NAVARCH_SANDBOX_MODE=docker
|
|
752
752
|
4. selectAdapter(config.agentType) (adapters/index.cts) picks one AgentAdapter
|
|
753
753
|
(adapters/types.cts) by NAVARCH_AGENT, then .run(...):
|
|
754
|
-
- claudeCodeAdapter (adapters/claude.cts) — `claude -p --mcp-config <path> < prompt`
|
|
754
|
+
- claudeCodeAdapter (adapters/claude.cts) — `claude -p --mcp-config <path> --output-format stream-json --verbose < prompt`
|
|
755
755
|
- codexAdapter (adapters/codex.cts) — `codex exec - --json -c mcp_servers.*=... < prompt`
|
|
756
756
|
- geminiAdapter (adapters/gemini.cts) — `gemini --output-format stream-json < prompt`
|
|
757
757
|
- openCodeAdapter (adapters/opencode.cts) — `opencode run --format json < prompt`
|
|
@@ -871,16 +871,17 @@ Claude Code headless → PR opens on GitHub → complete lands with evidence;
|
|
|
871
871
|
secrets absent from disk after exit"):
|
|
872
872
|
|
|
873
873
|
- Actually running `claude -p` headless and confirming its real
|
|
874
|
-
|
|
875
|
-
`--output-format json` by default
|
|
876
|
-
|
|
874
|
+
result shape (WP-13). `adapters/claude.cts` appends
|
|
875
|
+
`--output-format stream-json --verbose` by default, so the uploaded
|
|
876
|
+
transcript records every message and tool call, and best-effort parses the
|
|
877
|
+
last `type: "result"` record on stdout as a JSON result object shaped like `{ type, subtype, is_error, result,
|
|
877
878
|
session_id, total_cost_usd, usage: { input_tokens, output_tokens,
|
|
878
879
|
cache_creation_input_tokens, cache_read_input_tokens } }` (see
|
|
879
880
|
`exit-conditions.cts#parseClaudeJsonResult` for the exact assumption and
|
|
880
881
|
fallback behavior). Unit tests (`tests/adapter.test.cts`,
|
|
881
882
|
`tests/exit-conditions.test.cts`) cover the parsing and arg-construction
|
|
882
|
-
logic against fixed JSON strings
|
|
883
|
-
|
|
883
|
+
logic against fixed JSON strings recorded from Claude Code 2.1; a future
|
|
884
|
+
CLI release could still change this shape.
|
|
884
885
|
If it doesn't, parsing degrades to `null` and `tokensIn`/`tokensOut`/
|
|
885
886
|
`costUsd` fall back to 0 (session.cts's existing default) — never a thrown
|
|
886
887
|
error — but cost/spend data silently goes missing until the shape is
|
package/dist/adapters/claude.cjs
CHANGED
|
@@ -13,7 +13,7 @@ function hasFlag(args, flag) {
|
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* Headless Claude Code adapter (project-plan.md §3.9 / implementation-plan.md
|
|
16
|
-
* WP-07): `claude -p --mcp-config platform-mcp.json --output-format json`
|
|
16
|
+
* WP-07): `claude -p --mcp-config platform-mcp.json --output-format stream-json --verbose`
|
|
17
17
|
* with the context bundle on stdin (`claude -p` reads its prompt from stdin
|
|
18
18
|
* when none is given; Linux rejects any single argv string over 128 KiB, so
|
|
19
19
|
* an argv prompt failed `spawn E2BIG` before Claude started). Returns raw stdout/stderr/exit signals (plus
|
|
@@ -25,11 +25,10 @@ function hasFlag(args, flag) {
|
|
|
25
25
|
* (adapters/types.cts) — see adapters/codex.cts for the Codex CLI sibling
|
|
26
26
|
* session.cts picks between via NAVARCH_AGENT (config.cts's `agentType`).
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* real shape differs, parseClaudeJsonResult() returns null and
|
|
28
|
+
* `--output-format stream-json` prints one JSON record per line and ends with
|
|
29
|
+
* the same result object (`type: "result"`, `usage`, `total_cost_usd`) that
|
|
30
|
+
* `--output-format json` prints alone; parseClaudeJsonResult() reads that
|
|
31
|
+
* last record. If the real shape differs, parseClaudeJsonResult() returns null and
|
|
33
32
|
* tokensIn/tokensOut/costUsd fall back to 0 (session.cts's existing
|
|
34
33
|
* default) rather than throwing -- see runtime/README.md.
|
|
35
34
|
*/
|
|
@@ -135,9 +134,14 @@ async function runClaudeAttempt(options, automaticFallback) {
|
|
|
135
134
|
// Only append the default when the caller hasn't already asked for a
|
|
136
135
|
// specific --output-format (extraArgs wins so an operator can opt back
|
|
137
136
|
// into plain-text output, e.g. while diagnosing a live-verification
|
|
138
|
-
// mismatch, without an adapter code change).
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
// mismatch, without an adapter code change). stream-json records every
|
|
138
|
+
// message and tool call, which the task transcript viewer renders; plain
|
|
139
|
+
// `json` printed only the final result. Claude Code requires --verbose for
|
|
140
|
+
// stream-json under --print, and its last record is the same result object.
|
|
141
|
+
if (!hasFlag(options.extraArgs, "--output-format")) {
|
|
142
|
+
args.push("--output-format", "stream-json");
|
|
143
|
+
if (!hasFlag(options.extraArgs, "--verbose"))
|
|
144
|
+
args.push("--verbose");
|
|
141
145
|
}
|
|
142
146
|
args.push(...options.extraArgs);
|
|
143
147
|
// Project/task policy is appended after machine-wide extra arguments so a
|
|
@@ -157,7 +161,7 @@ async function runClaudeAttempt(options, automaticFallback) {
|
|
|
157
161
|
const raw = runOptions.dockerExec ? await runViaDocker(runOptions, args) : await runOnHost(runOptions, args);
|
|
158
162
|
return attachUsage(raw);
|
|
159
163
|
}
|
|
160
|
-
/** Parses
|
|
164
|
+
/** Parses the final `claude -p --output-format stream-json` result record for usage and folds it onto the raw result (best-effort; leaves tokensIn/tokensOut/costUsd unset when parsing fails). */
|
|
161
165
|
function attachUsage(result) {
|
|
162
166
|
const parsed = (0, exit_conditions_cjs_1.parseClaudeJsonResult)(result.stdout);
|
|
163
167
|
if (!parsed)
|
package/dist/exit-conditions.cjs
CHANGED
|
@@ -24,8 +24,9 @@ function agentAuthFailureReport(detail) {
|
|
|
24
24
|
"Log the coding agent in again on this machine (`claude /login` or `codex login`), then resume the agent.";
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
* Best-effort parse of `claude -p --output-format json`
|
|
28
|
-
*
|
|
27
|
+
* Best-effort parse of `claude -p --output-format json` (or `stream-json`,
|
|
28
|
+
* whose last result record has the same shape) stdout into the assumed
|
|
29
|
+
* result shape above. Tries the whole trimmed stdout first (the
|
|
29
30
|
* expected case); if that fails, tries each non-empty line that looks like a
|
|
30
31
|
* JSON object, in case a warning/log line preceded the result (last such
|
|
31
32
|
* line wins, since the final result is expected last). Returns null rather
|
|
@@ -39,6 +40,9 @@ function parseClaudeJsonResult(stdout) {
|
|
|
39
40
|
const isUsableResult = (value) => typeof value === "object" &&
|
|
40
41
|
value !== null &&
|
|
41
42
|
!Array.isArray(value) &&
|
|
43
|
+
// stream-json output interleaves typed message/tool records with the
|
|
44
|
+
// final `type: "result"` record; only that record carries the outcome.
|
|
45
|
+
(!("type" in value) || value.type === "result") &&
|
|
42
46
|
(!("result" in value) || typeof value.result === "string") &&
|
|
43
47
|
("result" in value || "usage" in value || "cost_usd" in value || "total_cost_usd" in value);
|
|
44
48
|
try {
|
package/package.json
CHANGED