@dungle-scrubs/harness-cli-normalizer 0.6.5 → 0.6.6
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 +23 -8
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +5 -2
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/inspect-context.js +4 -6
- package/dist/cli/inspect-context.js.map +1 -1
- package/dist/cli/inspect-session.js +1 -1
- package/dist/cli/inspect-session.js.map +1 -1
- package/dist/cli/inspect.d.ts.map +1 -1
- package/dist/cli/inspect.js +3 -2
- package/dist/cli/inspect.js.map +1 -1
- package/dist/cli/runtime-compatibility.d.ts +4 -3
- package/dist/cli/runtime-compatibility.d.ts.map +1 -1
- package/dist/cli/runtime-compatibility.js +4 -3
- package/dist/cli/runtime-compatibility.js.map +1 -1
- package/dist/execution/context-inspection.d.ts +1 -1
- package/dist/execution/context-inspection.d.ts.map +1 -1
- package/dist/execution/context-inspection.js +28 -30
- package/dist/execution/context-inspection.js.map +1 -1
- package/dist/execution/lines.d.ts +2 -1
- package/dist/execution/lines.d.ts.map +1 -1
- package/dist/execution/lines.js +4 -1
- package/dist/execution/lines.js.map +1 -1
- package/dist/interpretation/context-inspection.d.ts +8 -0
- package/dist/interpretation/context-inspection.d.ts.map +1 -1
- package/dist/interpretation/context-inspection.js +55 -5
- package/dist/interpretation/context-inspection.js.map +1 -1
- package/dist/knowledge/claude-code.d.ts.map +1 -1
- package/dist/knowledge/claude-code.js +5 -1
- package/dist/knowledge/claude-code.js.map +1 -1
- package/dist/knowledge/descriptor.d.ts +11 -3
- package/dist/knowledge/descriptor.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/help.ts +5 -2
- package/src/cli/inspect-context.ts +4 -8
- package/src/cli/inspect-session.ts +1 -1
- package/src/cli/inspect.ts +3 -2
- package/src/cli/runtime-compatibility.ts +10 -4
- package/src/execution/context-inspection.ts +35 -30
- package/src/execution/lines.ts +5 -1
- package/src/interpretation/context-inspection.ts +73 -4
- package/src/knowledge/claude-code.ts +5 -1
- package/src/knowledge/descriptor.ts +11 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { HarnessDescriptor } from "../knowledge/descriptor.js";
|
|
2
2
|
import type { SpawnArgvOptions } from "./argv.js";
|
|
3
3
|
import { buildSpawnArgv } from "./argv.js";
|
|
4
|
+
import { contentEventsOf } from "./content.js";
|
|
4
5
|
import { ArgvRefusalError } from "./refusal.js";
|
|
5
6
|
import { asRecord } from "./shape.js";
|
|
6
7
|
|
|
@@ -16,7 +17,7 @@ export function buildContextInspectionArgv(
|
|
|
16
17
|
harness: harness.name,
|
|
17
18
|
issue: "invalid-option-value",
|
|
18
19
|
option: "context",
|
|
19
|
-
supported: ["
|
|
20
|
+
supported: ["supported native context adapter without native passthrough"],
|
|
20
21
|
});
|
|
21
22
|
}
|
|
22
23
|
return [
|
|
@@ -74,6 +75,32 @@ export type ContextInspection =
|
|
|
74
75
|
const positive = (value: unknown): value is number =>
|
|
75
76
|
typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
76
77
|
|
|
78
|
+
/** Cleanup and caller interruption take precedence. Otherwise a recognized
|
|
79
|
+
* native failure explains a failed exchange more precisely than its framing. */
|
|
80
|
+
export function settledContextInspection(facts: {
|
|
81
|
+
readonly accounting: ContextInspection;
|
|
82
|
+
readonly clean: boolean;
|
|
83
|
+
readonly exitCode: number | null;
|
|
84
|
+
readonly nativeFailure: "auth" | "limit" | null;
|
|
85
|
+
}): ContextInspection {
|
|
86
|
+
const { accounting, clean, exitCode, nativeFailure } = facts;
|
|
87
|
+
if (!clean) return { status: "unavailable", reason: "cleanup" };
|
|
88
|
+
if (
|
|
89
|
+
accounting.status === "unavailable" &&
|
|
90
|
+
(accounting.reason === "cancelled" || accounting.reason === "timeout")
|
|
91
|
+
)
|
|
92
|
+
return accounting;
|
|
93
|
+
if (nativeFailure !== null) return { status: "unavailable", reason: nativeFailure };
|
|
94
|
+
if (
|
|
95
|
+
accounting.status === "unavailable" &&
|
|
96
|
+
accounting.reason === "transport" &&
|
|
97
|
+
exitCode !== null &&
|
|
98
|
+
exitCode !== 0
|
|
99
|
+
)
|
|
100
|
+
return { status: "unavailable", reason: "native-exit" };
|
|
101
|
+
return accounting;
|
|
102
|
+
}
|
|
103
|
+
|
|
77
104
|
/** Normalize only a complete native response. A window alone says nothing
|
|
78
105
|
* about remaining capacity, and invalid compaction data must not increase it. */
|
|
79
106
|
export function contextInspectionOf(input: unknown): ContextInspection {
|
|
@@ -135,7 +162,6 @@ export function createContextProbe(inputId: string, prompt: string): ContextProb
|
|
|
135
162
|
initial: control(initializeId, { subtype: "initialize", hooks: null }),
|
|
136
163
|
staged,
|
|
137
164
|
accept(line) {
|
|
138
|
-
if (phase === "finished") return null;
|
|
139
165
|
let decoded: unknown;
|
|
140
166
|
try {
|
|
141
167
|
decoded = JSON.parse(line);
|
|
@@ -144,7 +170,46 @@ export function createContextProbe(inputId: string, prompt: string): ContextProb
|
|
|
144
170
|
return { kind: "complete", accounting: { status: "unavailable", reason: "protocol" } };
|
|
145
171
|
}
|
|
146
172
|
const frame = asRecord(decoded);
|
|
147
|
-
|
|
173
|
+
const failure = contentEventsOf("claude", decoded).find(
|
|
174
|
+
(event) => event.kind === "limit" || (event.kind === "error" && event.terminal),
|
|
175
|
+
);
|
|
176
|
+
if (failure) {
|
|
177
|
+
phase = "finished";
|
|
178
|
+
return {
|
|
179
|
+
kind: "complete",
|
|
180
|
+
accounting: {
|
|
181
|
+
status: "unavailable",
|
|
182
|
+
reason: failure.kind === "limit" ? "limit" : "native-exit",
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const content = asRecord(frame?.message)?.content;
|
|
187
|
+
const toolResult =
|
|
188
|
+
frame?.type === "user" &&
|
|
189
|
+
(frame.parent_tool_use_id != null ||
|
|
190
|
+
(Array.isArray(content) &&
|
|
191
|
+
content.some((block) => asRecord(block)?.type === "tool_result")));
|
|
192
|
+
const allowed =
|
|
193
|
+
frame !== null &&
|
|
194
|
+
!Array.isArray(decoded) &&
|
|
195
|
+
!toolResult &&
|
|
196
|
+
(frame.type === "user" ||
|
|
197
|
+
frame.type === "control_response" ||
|
|
198
|
+
frame.type === "command_lifecycle" ||
|
|
199
|
+
(frame.type === "system" &&
|
|
200
|
+
["init", "hook_started", "hook_progress", "hook_response"].includes(
|
|
201
|
+
String(frame.subtype),
|
|
202
|
+
)) ||
|
|
203
|
+
(frame.type === "result" && frame.subtype === "success" && frame.num_turns === 0) ||
|
|
204
|
+
(frame.type === "rate_limit_event" &&
|
|
205
|
+
["allowed", "allowed_warning"].includes(
|
|
206
|
+
String(asRecord(frame.rate_limit_info)?.status),
|
|
207
|
+
)));
|
|
208
|
+
if (!allowed || frame === null) {
|
|
209
|
+
phase = "finished";
|
|
210
|
+
return { kind: "complete", accounting: { status: "unavailable", reason: "protocol" } };
|
|
211
|
+
}
|
|
212
|
+
if (phase === "finished") return null;
|
|
148
213
|
if (phase === "ack" && frame.type === "user" && frame.uuid === inputId) {
|
|
149
214
|
phase = "usage";
|
|
150
215
|
return { kind: "send", line: control(usageId, { subtype: "get_context_usage" }) };
|
|
@@ -154,7 +219,11 @@ export function createContextProbe(inputId: string, prompt: string): ContextProb
|
|
|
154
219
|
return null;
|
|
155
220
|
const expected = phase === "initialize" ? initializeId : phase === "usage" ? usageId : null;
|
|
156
221
|
if (expected === null || response.request_id !== expected) return null;
|
|
157
|
-
if (
|
|
222
|
+
if (
|
|
223
|
+
response.subtype !== "success" ||
|
|
224
|
+
(phase === "initialize" &&
|
|
225
|
+
(asRecord(response.response) === null || Array.isArray(response.response)))
|
|
226
|
+
) {
|
|
158
227
|
phase = "finished";
|
|
159
228
|
return { kind: "complete", accounting: { status: "unavailable", reason: "protocol" } };
|
|
160
229
|
}
|
|
@@ -41,6 +41,7 @@ export const claudeCode: HarnessDescriptor = deepFreeze({
|
|
|
41
41
|
idFlag: "--session-id",
|
|
42
42
|
},
|
|
43
43
|
resume: {
|
|
44
|
+
admission: { kind: "invocation", modes: ["headless-turn"] },
|
|
44
45
|
// A-005: claude resumes are id-stable - the caller-assigned id survives
|
|
45
46
|
// every resume, so there is no rotation handling and forking is only the
|
|
46
47
|
// explicit --fork-session flag (deliberate branching, never a default).
|
|
@@ -151,7 +152,10 @@ export const claudeCode: HarnessDescriptor = deepFreeze({
|
|
|
151
152
|
object: "context_window",
|
|
152
153
|
usedPctField: "used_percentage",
|
|
153
154
|
},
|
|
154
|
-
nativeContextManagement:
|
|
155
|
+
nativeContextManagement: {
|
|
156
|
+
kind: "native-session-auto-compaction",
|
|
157
|
+
modes: ["headless-turn"],
|
|
158
|
+
},
|
|
155
159
|
contextInspection: {
|
|
156
160
|
kind: "claude-control-v1",
|
|
157
161
|
flags: [...STREAM_INPUT_FLAGS, "--no-session-persistence", "--replay-user-messages"],
|
|
@@ -338,6 +338,12 @@ export interface HarnessDescriptor {
|
|
|
338
338
|
* anywhere else (the v1 first-UUID-wins scar: a UUID inside quoted prompt
|
|
339
339
|
* text was returned as the session id, and resuming it started a stranger). */
|
|
340
340
|
readonly resume: {
|
|
341
|
+
/** Declared invocation support by mode, not proof that a saved session exists.
|
|
342
|
+
* Omitted retains the verification-version admission policy. */
|
|
343
|
+
readonly admission?: {
|
|
344
|
+
readonly kind: "invocation";
|
|
345
|
+
readonly modes: readonly HarnessMode[];
|
|
346
|
+
};
|
|
341
347
|
readonly style: ResumeStyle;
|
|
342
348
|
readonly flag: string;
|
|
343
349
|
readonly aliases: readonly string[];
|
|
@@ -456,16 +462,18 @@ export interface HarnessDescriptor {
|
|
|
456
462
|
readonly object: string;
|
|
457
463
|
readonly usedPctField: string;
|
|
458
464
|
} | null;
|
|
459
|
-
/** Disposable native context accounting
|
|
465
|
+
/** Disposable native context accounting; the exchange validates support.
|
|
460
466
|
* Null is unknown support, never a model-window estimate. */
|
|
461
467
|
readonly contextInspection: {
|
|
462
468
|
readonly flags: readonly string[];
|
|
463
469
|
readonly forkFlag: string;
|
|
464
470
|
readonly kind: "claude-control-v1";
|
|
465
471
|
} | null;
|
|
466
|
-
/**
|
|
472
|
+
/** Curated native context handling, not a count or enabled-state observation.
|
|
473
|
+
* Native-session handling covers the native session; callers must prepare
|
|
474
|
+
* imported history. Disabled native compaction is not detected here. */
|
|
467
475
|
readonly nativeContextManagement: {
|
|
468
|
-
readonly kind: "auto-compaction";
|
|
476
|
+
readonly kind: "auto-compaction" | "native-session-auto-compaction";
|
|
469
477
|
readonly modes: readonly HarnessMode[];
|
|
470
478
|
} | null;
|
|
471
479
|
/** Resume-most-recent support (codex --last), or null. The race it opens
|