@robmclarty/volley 0.6.1 → 0.7.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/dist/index.d.ts CHANGED
@@ -1,14 +1,6 @@
1
- import { UsageTotals, FinishReason, Throughput, StreamChunk, Engine } from 'fascicle';
2
- import { z } from 'zod';
3
-
4
- /**
5
- * Shared value and type contracts for volley.
6
- *
7
- * Type aliases are PascalCase; value-level identifiers are snake_case.
8
- * Fascicle's usage/cost types are used verbatim so summaries carry the
9
- * substrate's shapes, not a re-derivation.
10
- */
11
-
1
+ import { Engine, FinishReason, StreamChunk, Throughput, UsageTotals } from "fascicle";
2
+ import { z } from "zod";
3
+ //#region src/types.d.ts
12
4
  type Verdict = 'approved' | 'changes_requested';
13
5
  type CriticPreset = 'reviewer' | 'optimizer' | 'researcher';
14
6
  /** Transport for the critic role. The critic is read-only + schema-constrained,
@@ -30,116 +22,128 @@ type CostSource = 'provider_reported' | 'engine_derived' | 'unknown';
30
22
  * died. Recorded alongside a critic retry so a degraded run says
31
23
  * *what* failed, not just that it retried. */
32
24
  type CauseKind = 'provider_5xx' | 'network' | 'unknown';
33
- type RunStatus = 'running' | 'success' | 'budget_exhausted' | 'cost_cap_reached'
25
+ type RunStatus = 'running' | 'success' | 'budget_exhausted' | 'cost_cap_reached' |
34
26
  /** The builder edited the gate that judges it, under `--fail-on-gate-edit`:
35
27
  * the run halts on the spot rather than iterating, because a check the builder
36
28
  * can rewrite is not evidence the work is done. */
37
- | 'gate_edit_blocked' | 'interrupted' | 'error';
29
+ 'gate_edit_blocked' | 'interrupted' | 'error';
38
30
  /** User-facing configuration, before resolution (config file / flags). */
39
31
  type VolleyConfig = {
40
- prompt: string;
41
- workspace: string;
42
- criteria: string;
43
- check?: CheckMode;
44
- builder_model?: string;
45
- builder_provider?: BuilderProvider;
46
- builder_max_steps?: number;
47
- allow_unsandboxed_builder?: boolean;
48
- critic_model?: string;
49
- critic_provider?: CriticProvider;
50
- builder_permission_mode?: BuilderPermissionMode;
51
- critic?: CriticPreset | (string & {});
52
- max_iterations?: number;
53
- max_cost_usd?: number | null;
54
- git_checkpoints?: boolean;
55
- worktree?: boolean;
56
- discard_worktree?: boolean;
57
- gate_paths?: string[];
58
- fail_on_gate_edit?: boolean;
59
- sandbox_image?: string;
60
- verbose?: boolean;
61
- quiet?: boolean;
62
- json?: boolean;
63
- show_thinking?: boolean;
64
- dry_run?: boolean;
32
+ prompt: string;
33
+ workspace: string;
34
+ criteria: string;
35
+ check?: CheckMode;
36
+ builder_model?: string;
37
+ builder_provider?: BuilderProvider;
38
+ builder_url?: string;
39
+ builder_max_steps?: number;
40
+ allow_unsandboxed_builder?: boolean;
41
+ critic_model?: string;
42
+ critic_provider?: CriticProvider;
43
+ critic_url?: string;
44
+ builder_permission_mode?: BuilderPermissionMode;
45
+ critic?: CriticPreset | (string & {});
46
+ max_iterations?: number;
47
+ max_cost_usd?: number | null;
48
+ git_checkpoints?: boolean;
49
+ worktree?: boolean;
50
+ discard_worktree?: boolean;
51
+ gate_paths?: string[];
52
+ fail_on_gate_edit?: boolean;
53
+ sandbox_image?: string;
54
+ verbose?: boolean;
55
+ quiet?: boolean;
56
+ json?: boolean;
57
+ show_thinking?: boolean;
58
+ dry_run?: boolean;
65
59
  };
66
60
  /** Fully resolved run configuration; `.volley/config.json` mirrors this. */
