@wildorder/nightshift 0.16.0 → 0.18.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.
Files changed (109) hide show
  1. package/README.md +289 -1
  2. package/dist/agent-runner.d.ts +95 -5
  3. package/dist/agent-runner.d.ts.map +1 -1
  4. package/dist/agent-runner.js +442 -32
  5. package/dist/agent-runner.js.map +1 -1
  6. package/dist/agent-session.d.ts +123 -0
  7. package/dist/agent-session.d.ts.map +1 -0
  8. package/dist/agent-session.js +114 -0
  9. package/dist/agent-session.js.map +1 -0
  10. package/dist/atomic-write.d.ts +18 -0
  11. package/dist/atomic-write.d.ts.map +1 -0
  12. package/dist/atomic-write.js +74 -0
  13. package/dist/atomic-write.js.map +1 -0
  14. package/dist/author.d.ts +118 -4
  15. package/dist/author.d.ts.map +1 -1
  16. package/dist/author.js +650 -163
  17. package/dist/author.js.map +1 -1
  18. package/dist/causal-analysis.d.ts +216 -0
  19. package/dist/causal-analysis.d.ts.map +1 -0
  20. package/dist/causal-analysis.js +786 -0
  21. package/dist/causal-analysis.js.map +1 -0
  22. package/dist/cli.js +22 -2
  23. package/dist/cli.js.map +1 -1
  24. package/dist/concurrency.d.ts +24 -0
  25. package/dist/concurrency.d.ts.map +1 -0
  26. package/dist/concurrency.js +28 -0
  27. package/dist/concurrency.js.map +1 -0
  28. package/dist/decider-review.d.ts +13 -1
  29. package/dist/decider-review.d.ts.map +1 -1
  30. package/dist/decider-review.js +21 -7
  31. package/dist/decider-review.js.map +1 -1
  32. package/dist/decision-ledger.d.ts +7 -0
  33. package/dist/decision-ledger.d.ts.map +1 -1
  34. package/dist/decision-ledger.js +25 -10
  35. package/dist/decision-ledger.js.map +1 -1
  36. package/dist/detect-package-manager.d.ts +10 -0
  37. package/dist/detect-package-manager.d.ts.map +1 -1
  38. package/dist/detect-package-manager.js +12 -0
  39. package/dist/detect-package-manager.js.map +1 -1
  40. package/dist/index.d.ts +8 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +8 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/manifest.d.ts +24 -5
  45. package/dist/manifest.d.ts.map +1 -1
  46. package/dist/manifest.js +254 -108
  47. package/dist/manifest.js.map +1 -1
  48. package/dist/permits.d.ts +18 -0
  49. package/dist/permits.d.ts.map +1 -1
  50. package/dist/permits.js +155 -0
  51. package/dist/permits.js.map +1 -1
  52. package/dist/preflight.d.ts +3 -0
  53. package/dist/preflight.d.ts.map +1 -1
  54. package/dist/preflight.js +73 -57
  55. package/dist/preflight.js.map +1 -1
  56. package/dist/prompt-telemetry.d.ts +64 -0
  57. package/dist/prompt-telemetry.d.ts.map +1 -0
  58. package/dist/prompt-telemetry.js +112 -0
  59. package/dist/prompt-telemetry.js.map +1 -0
  60. package/dist/provider-telemetry.d.ts +106 -0
  61. package/dist/provider-telemetry.d.ts.map +1 -0
  62. package/dist/provider-telemetry.js +423 -0
  63. package/dist/provider-telemetry.js.map +1 -0
  64. package/dist/review-pass.d.ts +52 -10
  65. package/dist/review-pass.d.ts.map +1 -1
  66. package/dist/review-pass.js +114 -30
  67. package/dist/review-pass.js.map +1 -1
  68. package/dist/run-analytics-report.d.ts +286 -0
  69. package/dist/run-analytics-report.d.ts.map +1 -0
  70. package/dist/run-analytics-report.js +1242 -0
  71. package/dist/run-analytics-report.js.map +1 -0
  72. package/dist/run-analytics.d.ts +844 -0
  73. package/dist/run-analytics.d.ts.map +1 -0
  74. package/dist/run-analytics.js +777 -0
  75. package/dist/run-analytics.js.map +1 -0
  76. package/dist/run-log.d.ts +16 -0
  77. package/dist/run-log.d.ts.map +1 -0
  78. package/dist/run-log.js +32 -0
  79. package/dist/run-log.js.map +1 -0
  80. package/dist/run-program.d.ts +268 -4
  81. package/dist/run-program.d.ts.map +1 -1
  82. package/dist/run-program.js +2508 -762
  83. package/dist/run-program.js.map +1 -1
  84. package/dist/scheduler.d.ts +75 -0
  85. package/dist/scheduler.d.ts.map +1 -0
  86. package/dist/scheduler.js +126 -0
  87. package/dist/scheduler.js.map +1 -0
  88. package/dist/verify-cache.d.ts +64 -0
  89. package/dist/verify-cache.d.ts.map +1 -0
  90. package/dist/verify-cache.js +56 -0
  91. package/dist/verify-cache.js.map +1 -0
  92. package/dist/whole-program-review.d.ts +3 -0
  93. package/dist/whole-program-review.d.ts.map +1 -1
  94. package/dist/whole-program-review.js +8 -1
  95. package/dist/whole-program-review.js.map +1 -1
  96. package/dist/worktree.d.ts +124 -0
  97. package/dist/worktree.d.ts.map +1 -0
  98. package/dist/worktree.js +397 -0
  99. package/dist/worktree.js.map +1 -0
  100. package/dist/write-queue.d.ts +25 -0
  101. package/dist/write-queue.d.ts.map +1 -0
  102. package/dist/write-queue.js +52 -0
  103. package/dist/write-queue.js.map +1 -0
  104. package/package.json +2 -2
  105. package/skills/plan-program/SKILL.md +37 -5
  106. package/dist/worktree-guard.d.ts +0 -40
  107. package/dist/worktree-guard.d.ts.map +0 -1
  108. package/dist/worktree-guard.js +0 -91
  109. package/dist/worktree-guard.js.map +0 -1
