@warble/codex-local 0.4.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.
@@ -0,0 +1,981 @@
1
+ declare class CodexDispatchError extends Error {
2
+ constructor(message: string);
3
+ }
4
+
5
+ /** The deliberately small host-facing contract for provider-owned model discovery. */
6
+ declare const MODEL_CATALOG_VERSION: 1;
7
+ interface ModelCatalogModel {
8
+ model: string;
9
+ displayName: string;
10
+ description?: string;
11
+ isDefault?: boolean;
12
+ reasoningEfforts?: Array<{
13
+ value: string;
14
+ displayName: string;
15
+ description?: string;
16
+ }>;
17
+ }
18
+ type ModelCatalogUnavailableCode = "not_authenticated" | "runtime_unavailable" | "timeout" | "protocol_error";
19
+ type ModelCatalogResult = {
20
+ version: typeof MODEL_CATALOG_VERSION;
21
+ status: "ready";
22
+ provider: "codex";
23
+ models: ModelCatalogModel[];
24
+ } | {
25
+ version: typeof MODEL_CATALOG_VERSION;
26
+ status: "unavailable";
27
+ provider: "codex";
28
+ code: ModelCatalogUnavailableCode;
29
+ retryable: boolean;
30
+ };
31
+ interface DiscoverCodexModelsOptions {
32
+ cwd?: string;
33
+ codexHome?: string;
34
+ codexBin?: string;
35
+ timeoutMs?: number;
36
+ env?: NodeJS.ProcessEnv;
37
+ }
38
+ /**
39
+ * List authenticated Codex models over app-server without creating a thread or a turn.
40
+ * Only explicitly mapped model-picker fields ever leave this module.
41
+ */
42
+ declare function discoverCodexModels(options?: DiscoverCodexModelsOptions): Promise<ModelCatalogResult>;
43
+
44
+ /**
45
+ * Host-verifiable contract for a bound-project enrichment run.
46
+ *
47
+ * This is deliberately a pure contract, not a Codex runtime implementation. The current local
48
+ * target has no human-approval callback for gated writes, so callers can draft and validate this
49
+ * envelope but must wall-hit before attempting to execute it. A host that later provides approval
50
+ * and sink-scoped tools can use the same deterministic policy without exposing raw material,
51
+ * credentials, provider session ids, or project-side state files.
52
+ */
53
+ declare const ENRICHMENT_CONTRACT_VERSION: "1";
54
+ declare const ENRICHMENT_SINKS: readonly ["mdl_model_description", "mdl_column_description", "knowledge_rule", "knowledge_sql", "cube", "view", "relationship", "mdl_metric", "calculated_column"];
55
+ type EnrichmentSink = (typeof ENRICHMENT_SINKS)[number];
56
+ type EnrichmentMode = "grill" | "autopilot";
57
+ type EnrichmentConfidence = "high" | "medium" | "low";
58
+ type EnrichmentStatus = "completed" | "paused_for_decision" | "rejected" | "failed";
59
+ type EnrichmentDecisionAction = "accept" | "edit" | "skip";
60
+ type EnrichmentOperationRisk = "low_risk" | "high_impact" | "raw_current_conflict" | "ambiguous_sink";
61
+ interface EnrichmentEvidence {
62
+ /** Opaque reference, never a raw excerpt or credential-bearing path. */
63
+ id: string;
64
+ kind: "structural" | "raw_claim" | "inference" | "probe";
65
+ confidence: EnrichmentConfidence;
66
+ /** A non-sensitive locator/digest supplied by the executor, never source content. */
67
+ locatorDigest: string;
68
+ }
69
+ interface EnrichmentChange {
70
+ operationId: string;
71
+ sink: EnrichmentSink;
72
+ /** Relative path inside the selected sink, never an absolute/workspace path. */
73
+ path: string;
74
+ /** Enrichment is append-only; replacements are never representable. */
75
+ operation: "append";
76
+ /** Opaque canonical digest of executor-held content; raw payload stays out of this contract. */
77
+ contentDigest: string;
78
+ evidenceIds: string[];
79
+ }
80
+ interface EnrichmentProposal {
81
+ id: string;
82
+ hash: string;
83
+ projectRevision: string;
84
+ mode: EnrichmentMode;
85
+ changes: EnrichmentChange[];
86
+ evidence: EnrichmentEvidence[];
87
+ rawCurrentConflict: boolean;
88
+ ambiguousSink: boolean;
89
+ }
90
+ interface EnrichmentDecision {
91
+ proposalId: string;
92
+ proposalHash: string;
93
+ projectRevision: string;
94
+ operationId: string;
95
+ action: EnrichmentDecisionAction;
96
+ }
97
+ /** A pending request is an identity-bearing terminal state, not prose asking for approval. */
98
+ interface EnrichmentDecisionRequest {
99
+ id: string;
100
+ proposalId: string;
101
+ proposalHash: string;
102
+ projectRevision: string;
103
+ operationId: string;
104
+ action: "pending";
105
+ }
106
+ /**
107
+ * A host-issued approval record. It is supplied out-of-band to validation; no model output,
108
+ * terminal decision, secret, or model-generated signature can stand in for this record.
109
+ */
110
+ interface HostApprovalAttestation {
111
+ id: string;
112
+ projectRevision: string;
113
+ proposalHash: string;
114
+ operationId: string;
115
+ sink: EnrichmentSink;
116
+ risk: Exclude<EnrichmentOperationRisk, "low_risk">;
117
+ }
118
+ /** The host's canonical operation classification, never copied from a terminal envelope. */
119
+ interface TrustedEnrichmentOperation {
120
+ operationId: string;
121
+ sink: EnrichmentSink;
122
+ risk: EnrichmentOperationRisk;
123
+ }
124
+ /**
125
+ * Snapshot of operations completed before the terminal being checked. A host may back this with a
126
+ * durable ledger or reconstruct it from an authoritative audit stream after provider-session loss.
127
+ */
128
+ interface CompletedOperationLedger {
129
+ wasCompleted(operationId: string): boolean;
130
+ }
131
+ /** Trusted, host-owned inputs required to validate a terminal envelope. */
132
+ interface EnrichmentHostContext {
133
+ projectRevision: string;
134
+ proposalId: string;
135
+ proposalHash: string;
136
+ operations: readonly TrustedEnrichmentOperation[];
137
+ approvals: readonly HostApprovalAttestation[];
138
+ completedOperations: CompletedOperationLedger;
139
+ }
140
+ interface ValidationProof {
141
+ operationId: string;
142
+ status: "passed" | "failed" | "not_required";
143
+ verifier: "context_validate" | "cube_sql_only";
144
+ proofDigest: string;
145
+ }
146
+ interface BuildProof {
147
+ status: "passed" | "failed" | "not_run";
148
+ verifier: "context_build";
149
+ proofDigest: string | null;
150
+ }
151
+ interface EnrichmentAudit {
152
+ appliedOperationIds: string[];
153
+ skippedOperationIds: string[];
154
+ revertedOperationIds: string[];
155
+ /** Resume state is host-owned; no gaps/state artifact is ever written in the project. */
156
+ resume: "provider_session" | "reconstructed" | "not_resumed";
157
+ }
158
+ interface EnrichmentTerminal {
159
+ contractVersion: typeof ENRICHMENT_CONTRACT_VERSION;
160
+ mode: EnrichmentMode;
161
+ status: EnrichmentStatus;
162
+ projectRevision: string;
163
+ proposal: Pick<EnrichmentProposal, "id" | "hash">;
164
+ decision: EnrichmentDecision | EnrichmentDecisionRequest | null;
165
+ evidence: EnrichmentEvidence[];
166
+ changes: EnrichmentChange[];
167
+ validations: ValidationProof[];
168
+ build: BuildProof;
169
+ audit: EnrichmentAudit;
170
+ }
171
+ type EnrichmentDisposition = {
172
+ kind: "ready_to_apply";
173
+ operationIds: string[];
174
+ skippedOperationIds: string[];
175
+ } | {
176
+ kind: "requires_decision";
177
+ operationIds: string[];
178
+ reasons: string[];
179
+ skippedOperationIds: string[];
180
+ } | {
181
+ kind: "requires_redraft";
182
+ operationId: string;
183
+ } | {
184
+ kind: "stale_approval";
185
+ reason: "project_revision" | "proposal_hash" | "proposal_id";
186
+ } | {
187
+ kind: "invalid";
188
+ reason: string;
189
+ };
190
+ interface EnrichmentPolicyInput {
191
+ proposal: EnrichmentProposal;
192
+ host: EnrichmentHostContext;
193
+ /** Successful build proof captured before the enrichment run starts. */
194
+ currentBuild: BuildProof;
195
+ decision?: EnrichmentDecision;
196
+ }
197
+ /**
198
+ * Pure policy for one proposal. It makes the native grill/autopilot split inspectable by a host:
199
+ * completed operation ids are removed before dispatch, making a reconstructed resume replay-safe.
200
+ */
201
+ declare function decideEnrichment(input: EnrichmentPolicyInput): EnrichmentDisposition;
202
+ /**
203
+ * Validates a terminal against trusted host context. Terminal decisions are display/audit data only:
204
+ * they are never authority to apply a high-risk operation or to suppress a prior-completion ledger.
205
+ */
206
+ declare function assertEnrichmentTerminal(terminal: EnrichmentTerminal, host: EnrichmentHostContext): void;
207
+
208
+ declare const TARGET: "codex:local";
209
+ declare const SUPPORTED_IR_VERSION: "0.6";
210
+ interface LlmCall {
211
+ name: string;
212
+ tier: string;
213
+ prompt: string;
214
+ consumes: string[];
215
+ produces: string | null;
216
+ conditional: boolean;
217
+ when: unknown;
218
+ }
219
+ interface Guardrail {
220
+ name: string;
221
+ locked: boolean;
222
+ scope?: string;
223
+ threshold?: number;
224
+ }
225
+ interface ComponentNode {
226
+ id: string;
227
+ verb: string;
228
+ type: string;
229
+ realization_kind: string;
230
+ llm_calls: LlmCall[];
231
+ required_capabilities: string[];
232
+ guardrails: Guardrail[];
233
+ trigger: {
234
+ kind: string;
235
+ };
236
+ effect: {
237
+ outcome: {
238
+ kind: string;
239
+ };
240
+ render_blocks: unknown[];
241
+ };
242
+ context_binding: {
243
+ binding_mode: string;
244
+ project: string;
245
+ };
246
+ }
247
+ interface WarbleIr {
248
+ warble_ir_version: string;
249
+ profile: string;
250
+ components: ComponentNode[];
251
+ }
252
+ declare function parseIr(raw: string): WarbleIr;
253
+
254
+ /**
255
+ * The only `when` dialect this transport (and the Ask path) evaluates: a step runs only when an
256
+ * earlier step in the same component failed. `target` names that earlier step.
257
+ */
258
+ interface OnFailureGuard {
259
+ guard: "on_failure";
260
+ target: string;
261
+ }
262
+
263
+ declare const SETUP_DOMAIN_CAPABILITIES: readonly ["source_connect", "context_build"];
264
+ type SetupDomainCapability = (typeof SETUP_DOMAIN_CAPABILITIES)[number];
265
+ declare const ENRICH_DOMAIN_CAPABILITIES: readonly ["semantic_introspection", "raw_material_read"];
266
+ type EnrichDomainCapability = (typeof ENRICH_DOMAIN_CAPABILITIES)[number];
267
+
268
+ interface McpServerConfig {
269
+ name: string;
270
+ command: string;
271
+ args?: string[];
272
+ toolsByCapability: Record<SetupDomainCapability, string[]>;
273
+ }
274
+ interface CapabilityResolution {
275
+ capability: string;
276
+ outcome: "native" | "realize-via";
277
+ via: string | null;
278
+ }
279
+ interface PreparedSetupStep {
280
+ name: string;
281
+ tier: string;
282
+ model: string;
283
+ prompt: string;
284
+ consumes: string[];
285
+ produces: string;
286
+ when: OnFailureGuard | null;
287
+ }
288
+ interface PreparedSetupComponent {
289
+ target: typeof TARGET;
290
+ profile: string;
291
+ node: ComponentNode;
292
+ componentId: string;
293
+ domainCapability: SetupDomainCapability;
294
+ steps: PreparedSetupStep[];
295
+ capabilities: CapabilityResolution[];
296
+ enabledTools: string[];
297
+ mcp: McpServerConfig;
298
+ }
299
+ interface PrepareInput {
300
+ ir: string | WarbleIr;
301
+ component: string;
302
+ /**
303
+ * A single string binds every step in the component to that one model (the shape every
304
+ * existing single-step fixture already uses, and still all that's required when a component
305
+ * declares only one tier). A per-tier map is required once a component declares steps at more
306
+ * than one tier — see `resolveStepModel`.
307
+ */
308
+ model: string | Record<string, string>;
309
+ mcp: McpServerConfig;
310
+ }
311
+ declare function matchesSetupContractShape(node: ComponentNode): boolean;
312
+ /**
313
+ * The specific reason a component's IR shape does not match the Setup contract, or null when it
314
+ * does match. This mirrors `matchesSetupContractShape`'s try/catch but preserves the validator's
315
+ * own wall-hit message instead of collapsing it to a boolean, so a caller classifying across all
316
+ * three families can surface precisely which structural expectation failed.
317
+ */
318
+ declare function setupContractMismatchReason(node: ComponentNode): string | null;
319
+ declare function prepareSetup(input: PrepareInput): PreparedSetupComponent;
320
+ declare function prepareAllSetup(raw: string, config: Omit<PrepareInput, "ir" | "component">): PreparedSetupComponent[];
321
+
322
+ /**
323
+ * The public CLI is intentionally profile-agnostic. These are implementation contracts selected
324
+ * from a parsed component's declared IR shape, never from a command spelling, profile name, or
325
+ * component identity.
326
+ */
327
+ type DispatchContract = "setup" | "ask" | "enrich";
328
+ /**
329
+ * Select the native execution contract only when exactly one complete structural contract matches.
330
+ * This check runs before configuration, preparation, or a runtime launch.
331
+ */
332
+ declare function classifyDispatchContract(ir: WarbleIr, component: string): DispatchContract;
333
+ /**
334
+ * Setup is the sole whole-profile manifest/describe contract. Other shapes are scoped dispatches
335
+ * and therefore require an explicit --component selection.
336
+ */
337
+ declare function supportsSetupAggregate(ir: WarbleIr): boolean;
338
+
339
+ interface AskMcpServerConfig {
340
+ name: string;
341
+ command: string;
342
+ args?: string[];
343
+ toolsByStep: Record<string, string[]>;
344
+ }
345
+ interface AskTierModels {
346
+ orchestrator: string;
347
+ cheap: string;
348
+ strong: string;
349
+ }
350
+ interface AskWhenGuard {
351
+ guard: "on_failure";
352
+ target: string;
353
+ }
354
+ interface PreparedAskStep {
355
+ name: string;
356
+ role: string;
357
+ tier: "cheap" | "strong";
358
+ model: string;
359
+ prompt: string;
360
+ consumes: string[];
361
+ produces: string;
362
+ conditional: boolean;
363
+ when: AskWhenGuard | null;
364
+ enabledTools: string[];
365
+ requireSuccessfulTool: boolean;
366
+ }
367
+ type AnalyticalExecutionKind = "answer_query" | "generate_dashboard";
368
+ interface PreparedAskComponent {
369
+ target: typeof TARGET;
370
+ profile: string;
371
+ node: ComponentNode;
372
+ componentId: string;
373
+ steps: PreparedAskStep[];
374
+ capabilities: CapabilityResolution[];
375
+ mcp: AskMcpServerConfig;
376
+ models: AskTierModels;
377
+ executionKind: AnalyticalExecutionKind;
378
+ maxRepairAttempts: number;
379
+ }
380
+ interface PrepareAskInput {
381
+ ir: string | WarbleIr;
382
+ component: string;
383
+ models: AskTierModels;
384
+ mcp: AskMcpServerConfig;
385
+ }
386
+ declare function matchesAskContractShape(node: ComponentNode): boolean;
387
+ /**
388
+ * The specific reason a component's IR shape does not match either Ask contract (answer_query or
389
+ * generate_dashboard), or null when it matches one of them. Mirrors `matchesAskContractShape`'s
390
+ * try/catch but preserves the validator's own wall-hit message so a caller classifying across all
391
+ * three families can surface precisely which structural expectation failed.
392
+ */
393
+ declare function askContractMismatchReason(node: ComponentNode): string | null;
394
+ declare function prepareAsk(input: PrepareAskInput): PreparedAskComponent;
395
+
396
+ interface EnrichMcpServerConfig {
397
+ name: string;
398
+ command: string;
399
+ args?: string[];
400
+ toolsByCapability: Record<EnrichDomainCapability, string[]>;
401
+ }
402
+ interface PreparedEnrichStep {
403
+ name: string;
404
+ tier: string;
405
+ model: string;
406
+ prompt: string;
407
+ consumes: string[];
408
+ produces: string;
409
+ when: OnFailureGuard | null;
410
+ }
411
+ interface PreparedEnrichComponent {
412
+ target: typeof TARGET;
413
+ profile: string;
414
+ node: ComponentNode;
415
+ componentId: string;
416
+ domainCapabilities: EnrichDomainCapability[];
417
+ steps: PreparedEnrichStep[];
418
+ capabilities: CapabilityResolution[];
419
+ enabledTools: string[];
420
+ mcp: EnrichMcpServerConfig;
421
+ }
422
+ interface PrepareEnrichInput {
423
+ ir: string | WarbleIr;
424
+ component: string;
425
+ /**
426
+ * A single string binds every step in the component to that one model. A per-tier map is
427
+ * required once a component declares steps at more than one tier — see `resolveStepModel`.
428
+ */
429
+ model: string | Record<string, string>;
430
+ mcp: EnrichMcpServerConfig;
431
+ }
432
+ declare function matchesEnrichContractShape(node: ComponentNode): boolean;
433
+ /**
434
+ * The specific reason a component's IR shape does not match the Enrich contract, or null when it
435
+ * does match. Mirrors `matchesEnrichContractShape`'s try/catch but preserves the validator's own
436
+ * wall-hit message so a caller classifying across all three families can surface precisely which
437
+ * structural expectation failed.
438
+ */
439
+ declare function enrichContractMismatchReason(node: ComponentNode): string | null;
440
+ declare function prepareEnrich(input: PrepareEnrichInput): PreparedEnrichComponent;
441
+
442
+ interface AskAgentConfigFile {
443
+ role: string;
444
+ path: string;
445
+ model: string;
446
+ tools: string[];
447
+ }
448
+ interface AskAgentConfigBundle {
449
+ directory: string;
450
+ requestFile: string;
451
+ stepRequestFile: string;
452
+ agents: AskAgentConfigFile[];
453
+ parentConfig: Record<string, unknown>;
454
+ bindRequest: (request: string) => void;
455
+ bindStepRequest: (request: string) => void;
456
+ cleanup: () => void;
457
+ }
458
+ declare function renderAskAgentToml(prepared: PreparedAskComponent, step: PreparedAskStep, requestFile: string, stepRequestFile: string): string;
459
+ declare function createAskAgentConfigBundle(prepared: PreparedAskComponent): AskAgentConfigBundle;
460
+
461
+ type WarbleCodexEvent = {
462
+ t: "step_start";
463
+ id: string;
464
+ name: string;
465
+ } | {
466
+ t: "tool_call";
467
+ id: string;
468
+ name: string;
469
+ } | {
470
+ t: "tool_result";
471
+ id: string;
472
+ ok: boolean;
473
+ error?: string;
474
+ } | {
475
+ t: "answer";
476
+ text: string;
477
+ } | {
478
+ t: "step_finish";
479
+ id: string;
480
+ ok: boolean;
481
+ detail?: string;
482
+ };
483
+ declare class CodexJsonlMapper {
484
+ private readonly stepId;
485
+ private readonly expectedMcpServer;
486
+ private started;
487
+ private finished;
488
+ private threadStarted;
489
+ private finalText;
490
+ private failureDetail;
491
+ private toolFailureDetail;
492
+ private readonly pendingTools;
493
+ private successfulToolCount;
494
+ private readonly enabledTools;
495
+ constructor(stepId: string, expectedMcpServer: string, enabledTools: readonly string[]);
496
+ nextLine(line: string): WarbleCodexEvent[];
497
+ result(): {
498
+ finalText: string;
499
+ threadStarted: boolean;
500
+ turnCompleted: boolean;
501
+ };
502
+ private onItem;
503
+ private finish;
504
+ }
505
+
506
+ declare const SESSION_REFERENCE_VERSION: "0.1";
507
+ interface CodexSessionReference {
508
+ version: typeof SESSION_REFERENCE_VERSION;
509
+ target: "codex:local";
510
+ threadId: string;
511
+ forkedFromThreadId: string | null;
512
+ }
513
+ type SessionTurnStatus = "in_progress" | "completed" | "interrupted" | "failed";
514
+ interface CodexTurnReference {
515
+ threadId: string;
516
+ turnId: string;
517
+ status: SessionTurnStatus;
518
+ }
519
+ interface CodexArtifactReference {
520
+ version: typeof SESSION_REFERENCE_VERSION;
521
+ kind: "mcp_tool_result";
522
+ threadId: string;
523
+ turnId: string;
524
+ itemId: string;
525
+ server: string;
526
+ tool: string;
527
+ ok: boolean;
528
+ }
529
+ type CodexHistoryItem = {
530
+ type: "user" | "assistant";
531
+ itemId: string;
532
+ } | {
533
+ type: "artifact";
534
+ reference: CodexArtifactReference;
535
+ };
536
+ interface CodexHistoryTurn {
537
+ id: string;
538
+ status: SessionTurnStatus;
539
+ items: CodexHistoryItem[];
540
+ }
541
+ interface CodexSessionHistory {
542
+ session: CodexSessionReference;
543
+ turns: CodexHistoryTurn[];
544
+ }
545
+ type CodexSessionEvent = {
546
+ t: "session_started" | "session_resumed" | "session_forked";
547
+ session: CodexSessionReference;
548
+ } | {
549
+ t: "session_recoverable";
550
+ threadId: string | null;
551
+ reason: "transport_disconnect" | "app_server_crash" | "turn_timeout";
552
+ } | {
553
+ t: "session_failed";
554
+ threadId: string | null;
555
+ reason: "protocol_violation";
556
+ } | {
557
+ t: "turn_started";
558
+ turn: CodexTurnReference;
559
+ } | {
560
+ t: "turn_completed";
561
+ turn: CodexTurnReference;
562
+ } | {
563
+ t: "artifact";
564
+ reference: CodexArtifactReference;
565
+ } | ({
566
+ threadId: string;
567
+ turnId: string;
568
+ } & WarbleCodexEvent);
569
+ interface SessionIsolationOptions {
570
+ codexHome: string;
571
+ cwd: string;
572
+ externalAuthentication: "provisioned";
573
+ codexBin?: string;
574
+ codexArgsPrefix?: string[];
575
+ timeoutMs?: number;
576
+ terminationGraceMs?: number;
577
+ env?: NodeJS.ProcessEnv;
578
+ onEvent?: (event: CodexSessionEvent) => void;
579
+ }
580
+
581
+ interface CodexAskStepResult {
582
+ step: string;
583
+ agentRole: string;
584
+ agentThreadId: string;
585
+ model: string;
586
+ produced: string;
587
+ ok: boolean;
588
+ value: unknown;
589
+ artifacts: CodexAskArtifactReference[];
590
+ }
591
+ interface CodexAskArtifactReference {
592
+ version: typeof SESSION_REFERENCE_VERSION;
593
+ kind: "mcp_tool_result";
594
+ parentThreadId: string;
595
+ parentTurnId: string;
596
+ agentThreadId: string;
597
+ step: string;
598
+ agentRole: string;
599
+ itemId: string;
600
+ server: string;
601
+ tool: string;
602
+ ok: boolean;
603
+ }
604
+ interface CodexRenderArtifactReference {
605
+ version: typeof SESSION_REFERENCE_VERSION;
606
+ kind: "render_envelope";
607
+ parentThreadId: string;
608
+ parentTurnId: string;
609
+ agentThreadId: string;
610
+ step: string;
611
+ agentRole: string;
612
+ verified: boolean;
613
+ blockTypes: string[];
614
+ }
615
+ type CodexAskEvent = {
616
+ t: "session_started" | "session_resumed";
617
+ session: CodexSessionReference;
618
+ } | {
619
+ t: "turn_started" | "turn_completed";
620
+ turn: CodexTurnReference;
621
+ } | {
622
+ t: "agent_started";
623
+ parentThreadId: string;
624
+ parentTurnId: string;
625
+ step: string;
626
+ agentRole: string;
627
+ agentThreadId: string;
628
+ model: string;
629
+ } | {
630
+ t: "step_finished";
631
+ parentThreadId: string;
632
+ parentTurnId: string;
633
+ step: string;
634
+ agentRole: string;
635
+ agentThreadId: string;
636
+ ok: boolean;
637
+ } | {
638
+ t: "artifact";
639
+ reference: CodexAskArtifactReference;
640
+ } | {
641
+ t: "render_artifact";
642
+ reference: CodexRenderArtifactReference;
643
+ } | {
644
+ t: "render_degraded";
645
+ parentThreadId: string;
646
+ parentTurnId: string;
647
+ reason: "invalid_render_envelope";
648
+ } | {
649
+ t: "session_recoverable";
650
+ threadId: string | null;
651
+ reason: "transport_disconnect" | "app_server_crash" | "turn_timeout" | "turn_cancelled";
652
+ } | {
653
+ t: "session_failed";
654
+ threadId: string | null;
655
+ reason: "protocol_violation";
656
+ };
657
+ interface CodexAskRuntimeOptions extends SessionIsolationOptions {
658
+ turnTimeoutMs?: number;
659
+ onAskEvent?: (event: CodexAskEvent) => void;
660
+ }
661
+ interface CodexAskRunResult {
662
+ target: "codex:local";
663
+ component: string;
664
+ session: CodexSessionReference;
665
+ turn: CodexTurnReference;
666
+ finalText: string;
667
+ value: unknown;
668
+ steps: CodexAskStepResult[];
669
+ artifact: CodexRenderArtifactReference | null;
670
+ renderDegraded: boolean;
671
+ }
672
+ declare function buildAskDriverPrompt(prepared: PreparedAskComponent): string;
673
+ declare class CodexAskRuntime {
674
+ private readonly prepared;
675
+ private readonly options;
676
+ private transport;
677
+ private bundle;
678
+ private session;
679
+ private active;
680
+ private startingTurn;
681
+ private pendingTurnNotifications;
682
+ private disconnected;
683
+ private constructor();
684
+ static connect(prepared: PreparedAskComponent, options: CodexAskRuntimeOptions): Promise<CodexAskRuntime>;
685
+ start(): Promise<CodexSessionReference>;
686
+ resume(reference: CodexSessionReference): Promise<CodexSessionReference>;
687
+ run(reference: CodexSessionReference, request: string, signal?: AbortSignal): Promise<CodexAskRunResult>;
688
+ restartAndResume(reference: CodexSessionReference): Promise<CodexSessionReference>;
689
+ close(): Promise<void>;
690
+ private onNotification;
691
+ private onItem;
692
+ private observeChildNotification;
693
+ private onCollabItem;
694
+ private completeWait;
695
+ private tryFinalizeTurn;
696
+ private synthesizeDirectCollaboration;
697
+ private validateChildren;
698
+ private stopTurn;
699
+ private onDisconnect;
700
+ private ensureConnected;
701
+ private emit;
702
+ }
703
+
704
+ interface JsonRecord {
705
+ [key: string]: unknown;
706
+ }
707
+ interface DashboardRenderEnvelope {
708
+ blocks: JsonRecord[];
709
+ summary?: string;
710
+ verified: boolean;
711
+ }
712
+ declare function validateDashboardRenderEnvelope(value: unknown, node: ComponentNode): DashboardRenderEnvelope;
713
+
714
+ interface StepManifest {
715
+ name: string;
716
+ tier: string;
717
+ model: string;
718
+ consumes: string[];
719
+ produces: string | null;
720
+ agent_role?: string;
721
+ conditional?: boolean;
722
+ when?: {
723
+ guard: string;
724
+ target: string;
725
+ } | null;
726
+ tools?: string[];
727
+ }
728
+ interface AgentManifest {
729
+ id: string;
730
+ verb: string;
731
+ component_type: string;
732
+ realization_kind: string;
733
+ trigger: string;
734
+ outcome: string;
735
+ steps: StepManifest[];
736
+ capabilities: PreparedSetupComponent["capabilities"];
737
+ tools: Array<{
738
+ name: string;
739
+ source: string;
740
+ agents?: string[];
741
+ }>;
742
+ guardrails: Record<string, unknown>;
743
+ artifact_output?: {
744
+ kind: "render_envelope";
745
+ persistence: "consumer";
746
+ block_types: string[];
747
+ };
748
+ }
749
+ interface Manifest {
750
+ manifest_version: "0.1";
751
+ compat: {
752
+ min_ir_version: typeof SUPPORTED_IR_VERSION;
753
+ max_ir_version: typeof SUPPORTED_IR_VERSION;
754
+ };
755
+ profile: string;
756
+ target: typeof TARGET;
757
+ session: SessionManifest;
758
+ agents: AgentManifest[];
759
+ }
760
+ declare const SESSION_LIFECYCLE_OPERATIONS: readonly ["start", "resume", "read", "turn", "steer", "interrupt", "fork"];
761
+ interface SessionManifest {
762
+ persistence: "codex_thread_history";
763
+ lifecycle_operations: Array<(typeof SESSION_LIFECYCLE_OPERATIONS)[number]>;
764
+ artifact_reference: "allowlisted_mcp_tool_result" | "allowlisted_mcp_tool_result_or_render_envelope";
765
+ isolation: "dedicated_persistent_codex_home";
766
+ authentication: "externally_provisioned";
767
+ }
768
+ interface TargetDescription {
769
+ target: typeof TARGET;
770
+ phase: "setup-only" | "setup-and-ask-parity" | "setup-ask-and-dashboard-parity" | "enrich-parity";
771
+ execution_modes: Array<"one_shot" | "persistent_session">;
772
+ session_persistence: SessionManifest["persistence"];
773
+ lifecycle_operations: SessionManifest["lifecycle_operations"];
774
+ supported_components: string[];
775
+ tiers: string[];
776
+ capabilities: string[];
777
+ tools: string[];
778
+ guardrails: string[];
779
+ }
780
+ declare function buildAskAgentManifest(prepared: PreparedAskComponent): AgentManifest;
781
+ declare function buildAskManifest(prepared: PreparedAskComponent): Manifest;
782
+ declare function describeAskTarget(prepared: PreparedAskComponent): TargetDescription;
783
+ declare function buildAgentManifest(prepared: PreparedSetupComponent): AgentManifest;
784
+ declare function buildManifest(prepared: readonly PreparedSetupComponent[]): Manifest;
785
+ declare function describeTarget(prepared: readonly PreparedSetupComponent[]): TargetDescription;
786
+ declare function buildEnrichAgentManifest(prepared: PreparedEnrichComponent): AgentManifest;
787
+ declare function buildEnrichManifest(prepared: PreparedEnrichComponent): Manifest;
788
+ declare function describeEnrichTarget(prepared: PreparedEnrichComponent): TargetDescription;
789
+
790
+ type PreparedOneShotComponent = PreparedSetupComponent | PreparedEnrichComponent;
791
+ /** Structurally matches both `PreparedSetupStep` and `PreparedEnrichStep` — the two engines stay
792
+ * separate types, but a single prepared step is enough to build this target's args/prompt for
793
+ * either one. */
794
+ interface PreparedStepLike {
795
+ name: string;
796
+ model: string;
797
+ prompt: string;
798
+ consumes: string[];
799
+ produces: string;
800
+ }
801
+ interface BuildPromptOptions {
802
+ /** Setup's host consumes the produced slot as terminal text; Enrich may marshal structured JSON. */
803
+ producedValue?: "string" | "json";
804
+ }
805
+ declare function sanitizeCodexEnvironment(source?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
806
+ interface InvocationArgsOptions {
807
+ cwd: string;
808
+ codexArgsPrefix?: string[];
809
+ }
810
+ declare function buildCodexArgs(prepared: PreparedOneShotComponent, step: PreparedStepLike, options: InvocationArgsOptions): string[];
811
+ /**
812
+ * `inputs` carries the marshalled values this step's `consumes` names resolve to from earlier
813
+ * steps' outputs in this same dispatch. When a step declares no `consumes` (every existing
814
+ * single-step fixture, and the first step of any multi-step component), no input section is added.
815
+ */
816
+ declare function buildPrompt(prepared: PreparedOneShotComponent, step: PreparedStepLike, request: string, inputs?: Record<string, unknown>, options?: BuildPromptOptions): string;
817
+
818
+ declare function validateSessionIsolation(options: SessionIsolationOptions): {
819
+ codexHome: string;
820
+ cwd: string;
821
+ };
822
+ declare function buildAppServerArgs(prepared: PreparedSetupComponent | PreparedEnrichComponent, options: SessionIsolationOptions): string[];
823
+ /** Read-only app-server startup for model discovery. It deliberately has no thread/session config. */
824
+ interface CatalogTransportOptions {
825
+ cwd: string;
826
+ codexHome?: string;
827
+ codexBin?: string;
828
+ codexArgsPrefix?: string[];
829
+ timeoutMs?: number;
830
+ terminationGraceMs?: number;
831
+ env?: NodeJS.ProcessEnv;
832
+ }
833
+ declare class CodexAppServerTransport {
834
+ private readonly timeoutMs;
835
+ private readonly terminationGraceMs;
836
+ private readonly onNotification;
837
+ private readonly onDisconnect;
838
+ private nextId;
839
+ private readonly pending;
840
+ private readonly lines;
841
+ private readonly child;
842
+ private closing;
843
+ private closed;
844
+ private killTimer;
845
+ private readonly closePromise;
846
+ private constructor();
847
+ static start(prepared: PreparedSetupComponent | PreparedEnrichComponent, options: SessionIsolationOptions, onNotification: (method: string, params: unknown) => void, onDisconnect: (error?: CodexDispatchError) => void): Promise<CodexAppServerTransport>;
848
+ static startWithArgs(args: string[], options: SessionIsolationOptions, onNotification: (method: string, params: unknown) => void, onDisconnect: (error?: CodexDispatchError) => void): Promise<CodexAppServerTransport>;
849
+ /**
850
+ * Start a narrowly read-only app-server transport for `model/list`. Unlike persistent sessions,
851
+ * catalog discovery may use the caller's normal logged-in Codex identity, but it never starts a
852
+ * thread or applies the session's MCP/tool isolation configuration.
853
+ */
854
+ static startCatalog(options: CatalogTransportOptions): Promise<CodexAppServerTransport>;
855
+ request(method: string, params?: unknown): Promise<unknown>;
856
+ notify(method: string, params?: unknown): void;
857
+ close(): Promise<void>;
858
+ private write;
859
+ private onLine;
860
+ private protocolFailure;
861
+ private rejectPending;
862
+ private signalTree;
863
+ }
864
+
865
+ declare class CodexSessionRuntime {
866
+ private readonly prepared;
867
+ private readonly options;
868
+ private transport;
869
+ private session;
870
+ private readonly activeTurns;
871
+ private readonly waiters;
872
+ private readonly stepNameByTurn;
873
+ private disconnected;
874
+ private constructor();
875
+ /**
876
+ * The model bound to this persistent thread for its whole lifetime. `thread/start` takes a
877
+ * single `model` with no per-turn override, so unlike Setup's one-shot-process-per-step
878
+ * transport, every step dispatched through one session must resolve to the same model — see
879
+ * `enrich_prepare.ts`'s single-tier-per-component requirement, which is what makes this true by
880
+ * construction rather than by convention.
881
+ */
882
+ private get model();
883
+ static connect(prepared: PreparedSetupComponent | PreparedEnrichComponent, options: SessionIsolationOptions): Promise<CodexSessionRuntime>;
884
+ start(): Promise<CodexSessionReference>;
885
+ resume(reference: CodexSessionReference): Promise<CodexSessionReference>;
886
+ read(reference: CodexSessionReference): Promise<CodexSessionHistory>;
887
+ /**
888
+ * `step`/`inputs` default to this component's first (and, for every existing single-step
889
+ * fixture, only) step with no marshalled inputs — so every pre-existing caller that never named
890
+ * a step keeps building the exact same prompt as before. A multi-step caller (the n-step Enrich
891
+ * executor) passes the step actually being dispatched this turn, plus that step's marshalled
892
+ * `consumes` values, and this records which step owns the resulting turn id so the
893
+ * `step_start`/`step_finish` events this turn emits are attributed correctly rather than always
894
+ * naming the component's first step.
895
+ */
896
+ turn(reference: CodexSessionReference, input: string, step?: PreparedStepLike, inputs?: Record<string, unknown>): Promise<CodexTurnReference>;
897
+ steer(reference: CodexSessionReference, turnId: string, input: string): Promise<CodexTurnReference>;
898
+ interrupt(reference: CodexSessionReference, turnId: string): Promise<void>;
899
+ fork(reference: CodexSessionReference, lastTurnId?: string): Promise<CodexSessionReference>;
900
+ waitForTurn(turn: CodexTurnReference, timeoutMs?: number): Promise<CodexTurnReference>;
901
+ restartAndResume(reference: CodexSessionReference): Promise<CodexSessionReference>;
902
+ close(): Promise<void>;
903
+ private onNotification;
904
+ private onItem;
905
+ private onTurnCompleted;
906
+ private projectHistoryTurn;
907
+ private ensureActiveTurn;
908
+ private requireCurrent;
909
+ private requireNotificationThread;
910
+ private requireNoActiveTurns;
911
+ private ensureConnected;
912
+ private onDisconnect;
913
+ private settleWaiters;
914
+ private removeWaiter;
915
+ private emit;
916
+ }
917
+
918
+ interface RunOptions {
919
+ cwd: string;
920
+ request: string;
921
+ codexBin?: string;
922
+ codexArgsPrefix?: string[];
923
+ timeoutMs?: number;
924
+ terminationGraceMs?: number;
925
+ signal?: AbortSignal;
926
+ env?: NodeJS.ProcessEnv;
927
+ onEvent?: (event: WarbleCodexEvent) => void;
928
+ }
929
+ /** One step's dispatch-time evidence: whether it ran (an on_failure guard may skip it) and, if
930
+ * it ran, whether its terminal matched its declared `produces` slot. */
931
+ interface SetupStepRunOutcome {
932
+ name: string;
933
+ ran: boolean;
934
+ ok: boolean;
935
+ value?: unknown;
936
+ }
937
+ interface RunResult {
938
+ target: "codex:local";
939
+ component: string;
940
+ /** The last step that actually ran's raw terminal text — unchanged for every existing
941
+ * single-step component, since there the last step run is the only step run. */
942
+ finalText: string;
943
+ events: WarbleCodexEvent[];
944
+ steps: SetupStepRunOutcome[];
945
+ }
946
+ declare function runSetup(prepared: PreparedSetupComponent, options: RunOptions): Promise<RunResult>;
947
+
948
+ /** One step's dispatch-time evidence: whether it ran (an on_failure guard may skip it) and, if it
949
+ * ran, whether its terminal matched its declared `produces` slot. Mirrors `run.ts`'s
950
+ * `SetupStepRunOutcome` — kept as a separate type (not imported from `run.ts`) so Setup and Enrich
951
+ * stay two independent engines, by design. */
952
+ interface EnrichStepRunOutcome {
953
+ name: string;
954
+ ran: boolean;
955
+ ok: boolean;
956
+ value?: unknown;
957
+ }
958
+ interface EnrichRunResult {
959
+ target: "codex:local";
960
+ component: string;
961
+ /** The last step that actually ran's raw terminal text — unchanged for every existing
962
+ * single-step component, since there the last step run is the only step run. */
963
+ finalText: string;
964
+ /** The parsed terminal object of the last step that actually ran. */
965
+ value: unknown;
966
+ events: CodexSessionEvent[];
967
+ steps: EnrichStepRunOutcome[];
968
+ }
969
+ /**
970
+ * Execute a read-only enrichment component's steps, in order, through one persistent Codex
971
+ * app-server session. The Codex thread is created before the first model turn begins; this
972
+ * preserves durable session history before any metered work can occur, while the host remains
973
+ * owner of enrichment run bookkeeping. Every step of one dispatch shares the same thread — see
974
+ * `session.ts`'s `CodexSessionRuntime.turn`, which now takes the current step and its marshalled
975
+ * `consumes` inputs — with produces/consumes marshalled between turns exactly as `run.ts`'s
976
+ * `runSetup` marshals them between one-shot processes, and the same recoverable-vs-fatal
977
+ * on_failure evaluation (`shouldRunStep`/`parseStepTerminal`).
978
+ */
979
+ declare function runEnrich(prepared: PreparedEnrichComponent, request: string, options: SessionIsolationOptions): Promise<EnrichRunResult>;
980
+
981
+ export { type AgentManifest, type AnalyticalExecutionKind, type AskAgentConfigBundle, type AskAgentConfigFile, type AskMcpServerConfig, type AskTierModels, type AskWhenGuard, type BuildProof, type CapabilityResolution, type CatalogTransportOptions, CodexAppServerTransport, type CodexArtifactReference, type CodexAskArtifactReference, type CodexAskEvent, type CodexAskRunResult, CodexAskRuntime, type CodexAskRuntimeOptions, type CodexAskStepResult, CodexDispatchError, type CodexHistoryItem, type CodexHistoryTurn, CodexJsonlMapper, type CodexRenderArtifactReference, type CodexSessionEvent, type CodexSessionHistory, type CodexSessionReference, CodexSessionRuntime, type CodexTurnReference, type CompletedOperationLedger, type ComponentNode, type DashboardRenderEnvelope, type DiscoverCodexModelsOptions, type DispatchContract, ENRICHMENT_CONTRACT_VERSION, ENRICHMENT_SINKS, type EnrichDomainCapability, type EnrichMcpServerConfig, type EnrichRunResult, type EnrichStepRunOutcome, type EnrichmentAudit, type EnrichmentChange, type EnrichmentConfidence, type EnrichmentDecision, type EnrichmentDecisionAction, type EnrichmentDecisionRequest, type EnrichmentDisposition, type EnrichmentEvidence, type EnrichmentHostContext, type EnrichmentMode, type EnrichmentOperationRisk, type EnrichmentPolicyInput, type EnrichmentProposal, type EnrichmentSink, type EnrichmentStatus, type EnrichmentTerminal, type Guardrail, type HostApprovalAttestation, type LlmCall, MODEL_CATALOG_VERSION, type Manifest, type McpServerConfig, type ModelCatalogModel, type ModelCatalogResult, type ModelCatalogUnavailableCode, type OnFailureGuard, type PrepareAskInput, type PrepareEnrichInput, type PrepareInput, type PreparedAskComponent, type PreparedAskStep, type PreparedEnrichComponent, type PreparedEnrichStep, type PreparedSetupComponent, type PreparedSetupStep, type RunOptions, type RunResult, SESSION_LIFECYCLE_OPERATIONS, SESSION_REFERENCE_VERSION, SUPPORTED_IR_VERSION, type SessionIsolationOptions, type SessionManifest, type SessionTurnStatus, type SetupDomainCapability, type SetupStepRunOutcome, type StepManifest, TARGET, type TargetDescription, type TrustedEnrichmentOperation, type ValidationProof, type WarbleCodexEvent, type WarbleIr, askContractMismatchReason, assertEnrichmentTerminal, buildAgentManifest, buildAppServerArgs, buildAskAgentManifest, buildAskDriverPrompt, buildAskManifest, buildCodexArgs, buildEnrichAgentManifest, buildEnrichManifest, buildManifest, buildPrompt, classifyDispatchContract, createAskAgentConfigBundle, decideEnrichment, describeAskTarget, describeEnrichTarget, describeTarget, discoverCodexModels, enrichContractMismatchReason, matchesAskContractShape, matchesEnrichContractShape, matchesSetupContractShape, parseIr, prepareAllSetup, prepareAsk, prepareEnrich, prepareSetup, renderAskAgentToml, runEnrich, runSetup, sanitizeCodexEnvironment, setupContractMismatchReason, supportsSetupAggregate, validateDashboardRenderEnvelope, validateSessionIsolation };