67
61
  type ResolvedConfig = {
68
- version: 2;
69
- run_id: string;
70
- started_at: string;
71
- prompt: string;
72
- criteria: string;
73
- check: CheckMode;
74
- check_resolved: CheckRunnerKind;
75
- builder_model: string;
76
- builder_provider: BuilderProvider;
77
- builder_max_steps: number;
78
- /** Operator opt-out permitting a local (non-`claude_cli`) builder to run
79
- * without a sandbox — it gets a real host bash. Refused by default. */
80
- allow_unsandboxed_builder: boolean;
81
- critic_model: string;
82
- critic_provider: CriticProvider;
83
- builder_permission_mode: BuilderPermissionMode;
84
- critic_preset: CriticPreset | 'custom';
85
- critic_prompt_path: string | null;
86
- max_iterations: number;
87
- max_cost_usd: number | null;
88
- git_checkpoints: boolean;
89
- /** Isolate the builder run's effects in a per-run git worktree: the
90
- * builder/critic file tools' containment root moves to the worktree, while
91
- * `.volley/` state stays under `workspace` (the control plane). Off by
92
- * default; requires the workspace to be a git repository. */
93
- worktree: boolean;
94
- /** Throw a `--worktree` run's effects away at teardown even when it converged:
95
- * the run branch is force-deleted rather than kept, because only the
96
- * verdicts are wanted. This is what `volley matrix` sweeps with — one config,
97
- * many builder×critic seats, no per-seat commits or branches left anywhere.
98
- * Refused without `--worktree`; `--git` still wins, so a `--worktree --git`
99
- * run integrates exactly as it always has. */
100
- discard_worktree: boolean;
101
- /** Glob patterns naming the *gate*: the tests, fixtures, and check
102
- * configuration that decide whether the builder's work passes. An edit to one
103
- * is reported to the critic and recorded in the summary — and refused outright
104
- * under `fail_on_gate_edit`. Defaults to `DEFAULT_GATE_PATTERNS`; a config's
105
- * own list replaces it, because what counts as the gate is the task's call
106
- * (a test-writing task edits tests by design). */
107
- gate_paths: string[];
108
- /** Halt the run when the builder edits a `gate_paths` match, instead of
109
- * reporting it and continuing. Off by default: a gate edit is legitimate often
110
- * enough that refusing it by default would break honest tasks, and the mark on
111
- * the summary already makes it impossible to miss. */
112
- fail_on_gate_edit: boolean;
113
- /** Container image the local-builder Docker sandbox runs. Defaults to
114
- * volley's own `Dockerfile`-built image; `--sandbox-image <tag>` /
115
- * `VOLLEY_SANDBOX_IMAGE` override it. Meaningful only for a local builder —
116
- * the `claude_cli` path never uses Docker. */
117
- sandbox_image: string;
118
- workspace: string;
119
- verbose: boolean;
120
- quiet: boolean;
121
- json: boolean;
122
- show_thinking: boolean;
62
+ version: 2;
63
+ run_id: string;
64
+ started_at: string;
65
+ prompt: string;
66
+ criteria: string;
67
+ check: CheckMode;
68
+ check_resolved: CheckRunnerKind;
69
+ builder_model: string;
70
+ builder_provider: BuilderProvider;
71
+ /** The builder seat's own model server base URL (`--builder-url`), as given.
72
+ * It is normalized, and crossed to the host LLM endpoint when contained, only
73
+ * where it is used, because the crossing depends on where the run executes.
74
+ * Null falls back to the provider's env var (`VOLLEY_OLLAMA_URL` /
75
+ * `VOLLEY_LMSTUDIO_URL`), then its default, never to the critic's URL. Only
76
+ * a provider volley reaches at a base URL (ollama, lmstudio) takes one. */
77
+ builder_url: string | null;
78
+ builder_max_steps: number;
79
+ /** Operator opt-out permitting a local (non-`claude_cli`) builder to run
80
+ * without a sandbox — it gets a real host bash. Refused by default. */
81
+ allow_unsandboxed_builder: boolean;
82
+ critic_model: string;
83
+ critic_provider: CriticProvider;
84
+ /** The critic seat's own model server base URL (`--critic-url`), as given;
85
+ * resolved like `builder_url`, and null never falls back to the builder's. */
86
+ critic_url: string | null;
87
+ builder_permission_mode: BuilderPermissionMode;
88
+ critic_preset: CriticPreset | 'custom';
89
+ critic_prompt_path: string | null;
90
+ max_iterations: number;
91
+ max_cost_usd: number | null;
92
+ git_checkpoints: boolean;
93
+ /** Isolate the builder run's effects in a per-run git worktree: the
94
+ * builder/critic file tools' containment root moves to the worktree, while
95
+ * `.volley/` state stays under `workspace` (the control plane). Off by
96
+ * default; requires the workspace to be a git repository. */
97
+ worktree: boolean;
98
+ /** Throw a `--worktree` run's effects away at teardown even when it converged:
99
+ * the run branch is force-deleted rather than kept, because only the
100
+ * verdicts are wanted. This is what `volley matrix` sweeps with — one config,
101
+ * many builder×critic seats, no per-seat commits or branches left anywhere.
102
+ * Refused without `--worktree`; `--git` still wins, so a `--worktree --git`
103
+ * run integrates exactly as it always has. */
104
+ discard_worktree: boolean;
105
+ /** Glob patterns naming the *gate*: the tests, fixtures, and check
106
+ * configuration that decide whether the builder's work passes. An edit to one
107
+ * is reported to the critic and recorded in the summary — and refused outright
108
+ * under `fail_on_gate_edit`. Defaults to `DEFAULT_GATE_PATTERNS`; a config's
109
+ * own list replaces it, because what counts as the gate is the task's call
110
+ * (a test-writing task edits tests by design). */
111
+ gate_paths: string[];
112
+ /** Halt the run when the builder edits a `gate_paths` match, instead of
113
+ * reporting it and continuing. Off by default: a gate edit is legitimate often
114
+ * enough that refusing it by default would break honest tasks, and the mark on
115
+ * the summary already makes it impossible to miss. */
116
+ fail_on_gate_edit: boolean;
117
+ /** Container image the local-builder Docker sandbox runs. Defaults to
118
+ * volley's own `Dockerfile`-built image; `--sandbox-image <tag>` /
119
+ * `VOLLEY_SANDBOX_IMAGE` override it. Meaningful only for a local builder —
120
+ * the `claude_cli` path never uses Docker. */
121
+ sandbox_image: string;
122
+ workspace: string;
123
+ verbose: boolean;
124
+ quiet: boolean;
125
+ json: boolean;
126
+ show_thinking: boolean;
123
127
  };