@@ -0,0 +1,106 @@
1
+ import type { Dimensions, Coverage, EvidenceReference, PointObservationInput } from "./run-analytics.js";
2
+ /**
3
+ * Provider-neutral normalization of a Claude `--output-format stream-json`
4
+ * transcript into coverage-labelled facts (WS-03, SC-08). Kept apart from
5
+ * `agent-runner.ts` so the normalizer is unit-testable against fixtures
6
+ * without spawning anything; `agent-runner.ts`'s demultiplexer feeds this
7
+ * module's accumulator the same already-parsed events it routes for
8
+ * commands/denials, so production never parses the stream twice.
9
+ *
10
+ * The one rule every field here answers to: absent or unsupported telemetry
11
+ * is `{ coverage: "unavailable" }` with no `value` — never a measured zero.
12
+ */
13
+ export declare const PROVIDER_TELEMETRY_KIND: "provider-telemetry";
14
+ /** A numeric fact with its observability label. `value` is absent whenever `coverage` is `"unavailable"`. */
15
+ export interface Measured {
16
+ coverage: Coverage;
17
+ value?: number;
18
+ unit?: string;
19
+ }
20
+ /** A string-valued fact (model identity, provider label) with its observability label. */
21
+ export interface MeasuredString {
22
+ coverage: Coverage;
23
+ value?: string;
24
+ }
25
+ /** One `compact_boundary` event, when the stream exposes one. */
26
+ export interface CompactionOccurrence {
27
+ tokensBefore: Measured;
28
+ at: Measured;
29
+ }
30
+ /**
31
+ * The internal, in-memory normalization of one spawn's provider telemetry.
32
+ * Never persisted as-is — `providerTelemetryPoints` fans it out into one
33
+ * scalar `PointObservationInput` per measured fact.
34
+ */
35
+ export interface NormalizedTelemetry {
36
+ provider: MeasuredString;
37
+ model: MeasuredString;
38
+ configuredModel: MeasuredString;
39
+ inputTokens: Measured;
40
+ outputTokens: Measured;
41
+ cacheReadTokens: Measured;
42
+ cacheCreationTokens: Measured;
43
+ reasoningTokens: Measured;
44
+ contextCapacityTokens: Measured;
45
+ peakContextOccupancyTokens: Measured;
46
+ compactions: CompactionOccurrence[];
47
+ compactionCount: Measured;
48
+ continuationTurns: Measured;
49
+ toolCalls: Measured;
50
+ fileActivity: {
51
+ reads: Measured;
52
+ writes: Measured;
53
+ edits: Measured;
54
+ };
55
+ commandOutputBytes: Measured;
56
+ costUsd?: Measured;
57
+ }
58
+ /**
59
+ * Parses `--model <value>` and `--model=<value>` out of a derived
60
+ * invocation's argv — free operator-authored args routinely carry an
61
+ * explicit model override even though `AgentConfig` has no dedicated model
62
+ * property (SC-05).
63
+ */
64
+ export declare function parseConfiguredModel(args: readonly string[]): MeasuredString;
65
+ /**
66
+ * A coarse provider label derived from the configured command when the
67
+ * stream itself exposes no model — an inference from the invocation, never
68
+ * a provider-reported fact, hence `"estimated"`.
69
+ */
70
+ export declare function providerLabelFromCommand(command: string | undefined): MeasuredString;
71
+ interface TelemetryAccumulatorOptions {
72
+ /** Precomputed from the derived invocation's argv (SC-05). */
73
+ configuredModel: MeasuredString;
74
+ /** Precomputed from the derived invocation's command, for the provider fallback. */
75
+ commandProviderGuess: MeasuredString;
76
+ }
77
+ export interface TelemetryAccumulator {
78
+ observeEvent(event: unknown): void;
79
+ finish(flags: {
80
+ observed: boolean;
81
+ corrupted: boolean;
82
+ }): NormalizedTelemetry;
83
+ }
84
+ /**
85
+ * A pure, non-throwing, stateful accumulator fed one already-parsed
86
+ * stream-json event at a time. `agent-runner.ts`'s demultiplexer routes each
87
+ * event to both its own command/denial routing and this accumulator's
88
+ * `observeEvent`, so the underlying text is parsed exactly once in
89
+ * production; `normalizeClaudeTelemetry` below wraps the same accumulator
90
+ * with its own line-splitting for standalone fixture-driven tests.
91
+ */
92
+ export declare function createTelemetryAccumulator(options: TelemetryAccumulatorOptions): TelemetryAccumulator;
93
+ /**
94
+ * Demultiplexes a whole captured stream-json string in one call, purely for
95
+ * fixture-driven tests — production feeds `createTelemetryAccumulator`
96
+ * directly from `agent-runner.ts`'s single event-parsing pass so the raw
97
+ * text is never parsed twice.
98
+ */
99
+ export declare function normalizeClaudeTelemetry(raw: string, options?: {
100
+ configuredArgs?: readonly string[];
101
+ command?: string;
102
+ }): NormalizedTelemetry;
103
+ /** One point per SC-08-enumerated metric, scalar and coverage-labelled, never a fabricated zero for a metric the stream did not expose. */
104
+ export declare function providerTelemetryPoints(telemetry: NormalizedTelemetry, dimensions: Partial<Dimensions>, evidence: EvidenceReference[]): PointObservationInput[];
105
+ export {};
106
+ //# sourceMappingURL=provider-telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-telemetry.d.ts","sourceRoot":"","sources":["../src/provider-telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEzG;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,uBAAuB,EAAG,oBAA6B,CAAC;AAErE,6GAA6G;AAC7G,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,0FAA0F;AAC1F,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iEAAiE;AACjE,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,QAAQ,CAAC;IACvB,EAAE,EAAE,QAAQ,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,cAAc,CAAC;IACtB,eAAe,EAAE,cAAc,CAAC;IAChC,WAAW,EAAE,QAAQ,CAAC;IACtB,YAAY,EAAE,QAAQ,CAAC;IACvB,eAAe,EAAE,QAAQ,CAAC;IAC1B,mBAAmB,EAAE,QAAQ,CAAC;IAC9B,eAAe,EAAE,QAAQ,CAAC;IAC1B,qBAAqB,EAAE,QAAQ,CAAC;IAChC,0BAA0B,EAAE,QAAQ,CAAC;IACrC,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,eAAe,EAAE,QAAQ,CAAC;IAC1B,iBAAiB,EAAE,QAAQ,CAAC;IAC5B,SAAS,EAAE,QAAQ,CAAC;IACpB,YAAY,EAAE;QAAE,KAAK,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,QAAQ,CAAA;KAAE,CAAC;IACrE,kBAAkB,EAAE,QAAQ,CAAC;IAC7B,OAAO,CAAC,EAAE,QAAQ,CAAC;CACpB;AAuBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,CAa5E;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CASpF;AAiBD,UAAU,2BAA2B;IACnC,8DAA8D;IAC9D,eAAe,EAAE,cAAc,CAAC;IAChC,oFAAoF;IACpF,oBAAoB,EAAE,cAAc,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,MAAM,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,mBAAmB,CAAC;CAC/E;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG,oBAAoB,CAqOrG;AAMD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACrE,mBAAmB,CA+BrB;AAED,2IAA2I;AAC3I,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,EAC/B,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,qBAAqB,EAAE,CAkEzB"}
@@ -0,0 +1,423 @@
1
+ /**
2
+ * Provider-neutral normalization of a Claude `--output-format stream-json`
3
+ * transcript into coverage-labelled facts (WS-03, SC-08). Kept apart from
4
+ * `agent-runner.ts` so the normalizer is unit-testable against fixtures
5
+ * without spawning anything; `agent-runner.ts`'s demultiplexer feeds this
6
+ * module's accumulator the same already-parsed events it routes for
7
+ * commands/denials, so production never parses the stream twice.
8
+ *
9
+ * The one rule every field here answers to: absent or unsupported telemetry
10
+ * is `{ coverage: "unavailable" }` with no `value` — never a measured zero.
11
+ */
12
+ export const PROVIDER_TELEMETRY_KIND = "provider-telemetry";
13
+ const UNAVAILABLE = { coverage: "unavailable" };
14
+ const UNAVAILABLE_STRING = { coverage: "unavailable" };
15
+ function observedNumber(value, unit) {
16
+ return { coverage: "observed", value, unit };
17
+ }
18
+ function estimatedNumber(value, unit) {
19
+ return { coverage: "estimated", value, unit };
20
+ }
21
+ function incompleteNumber(value, unit) {
22
+ return { coverage: "incomplete", value, unit };
23
+ }
24
+ /** Downgrades an observed/estimated tally to `incomplete` when the stream lost a mid-stream line; leaves anything already unavailable alone. */
25
+ function maybeIncomplete(measured, corrupted) {
26
+ if (!corrupted || measured.coverage === "unavailable")
27
+ return measured;
28
+ return { ...measured, coverage: "incomplete" };
29
+ }
30
+ /**
31
+ * Parses `--model <value>` and `--model=<value>` out of a derived
32
+ * invocation's argv — free operator-authored args routinely carry an
33
+ * explicit model override even though `AgentConfig` has no dedicated model
34
+ * property (SC-05).
35
+ */
36
+ export function parseConfiguredModel(args) {
37
+ for (let i = 0; i < args.length; i++) {
38
+ const arg = args[i];
39
+ if (arg === undefined)
40
+ continue;
41
+ const next = args[i + 1];
42
+ if (arg === "--model" && typeof next === "string") {
43
+ return { coverage: "observed", value: next };
44
+ }
45
+ if (arg.startsWith("--model=")) {
46
+ return { coverage: "observed", value: arg.slice("--model=".length) };
47
+ }
48
+ }
49
+ return UNAVAILABLE_STRING;
50
+ }
51
+ /**
52
+ * A coarse provider label derived from the configured command when the
53
+ * stream itself exposes no model — an inference from the invocation, never
54
+ * a provider-reported fact, hence `"estimated"`.
55
+ */
56
+ export function providerLabelFromCommand(command) {
57
+ if (command === undefined || command.trim() === "")
58
+ return UNAVAILABLE_STRING;
59
+ const base = command
60
+ .replaceAll("\\", "/")
61
+ .split("/")
62
+ .pop()
63
+ ?.replace(/\.(cmd|exe|bat|sh)$/iu, "");
64
+ if (base === undefined || base.trim() === "")
65
+ return UNAVAILABLE_STRING;
66
+ return { coverage: "estimated", value: base };
67
+ }
68
+ /** The text of a `tool_result` block, whether the CLI sent it as a string or as content blocks. */
69
+ function toolResultBytes(block) {
70
+ if (typeof block.content === "string")
71
+ return Buffer.byteLength(block.content, "utf8");
72
+ if (Array.isArray(block.content)) {
73
+ const texts = block.content
74
+ .filter((part) => part?.type === "text" && typeof part.text === "string")
75
+ .map((part) => part.text);
76
+ if (texts.length === 0)
77
+ return undefined;
78
+ return Buffer.byteLength(texts.join("\n"), "utf8");
79
+ }
80
+ return undefined;
81
+ }
82
+ const FILE_TOOL_KEYS = { Read: "reads", Write: "writes", Edit: "edits" };
83
+ /**
84
+ * A pure, non-throwing, stateful accumulator fed one already-parsed
85
+ * stream-json event at a time. `agent-runner.ts`'s demultiplexer routes each
86
+ * event to both its own command/denial routing and this accumulator's
87
+ * `observeEvent`, so the underlying text is parsed exactly once in
88
+ * production; `normalizeClaudeTelemetry` below wraps the same accumulator
89
+ * with its own line-splitting for standalone fixture-driven tests.
90
+ */
91
+ export function createTelemetryAccumulator(options) {
92
+ let streamModel;
93
+ let toolCallCount = 0;
94
+ let reads = 0;
95
+ let writes = 0;
96
+ let edits = 0;
97
+ let commandOutputBytes = 0;
98
+ let hadOrphanToolResult = false;
99
+ const toolNameById = new Map();
100
+ let reasoningTokens;
101
+ const compactions = [];
102
+ // Final `result`-event figures, captured once.
103
+ let sawResultEvent = false;
104
+ let inputTokens;
105
+ let outputTokens;
106
+ let cacheReadTokens;
107
+ let cacheCreationTokens;
108
+ let numTurns;
109
+ let costUsd;
110
+ let contextCapacityTokens;
111
+ let peakContextOccupancy;
112
+ function observeEvent(event) {
113
+ try {
114
+ if (event === null || typeof event !== "object")
115
+ return;
116
+ const record = event;
117
+ if (record.type === "system" && record.subtype === "init") {
118
+ if (typeof record.model === "string")
119
+ streamModel = record.model;
120
+ return;
121
+ }
122
+ if (record.type === "system" && record.subtype === "thinking_tokens") {
123
+ if (typeof record.estimated_tokens === "number")
124
+ reasoningTokens = record.estimated_tokens;
125
+ return;
126
+ }
127
+ if (record.type === "system" && record.subtype === "compact_boundary") {
128
+ const preTokens = typeof record.pre_tokens === "number" ? observedNumber(record.pre_tokens, "tokens") : UNAVAILABLE;
129
+ let at = UNAVAILABLE;
130
+ if (typeof record.timestamp === "string") {
131
+ const parsed = Date.parse(record.timestamp);
132
+ if (!Number.isNaN(parsed))
133
+ at = observedNumber(parsed, "ms-since-epoch");
134
+ }
135
+ else if (typeof record.turn === "number") {
136
+ at = observedNumber(record.turn, "turn");
137
+ }
138
+ compactions.push({ tokensBefore: preTokens, at });
139
+ return;
140
+ }
141
+ if (record.type === "assistant") {
142
+ const content = record.message?.content;
143
+ if (Array.isArray(content)) {
144
+ for (const block of content) {
145
+ if (block?.type !== "tool_use")
146
+ continue;
147
+ toolCallCount += 1;
148
+ const name = typeof block.name === "string" ? block.name : undefined;
149
+ const id = typeof block.id === "string" ? block.id : undefined;
150
+ if (name !== undefined && id !== undefined)
151
+ toolNameById.set(id, name);
152
+ if (name !== undefined && name in FILE_TOOL_KEYS) {
153
+ const key = FILE_TOOL_KEYS[name];
154
+ if (key === "reads")
155
+ reads += 1;
156
+ else if (key === "writes")
157
+ writes += 1;
158
+ else
159
+ edits += 1;
160
+ }
161
+ }
162
+ }
163
+ return;
164
+ }
165
+ if (record.type === "user") {
166
+ const content = record.message?.content;
167
+ if (Array.isArray(content)) {
168
+ for (const block of content) {
169
+ if (block?.type !== "tool_result")
170
+ continue;
171
+ const toolUseId = typeof block.tool_use_id === "string" ? block.tool_use_id : undefined;
172
+ const toolName = toolUseId === undefined ? undefined : toolNameById.get(toolUseId);
173
+ if (toolName === undefined) {
174
+ hadOrphanToolResult = true;
175
+ continue;
176
+ }
177
+ if (toolName !== "Bash")
178
+ continue;
179
+ const bytes = toolResultBytes(block);
180
+ if (bytes !== undefined)
181
+ commandOutputBytes += bytes;
182
+ }
183
+ }
184
+ return;
185
+ }
186
+ if (record.type === "result") {
187
+ sawResultEvent = true;
188
+ if (typeof record.num_turns === "number")
189
+ numTurns = record.num_turns;
190
+ if (typeof record.total_cost_usd === "number")
191
+ costUsd = record.total_cost_usd;
192
+ const usage = record.usage;
193
+ if (usage) {
194
+ if (typeof usage.input_tokens === "number")
195
+ inputTokens = usage.input_tokens;
196
+ if (typeof usage.output_tokens === "number")
197
+ outputTokens = usage.output_tokens;
198
+ if (typeof usage.cache_read_input_tokens === "number")
199
+ cacheReadTokens = usage.cache_read_input_tokens;
200
+ if (typeof usage.cache_creation_input_tokens === "number") {
201
+ cacheCreationTokens = usage.cache_creation_input_tokens;
202
+ }
203
+ const iterations = usage.iterations;
204
+ if (Array.isArray(iterations)) {
205
+ let peak;
206
+ let anyIterationPartial = false;
207
+ for (const iteration of iterations) {
208
+ const fields = [
209
+ iteration.input_tokens,
210
+ iteration.output_tokens,
211
+ iteration.cache_read_input_tokens,
212
+ iteration.cache_creation_input_tokens,
213
+ ];
214
+ // An iteration exposing none of the four occupancy fields (e.g.
215
+ // `{}`) contributes no usable measurement at all — folding it
216
+ // in via numberOr0 would invent a fabricated 0 that could win
217
+ // the max, misreporting "the provider observed zero occupancy"
218
+ // for an iteration the provider told us nothing about. Skip it
219
+ // rather than let it participate in the max.
220
+ if (!fields.some((field) => typeof field === "number")) {
221
+ anyIterationPartial = true;
222
+ continue;
223
+ }
224
+ // An iteration with only *some* of the four fields present is
225
+ // still counted (using 0 for the fields it does lack), but the
226
+ // result can undercount that iteration's true occupancy, so the
227
+ // overall peak is downgraded to "incomplete" rather than
228
+ // "observed" below.
229
+ if (!fields.every((field) => typeof field === "number"))
230
+ anyIterationPartial = true;
231
+ const occupancy = fields.reduce((sum, field) => sum + numberOr0(field), 0);
232
+ if (peak === undefined || occupancy > peak)
233
+ peak = occupancy;
234
+ }
235
+ if (peak !== undefined)
236
+ peakContextOccupancy = { value: peak, incomplete: anyIterationPartial };
237
+ }
238
+ }
239
+ const modelUsage = record.modelUsage;
240
+ if (modelUsage) {
241
+ const key = streamModel !== undefined && modelUsage[streamModel] ? streamModel : Object.keys(modelUsage)[0];
242
+ const entry = key === undefined ? undefined : modelUsage[key];
243
+ if (entry && typeof entry.contextWindow === "number")
244
+ contextCapacityTokens = entry.contextWindow;
245
+ if (costUsd === undefined && entry && typeof entry.costUSD === "number")
246
+ costUsd = entry.costUSD;
247
+ }
248
+ }
249
+ }
250
+ catch {
251
+ // The accumulator is total and non-throwing (SC-13): one malformed
252
+ // event never poisons every fact collected so far.
253
+ }
254
+ }
255
+ function finish(flags) {
256
+ // Model/provider precedence (SC-05) does not gate on whether the stream
257
+ // itself parsed: `streamModel` is only ever set from an observed stream,
258
+ // so this is a no-op widening for the observed branch and, for a
259
+ // non-NDJSON or crashed spawn, still honors an explicit `--model` in the
260
+ // invocation args and a command-derived provider guess rather than
261
+ // discarding facts the invocation itself already gave us.
262
+ const model = streamModel !== undefined
263
+ ? { coverage: "observed", value: streamModel }
264
+ : options.configuredModel.value !== undefined
265
+ ? { coverage: "observed", value: options.configuredModel.value }
266
+ : UNAVAILABLE_STRING;
267
+ const provider = streamModel !== undefined ? { coverage: "observed", value: "claude" } : options.commandProviderGuess;
268
+ if (!flags.observed) {
269
+ return {
270
+ provider,
271
+ model,
272
+ configuredModel: options.configuredModel,
273
+ inputTokens: UNAVAILABLE,
274
+ outputTokens: UNAVAILABLE,
275
+ cacheReadTokens: UNAVAILABLE,
276
+ cacheCreationTokens: UNAVAILABLE,
277
+ reasoningTokens: UNAVAILABLE,
278
+ contextCapacityTokens: UNAVAILABLE,
279
+ peakContextOccupancyTokens: UNAVAILABLE,
280
+ compactions: [],
281
+ compactionCount: UNAVAILABLE,
282
+ continuationTurns: UNAVAILABLE,
283
+ toolCalls: UNAVAILABLE,
284
+ fileActivity: { reads: UNAVAILABLE, writes: UNAVAILABLE, edits: UNAVAILABLE },
285
+ commandOutputBytes: UNAVAILABLE,
286
+ };
287
+ }
288
+ const commandOutputIncomplete = flags.corrupted && hadOrphanToolResult;
289
+ return {
290
+ provider,
291
+ model,
292
+ configuredModel: options.configuredModel,
293
+ inputTokens: sawResultEvent && inputTokens !== undefined ? observedNumber(inputTokens, "tokens") : UNAVAILABLE,
294
+ outputTokens: sawResultEvent && outputTokens !== undefined ? observedNumber(outputTokens, "tokens") : UNAVAILABLE,
295
+ cacheReadTokens: sawResultEvent && cacheReadTokens !== undefined ? observedNumber(cacheReadTokens, "tokens") : UNAVAILABLE,
296
+ cacheCreationTokens: sawResultEvent && cacheCreationTokens !== undefined
297
+ ? observedNumber(cacheCreationTokens, "tokens")
298
+ : UNAVAILABLE,
299
+ reasoningTokens: reasoningTokens !== undefined ? estimatedNumber(reasoningTokens, "tokens") : UNAVAILABLE,
300
+ contextCapacityTokens: contextCapacityTokens !== undefined ? observedNumber(contextCapacityTokens, "tokens") : UNAVAILABLE,
301
+ peakContextOccupancyTokens: peakContextOccupancy === undefined
302
+ ? UNAVAILABLE
303
+ : peakContextOccupancy.incomplete
304
+ ? incompleteNumber(peakContextOccupancy.value, "tokens")
305
+ : observedNumber(peakContextOccupancy.value, "tokens"),
306
+ compactions,
307
+ compactionCount: compactions.length > 0 ? observedNumber(compactions.length, "count") : UNAVAILABLE,
308
+ continuationTurns: sawResultEvent && numTurns !== undefined ? observedNumber(numTurns, "count") : UNAVAILABLE,
309
+ toolCalls: maybeIncomplete(observedNumber(toolCallCount, "count"), flags.corrupted),
310
+ fileActivity: {
311
+ reads: maybeIncomplete(observedNumber(reads, "count"), flags.corrupted),
312
+ writes: maybeIncomplete(observedNumber(writes, "count"), flags.corrupted),
313
+ edits: maybeIncomplete(observedNumber(edits, "count"), flags.corrupted),
314
+ },
315
+ commandOutputBytes: commandOutputIncomplete
316
+ ? incompleteNumber(commandOutputBytes, "bytes")
317
+ : observedNumber(commandOutputBytes, "bytes"),
318
+ ...(costUsd !== undefined ? { costUsd: observedNumber(costUsd, "usd") } : {}),
319
+ };
320
+ }
321
+ return { observeEvent, finish };
322
+ }
323
+ function numberOr0(value) {
324
+ return typeof value === "number" ? value : 0;
325
+ }
326
+ /**
327
+ * Demultiplexes a whole captured stream-json string in one call, purely for
328
+ * fixture-driven tests — production feeds `createTelemetryAccumulator`
329
+ * directly from `agent-runner.ts`'s single event-parsing pass so the raw
330
+ * text is never parsed twice.
331
+ */
332
+ export function normalizeClaudeTelemetry(raw, options = {}) {
333
+ const accumulator = createTelemetryAccumulator({
334
+ configuredModel: parseConfiguredModel(options.configuredArgs ?? []),
335
+ commandProviderGuess: providerLabelFromCommand(options.command),
336
+ });
337
+ let firstLineSeen = false;
338
+ let isNdjson = true;
339
+ let corrupted = false;
340
+ for (const rawLine of raw.split("\n")) {
341
+ const line = rawLine.trim();
342
+ if (line === "")
343
+ continue;
344
+ if (!firstLineSeen) {
345
+ firstLineSeen = true;
346
+ try {
347
+ accumulator.observeEvent(JSON.parse(line));
348
+ }
349
+ catch {
350
+ isNdjson = false;
351
+ }
352
+ continue;
353
+ }
354
+ if (!isNdjson)
355
+ break;
356
+ try {
357
+ accumulator.observeEvent(JSON.parse(line));
358
+ }
359
+ catch {
360
+ corrupted = true;
361
+ }
362
+ }
363
+ return accumulator.finish({ observed: firstLineSeen && isNdjson, corrupted });
364
+ }
365
+ /** One point per SC-08-enumerated metric, scalar and coverage-labelled, never a fabricated zero for a metric the stream did not expose. */
366
+ export function providerTelemetryPoints(telemetry, dimensions, evidence) {
367
+ const points = [];
368
+ const stringPoint = (label, fact, detailOverride) => {
369
+ points.push({
370
+ kind: PROVIDER_TELEMETRY_KIND,
371
+ label,
372
+ coverage: fact.coverage,
373
+ ...(detailOverride !== undefined
374
+ ? { detail: detailOverride }
375
+ : fact.value !== undefined
376
+ ? { detail: fact.value }
377
+ : {}),
378
+ dimensions,
379
+ evidence,
380
+ });
381
+ };
382
+ const numberPoint = (label, fact) => {
383
+ points.push({
384
+ kind: PROVIDER_TELEMETRY_KIND,
385
+ label,
386
+ coverage: fact.coverage,
387
+ ...(fact.value === undefined ? {} : { value: fact.value }),
388
+ ...(fact.unit === undefined ? {} : { unit: fact.unit }),
389
+ dimensions,
390
+ evidence,
391
+ });
392
+ };
393
+ stringPoint("provider", telemetry.provider);
394
+ const modelMismatch = telemetry.model.value !== undefined &&
395
+ telemetry.configuredModel.value !== undefined &&
396
+ telemetry.model.value !== telemetry.configuredModel.value;
397
+ stringPoint("model", telemetry.model, modelMismatch
398
+ ? `${telemetry.model.value} (configured invocation specified ${telemetry.configuredModel.value})`
399
+ : undefined);
400
+ stringPoint("configured-model", telemetry.configuredModel);
401
+ numberPoint("input-tokens", telemetry.inputTokens);
402
+ numberPoint("output-tokens", telemetry.outputTokens);
403
+ numberPoint("cache-read-tokens", telemetry.cacheReadTokens);
404
+ numberPoint("cache-creation-tokens", telemetry.cacheCreationTokens);
405
+ numberPoint("reasoning-tokens", telemetry.reasoningTokens);
406
+ numberPoint("context-capacity-tokens", telemetry.contextCapacityTokens);
407
+ numberPoint("peak-context-occupancy-tokens", telemetry.peakContextOccupancyTokens);
408
+ numberPoint("continuation-turns", telemetry.continuationTurns);
409
+ numberPoint("tool-calls", telemetry.toolCalls);
410
+ numberPoint("file-activity-reads", telemetry.fileActivity.reads);
411
+ numberPoint("file-activity-writes", telemetry.fileActivity.writes);
412
+ numberPoint("file-activity-edits", telemetry.fileActivity.edits);
413
+ numberPoint("command-output-bytes", telemetry.commandOutputBytes);
414
+ numberPoint("compaction-count", telemetry.compactionCount);
415
+ if (telemetry.costUsd !== undefined)
416
+ numberPoint("cost-usd", telemetry.costUsd);
417
+ for (const occurrence of telemetry.compactions) {
418
+ numberPoint("compaction-tokens-before", occurrence.tokensBefore);
419
+ numberPoint("compaction-at", occurrence.at);
420
+ }
421
+ return points;
422
+ }
423
+ //# sourceMappingURL=provider-telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-telemetry.js","sourceRoot":"","sources":["../src/provider-telemetry.ts"],"names":[],"mappings":"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"}
@@ -49,8 +49,30 @@ export type FindingDestination = "decision-oneway" | "decision" | "report";
49
49
  * advisory -> "report"
