@claudexor/harness-claude 1.0.0
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/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +482 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive.d.ts +67 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +154 -0
- package/dist/interactive.js.map +1 -0
- package/dist/parse.d.ts +18 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +347 -0
- package/dist/parse.js.map +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 joi-lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# @claudexor/harness-claude
|
|
2
|
+
|
|
3
|
+
Internal package of [Claudexor](https://github.com/razzant/claudexor) — Claude Code adapter (claude -p --output-format stream-json).
|
|
4
|
+
|
|
5
|
+
Published as part of the Claudexor toolchain; it follows the monorepo's
|
|
6
|
+
lockstep version and has no separate semver contract. Use the `claudexor`
|
|
7
|
+
CLI (or `@claudexor/cli`) as the supported entry point.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HarnessRunSpec } from "@claudexor/schema";
|
|
2
|
+
import type { HarnessAdapter } from "@claudexor/core";
|
|
3
|
+
/** The user's real Claude config dir (native subscription session lives here). */
|
|
4
|
+
export declare function defaultNativeClaudeConfigDir(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Seed the user's NATIVE Claude session (`.credentials.json`, subscription OAuth)
|
|
7
|
+
* into an isolated CLAUDE_CONFIG_DIR so a Pro/Max subscriber with NO API key can
|
|
8
|
+
* run inside a Claudexor envelope. Copies only if scoped creds are absent and a
|
|
9
|
+
* native credentials file exists; never overwrites. Returns true when scoped
|
|
10
|
+
* creds are present afterwards.
|
|
11
|
+
*
|
|
12
|
+
* Caveats encoded by the caller: `ANTHROPIC_API_KEY` takes precedence over the
|
|
13
|
+
* OAuth session, and `--bare` disables it — so the subscription route must set
|
|
14
|
+
* neither.
|
|
15
|
+
*/
|
|
16
|
+
export declare function ensureClaudeNativeAuth(env?: Record<string, string>, nativeDir?: string): boolean;
|
|
17
|
+
export declare function createClaudeAdapter(): HarnessAdapter;
|
|
18
|
+
export declare function claudeArgsForSpec(spec: HarnessRunSpec, interactive?: boolean, suppressBare?: boolean): string[];
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAyG,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE/J,OAAO,KAAK,EAAc,cAAc,EAAsB,MAAM,iBAAiB,CAAC;AAmFtF,kFAAkF;AAClF,wBAAgB,4BAA4B,IAAI,MAAM,CAIrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,SAAS,GAAE,MAAuC,GACjD,OAAO,CAmBT;AAoCD,wBAAgB,mBAAmB,IAAI,cAAc,CA2HpD;AAOD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,UAAQ,EAAE,YAAY,UAAQ,GAAG,MAAM,EAAE,CA8B3G"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
import { chmodSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { homedir, tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { ConformanceReport as ConformanceReportSchema, HarnessCapabilityProfile as HarnessCapabilityProfileSchema, HarnessManifest as HarnessManifestSchema } from "@claudexor/schema";
|
|
5
|
+
import { HarnessUnavailableError, interactionChannelFromSpec, normalizeEffort, playwrightMcpArgs, providerScrubEnv, readonlyMechanism, resolveNpxBin, runCapture, runCliHarness, PROVIDER_SECRET_ENV } from "@claudexor/core";
|
|
6
|
+
import { resolveSecret } from "@claudexor/secrets";
|
|
7
|
+
import { CLAUDEXOR_VERSION, nowIso, redactSecrets } from "@claudexor/util";
|
|
8
|
+
import { createClaudeParser } from "./parse.js";
|
|
9
|
+
import { handleControlRequestFrame, initialSessionFrames, isControlRequestFrame, isResultFrame } from "./interactive.js";
|
|
10
|
+
const BIN = process.env.CLAUDEXOR_CLAUDE_BIN || "claude";
|
|
11
|
+
const CLAUDE_PROVIDER_ENV_DENYLIST = PROVIDER_SECRET_ENV.filter((k) => k !== "ANTHROPIC_API_KEY");
|
|
12
|
+
const CLAUDE_CAPABILITY_PROFILE = HarnessCapabilityProfileSchema.parse({
|
|
13
|
+
auth: {
|
|
14
|
+
supported_sources: ["native_session", "api_key_env"],
|
|
15
|
+
preferred_source: null,
|
|
16
|
+
credential_transports: [
|
|
17
|
+
{ source: "native_session", kind: "config_file", relocatable_by: ["CONFIG_DIR"] },
|
|
18
|
+
{ source: "api_key_env", kind: "env_var", relocatable_by: ["ENV"] },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
access_control: { readonly_mechanism: "tool_allowlist" },
|
|
22
|
+
isolation: { supported_containment: ["env_or_file_injection"] },
|
|
23
|
+
image_input: "base64_stream",
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Ordered (weakest→strongest) reasoning-effort levels `claude --effort` accepts.
|
|
27
|
+
* Verified against the installed CLI (`claude --help`, v2.1.165): the full
|
|
28
|
+
* ladder is low|medium|high|xhigh|max. SINGLE source for the manifest's
|
|
29
|
+
* `effort_levels` and the run-time normalizer (which now clamps nothing away).
|
|
30
|
+
*/
|
|
31
|
+
const CLAUDE_EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
32
|
+
function permissionArgs(access) {
|
|
33
|
+
switch (access) {
|
|
34
|
+
case "readonly":
|
|
35
|
+
return [];
|
|
36
|
+
case "workspace_write":
|
|
37
|
+
return ["--permission-mode", "acceptEdits"];
|
|
38
|
+
case "full":
|
|
39
|
+
case "external_sandbox_full":
|
|
40
|
+
return ["--permission-mode", "bypassPermissions"];
|
|
41
|
+
case "inherit_native":
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function detectVersion() {
|
|
46
|
+
try {
|
|
47
|
+
const r = await runCapture(BIN, ["--version"], { timeoutMs: 10_000 });
|
|
48
|
+
return r.stdout.trim() || `${BIN} (version unknown)`;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function authStatusOk() {
|
|
55
|
+
try {
|
|
56
|
+
const env = Object.fromEntries(CLAUDE_PROVIDER_ENV_DENYLIST.map((name) => [name, null]));
|
|
57
|
+
// Probe a REAL native/subscription session only: `claude auth status` reports
|
|
58
|
+
// loggedIn:true for a bare ANTHROPIC_API_KEY (authMethod:api_key), which would
|
|
59
|
+
// make the run path mistake an API key for a native session and pick the
|
|
60
|
+
// subscription route (scrubs the key -> "Not logged in"). Scrub it here so this
|
|
61
|
+
// probe reflects native-session readiness alone; the api_key route is chosen
|
|
62
|
+
// separately by runClaude when no native session exists.
|
|
63
|
+
env.ANTHROPIC_API_KEY = null;
|
|
64
|
+
const r = await runCapture(BIN, ["auth", "status"], { env, timeoutMs: 10_000 });
|
|
65
|
+
return r.code === 0;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function anthropicApiKey() {
|
|
72
|
+
return process.env.CLAUDEXOR_ANTHROPIC_API_KEY || resolveSecret("anthropic") || process.env.ANTHROPIC_API_KEY || null;
|
|
73
|
+
}
|
|
74
|
+
/** A stored/long-lived Claude Code OAuth (`claude setup-token`) for headless
|
|
75
|
+
* subscription auth. The hermetic kill switch is honored inside resolveSecret
|
|
76
|
+
* (single owner), so this reads env-only under CLAUDEXOR_DISABLE_STORED_SECRETS. */
|
|
77
|
+
function claudeOAuthToken() {
|
|
78
|
+
return resolveSecret("claude_oauth") || process.env.CLAUDE_CODE_OAUTH_TOKEN || null;
|
|
79
|
+
}
|
|
80
|
+
/** The user's real Claude config dir (native subscription session lives here). */
|
|
81
|
+
export function defaultNativeClaudeConfigDir() {
|
|
82
|
+
const override = process.env.CLAUDEXOR_CLAUDE_NATIVE_DIR;
|
|
83
|
+
if (override && override.trim())
|
|
84
|
+
return override;
|
|
85
|
+
return join(homedir(), ".claude");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Seed the user's NATIVE Claude session (`.credentials.json`, subscription OAuth)
|
|
89
|
+
* into an isolated CLAUDE_CONFIG_DIR so a Pro/Max subscriber with NO API key can
|
|
90
|
+
* run inside a Claudexor envelope. Copies only if scoped creds are absent and a
|
|
91
|
+
* native credentials file exists; never overwrites. Returns true when scoped
|
|
92
|
+
* creds are present afterwards.
|
|
93
|
+
*
|
|
94
|
+
* Caveats encoded by the caller: `ANTHROPIC_API_KEY` takes precedence over the
|
|
95
|
+
* OAuth session, and `--bare` disables it — so the subscription route must set
|
|
96
|
+
* neither.
|
|
97
|
+
*/
|
|
98
|
+
export function ensureClaudeNativeAuth(env, nativeDir = defaultNativeClaudeConfigDir()) {
|
|
99
|
+
const dir = env?.["CLAUDE_CONFIG_DIR"];
|
|
100
|
+
if (!dir)
|
|
101
|
+
return false;
|
|
102
|
+
const dest = join(dir, ".credentials.json");
|
|
103
|
+
if (existsSync(dest))
|
|
104
|
+
return true;
|
|
105
|
+
const src = join(nativeDir, ".credentials.json");
|
|
106
|
+
if (!existsSync(src))
|
|
107
|
+
return false;
|
|
108
|
+
try {
|
|
109
|
+
mkdirSync(dir, { recursive: true });
|
|
110
|
+
copyFileSync(src, dest);
|
|
111
|
+
try {
|
|
112
|
+
chmodSync(dest, 0o600);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
/* best-effort perms */
|
|
116
|
+
}
|
|
117
|
+
return existsSync(dest);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** True when a native Claude session exists and can be seeded into an envelope. */
|
|
124
|
+
function nativeClaudeSeedable() {
|
|
125
|
+
return existsSync(join(defaultNativeClaudeConfigDir(), ".credentials.json"));
|
|
126
|
+
}
|
|
127
|
+
async function smokeIsolatedApiKey() {
|
|
128
|
+
const key = anthropicApiKey();
|
|
129
|
+
if (!key)
|
|
130
|
+
return { ok: false, detail: "no API key fallback available" };
|
|
131
|
+
const dir = mkdtempSync(`${tmpdir()}/claudexor-claude-smoke-`);
|
|
132
|
+
try {
|
|
133
|
+
const env = Object.fromEntries(CLAUDE_PROVIDER_ENV_DENYLIST.map((name) => [name, null]));
|
|
134
|
+
env.HOME = dir;
|
|
135
|
+
env.XDG_CONFIG_HOME = `${dir}/.config`;
|
|
136
|
+
env.CLAUDE_CONFIG_DIR = dir;
|
|
137
|
+
env.ANTHROPIC_API_KEY = key;
|
|
138
|
+
const r = await runCapture(BIN, ["-p", "Reply exactly OK", "--output-format", "stream-json", "--verbose", "--permission-mode", "plan"], { cwd: dir, env, timeoutMs: 60_000 });
|
|
139
|
+
const text = `${r.stdout}\n${r.stderr}`;
|
|
140
|
+
if (r.code === 0 && text.includes("OK"))
|
|
141
|
+
return { ok: true, detail: "isolated CLAUDE_CONFIG_DIR smoke passed" };
|
|
142
|
+
return { ok: false, detail: redactClaudeDoctorDetail(text || `claude exited with code ${r.code}`) };
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
return { ok: false, detail: redactClaudeDoctorDetail(err instanceof Error ? err.message : String(err)) };
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
rmSync(dir, { recursive: true, force: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function redactClaudeDoctorDetail(text) {
|
|
152
|
+
return redactSecrets(text).slice(0, 500);
|
|
153
|
+
}
|
|
154
|
+
export function createClaudeAdapter() {
|
|
155
|
+
return {
|
|
156
|
+
id: "claude",
|
|
157
|
+
async discover() {
|
|
158
|
+
const version = await detectVersion();
|
|
159
|
+
if (version === null) {
|
|
160
|
+
throw new HarnessUnavailableError("claude CLI not found on PATH (set CLAUDEXOR_CLAUDE_BIN to override)");
|
|
161
|
+
}
|
|
162
|
+
const apiKey = anthropicApiKey() !== null;
|
|
163
|
+
const authed = await authStatusOk();
|
|
164
|
+
const authModes = [
|
|
165
|
+
...(authed ? ["local_session"] : []),
|
|
166
|
+
...(apiKey ? ["api_key"] : []),
|
|
167
|
+
];
|
|
168
|
+
return HarnessManifestSchema.parse({
|
|
169
|
+
id: "claude",
|
|
170
|
+
display_name: "Claude Code",
|
|
171
|
+
kind: "local_cli",
|
|
172
|
+
version,
|
|
173
|
+
adapter_version: CLAUDEXOR_VERSION,
|
|
174
|
+
provider_family: "anthropic",
|
|
175
|
+
capabilities: {
|
|
176
|
+
plan: true,
|
|
177
|
+
implement: true,
|
|
178
|
+
create_from_scratch: true,
|
|
179
|
+
review: true,
|
|
180
|
+
verify: true,
|
|
181
|
+
synthesize: true,
|
|
182
|
+
read_files: true,
|
|
183
|
+
// inline JSON (no disk write) — gated on web policy.
|
|
184
|
+
browser_tool: true,
|
|
185
|
+
// LIVE-VERIFIED (claude 2.1.165): `--json-schema <schema>` (inline JSON).
|
|
186
|
+
json_schema_output: true,
|
|
187
|
+
web_policy: "tools",
|
|
188
|
+
max_turns: true,
|
|
189
|
+
tool_lists: true,
|
|
190
|
+
interactive: true,
|
|
191
|
+
orchestrate: true,
|
|
192
|
+
// claude --effort accepts low|medium|high|xhigh|max (verified against
|
|
193
|
+
// the installed CLI's --help). Single source for the run-time normalizer.
|
|
194
|
+
effort_levels: [...CLAUDE_EFFORT_LEVELS],
|
|
195
|
+
// Manifest model truth source (strict model-truth validation: an explicit model outside
|
|
196
|
+
// this list is refused, never forwarded to die as a native error).
|
|
197
|
+
// Stable aliases plus current full ids; verified against the vendor
|
|
198
|
+
// model-config docs and the installed CLI recorded below.
|
|
199
|
+
known_models: [
|
|
200
|
+
"sonnet",
|
|
201
|
+
"opus",
|
|
202
|
+
"haiku",
|
|
203
|
+
"fable",
|
|
204
|
+
"best",
|
|
205
|
+
"claude-fable-5",
|
|
206
|
+
"claude-sonnet-5",
|
|
207
|
+
"claude-opus-4-8",
|
|
208
|
+
"claude-opus-4-7",
|
|
209
|
+
"claude-opus-4-6",
|
|
210
|
+
"claude-sonnet-4-6",
|
|
211
|
+
"claude-sonnet-4-5",
|
|
212
|
+
"claude-haiku-4-5",
|
|
213
|
+
],
|
|
214
|
+
known_models_verified_against: "2.1.165",
|
|
215
|
+
},
|
|
216
|
+
capability_profile: {
|
|
217
|
+
...CLAUDE_CAPABILITY_PROFILE,
|
|
218
|
+
auth: {
|
|
219
|
+
...CLAUDE_CAPABILITY_PROFILE.auth,
|
|
220
|
+
preferred_source: apiKey ? "api_key_env" : authed ? "native_session" : null,
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
auth_modes: authModes,
|
|
224
|
+
access_profiles_supported: ["readonly", "workspace_write", "full", "inherit_native"],
|
|
225
|
+
});
|
|
226
|
+
},
|
|
227
|
+
async doctor(_spec) {
|
|
228
|
+
const version = await detectVersion();
|
|
229
|
+
if (version === null) {
|
|
230
|
+
return ConformanceReportSchema.parse({
|
|
231
|
+
harness_id: "claude",
|
|
232
|
+
status: "unavailable",
|
|
233
|
+
checks: [{ id: "installed", status: "fail", detail: "claude not found on PATH" }],
|
|
234
|
+
reasons: ["claude CLI not found (install Claude Code or set CLAUDEXOR_CLAUDE_BIN)"],
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
const apiKey = anthropicApiKey() !== null;
|
|
238
|
+
const authed = await authStatusOk();
|
|
239
|
+
// Native subscription readiness is FIRST-CLASS: a logged-in session whose
|
|
240
|
+
// .credentials.json we can seed into the envelope is `ok` with no paid API
|
|
241
|
+
// smoke. A stored OAuth token (claude setup-token) is also native-ready.
|
|
242
|
+
const nativeReady = (authed && nativeClaudeSeedable()) || claudeOAuthToken() !== null;
|
|
243
|
+
const smoke = !nativeReady && apiKey ? await smokeIsolatedApiKey() : { ok: false, detail: nativeReady ? "skipped (native session ready)" : "no API key fallback available" };
|
|
244
|
+
const ok = nativeReady || smoke.ok;
|
|
245
|
+
const allIntents = ["plan", "spec", "implement", "repair", "create_from_scratch", "review", "verify", "synthesize", "explain", "audit", "orchestrate"];
|
|
246
|
+
return ConformanceReportSchema.parse({
|
|
247
|
+
harness_id: "claude",
|
|
248
|
+
status: ok ? "ok" : authed || apiKey ? "degraded" : "unavailable",
|
|
249
|
+
checks: [
|
|
250
|
+
{ id: "installed", status: "pass", detail: version },
|
|
251
|
+
{ id: "native_session", status: nativeReady ? "pass" : "fail", detail: nativeReady ? "native Claude session seedable into envelope" : authed ? "logged in but ~/.claude/.credentials.json not found" : "not logged in (run `claude /login` or store a setup-token)" },
|
|
252
|
+
{ id: "stored_key", status: apiKey ? "pass" : "fail", detail: apiKey ? "anthropic secret/env available (api-key fallback)" : "no anthropic key fallback" },
|
|
253
|
+
{ id: "isolated_api_smoke", status: smoke.ok ? "pass" : nativeReady ? "skip" : apiKey ? "fail" : "skip", detail: smoke.detail },
|
|
254
|
+
],
|
|
255
|
+
enabled_intents: ok ? allIntents : [],
|
|
256
|
+
disabled_intents: ok ? [] : allIntents,
|
|
257
|
+
reasons: ok
|
|
258
|
+
? []
|
|
259
|
+
: apiKey
|
|
260
|
+
? [`isolated Claude API-key smoke failed: ${smoke.detail}`]
|
|
261
|
+
: ["not authenticated (run `claude /login` for native/subscription use, or store an anthropic API key fallback)"],
|
|
262
|
+
});
|
|
263
|
+
},
|
|
264
|
+
run(spec) {
|
|
265
|
+
return runClaude(spec);
|
|
266
|
+
},
|
|
267
|
+
review(spec) {
|
|
268
|
+
return runClaude(spec);
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/** Claude's native names for web-permissioned tools. This knowledge lives ONLY in the adapter. */
|
|
273
|
+
const CLAUDE_WEB_TOOLS = ["WebSearch", "WebFetch"];
|
|
274
|
+
const CLAUDE_READONLY_ALLOWED_TOOLS = ["Read", "Glob", "Grep", "LS"];
|
|
275
|
+
const CLAUDE_READONLY_DENIED_TOOLS = ["Write", "Edit", "MultiEdit", "NotebookEdit"];
|
|
276
|
+
export function claudeArgsForSpec(spec, interactive = false, suppressBare = false) {
|
|
277
|
+
// Interactive sessions deliver the prompt as a stream-json user message on
|
|
278
|
+
// stdin (the control protocol's transport); one-shot runs keep the prompt arg.
|
|
279
|
+
// `--permission-prompt-tool stdio` is the live-verified switch that routes
|
|
280
|
+
// permission prompts (AskUserQuestion included) onto the control channel as
|
|
281
|
+
// control_request frames instead of headless auto-denial.
|
|
282
|
+
const args = interactive
|
|
283
|
+
? ["-p", "--output-format", "stream-json", "--input-format", "stream-json", "--verbose", "--permission-prompt-tool", "stdio", ...permissionArgs(spec.access)]
|
|
284
|
+
: ["-p", spec.prompt, "--output-format", "stream-json", "--verbose", ...permissionArgs(spec.access)];
|
|
285
|
+
if (spec.model_hint)
|
|
286
|
+
args.push("--model", spec.model_hint);
|
|
287
|
+
// Clamp onto claude's declared effort ladder; null = not
|
|
288
|
+
// requested OR not tunable -> pass no flag. Never sends an invalid level.
|
|
289
|
+
const eff = normalizeEffort(spec.effort_hint, CLAUDE_EFFORT_LEVELS);
|
|
290
|
+
if (eff)
|
|
291
|
+
args.push("--effort", eff);
|
|
292
|
+
if (spec.max_turns !== null && spec.max_turns > 0)
|
|
293
|
+
args.push("--max-turns", String(spec.max_turns));
|
|
294
|
+
// Structured output: constrain the FINAL message to the caller's JSON
|
|
295
|
+
// Schema. LIVE-VERIFIED (2.1.165): `--json-schema <inline JSON>` with
|
|
296
|
+
// --output-format stream-json. Passed only when the engine set it (the
|
|
297
|
+
// engine gates on the json_schema_output capability).
|
|
298
|
+
if (spec.output_schema !== undefined && spec.output_schema !== null) {
|
|
299
|
+
args.push("--json-schema", JSON.stringify(spec.output_schema));
|
|
300
|
+
}
|
|
301
|
+
// Resume a native Claude session as a follow-up turn of the same conversation.
|
|
302
|
+
if (spec.resume_session_id)
|
|
303
|
+
args.push("--resume", spec.resume_session_id);
|
|
304
|
+
args.push(...claudeBrowserArgs(spec));
|
|
305
|
+
args.push(...toolPermissionArgs(spec));
|
|
306
|
+
// `--bare` disables OAuth/keychain auth, so it is mutually exclusive with the
|
|
307
|
+
// subscription (native session) route — suppress it there or the run 401s.
|
|
308
|
+
if (spec.extra?.["bare"] === true && !suppressBare)
|
|
309
|
+
args.push("--bare");
|
|
310
|
+
return args;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Map the external-context policy plus the user's per-harness tool allow/deny
|
|
314
|
+
* lists to Claude flags. Uses the single comma-separated form: the repeated
|
|
315
|
+
* variadic form is a known-fragile area of the Claude CLI.
|
|
316
|
+
* Note `cached` executes as live web here (Claude has no cached web index);
|
|
317
|
+
* the orchestrator discloses that upgrade via `policy.web.upgraded`.
|
|
318
|
+
*/
|
|
319
|
+
function toolPermissionArgs(spec) {
|
|
320
|
+
const { allow, deny } = toolPermissionSets(spec);
|
|
321
|
+
const args = [];
|
|
322
|
+
if (allow.size > 0)
|
|
323
|
+
args.push("--allowedTools", [...allow].join(","));
|
|
324
|
+
if (deny.size > 0)
|
|
325
|
+
args.push("--disallowedTools", [...deny].join(","));
|
|
326
|
+
return args;
|
|
327
|
+
}
|
|
328
|
+
function toolPermissionSets(spec) {
|
|
329
|
+
const policy = spec.external_context_policy;
|
|
330
|
+
const allow = new Set(spec.tool_permission_policy.allow);
|
|
331
|
+
const deny = new Set(spec.tool_permission_policy.deny);
|
|
332
|
+
if (spec.access === "readonly" && readonlyMechanism(CLAUDE_CAPABILITY_PROFILE) === "tool_allowlist") {
|
|
333
|
+
for (const tool of CLAUDE_READONLY_ALLOWED_TOOLS) {
|
|
334
|
+
if (!deny.has(tool))
|
|
335
|
+
allow.add(tool);
|
|
336
|
+
}
|
|
337
|
+
for (const tool of CLAUDE_READONLY_DENIED_TOOLS) {
|
|
338
|
+
deny.add(tool);
|
|
339
|
+
allow.delete(tool);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (policy === "off") {
|
|
343
|
+
for (const tool of CLAUDE_WEB_TOOLS) {
|
|
344
|
+
deny.add(tool);
|
|
345
|
+
allow.delete(tool);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
for (const tool of CLAUDE_WEB_TOOLS) {
|
|
350
|
+
if (!deny.has(tool))
|
|
351
|
+
allow.add(tool);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// A browser-tool run allows the injected MCP server's tools (claude names them
|
|
355
|
+
// `mcp__browser__*`; the server prefix `mcp__browser` allows the whole set).
|
|
356
|
+
// Gated on policy: under `off` the MCP is never injected (claudeBrowserArgs is
|
|
357
|
+
// empty), so this allow has no tool to match anyway.
|
|
358
|
+
if (spec.browser && policy !== "off")
|
|
359
|
+
allow.add("mcp__browser");
|
|
360
|
+
return { allow, deny };
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Inject the Playwright browser MCP via `--mcp-config` inline JSON (no disk
|
|
364
|
+
* write — fits the scoped HOME and works under `--bare`). Empty when no browser
|
|
365
|
+
* this run OR when web policy is `off` (the browser is live egress and must ride
|
|
366
|
+
* `external_context_policy`, mirroring web-tool gating).
|
|
367
|
+
*/
|
|
368
|
+
function claudeBrowserArgs(spec) {
|
|
369
|
+
if (!spec.browser || spec.external_context_policy === "off")
|
|
370
|
+
return [];
|
|
371
|
+
const cfg = JSON.stringify({ mcpServers: { browser: { command: resolveNpxBin(), args: playwrightMcpArgs(spec.browser) } } });
|
|
372
|
+
return ["--mcp-config", cfg];
|
|
373
|
+
}
|
|
374
|
+
/** Build Claude base64 image blocks from image attachments (read at spec time). */
|
|
375
|
+
function claudeImageBlocks(attachments) {
|
|
376
|
+
const blocks = [];
|
|
377
|
+
for (const a of attachments ?? []) {
|
|
378
|
+
if (a.kind !== "image")
|
|
379
|
+
continue;
|
|
380
|
+
try {
|
|
381
|
+
blocks.push({ type: "image", source: { type: "base64", media_type: a.mime, data: readFileSync(a.path).toString("base64") } });
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
// A late-deleted attachment is non-fatal: proceed with the text prompt.
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return blocks;
|
|
388
|
+
}
|
|
389
|
+
async function* runClaude(spec) {
|
|
390
|
+
const channel = interactionChannelFromSpec(spec);
|
|
391
|
+
const imageBlocks = claudeImageBlocks(spec.attachments);
|
|
392
|
+
// Images ride ONLY the stdin stream-json transport, so an attachment forces
|
|
393
|
+
// the interactive path even with no interaction channel (control frames then
|
|
394
|
+
// auto-decline). claudeArgsForSpec(interactive) selects --input-format stream-json.
|
|
395
|
+
const interactive = channel !== undefined || imageBlocks.length > 0;
|
|
396
|
+
const nativeAuthed = await authStatusOk();
|
|
397
|
+
const key = anthropicApiKey();
|
|
398
|
+
const oauthToken = claudeOAuthToken();
|
|
399
|
+
const preferApi = spec.auth_preference === "api_key";
|
|
400
|
+
const scopedConfig = Boolean(spec.env?.["CLAUDE_CONFIG_DIR"]);
|
|
401
|
+
// Choose the auth route (BOTH supported, auto-fallback). Subscription seeds the
|
|
402
|
+
// native session (credentials copy) or uses a stored OAuth token; api_key sets
|
|
403
|
+
// ANTHROPIC_API_KEY. ANTHROPIC_API_KEY overrides OAuth and --bare disables it,
|
|
404
|
+
// so the subscription route sets neither (and suppresses --bare).
|
|
405
|
+
let seededCreds = false;
|
|
406
|
+
const trySub = () => {
|
|
407
|
+
if (scopedConfig && nativeAuthed && ensureClaudeNativeAuth(spec.env)) {
|
|
408
|
+
seededCreds = true;
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
return (!scopedConfig && nativeAuthed) || oauthToken !== null;
|
|
412
|
+
};
|
|
413
|
+
const canKey = key !== null;
|
|
414
|
+
const route = preferApi
|
|
415
|
+
? canKey
|
|
416
|
+
? "api_key"
|
|
417
|
+
: trySub()
|
|
418
|
+
? "subscription"
|
|
419
|
+
: null
|
|
420
|
+
: trySub()
|
|
421
|
+
? "subscription"
|
|
422
|
+
: canKey
|
|
423
|
+
? "api_key"
|
|
424
|
+
: null;
|
|
425
|
+
// An EXPLICIT auth preference that could not be honored is disclosed as a
|
|
426
|
+
// typed marker; the orchestrator lifts it into route.fallback.auth_switched.
|
|
427
|
+
const preferredRoute = preferApi ? "api_key" : "subscription";
|
|
428
|
+
if (spec.auth_preference !== "auto" && route !== null && route !== preferredRoute) {
|
|
429
|
+
yield {
|
|
430
|
+
type: "message",
|
|
431
|
+
session_id: spec.session_id,
|
|
432
|
+
ts: nowIso(),
|
|
433
|
+
text: `[auth] ${preferredRoute} route unavailable; fell back to ${route}`,
|
|
434
|
+
payload: {
|
|
435
|
+
auth_switched: true,
|
|
436
|
+
from_auth_mode: preferredRoute === "subscription" ? "local_session" : "api_key",
|
|
437
|
+
to_auth_mode: route === "subscription" ? "local_session" : "api_key",
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
if (route === null) {
|
|
442
|
+
yield {
|
|
443
|
+
type: "error",
|
|
444
|
+
session_id: spec.session_id,
|
|
445
|
+
ts: nowIso(),
|
|
446
|
+
error: "no usable claude auth for this envelope: native session not seedable (run `claude /login` or store a setup-token) and no Anthropic API key fallback available",
|
|
447
|
+
};
|
|
448
|
+
yield { type: "completed", session_id: spec.session_id, ts: nowIso() };
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
const useSubscription = route === "subscription";
|
|
452
|
+
const args = claudeArgsForSpec(spec, interactive, useSubscription);
|
|
453
|
+
// Scrub EVERY provider secret (incl. OpenAI/others — the cross-provider leak
|
|
454
|
+
// fix) via the single core table, then re-add only the var this route needs.
|
|
455
|
+
const env = { ...spec.env, ...providerScrubEnv() };
|
|
456
|
+
if (route === "api_key" && key) {
|
|
457
|
+
env.ANTHROPIC_API_KEY = key;
|
|
458
|
+
}
|
|
459
|
+
else if (route === "subscription" && !seededCreds && oauthToken) {
|
|
460
|
+
env.CLAUDE_CODE_OAUTH_TOKEN = oauthToken;
|
|
461
|
+
}
|
|
462
|
+
yield* runCliHarness({
|
|
463
|
+
bin: BIN,
|
|
464
|
+
args,
|
|
465
|
+
spec,
|
|
466
|
+
env,
|
|
467
|
+
label: "claude",
|
|
468
|
+
redact: redactSecrets,
|
|
469
|
+
parseEvent: createClaudeParser({ deniedTools: toolPermissionSets(spec).deny }),
|
|
470
|
+
...(interactive
|
|
471
|
+
? {
|
|
472
|
+
session: {
|
|
473
|
+
initialStdin: initialSessionFrames(spec.prompt, imageBlocks),
|
|
474
|
+
matches: isControlRequestFrame,
|
|
475
|
+
handle: (obj, io) => handleControlRequestFrame(obj, io, spec.session_id, channel),
|
|
476
|
+
closeStdinOn: isResultFrame,
|
|
477
|
+
},
|
|
478
|
+
}
|
|
479
|
+
: {}),
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ChildStdin, InteractionChannel } from "@claudexor/core";
|
|
2
|
+
import type { HarnessEvent, InteractionAnswerSet, InteractionRequest } from "@claudexor/schema";
|
|
3
|
+
type Json = any;
|
|
4
|
+
/**
|
|
5
|
+
* Claude Code bidirectional stream-json control protocol (the same channel the
|
|
6
|
+
* Agent SDK's `canUseTool` rides on):
|
|
7
|
+
*
|
|
8
|
+
* CLI -> client : {"type":"control_request","request_id":X,
|
|
9
|
+
* "request":{"subtype":"can_use_tool","tool_name":T,"input":I,...}}
|
|
10
|
+
* client -> CLI : {"type":"control_response","response":{"subtype":"success",
|
|
11
|
+
* "request_id":X,"response":{"behavior":"allow"|"deny",...}}}
|
|
12
|
+
*
|
|
13
|
+
* For AskUserQuestion the answers ride in `updatedInput.answers` as a record of
|
|
14
|
+
* question text -> selected label(s) (docs: "Handle approvals and user input").
|
|
15
|
+
* Frame shapes are LIVE-VERIFIED against Claude Code 2.1.165: the full
|
|
16
|
+
* bidirectional exchange (initialize -> can_use_tool -> allow -> ok
|
|
17
|
+
* tool_result -> result) is recorded in fixtures/protocol/control-handshake.jsonl.
|
|
18
|
+
* The control channel only activates with `--permission-prompt-tool stdio`;
|
|
19
|
+
* without it the headless CLI auto-denies interactive tools itself.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isControlRequestFrame(obj: Json): boolean;
|
|
22
|
+
export declare function isResultFrame(obj: Json): boolean;
|
|
23
|
+
/** A Claude stream-json image content block (base64 source). Claude carries
|
|
24
|
+
* images ONLY on the stdin stream-json transport — a one-shot `-p` argv run
|
|
25
|
+
* cannot, so a turn with attachments must use the interactive path. */
|
|
26
|
+
export interface ClaudeImageBlock {
|
|
27
|
+
type: "image";
|
|
28
|
+
source: {
|
|
29
|
+
type: "base64";
|
|
30
|
+
media_type: string;
|
|
31
|
+
data: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Initial user message frame for `--input-format stream-json` sessions. */
|
|
35
|
+
export declare function initialUserMessageFrame(prompt: string, images?: ClaudeImageBlock[]): string;
|
|
36
|
+
/**
|
|
37
|
+
* Initial stdin block for an interactive session: the initialize handshake
|
|
38
|
+
* (announces a live control-protocol client) followed by the user message.
|
|
39
|
+
* Live-verified against Claude Code 2.1.165: both frames may be written in
|
|
40
|
+
* one block without waiting for the initialize response
|
|
41
|
+
* (fixtures/protocol/control-handshake.jsonl).
|
|
42
|
+
*/
|
|
43
|
+
export declare function initialSessionFrames(prompt: string, images?: ClaudeImageBlock[]): string;
|
|
44
|
+
/** Map the native AskUserQuestion input into the typed InteractionRequest. */
|
|
45
|
+
export declare function interactionRequestFromNative(requestId: string, input: Json): InteractionRequest;
|
|
46
|
+
/**
|
|
47
|
+
* Build the allow control_response carrying the user's answers.
|
|
48
|
+
* Per the documented contract, `answers` maps the QUESTION TEXT to the
|
|
49
|
+
* selected label, multi-select labels joined with ", ", free text passed
|
|
50
|
+
* through verbatim.
|
|
51
|
+
*/
|
|
52
|
+
export declare function allowResponseFrame(requestId: string, nativeInput: Json, request: InteractionRequest, answers: InteractionAnswerSet): string;
|
|
53
|
+
/** Deny control_response: benign decline; the model continues with assumptions. */
|
|
54
|
+
export declare function denyResponseFrame(requestId: string, message: string): string;
|
|
55
|
+
/** Error control_response for request subtypes this adapter does not handle. */
|
|
56
|
+
export declare function errorResponseFrame(requestId: string, error: string): string;
|
|
57
|
+
export declare const DECLINE_MESSAGE = "No user answer is available (declined or timed out). Continue with your best assumptions and state them explicitly.";
|
|
58
|
+
/**
|
|
59
|
+
* Handle one control_request frame. AskUserQuestion is routed through the
|
|
60
|
+
* orchestrator's InteractionChannel (pausing only this tool); every other
|
|
61
|
+
* permission request is DENIED — flag-based permission modes already encode
|
|
62
|
+
* the run's policy, and headless print-mode behavior (no interactive approver)
|
|
63
|
+
* must not be silently liberalized by the control channel.
|
|
64
|
+
*/
|
|
65
|
+
export declare function handleControlRequestFrame(obj: Json, io: ChildStdin, sessionId: string, channel: InteractionChannel | undefined): AsyncGenerator<HarnessEvent>;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=interactive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAuB,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGrH,KAAK,IAAI,GAAG,GAAG,CAAC;AAEhB;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAExD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAEhD;AAED;;wEAEwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,gBAAgB,EAAO,GAAG,MAAM,CAQ/F;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,gBAAgB,EAAO,GAAG,MAAM,CAO5F;AAED,8EAA8E;AAC9E,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,kBAAkB,CAa/F;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAuB3I;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAW5E;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO3E;AAED,eAAO,MAAM,eAAe,wHAC2F,CAAC;AAExH;;;;;;GAMG;AACH,wBAAuB,yBAAyB,CAC9C,GAAG,EAAE,IAAI,EACT,EAAE,EAAE,UAAU,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kBAAkB,GAAG,SAAS,GACtC,cAAc,CAAC,YAAY,CAAC,CAqC9B"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { nowIso, redactSecrets } from "@claudexor/util";
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code bidirectional stream-json control protocol (the same channel the
|
|
4
|
+
* Agent SDK's `canUseTool` rides on):
|
|
5
|
+
*
|
|
6
|
+
* CLI -> client : {"type":"control_request","request_id":X,
|
|
7
|
+
* "request":{"subtype":"can_use_tool","tool_name":T,"input":I,...}}
|
|
8
|
+
* client -> CLI : {"type":"control_response","response":{"subtype":"success",
|
|
9
|
+
* "request_id":X,"response":{"behavior":"allow"|"deny",...}}}
|
|
10
|
+
*
|
|
11
|
+
* For AskUserQuestion the answers ride in `updatedInput.answers` as a record of
|
|
12
|
+
* question text -> selected label(s) (docs: "Handle approvals and user input").
|
|
13
|
+
* Frame shapes are LIVE-VERIFIED against Claude Code 2.1.165: the full
|
|
14
|
+
* bidirectional exchange (initialize -> can_use_tool -> allow -> ok
|
|
15
|
+
* tool_result -> result) is recorded in fixtures/protocol/control-handshake.jsonl.
|
|
16
|
+
* The control channel only activates with `--permission-prompt-tool stdio`;
|
|
17
|
+
* without it the headless CLI auto-denies interactive tools itself.
|
|
18
|
+
*/
|
|
19
|
+
export function isControlRequestFrame(obj) {
|
|
20
|
+
return obj?.type === "control_request";
|
|
21
|
+
}
|
|
22
|
+
export function isResultFrame(obj) {
|
|
23
|
+
return obj?.type === "result";
|
|
24
|
+
}
|
|
25
|
+
/** Initial user message frame for `--input-format stream-json` sessions. */
|
|
26
|
+
export function initialUserMessageFrame(prompt, images = []) {
|
|
27
|
+
const content = [{ type: "text", text: prompt }, ...images];
|
|
28
|
+
return (JSON.stringify({
|
|
29
|
+
type: "user",
|
|
30
|
+
message: { role: "user", content },
|
|
31
|
+
}) + "\n");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Initial stdin block for an interactive session: the initialize handshake
|
|
35
|
+
* (announces a live control-protocol client) followed by the user message.
|
|
36
|
+
* Live-verified against Claude Code 2.1.165: both frames may be written in
|
|
37
|
+
* one block without waiting for the initialize response
|
|
38
|
+
* (fixtures/protocol/control-handshake.jsonl).
|
|
39
|
+
*/
|
|
40
|
+
export function initialSessionFrames(prompt, images = []) {
|
|
41
|
+
const initialize = JSON.stringify({
|
|
42
|
+
type: "control_request",
|
|
43
|
+
request_id: "req_claudexor_init",
|
|
44
|
+
request: { subtype: "initialize" },
|
|
45
|
+
});
|
|
46
|
+
return initialize + "\n" + initialUserMessageFrame(prompt, images);
|
|
47
|
+
}
|
|
48
|
+
/** Map the native AskUserQuestion input into the typed InteractionRequest. */
|
|
49
|
+
export function interactionRequestFromNative(requestId, input) {
|
|
50
|
+
const rawQuestions = Array.isArray(input?.questions) ? input.questions : [];
|
|
51
|
+
const questions = rawQuestions.map((q, idx) => ({
|
|
52
|
+
id: `q${idx + 1}`,
|
|
53
|
+
question: redactSecrets(String(q?.question ?? "")).slice(0, 2000),
|
|
54
|
+
header: typeof q?.header === "string" ? redactSecrets(q.header).slice(0, 100) : null,
|
|
55
|
+
options: (Array.isArray(q?.options) ? q.options : []).map((o) => ({
|
|
56
|
+
label: redactSecrets(String(o?.label ?? "")).slice(0, 500),
|
|
57
|
+
description: typeof o?.description === "string" ? redactSecrets(o.description).slice(0, 1000) : null,
|
|
58
|
+
})),
|
|
59
|
+
multi_select: q?.multiSelect === true,
|
|
60
|
+
}));
|
|
61
|
+
return { interaction_id: requestId, questions, source_tool: "AskUserQuestion" };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Build the allow control_response carrying the user's answers.
|
|
65
|
+
* Per the documented contract, `answers` maps the QUESTION TEXT to the
|
|
66
|
+
* selected label, multi-select labels joined with ", ", free text passed
|
|
67
|
+
* through verbatim.
|
|
68
|
+
*/
|
|
69
|
+
export function allowResponseFrame(requestId, nativeInput, request, answers) {
|
|
70
|
+
const byId = new Map(answers.answers.map((a) => [a.question_id, a]));
|
|
71
|
+
const answerMap = {};
|
|
72
|
+
for (const q of request.questions) {
|
|
73
|
+
const a = byId.get(q.id);
|
|
74
|
+
if (!a)
|
|
75
|
+
continue;
|
|
76
|
+
const labels = a.selected_labels.filter((l) => l.trim().length > 0);
|
|
77
|
+
const value = a.free_text && a.free_text.trim().length > 0 ? a.free_text.trim() : labels.join(", ");
|
|
78
|
+
if (value)
|
|
79
|
+
answerMap[q.question] = value;
|
|
80
|
+
}
|
|
81
|
+
return (JSON.stringify({
|
|
82
|
+
type: "control_response",
|
|
83
|
+
response: {
|
|
84
|
+
subtype: "success",
|
|
85
|
+
request_id: requestId,
|
|
86
|
+
response: {
|
|
87
|
+
behavior: "allow",
|
|
88
|
+
updatedInput: { questions: nativeInput?.questions ?? [], answers: answerMap },
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
}) + "\n");
|
|
92
|
+
}
|
|
93
|
+
/** Deny control_response: benign decline; the model continues with assumptions. */
|
|
94
|
+
export function denyResponseFrame(requestId, message) {
|
|
95
|
+
return (JSON.stringify({
|
|
96
|
+
type: "control_response",
|
|
97
|
+
response: {
|
|
98
|
+
subtype: "success",
|
|
99
|
+
request_id: requestId,
|
|
100
|
+
response: { behavior: "deny", message, interrupt: false },
|
|
101
|
+
},
|
|
102
|
+
}) + "\n");
|
|
103
|
+
}
|
|
104
|
+
/** Error control_response for request subtypes this adapter does not handle. */
|
|
105
|
+
export function errorResponseFrame(requestId, error) {
|
|
106
|
+
return (JSON.stringify({
|
|
107
|
+
type: "control_response",
|
|
108
|
+
response: { subtype: "error", request_id: requestId, error },
|
|
109
|
+
}) + "\n");
|
|
110
|
+
}
|
|
111
|
+
export const DECLINE_MESSAGE = "No user answer is available (declined or timed out). Continue with your best assumptions and state them explicitly.";
|
|
112
|
+
/**
|
|
113
|
+
* Handle one control_request frame. AskUserQuestion is routed through the
|
|
114
|
+
* orchestrator's InteractionChannel (pausing only this tool); every other
|
|
115
|
+
* permission request is DENIED — flag-based permission modes already encode
|
|
116
|
+
* the run's policy, and headless print-mode behavior (no interactive approver)
|
|
117
|
+
* must not be silently liberalized by the control channel.
|
|
118
|
+
*/
|
|
119
|
+
export async function* handleControlRequestFrame(obj, io, sessionId, channel) {
|
|
120
|
+
const requestId = String(obj?.request_id ?? "");
|
|
121
|
+
const request = obj?.request ?? {};
|
|
122
|
+
const subtype = String(request?.subtype ?? "");
|
|
123
|
+
if (subtype !== "can_use_tool") {
|
|
124
|
+
io.write(errorResponseFrame(requestId, `unsupported control request subtype: ${subtype || "(none)"}`));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const toolName = String(request?.tool_name ?? "");
|
|
128
|
+
if (toolName !== "AskUserQuestion" || !channel) {
|
|
129
|
+
io.write(denyResponseFrame(requestId, toolName === "AskUserQuestion" ? DECLINE_MESSAGE : "Not permitted by Claudexor policy for this run."));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const interaction = interactionRequestFromNative(requestId, request?.input ?? {});
|
|
133
|
+
yield {
|
|
134
|
+
type: "interaction_requested",
|
|
135
|
+
session_id: sessionId,
|
|
136
|
+
ts: nowIso(),
|
|
137
|
+
text: interaction.questions.map((q) => q.question).join(" | ").slice(0, 500),
|
|
138
|
+
interaction,
|
|
139
|
+
};
|
|
140
|
+
let answers = null;
|
|
141
|
+
try {
|
|
142
|
+
answers = await channel.request(interaction);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
answers = null;
|
|
146
|
+
}
|
|
147
|
+
if (answers && answers.answers.length > 0) {
|
|
148
|
+
io.write(allowResponseFrame(requestId, request?.input ?? {}, interaction, answers));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
io.write(denyResponseFrame(requestId, DECLINE_MESSAGE));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"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"}
|
package/dist/parse.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HarnessEvent } from "@claudexor/schema";
|
|
2
|
+
type Json = any;
|
|
3
|
+
export type ClaudeEventParser = (obj: Json, sessionId: string) => HarnessEvent[] | null;
|
|
4
|
+
export interface ClaudeParserOptions {
|
|
5
|
+
deniedTools?: Iterable<string>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create a stateful per-run parser for Claude `--output-format stream-json`.
|
|
9
|
+
* State is needed to resolve tool_result blocks (which only carry tool_use_id)
|
|
10
|
+
* back to the tool name/kind/target of the originating tool_use block, so the
|
|
11
|
+
* normalized `tool_result` event is self-describing.
|
|
12
|
+
* Returns `null` for unrecognized top-level shapes (counted as dropped by the
|
|
13
|
+
* run loop) and `[]` for recognized events that produce nothing.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createClaudeParser(opts?: ClaudeParserOptions): ClaudeEventParser;
|
|
16
|
+
export declare function parseClaudeEvent(obj: Json, sessionId: string): HarnessEvent[] | null;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,mBAAmB,CAAC;AAGzE,KAAK,IAAI,GAAG,GAAG,CAAC;AAchB,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,KAAK,YAAY,EAAE,GAAG,IAAI,CAAC;AAExF,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,iBAAiB,CAKpF;AAwDD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE,GAAG,IAAI,CAEpF"}
|
package/dist/parse.js
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { nowIso, redactSecrets } from "@claudexor/util";
|
|
2
|
+
const EDIT_TOOLS = new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
3
|
+
const CLAUDE_TRANSIENT_RE = /overloaded|temporar(?:y|ily) unavailable|network|econnreset|etimedout|enotfound|eai_again|stream/i;
|
|
4
|
+
function toolKindFor(name) {
|
|
5
|
+
if (name === "WebSearch" || name === "WebFetch")
|
|
6
|
+
return "web";
|
|
7
|
+
if (name === "Bash" || name === "BashOutput" || name === "KillShell")
|
|
8
|
+
return "command";
|
|
9
|
+
if (name === "Glob" || name === "Grep")
|
|
10
|
+
return "search";
|
|
11
|
+
if (name === "Read" || name === "LS" || EDIT_TOOLS.has(name))
|
|
12
|
+
return "file";
|
|
13
|
+
if (name.startsWith("mcp__"))
|
|
14
|
+
return "mcp";
|
|
15
|
+
return "other";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create a stateful per-run parser for Claude `--output-format stream-json`.
|
|
19
|
+
* State is needed to resolve tool_result blocks (which only carry tool_use_id)
|
|
20
|
+
* back to the tool name/kind/target of the originating tool_use block, so the
|
|
21
|
+
* normalized `tool_result` event is self-describing.
|
|
22
|
+
* Returns `null` for unrecognized top-level shapes (counted as dropped by the
|
|
23
|
+
* run loop) and `[]` for recognized events that produce nothing.
|
|
24
|
+
*/
|
|
25
|
+
export function createClaudeParser(opts = {}) {
|
|
26
|
+
const pendingTools = new Map();
|
|
27
|
+
const deniedTools = new Set(opts.deniedTools ?? []);
|
|
28
|
+
return (obj, sessionId) => parseClaudeEventStateful(obj, sessionId, pendingTools, deniedTools);
|
|
29
|
+
}
|
|
30
|
+
const sessionTasks = new Map();
|
|
31
|
+
const SESSION_TASKS_MAX_SESSIONS = 64;
|
|
32
|
+
function applySessionTask(sessionId, tool, input) {
|
|
33
|
+
if (!sessionTasks.has(sessionId) && sessionTasks.size >= SESSION_TASKS_MAX_SESSIONS) {
|
|
34
|
+
const oldest = sessionTasks.keys().next().value;
|
|
35
|
+
if (oldest !== undefined)
|
|
36
|
+
sessionTasks.delete(oldest);
|
|
37
|
+
}
|
|
38
|
+
const list = sessionTasks.get(sessionId) ?? [];
|
|
39
|
+
if (tool === "TaskCreate") {
|
|
40
|
+
const title = typeof input["subject"] === "string" ? input["subject"] : null;
|
|
41
|
+
if (!title)
|
|
42
|
+
return false;
|
|
43
|
+
list.push({ id: String(list.length + 1), title, status: "pending" });
|
|
44
|
+
sessionTasks.set(sessionId, list);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
// TaskUpdate: {taskId, status?} — ids are 1-based creation order (the CLI's
|
|
48
|
+
// own numbering, observed live).
|
|
49
|
+
const taskId = typeof input["taskId"] === "string" ? input["taskId"] : null;
|
|
50
|
+
if (!taskId)
|
|
51
|
+
return false;
|
|
52
|
+
let task = list.find((t) => t.id === taskId);
|
|
53
|
+
const status = input["status"];
|
|
54
|
+
if (status !== "completed" && status !== "in_progress" && status !== "pending")
|
|
55
|
+
return false;
|
|
56
|
+
if (!task) {
|
|
57
|
+
// RESUMED session: the CLI's numbering continues from prior turns while
|
|
58
|
+
// this accumulator started fresh — create-on-miss with the CLI's own id
|
|
59
|
+
// (subject line unknown; the status update is still honest progress).
|
|
60
|
+
const subject = typeof input["subject"] === "string" ? input["subject"] : `Task ${taskId}`;
|
|
61
|
+
task = { id: taskId, title: subject, status };
|
|
62
|
+
list.push(task);
|
|
63
|
+
sessionTasks.set(sessionId, list);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
task.status = status;
|
|
67
|
+
sessionTasks.set(sessionId, list);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
/** Session finished: release its accumulated task list (long-lived daemons
|
|
71
|
+
* must not hold every historical session's checklist). */
|
|
72
|
+
function releaseSessionTasks(sessionId) {
|
|
73
|
+
sessionTasks.delete(sessionId);
|
|
74
|
+
}
|
|
75
|
+
function sessionTaskItems(sessionId) {
|
|
76
|
+
return (sessionTasks.get(sessionId) ?? []).map((t) => ({ id: `claude-${t.id}`, title: t.title, status: t.status }));
|
|
77
|
+
}
|
|
78
|
+
export function parseClaudeEvent(obj, sessionId) {
|
|
79
|
+
return parseClaudeEventStateful(obj, sessionId, new Map());
|
|
80
|
+
}
|
|
81
|
+
function parseClaudeEventStateful(obj, sessionId, pendingTools, deniedTools = new Set()) {
|
|
82
|
+
const ts = nowIso();
|
|
83
|
+
const type = obj?.type;
|
|
84
|
+
if (type === "system" && obj.subtype === "init") {
|
|
85
|
+
return [
|
|
86
|
+
{
|
|
87
|
+
type: "started",
|
|
88
|
+
session_id: sessionId,
|
|
89
|
+
ts,
|
|
90
|
+
observed_model: typeof obj.model === "string" ? obj.model : undefined,
|
|
91
|
+
// The native session id (when present) lets the engine resume this thread.
|
|
92
|
+
payload: {
|
|
93
|
+
tools: obj.tools,
|
|
94
|
+
plugins: obj.plugins,
|
|
95
|
+
mcp_servers: obj.mcp_servers,
|
|
96
|
+
...(typeof obj.session_id === "string" ? { native_session_id: obj.session_id } : {}),
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
if (type === "system" && obj.subtype === "api_retry") {
|
|
102
|
+
const errText = String(obj.error ?? "");
|
|
103
|
+
const ev = {
|
|
104
|
+
type: "thinking",
|
|
105
|
+
session_id: sessionId,
|
|
106
|
+
ts,
|
|
107
|
+
text: `api_retry: ${redactSecrets(errText)}`,
|
|
108
|
+
payload: { api_retry: true, retry_delay_ms: obj.retry_delay_ms },
|
|
109
|
+
};
|
|
110
|
+
// Adapter-layer translation of claude's native retry into a TYPED rate-limit
|
|
111
|
+
// signal (the budget layer reads the typed field, not the prose).
|
|
112
|
+
if (/rate.?limit|overloaded|too many requests|quota/i.test(errText)) {
|
|
113
|
+
ev.rate_limit = {
|
|
114
|
+
resets_at: null,
|
|
115
|
+
retry_delay_ms: typeof obj.retry_delay_ms === "number" ? obj.retry_delay_ms : null,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (CLAUDE_TRANSIENT_RE.test(errText)) {
|
|
119
|
+
ev.transient = {
|
|
120
|
+
kind: /overloaded|temporar(?:y|ily) unavailable/i.test(errText) ? "service_unavailable" : "network",
|
|
121
|
+
retry_delay_ms: typeof obj.retry_delay_ms === "number" ? obj.retry_delay_ms : null,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return [ev];
|
|
125
|
+
}
|
|
126
|
+
if (type === "assistant") {
|
|
127
|
+
const content = obj.message?.content ?? [];
|
|
128
|
+
const out = [];
|
|
129
|
+
for (const block of content) {
|
|
130
|
+
if (block?.type === "text" && block.text) {
|
|
131
|
+
out.push({ type: "message", session_id: sessionId, ts, text: String(block.text) });
|
|
132
|
+
}
|
|
133
|
+
else if (block?.type === "thinking" && typeof block.thinking === "string" && block.thinking.trim()) {
|
|
134
|
+
out.push({ type: "thinking", session_id: sessionId, ts, text: String(block.thinking) });
|
|
135
|
+
}
|
|
136
|
+
else if (block?.type === "tool_use") {
|
|
137
|
+
const name = String(block.name ?? "tool");
|
|
138
|
+
const input = block.input ?? {};
|
|
139
|
+
const tool = {
|
|
140
|
+
name,
|
|
141
|
+
kind: toolKindFor(name),
|
|
142
|
+
use_id: typeof block.id === "string" ? block.id : undefined,
|
|
143
|
+
target: toolTarget(name, input),
|
|
144
|
+
};
|
|
145
|
+
if (tool.use_id)
|
|
146
|
+
pendingTools.set(tool.use_id, tool);
|
|
147
|
+
if (EDIT_TOOLS.has(name)) {
|
|
148
|
+
const path = input.file_path ?? input.path ?? input.notebook_path;
|
|
149
|
+
out.push({ type: "file_change", session_id: sessionId, ts, tool, payload: { path, tool: name, tool_use_id: block.id } });
|
|
150
|
+
}
|
|
151
|
+
else if (name === "TodoWrite" && Array.isArray(input.todos)) {
|
|
152
|
+
// Typed plan progress, legacy surface: older claude CLIs plan
|
|
153
|
+
// via TodoWrite (whole-list updates; statuses map 1:1).
|
|
154
|
+
const items = input.todos.map((t, i) => ({
|
|
155
|
+
id: `claude-${i}`,
|
|
156
|
+
title: String(t.content ?? ""),
|
|
157
|
+
status: t.status === "completed" ? "completed" : t.status === "in_progress" ? "in_progress" : "pending",
|
|
158
|
+
}));
|
|
159
|
+
out.push({ type: "tool_call", session_id: sessionId, ts, text: name, tool, plan_progress: { items } });
|
|
160
|
+
}
|
|
161
|
+
else if (name === "TaskCreate" || name === "TaskUpdate") {
|
|
162
|
+
// Typed plan progress, current surface (LIVE-VERIFIED 2.1.165):
|
|
163
|
+
// claude plans via TaskCreate/TaskUpdate. The adapter accumulates the
|
|
164
|
+
// session's task list and re-emits the WHOLE list on every change
|
|
165
|
+
// (the run-event contract is last-wins).
|
|
166
|
+
const taskChanged = applySessionTask(sessionId, name, input);
|
|
167
|
+
if (taskChanged) {
|
|
168
|
+
out.push({
|
|
169
|
+
type: "tool_call",
|
|
170
|
+
session_id: sessionId,
|
|
171
|
+
ts,
|
|
172
|
+
text: name,
|
|
173
|
+
tool,
|
|
174
|
+
plan_progress: { items: sessionTaskItems(sessionId) },
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
out.push({ type: "tool_call", session_id: sessionId, ts, text: name, tool, payload: { input } });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else if (name === "ExitPlanMode" && typeof input.plan === "string" && input.plan.trim()) {
|
|
182
|
+
// The produced plan rides in ExitPlanMode's INPUT; surface it as the
|
|
183
|
+
// message it is so plan-mode runs keep their work product headless.
|
|
184
|
+
out.push({ type: "message", session_id: sessionId, ts, text: String(input.plan) });
|
|
185
|
+
out.push({ type: "tool_call", session_id: sessionId, ts, text: name, tool });
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
out.push({ type: "tool_call", session_id: sessionId, ts, text: name, tool, payload: { input } });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
194
|
+
if (type === "user") {
|
|
195
|
+
const content = obj.message?.content ?? [];
|
|
196
|
+
const out = [];
|
|
197
|
+
for (const block of content) {
|
|
198
|
+
if (block?.type === "tool_result") {
|
|
199
|
+
const detail = summarizeToolResultContent(block.content);
|
|
200
|
+
const isError = block.is_error === true;
|
|
201
|
+
const useId = typeof block.tool_use_id === "string" ? block.tool_use_id : undefined;
|
|
202
|
+
const origin = useId ? pendingTools.get(useId) : undefined;
|
|
203
|
+
if (useId)
|
|
204
|
+
pendingTools.delete(useId);
|
|
205
|
+
// ExitPlanMode and AskUserQuestion are Claude's interactive FLOW
|
|
206
|
+
// CONTROL tools, not work tools. A headless (or declined / timed-out)
|
|
207
|
+
// is_error result is their documented way of ending the interaction —
|
|
208
|
+
// translate it to a benign thinking event (detail preserved, the
|
|
209
|
+
// question text stays in the timeline) instead of a blocking error
|
|
210
|
+
// tool_result. Recovery-by-same-tool is impossible by construction for
|
|
211
|
+
// these tools, so the generic unrecovered-tool-error rule must never
|
|
212
|
+
// fail a run over them (CLAUDEXOR_BIBLE §5).
|
|
213
|
+
if (origin?.name === "ExitPlanMode" && isError) {
|
|
214
|
+
out.push({
|
|
215
|
+
type: "thinking",
|
|
216
|
+
session_id: sessionId,
|
|
217
|
+
ts,
|
|
218
|
+
text: `plan mode ended (ExitPlanMode has no headless approver${detail ? `: ${detail}` : ""})`,
|
|
219
|
+
payload: { tool: "ExitPlanMode", tool_use_id: useId },
|
|
220
|
+
});
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (origin?.name === "AskUserQuestion" && isError) {
|
|
224
|
+
out.push({
|
|
225
|
+
type: "thinking",
|
|
226
|
+
session_id: sessionId,
|
|
227
|
+
ts,
|
|
228
|
+
text: `clarifying questions declined (no user answer); the model continues with assumptions${detail ? `: ${detail}` : ""}`,
|
|
229
|
+
payload: { tool: "AskUserQuestion", tool_use_id: useId },
|
|
230
|
+
});
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const denied = isError && origin?.name !== undefined && deniedTools.has(origin.name);
|
|
234
|
+
const status = denied ? "denied" : isError ? "error" : "ok";
|
|
235
|
+
const tool = {
|
|
236
|
+
name: origin?.name ?? "tool",
|
|
237
|
+
kind: origin?.kind ?? "other",
|
|
238
|
+
use_id: useId,
|
|
239
|
+
target: origin?.target,
|
|
240
|
+
status,
|
|
241
|
+
error_summary: status === "error" ? detail || "tool result marked error" : undefined,
|
|
242
|
+
content_summary: detail || undefined,
|
|
243
|
+
};
|
|
244
|
+
out.push({
|
|
245
|
+
type: "tool_result",
|
|
246
|
+
session_id: sessionId,
|
|
247
|
+
ts,
|
|
248
|
+
text: status !== "ok" ? `tool_result: ${status}${detail ? `: ${detail}` : ""}` : "tool_result",
|
|
249
|
+
tool,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
if (type === "result") {
|
|
256
|
+
// The session is finishing: release its accumulated task list.
|
|
257
|
+
releaseSessionTasks(sessionId);
|
|
258
|
+
const out = [];
|
|
259
|
+
const u = obj.usage ?? {};
|
|
260
|
+
out.push({
|
|
261
|
+
type: "usage",
|
|
262
|
+
session_id: sessionId,
|
|
263
|
+
ts,
|
|
264
|
+
usage: {
|
|
265
|
+
input_tokens: numberOrUndef(u.input_tokens),
|
|
266
|
+
output_tokens: numberOrUndef(u.output_tokens),
|
|
267
|
+
cached_input_tokens: sumOrUndef(u.cache_read_input_tokens, u.cache_creation_input_tokens),
|
|
268
|
+
cost_usd: numberOrUndef(obj.total_cost_usd),
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
if (typeof obj.result === "string" && obj.result.trim()) {
|
|
272
|
+
out.push({ type: "message", session_id: sessionId, ts, text: obj.result });
|
|
273
|
+
}
|
|
274
|
+
if (obj.subtype && obj.subtype !== "success") {
|
|
275
|
+
// `error_max_turns` is NOT a run failure: the turn ended because it hit the
|
|
276
|
+
// configured --max-turns ceiling, with all partial work already streamed
|
|
277
|
+
// (file_change / message events). Mirror the ExitPlanMode / AskUserQuestion
|
|
278
|
+
// benign-event handling above — surface it as a normal timeline event so
|
|
279
|
+
// the run is NOT marked errored. (CLAUDEXOR_BIBLE §5: benign turn-control
|
|
280
|
+
// outcomes never fail a run.)
|
|
281
|
+
if (obj.subtype === "error_max_turns") {
|
|
282
|
+
out.push({
|
|
283
|
+
type: "thinking",
|
|
284
|
+
session_id: sessionId,
|
|
285
|
+
ts,
|
|
286
|
+
text: "turn ended at the configured max-turns limit (partial work preserved)",
|
|
287
|
+
payload: { max_turns_reached: true, num_turns: numberOrUndef(obj.num_turns) },
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
out.push({ type: "error", session_id: sessionId, ts, error: `result subtype: ${obj.subtype}` });
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
296
|
+
if (type === "system")
|
|
297
|
+
return []; // recognized but uninteresting system subtypes
|
|
298
|
+
// Control-protocol plumbing frames. Incoming control_requests are consumed
|
|
299
|
+
// by the interactive session handler BEFORE this parser; responses to OUR
|
|
300
|
+
// initialize handshake (and cancel acks) are recognized plumbing, never
|
|
301
|
+
// counted as dropped events.
|
|
302
|
+
if (type === "control_response" || type === "control_cancel_request")
|
|
303
|
+
return [];
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
function toolTarget(name, input) {
|
|
307
|
+
const candidates = [
|
|
308
|
+
input["query"],
|
|
309
|
+
input["url"],
|
|
310
|
+
input["file_path"],
|
|
311
|
+
input["path"],
|
|
312
|
+
input["command"],
|
|
313
|
+
];
|
|
314
|
+
const found = candidates.find((v) => typeof v === "string" && v.trim().length > 0);
|
|
315
|
+
return found ? redactSecrets(`${name}: ${String(found)}`).slice(0, 500) : undefined;
|
|
316
|
+
}
|
|
317
|
+
function summarizeToolResultContent(content) {
|
|
318
|
+
if (typeof content === "string")
|
|
319
|
+
return redactSecrets(content).trim().replace(/\s+/g, " ").slice(0, 1000);
|
|
320
|
+
if (Array.isArray(content)) {
|
|
321
|
+
const parts = content
|
|
322
|
+
.map((item) => {
|
|
323
|
+
if (typeof item === "string")
|
|
324
|
+
return item;
|
|
325
|
+
if (!item || typeof item !== "object" || Array.isArray(item))
|
|
326
|
+
return "";
|
|
327
|
+
const rec = item;
|
|
328
|
+
return typeof rec["text"] === "string" ? rec["text"] : typeof rec["content"] === "string" ? rec["content"] : "";
|
|
329
|
+
})
|
|
330
|
+
.filter(Boolean);
|
|
331
|
+
return redactSecrets(parts.join(" ")).trim().replace(/\s+/g, " ").slice(0, 1000);
|
|
332
|
+
}
|
|
333
|
+
if (content && typeof content === "object") {
|
|
334
|
+
return redactSecrets(JSON.stringify(content)).slice(0, 1000);
|
|
335
|
+
}
|
|
336
|
+
return "";
|
|
337
|
+
}
|
|
338
|
+
function numberOrUndef(v) {
|
|
339
|
+
return typeof v === "number" ? v : undefined;
|
|
340
|
+
}
|
|
341
|
+
function sumOrUndef(...values) {
|
|
342
|
+
const nums = values.filter((v) => typeof v === "number");
|
|
343
|
+
if (nums.length === 0)
|
|
344
|
+
return undefined;
|
|
345
|
+
return nums.reduce((a, b) => a + b, 0);
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@claudexor/harness-claude",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Claude Code adapter (claude -p --output-format stream-json).",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@claudexor/core": "1.0.0",
|
|
20
|
+
"@claudexor/schema": "1.0.0",
|
|
21
|
+
"@claudexor/util": "1.0.0",
|
|
22
|
+
"@claudexor/secrets": "1.0.0"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/razzant/claudexor.git",
|
|
27
|
+
"directory": "packages/harness-claude"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/razzant/claudexor#readme",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/razzant/claudexor/issues"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=20.19"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc",
|
|
41
|
+
"typecheck": "tsc --noEmit"
|
|
42
|
+
}
|
|
43
|
+
}
|