124
128
  /** One failing check slot's raw artifact, for the critic prompt. */
125
129
  type CheckArtifact = {
126
- slot: string;
127
- path: string | null;
128
- content: string;
129
- truncated: boolean;
130
+ slot: string;
131
+ path: string | null;
132
+ content: string;
133
+ truncated: boolean;
130
134
  };
131
135
  type CheckResult = {
132
- ran: boolean;
133
- runner: CheckRunnerKind;
134
- ok: boolean;
135
- exit_code: number | null;
136
- duration_ms: number;
137
- failing_slots: string[];
138
- detail: CheckArtifact[];
139
- /** Raw checkride summary JSON (when the runner is checkride). */
140
- summary?: unknown;
141
- /** Captured combined output (when the runner is a shell command). */
142
- log?: string;
136
+ ran: boolean;
137
+ runner: CheckRunnerKind;
138
+ ok: boolean;
139
+ exit_code: number | null;
140
+ duration_ms: number;
141
+ failing_slots: string[];
142
+ detail: CheckArtifact[];
143
+ /** Raw checkride summary JSON (when the runner is checkride). */
144
+ summary?: unknown;
145
+ /** Captured combined output (when the runner is a shell command). */
146
+ log?: string;
143
147
  };
144
148
  /** How one path changed between the run's baseline and the builder's output.
145
149
  * `renamed` covers git's rename/copy detection (the destination path is the one
@@ -150,175 +154,184 @@ type ChangeStatus = 'added' | 'modified' | 'deleted' | 'renamed' | 'unknown';
150
154
  * passes. A gate edit is not misconduct by itself (some tasks are *about* the
151
155
  * tests); it is the fact that makes a green check prove less. */
152
156
  type ChangedFile = {
153
- path: string;
154
- status: ChangeStatus;
155
- gate: boolean;
157
+ path: string;
158
+ status: ChangeStatus;
159
+ gate: boolean;
156
160
  };
157
161
  /** What the builder changed since the run's baseline, as the harness sees it
158
162
  * (`src/changes.ts`). Null in `LoopState` when the build root is not a git
159
163
  * repository — change detection is evidence, never a precondition. */
160
164
  type ChangeSet = {
161
- /** The commit the changes are measured against — the build root's HEAD before
162
- * the first iteration. Null in a repository with no commits yet, where only
163
- * untracked files can be reported. */
164
- baseline: string | null;
165
- /** The changed paths, sorted, capped at the collection limit. */
166
- files: ChangedFile[];
167
- /** Every gate-matching path — computed over the *full* list before the cap,
168
- * so truncation can never hide a gate edit. */
169
- gate_edits: string[];
170
- /** How many paths changed in total, before the cap. */
171
- total: number;
172
- truncated: boolean;
165
+ /** The commit the changes are measured against — the build root's HEAD before
166
+ * the first iteration. Null in a repository with no commits yet, where only
167
+ * untracked files can be reported. */
168
+ baseline: string | null;
169
+ /** The changed paths, sorted, capped at the collection limit. */
170
+ files: ChangedFile[];
171
+ /** Every gate-matching path — computed over the *full* list before the cap,
172
+ * so truncation can never hide a gate edit. */
173
+ gate_edits: string[];
174
+ /** How many paths changed in total, before the cap. */
175
+ total: number;
176
+ truncated: boolean;
173
177
  };