50
50
  */
51
51
  export declare function findingDestination(severity: Severity): FindingDestination;
52
- export declare const REVIEW_ROUND_CAP = 2;
53
- export type StopReason = "converged" | "cap-reached" | "reviewer-error" | "no-reviewer";
52
+ /** Test critique gets one reviewer-then-fix cycle at every size (SC-16). */
53
+ export declare const TEST_CRITIQUE_CYCLES = 1;
54
+ export type WorkstreamSize = "S" | "M" | "L";
55
+ /**
56
+ * Total, never-throwing normalization of the manifest's optional free-string
57
+ * `size` (`manifest.ts`). Accepts the `plan-program` skill's `S`/`M`/`L` in
58
+ * any case with surrounding whitespace, and the long forms a human might
59
+ * type by hand. Anything else — absent, empty, "XL", a sentence — is M, the
60
+ * middle, because an unknown size must not silently buy or lose a cycle.
61
+ */
62
+ export declare function normalizeWorkstreamSize(size: string | undefined): WorkstreamSize;
63
+ /**
64
+ * The spec-critique cycle budget and the sentence the run report prints to
65
+ * disclose it (SC-16). Constants, never config keys.
66
+ * S, M -> 1 "size S — one reviewer-then-fix cycle (S and M get one, L gets two)"
67
+ * L -> 2 "size L — two reviewer-then-fix cycles"
68
+ */
69
+ export declare function specCritiqueBudget(size: string | undefined): {
70
+ cycles: number;
71
+ note: string;
72
+ };
73
+ /** Test critique's cycle budget note — the constant string every size shares (SC-16). */
74
+ export declare const TEST_CRITIQUE_CYCLE_NOTE = "one cycle for every size";
75
+ export type StopReason = "converged" | "cycles-spent" | "reviewer-error" | "no-reviewer";
54
76
  export interface ReviewRoundResult {
55
77
  findings: Finding[];
56
78
  errors: string[];
@@ -65,13 +87,29 @@ export interface ReviewPassOutcome {
65
87
  errors: string[];
66
88
  writerNotes: string[];
67
89
  severityCounts: Record<Severity, number>;
90
+ /** Fix passes actually spawned — 0 on a converged or errored pass. */
91
+ fixesRun: number;
92
+ /** The cycle budget this pass was given (SC-16). */
93
+ cyclesAllotted: number;
94
+ /** Why that budget, in human words: "size M", "one cycle for every size". */
95
+ cycleNote: string;
96
+ /**
97
+ * True when the findings in `open` were read by a reviewer *after* the
98
+ * last fix — i.e. `open` is a residue rather than a raised set. Under this
99
+ * workstream's loop that holds only when the pass converged or errored
100
+ * without fixing.
101
+ */
102
+ openReReadAfterFix: boolean;
68
103
  }
69
104
  export interface RunReviewPassOptions {
70
- cap?: number;
71
- /** Invoke the reviewer for round `n`; parse and return its findings. Stage-owned. */
72
- review: (round: number, priorOpen: Finding[]) => Promise<ReviewRoundResult>;
73
- /** Re-brief the writer with this round's findings; return its prose reply. Stage-owned. */
74
- respond: (round: number, findings: Finding[]) => Promise<{
105
+ /** How many reviewer-then-fix cycles this pass is allotted (§3.7). */
106
+ cycles: number;
107
+ /** Why that number, in human words, for the report — e.g. "size M". */
108
+ cycleNote: string;
109
+ /** Invoke the reviewer for cycle `n`; parse and return its findings. Stage-owned. */
110
+ review: (cycle: number, priorOpen: Finding[]) => Promise<ReviewRoundResult>;
111
+ /** Triage-and-fix. Stage-owned. */
112
+ respond: (cycle: number, findings: Finding[]) => Promise<{
75
113
  note?: string;
76
114
  }>;
77
115
  }
@@ -89,8 +127,12 @@ export declare function findingsToLedgerEvents(options: FindingsToLedgerOptions)
89
127
  /**
90
128
  * A human-facing summary of one completed (or absent) pass, for the run
91
129
  * report. `label` is the pass name the stage supplies ("Spec critique",
92
- * "Test critique"). Returns markdown lines; the caller splices them under
93
- * its own section heading.
130
+ * "Test critique"). `verifyStepLabel` names what ends each cycle "runner
131
+ * verify" (the configured verify suite, the build side) or "runner spec
132
+ * check" (the runner's own deterministic artifact/scope/change gate, the
133
+ * authoring side, §3.7.3) — defaulting to the build side's phrase since that
134
+ * is the more common caller. Returns markdown lines; the caller splices them
135
+ * under its own section heading.
94
136
  */
95
- export declare function renderPassReport(label: string, outcome: ReviewPassOutcome): string[];
137
+ export declare function renderPassReport(label: string, outcome: ReviewPassOutcome, verifyStepLabel?: string): string[];
96
138
  //# sourceMappingURL=review-pass.d.ts.map