174
178
  /** Per-phase record for iteration summaries. */
175
179
  type PhaseRecord = {
176
- provider: string;
177
- model: string;
178
- session_id: string | null;
179
- /** Wall-clock of the phase's model work, the same measure for every provider
180
- * so an all-local run and an all-Claude run compare directly. The builder's is
181
- * fascicle's `GenerateResult.timing`: the whole call, every turn and the tools
182
- * between them. The critic's spans its whole degradation ladder, failed
183
- * attempts included, since no one result's timing covers the attempts before
184
- * it. Neither counts the Ollama prewarm. */
185
- duration_ms: number;
186
- usage: UsageTotals;
187
- cost_usd: number | null;
188
- cost_source: CostSource;
189
- /** How the phase's generate call ended. For a local builder,
190
- * `'max_steps'` is a budget cutoff surfaced as a warning, not an error. */
191
- finish_reason: FinishReason;
192
- /** Tool calls fascicle executed in this phase, and how many were recovered
193
- * from assistant text rather than returned structurally — the raw
194
- * counts behind the salvage-rate health metric. */
195
- tool_calls: number;
196
- salvaged_tool_calls: number;
197
- /** Provider-error retries that preceded this phase's successful call
198
- * — the local-critic degradation ladder's first rung: a stochastic
199
- * Ollama stream death is retried once before falling back. Set on the critic
200
- * record (0 when the first call succeeded); absent on the builder, which is
201
- * not retried this build. Additive — old summary consumers ignore it. */
202
- retries?: number;
203
- /** The `cause_kind` of the retried provider error, recorded with `retries`.
204
- * Absent when no retry happened. */
205
- retry_cause_kind?: CauseKind;
206
- /** This local-critic verdict was rendered by the tool-less fallback rung:
207
- * the tool-bearing critique kept dying on the provider's stream
208
- * even after the bounded retry, so the critic judged with no read access —
209
- * grounded only by the criteria, the raw check artifacts, and a workspace file
210
- * inventory. Set (true) on a degraded critic record; absent on a full
211
- * critique and on the builder. Additive, and a degraded verdict is *always*
212
- * marked so it never passes silently as a full one. */
213
- critic_degraded?: boolean;
214
- /** Output tokens per second over the model's own turns (tool execution and
215
- * retry backoff excluded), from fascicle's per-step timing. `basis` is
216
- * `decode` when every turn streamed, `blended` when any round trip counted
217
- * prefill and network too — always the case for `claude_cli`, whose rate
218
- * fascicle derives from the CLI's reported API time. Absent when no turn
219
- * carried timing. Additive. */
220
- throughput?: Throughput;
180
+ provider: string;
181
+ model: string;
182
+ session_id: string | null;
183
+ /** Wall-clock of the phase's model work, the same measure for every provider
184
+ * so an all-local run and an all-Claude run compare directly. The builder's is
185
+ * fascicle's `GenerateResult.timing`: the whole call, every turn and the tools
186
+ * between them. The critic's spans its whole degradation ladder, failed
187
+ * attempts included, since no one result's timing covers the attempts before
188
+ * it. Neither counts the Ollama prewarm. */
189
+ duration_ms: number;
190
+ usage: UsageTotals;
191
+ cost_usd: number | null;
192
+ cost_source: CostSource;
193
+ /** How the phase's generate call ended. For a local builder,
194
+ * `'max_steps'` is a budget cutoff surfaced as a warning, not an error. */
195
+ finish_reason: FinishReason;
196
+ /** Tool calls fascicle executed in this phase, and how many were recovered
197
+ * from assistant text rather than returned structurally — the raw
198
+ * counts behind the salvage-rate health metric. */
199
+ tool_calls: number;
200
+ salvaged_tool_calls: number;
201
+ /** Provider-error retries that preceded this phase's successful call
202
+ * — the local-critic degradation ladder's first rung: a stochastic
203
+ * Ollama stream death is retried once before falling back. Set on the critic
204
+ * record (0 when the first call succeeded); absent on the builder, which is
205
+ * not retried this build. Additive — old summary consumers ignore it. */
206
+ retries?: number;
207
+ /** The `cause_kind` of the retried provider error, recorded with `retries`.
208
+ * Absent when no retry happened. */
209
+ retry_cause_kind?: CauseKind;
210
+ /** This local-critic verdict was rendered by the tool-less fallback rung:
211
+ * the tool-bearing critique kept dying on the provider's stream
212
+ * even after the bounded retry, so the critic judged with no read access —
213
+ * grounded only by the criteria, the raw check artifacts, and a workspace file
214
+ * inventory. Set (true) on a degraded critic record; absent on a full
215
+ * critique and on the builder. Additive, and a degraded verdict is *always*
216
+ * marked so it never passes silently as a full one. */
217
+ critic_degraded?: boolean;
218
+ /** Output tokens per second over the model's own turns (tool execution and
219
+ * retry backoff excluded), from fascicle's per-step timing. `basis` is
220
+ * `decode` when every turn streamed, `blended` when any round trip counted
221
+ * prefill and network too — always the case for `claude_cli`, whose rate
222
+ * fascicle derives from the CLI's reported API time. Absent when no turn
223
+ * carried timing. Additive.
224
+ *
225
+ * On Ollama, `decode` holds only while a turn's first chunk arrives as its
226
+ * first token is generated. Ollama sends a tool call whole, so a turn whose
227
+ * only output is a tool call dispatches nothing until generation ends, and
228
+ * its tokens are divided by the last few milliseconds: a non-thinking seat's
229
+ * rate reads far too high until robmclarty/fascicle#12 times those turns
230
+ * another way. A thinking seat needs ai-sdk-ollama 4.3.0 or later, which
231
+ * streams the reasoning even though volley never sets `think`. */
232
+ throughput?: Throughput;
221
233
  };
222
234
  type HaltReason = 'cost_cap' | 'gate_edit' | null;
223
235
  /** Carry-state threaded through the fascicle loop. */
224
236
  type LoopState = {
225
- iteration: number;
226
- iteration_started_at: string;
227
- feedback: string | null;
228
- verdict: Verdict | null;
229
- unmet_criteria: string[];
230
- check: CheckResult | null;
231
- /** What the builder changed this iteration, measured against the run's
232
- * baseline (`src/changes.ts`). Null when the build root is not a git
233
- * repository, and before the first `build` step of a run. */
234
- changes: ChangeSet | null;
235
- builder: PhaseRecord | null;
236
- critic: PhaseRecord | null;
237
- total_usage: UsageTotals;
238
- total_cost_usd: number;
239
- builder_cost_usd: number;
240
- critic_cost_usd: number;
241
- check_duration_ms: number;
242
- iteration_cost_usd: number;
243
- halt: HaltReason;
244
- cost_warned: boolean;
237
+ iteration: number;
238
+ iteration_started_at: string;
239
+ feedback: string | null;
240
+ verdict: Verdict | null;
241
+ unmet_criteria: string[];
242
+ check: CheckResult | null;
243
+ /** What the builder changed this iteration, measured against the run's
244
+ * baseline (`src/changes.ts`). Null when the build root is not a git
245
+ * repository, and before the first `build` step of a run. */
246
+ changes: ChangeSet | null;
247
+ builder: PhaseRecord | null;
248
+ critic: PhaseRecord | null;
249
+ total_usage: UsageTotals;
250
+ total_cost_usd: number;
251
+ builder_cost_usd: number;
252
+ critic_cost_usd: number;
253
+ check_duration_ms: number;
254
+ iteration_cost_usd: number;
255
+ halt: HaltReason;
256
+ cost_warned: boolean;
245
257
  };
246
258
  /** Projection of final loop state; `.volley/summary.json` mirrors this. */
247
259
  type RunResult = {
248
- run_id: string;
249
- status: RunStatus;
250
- started_at: string;
251
- completed_at: string | null;
252
- iterations_completed: number;
253
- total_usage: UsageTotals;
254
- total_cost_usd: number;
255
- builder_cost_usd: number;
256
- critic_cost_usd: number;
257
- check_duration_ms: number;
258
- final_verdict: Verdict | null;
259
- /** The run branch teardown left behind because this run's work was never
260
- * integrated: under `--worktree` without `--git` a converged run has no
261
- * other copy of its effects, so teardown commits them onto `volley/<run id>`
262
- * and keeps the branch instead of force-deleting it. Null whenever nothing
263
- * survived — every non-worktree run, every integrated run, every discarded
264
- * one. `--json` consumers read it here; `.volley/summary.json` mirrors it. */
265
- salvaged_branch: string | null;
260
+ run_id: string;
261
+ status: RunStatus;
262
+ started_at: string;
263
+ completed_at: string | null;
264
+ iterations_completed: number;
265
+ total_usage: UsageTotals;
266
+ total_cost_usd: number;
267
+ builder_cost_usd: number;
268
+ critic_cost_usd: number;
269
+ check_duration_ms: number;
270
+ final_verdict: Verdict | null;
271
+ /** The run branch teardown left behind because this run's work was never
272
+ * integrated: under `--worktree` without `--git` a converged run has no
273
+ * other copy of its effects, so teardown commits them onto `volley/<run id>`
274
+ * and keeps the branch instead of force-deleting it. Null whenever nothing
275
+ * survived — every non-worktree run, every integrated run, every discarded
276
+ * one. `--json` consumers read it here; `.volley/summary.json` mirrors it. */
277
+ salvaged_branch: string | null;
266
278
  };
267
-
279
+ //#endregion
280
+ //#region src/config.d.ts
268
281
  /** `@path/to/file` reads the file; any other string passes through. */
269
- declare function expand_at_file(value: string, cwd: string): string;
282
+ export declare function expand_at_file(value: string, cwd: string): string;
270
283
  /** Load a `volley.config.ts` / `.js` file's default export. */
271
- declare function load_config_file(path: string): Promise<VolleyConfig>;
284
+ export declare function load_config_file(path: string): Promise<VolleyConfig>;
272
285
  type ResolveOptions = {
273
- cwd?: string;
274
- run_id?: string;
275
- started_at?: string;
276
- env?: Record<string, string | undefined>;
286
+ cwd?: string;
287
+ run_id?: string;
288
+ started_at?: string;
289
+ env?: Record<string, string | undefined>;
277
290
  };
278
291
  /** Merge, expand, and validate a raw `VolleyConfig` into a `ResolvedConfig`.
279
292
  * `check_resolved` comes from check detection against the workspace, so the
280
293
  * SDK and the CLI resolve `auto` and a command check the same way. */
281
- declare function resolve_config(raw: VolleyConfig, options?: ResolveOptions): ResolvedConfig;
282
-
294
+ export declare function resolve_config(raw: VolleyConfig, options?: ResolveOptions): ResolvedConfig;
295
+ //#endregion
296
+ //#region src/render/format.d.ts
283
297
  type Role = 'builder' | 'critic' | 'check';
284
-
285
- /**
286
- * Live output renderer: consumes `StreamChunk`s from each
287
- * `generate` call plus volley's own phase/cost lines, and writes human
288
- * progress to stderr. Streaming is a display concern only — the trajectory
289
- * jsonl is the durable record.
290
- */
291
-
298
+ //#endregion
299
+ //#region src/render/renderer.d.ts
292
300
  type RenderMode = 'default' | 'verbose' | 'quiet' | 'json';
293
301
  type RendererOptions = {
294
- mode: RenderMode;
295
- show_thinking: boolean;
296
- color: boolean;
297
- max_cost_usd: number | null;
298
- write?: (text: string) => void;
302
+ mode: RenderMode;
303
+ show_thinking: boolean;
304
+ color: boolean;
305
+ max_cost_usd: number | null;
306
+ write?: (text: string) => void;
299
307
  };
300
308
  type Renderer = {
301
- builder_chunk: (chunk: StreamChunk) => void;
302
- critic_chunk: (chunk: StreamChunk) => void;
303
- phase_start: (iteration: number, phase: Role) => void;
304
- phase_end: (iteration: number, phase: Role, ok: boolean, detail?: string) => void;
305
- cost_line: (iteration: number, phase: Role, phase_cost: number | null, run_total: number) => void;
306
- info: (message: string) => void;
307
- warn: (message: string) => void;
308
- error: (message: string) => void;
309
- final_summary: (result: RunResult) => void;
309
+ builder_chunk: (chunk: StreamChunk) => void;
310
+ critic_chunk: (chunk: StreamChunk) => void;
311
+ phase_start: (iteration: number, phase: Role) => void;
312
+ phase_end: (iteration: number, phase: Role, ok: boolean, detail?: string) => void;
313
+ cost_line: (iteration: number, phase: Role, phase_cost: number | null, run_total: number) => void;
314
+ info: (message: string) => void;
315
+ warn: (message: string) => void;
316
+ error: (message: string) => void;
317
+ final_summary: (result: RunResult) => void;
310
318
  };
311
- declare function create_renderer(options: RendererOptions): Renderer;
312
-
319
+ export declare function create_renderer(options: RendererOptions): Renderer;
320
+ //#endregion
321
+ //#region src/orchestrator.d.ts
313
322
  type OrchestratorDeps = {
314
- renderer: Renderer;
315
- engine?: Engine;
316
- abort?: AbortSignal;
317
- install_signal_handlers?: boolean;
323
+ renderer: Renderer;
324
+ /** An engine to run both seats on in place of the ones built from the
325
+ * config. It serves both seats as-is, so the seat URLs then steer only
326
+ * volley's own requests (prewarm and the context probe), not model calls. */
327
+ engine?: Engine;
328
+ abort?: AbortSignal;
329
+ install_signal_handlers?: boolean;
318
330
  };
319
- declare function run_volley(config: ResolvedConfig, deps: OrchestratorDeps, resume_from?: LoopState | null): Promise<RunResult>;
320
-
321
- declare function initial_state(): LoopState;
331
+ export declare function run_volley(config: ResolvedConfig, deps: OrchestratorDeps, resume_from?: LoopState | null): Promise<RunResult>;
332
+ //#endregion
333
+ //#region src/loop_state.d.ts
334
+ export declare function initial_state(): LoopState;
322
335
  /** All stopping conditions live here: acceptance, cost cap, the gate
323
336
  * edit refusal, and — implicitly via `max_rounds` — the iteration budget.
324
337
  * Success wins when it and the cap land on the same iteration.
@@ -327,34 +340,30 @@ declare function initial_state(): LoopState;
327
340
  * it: the run passed a check the builder had rewritten, so the pass is exactly
328
341
  * what is in question. It stops the run instead of iterating, because a model
329
342
  * that just edited the gate is not a promising candidate to be asked again. */
330
- declare function gate(config: ResolvedConfig, state: LoopState): {
331
- stop: boolean;
332
- state: LoopState;
343
+ export declare function gate(config: ResolvedConfig, state: LoopState): {
344
+ stop: boolean;
345
+ state: LoopState;
333
346
  };
334
- declare function status_of(value: LoopState, converged: boolean): RunStatus;
335
-
336
- /**
337
- * Critic invocation: a read-only session (`claude_cli`, or a local model with
338
- * volley's read tools) returning a schema-validated structured verdict. The
339
- * harness — not the critic — writes `.volley/feedback.md` and `.volley/verdict`.
340
- */
341
-
342
- declare const verdict_schema: z.ZodObject<{
343
- verdict: z.ZodEnum<{
344
- approved: "approved";
345
- changes_requested: "changes_requested";
346
- }>;
347
- feedback: z.ZodString;
348
- unmet_criteria: z.ZodArray<z.ZodString>;
347
+ export declare function status_of(value: LoopState, converged: boolean): RunStatus;
348
+ //#endregion
349
+ //#region src/critic/run.d.ts
350
+ export declare const verdict_schema: z.ZodObject<{
351
+ verdict: z.ZodEnum<{
352
+ approved: "approved";
353
+ changes_requested: "changes_requested";
354
+ }>;
355
+ feedback: z.ZodString;
356
+ unmet_criteria: z.ZodArray<z.ZodString>;
349
357
  }, z.core.$strip>;
350
358
  type VerdictOutput = z.infer<typeof verdict_schema>;
351
-
359
+ //#endregion
360
+ //#region src/sandbox.d.ts
352
361
  /** Canonical identity of the allowlist bridge the examples create (`docker
353
362
  * network create --subnet <SANDBOX_NETWORK_SUBNET> <SANDBOX_NETWORK_NAME>`) and
354
363
  * the host `DOCKER-USER` rules scope to. Exported so the blessed examples
355
364
  * share one spelling of the invocation spec. */
356
- declare const SANDBOX_NETWORK_NAME = "volley-sandbox-net";
357
- declare const SANDBOX_NETWORK_SUBNET = "172.31.99.0/24";
365
+ export declare const SANDBOX_NETWORK_NAME = "volley-sandbox-net";
366
+ export declare const SANDBOX_NETWORK_SUBNET = "172.31.99.0/24";
358
367
  /**
359
368
  * The container's egress posture. Under whole-process containment
360
369
  * the model client and the `fetch` tool run inside the container, so its
@@ -390,7 +399,7 @@ type SandboxNetwork = 'none' | 'allowlist';
390
399
  * collapses the allowlist targets onto the host gateway (`host.docker.internal`,
391
400
  * the Linux-portable spelling — harmless where Docker Desktop already provides it).
392
401
  */
393
- declare function network_run_args(network: SandboxNetwork, network_name: string): string[];
402
+ export declare function network_run_args(network: SandboxNetwork, network_name: string): string[];
394
403
  /**
395
404
  * The hardened `docker run` argv that launches volley inside its container.
396
405
  * Pure and exported so the flag set is unit-testable without a
@@ -417,30 +426,32 @@ declare function network_run_args(network: SandboxNetwork, network_name: string)
417
426
  * `--read-only` rootfs is an explicit tmpfs or volume; the bind-mounted worktree
418
427
  * is the one host-visible write path.
419
428
  */
420
- declare function sandbox_run_args(options: {
421
- image: string;
422
- build_root: string;
423
- uid: number | null;
424
- gid: number | null;
425
- store_volume?: string | null;
426
- network: SandboxNetwork;
427
- network_name: string;
428
- name?: string | null;
429
- env?: ReadonlyArray<readonly [string, string]>;
430
- labels?: ReadonlyArray<readonly [string, string]>;
431
- entrypoint?: string | null;
432
- command?: ReadonlyArray<string>;
429
+ export declare function sandbox_run_args(options: {
430
+ image: string;
431
+ build_root: string;
432
+ uid: number | null;
433
+ gid: number | null;
434
+ store_volume?: string | null;
435
+ network: SandboxNetwork;
436
+ network_name: string;
437
+ name?: string | null;
438
+ env?: ReadonlyArray<readonly [string, string]>;
439
+ labels?: ReadonlyArray<readonly [string, string]>;
440
+ entrypoint?: string | null;
441
+ command?: ReadonlyArray<string>;
433
442
  }): string[];
434
-
435
- declare const EXIT_SUCCESS = 0;
436
- declare const EXIT_BUDGET_EXHAUSTED = 2;
437
- declare const EXIT_BUILDER_ERROR = 3;
438
- declare const EXIT_CHECK_ERROR = 4;
439
- declare const EXIT_CONFIG_ERROR = 5;
440
- declare const EXIT_CRITIC_ERROR = 6;
441
- declare const EXIT_COST_CAP = 7;
442
- declare const EXIT_INTERRUPTED = 130;
443
- declare function exit_code_for_status(status: RunStatus): number;
444
- declare function exit_code_for_error(err: unknown): number;
445
-
446
- export { type BuilderPermissionMode, type CheckArtifact, type CheckMode, type CheckResult, type CheckRunnerKind, type CostSource, type CriticPreset, type CriticProvider, EXIT_BUDGET_EXHAUSTED, EXIT_BUILDER_ERROR, EXIT_CHECK_ERROR, EXIT_CONFIG_ERROR, EXIT_COST_CAP, EXIT_CRITIC_ERROR, EXIT_INTERRUPTED, EXIT_SUCCESS, type HaltReason, type LoopState, type PhaseRecord, type RenderMode, type Renderer, type RendererOptions, type ResolvedConfig, type RunResult, type RunStatus, SANDBOX_NETWORK_NAME, SANDBOX_NETWORK_SUBNET, type SandboxNetwork, type Verdict, type VerdictOutput, type VolleyConfig, create_renderer, exit_code_for_error, exit_code_for_status, expand_at_file, gate, initial_state, load_config_file, network_run_args, resolve_config, run_volley, sandbox_run_args, status_of, verdict_schema };
443
+ //#endregion
444
+ //#region src/exit_codes.d.ts
445
+ export declare const EXIT_SUCCESS = 0;
446
+ export declare const EXIT_BUDGET_EXHAUSTED = 2;
447
+ export declare const EXIT_BUILDER_ERROR = 3;
448
+ export declare const EXIT_CHECK_ERROR = 4;
449
+ export declare const EXIT_CONFIG_ERROR = 5;
450
+ export declare const EXIT_CRITIC_ERROR = 6;
451
+ export declare const EXIT_COST_CAP = 7;
452
+ export declare const EXIT_INTERRUPTED = 130;
453
+ export declare function exit_code_for_status(status: RunStatus): number;
454
+ export declare function exit_code_for_error(err: unknown): number;
455
+ //#endregion
456
+ export type { BuilderPermissionMode, CheckArtifact, CheckMode, CheckResult, CheckRunnerKind, CostSource, CriticPreset, CriticProvider, HaltReason, LoopState, PhaseRecord, RenderMode, Renderer, RendererOptions, ResolvedConfig, RunResult, RunStatus, SandboxNetwork, Verdict, VerdictOutput, VolleyConfig };
457
+ //# sourceMappingURL=index.d.ts.map