hankweave 0.5.7 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -11
- package/dist/base-process-manager.d.ts +30 -0
- package/dist/budget.d.ts +315 -0
- package/dist/checkpoint-git.d.ts +98 -0
- package/dist/claude-agent-sdk-manager.d.ts +144 -0
- package/dist/claude-log-parser.d.ts +63 -0
- package/dist/claude-runtime-extractor.d.ts +73 -0
- package/dist/codex-runtime-extractor.d.ts +107 -0
- package/dist/codon-runner.d.ts +278 -0
- package/dist/config-validation/model-validator.d.ts +16 -0
- package/dist/config-validation/sentinel.schema.d.ts +6967 -0
- package/dist/config.d.ts +40815 -0
- package/dist/cost-tracker.d.ts +72 -0
- package/dist/execution-planner.d.ts +62 -0
- package/dist/execution-thread.d.ts +71 -0
- package/dist/exports/schemas.d.ts +9 -0
- package/dist/exports/schemas.js +1019 -0
- package/dist/exports/types.d.ts +15 -0
- package/dist/exports/types.js +60 -0
- package/dist/file-resolver.d.ts +33 -0
- package/dist/index.js +380 -293
- package/dist/index.js.map +33 -29
- package/dist/llm/llm-provider-registry.d.ts +207 -0
- package/dist/llm/models-dev-schema.d.ts +679 -0
- package/dist/llm/provider-config.d.ts +30 -0
- package/dist/prompt-builder.d.ts +75 -0
- package/dist/prompt-frontmatter.d.ts +61 -0
- package/dist/replay-process-manager.d.ts +82 -0
- package/dist/runtime-extractor-base.d.ts +120 -0
- package/dist/schemas/event-schemas.d.ts +8389 -0
- package/dist/schemas/websocket-log-schemas.d.ts +4502 -0
- package/dist/shim-process-manager.d.ts +98 -0
- package/dist/shim-runtime-extractor.d.ts +51 -0
- package/dist/shims/codex/README.md +129 -0
- package/dist/shims/codex/THIRDPARTY.md +18 -0
- package/dist/shims/codex/VERSION +1 -0
- package/dist/shims/codex/common/package.json +24 -0
- package/dist/shims/codex/index.js +1154 -970
- package/dist/shims/codex/package.json +46 -0
- package/dist/shims/codex/tsup.config.ts +16 -0
- package/dist/shims/gemini/README.md +59 -0
- package/dist/shims/gemini/THIRDPARTY.md +32 -0
- package/dist/shims/gemini/VERSION +1 -0
- package/dist/shims/gemini/common/package.json +24 -0
- package/dist/shims/gemini/index.js +1359 -30
- package/dist/shims/gemini/package.json +37 -0
- package/dist/shims/opencode/README.md +82 -0
- package/dist/shims/opencode/THIRDPARTY.md +32 -0
- package/dist/shims/opencode/VERSION +1 -0
- package/dist/shims/opencode/common/package.json +24 -0
- package/dist/shims/opencode/index.js +1476 -0
- package/dist/shims/opencode/package.json +38 -0
- package/dist/shims/pi/README.md +87 -0
- package/dist/shims/pi/THIRDPARTY.md +24 -0
- package/dist/shims/pi/VERSION +1 -0
- package/dist/shims/pi/common/package.json +24 -0
- package/dist/shims/pi/index.js +249832 -0
- package/dist/shims/pi/package.json +53 -0
- package/dist/state-manager.d.ts +161 -0
- package/dist/state-transition-guards.d.ts +37 -0
- package/dist/telemetry/telemetry-types.d.ts +206 -0
- package/dist/typed-event-emitter.d.ts +57 -0
- package/dist/types/branded-types.d.ts +15 -0
- package/dist/types/budget-types.d.ts +82 -0
- package/dist/types/claude-session-schema.d.ts +2430 -0
- package/dist/types/error-types.d.ts +44 -0
- package/dist/types/input-ai-types.d.ts +1070 -0
- package/dist/types/llm-call-types.d.ts +3829 -0
- package/dist/types/sentinel-types.d.ts +66 -0
- package/dist/types/state-types.d.ts +1099 -0
- package/dist/types/tool-types.d.ts +86 -0
- package/dist/types/types.d.ts +367 -0
- package/dist/types/websocket-log-types.d.ts +7 -0
- package/dist/utils.d.ts +452 -0
- package/package.json +15 -2
- package/schemas/hank.schema.json +158 -3
- package/schemas/hankweave.schema.json +17 -1
- package/shims/codex/index.js +0 -1583
- package/shims/gemini/index.js +0 -31
|
@@ -0,0 +1,1099 @@
|
|
|
1
|
+
import type { CodonId, RunId, SessionId } from "./branded-types.js";
|
|
2
|
+
import type { BudgetExceededData } from "./budget-types.js";
|
|
3
|
+
import type { FailureReason, TokenUsage } from "./types.js";
|
|
4
|
+
export type { CodonId, RunId, SessionId, FailureReason, TokenUsage };
|
|
5
|
+
/**
|
|
6
|
+
* State tracking for a single sentinel within a codon.
|
|
7
|
+
* Mutable structure updated in-place during codon execution.
|
|
8
|
+
*/
|
|
9
|
+
export interface SentinelState {
|
|
10
|
+
id: string;
|
|
11
|
+
model: string;
|
|
12
|
+
loadedAt: string;
|
|
13
|
+
unloadedAt?: string;
|
|
14
|
+
llmCallCount: number;
|
|
15
|
+
failedLLMCalls: number;
|
|
16
|
+
lastLlmCallAt?: string;
|
|
17
|
+
totalTriggers: number;
|
|
18
|
+
totalCost: number;
|
|
19
|
+
status: "active" | "unloaded";
|
|
20
|
+
unloadReason?: "codon-complete" | "fatal-error" | "consecutive-failures";
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Codon execution status progression.
|
|
24
|
+
*
|
|
25
|
+
* Normal flow: preparing → starting → initializing → running → completing-sentinels → completed
|
|
26
|
+
* Can skip to "failed" or "skipped" from any non-terminal state.
|
|
27
|
+
*
|
|
28
|
+
* Intent: Track granular progress for better crash recovery and user feedback.
|
|
29
|
+
*/
|
|
30
|
+
export type CodonStatus = "preparing" | "starting" | "initializing" | "running" | "completing-sentinels" | "completed" | "failed" | "skipped";
|
|
31
|
+
/**
|
|
32
|
+
* Base properties shared by all codon states.
|
|
33
|
+
* These are set when the codon starts and never change.
|
|
34
|
+
*/
|
|
35
|
+
interface BaseCodon {
|
|
36
|
+
/**
|
|
37
|
+
* Which codon configuration this execution is for.
|
|
38
|
+
* References the codon in hank.json.
|
|
39
|
+
*
|
|
40
|
+
* Used by: UI to show codon name, state queries for codon history
|
|
41
|
+
*/
|
|
42
|
+
codonId: CodonId;
|
|
43
|
+
/**
|
|
44
|
+
* When this codon execution started.
|
|
45
|
+
* ISO 8601 timestamp.
|
|
46
|
+
*
|
|
47
|
+
* Used by: Duration calculations, UI timeline display
|
|
48
|
+
*/
|
|
49
|
+
startTime: string;
|
|
50
|
+
/**
|
|
51
|
+
* Loop context if this codon is part of a loop iteration.
|
|
52
|
+
* Used for resuming loops after interruption and rollback.
|
|
53
|
+
*/
|
|
54
|
+
loopContext?: {
|
|
55
|
+
loopId: CodonId;
|
|
56
|
+
iteration: number;
|
|
57
|
+
codonIndexInLoop: number;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Codon is preparing rig (running rig setup operations).
|
|
62
|
+
*
|
|
63
|
+
* Next states:
|
|
64
|
+
* - starting: Rig setup succeeded
|
|
65
|
+
* - failed: Copy failed, command failed, etc.
|
|
66
|
+
* - skipped: User skipped during prep
|
|
67
|
+
*/
|
|
68
|
+
export interface PreparingCodon extends BaseCodon {
|
|
69
|
+
status: "preparing";
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Spawning Claude process.
|
|
73
|
+
*
|
|
74
|
+
* Next states:
|
|
75
|
+
* - initializing: Process started successfully
|
|
76
|
+
* - failed: Spawn failed (Claude not found, etc.)
|
|
77
|
+
* - skipped: User skipped during startup
|
|
78
|
+
*/
|
|
79
|
+
export interface StartingCodon extends BaseCodon {
|
|
80
|
+
status: "starting";
|
|
81
|
+
/**
|
|
82
|
+
* Git commit SHA after rig setup completed.
|
|
83
|
+
* Only set if codon config has rigSetup operations.
|
|
84
|
+
*
|
|
85
|
+
* Used by: Rollback to know exact state after setup
|
|
86
|
+
* Edge case: May be undefined if no rig setup configured
|
|
87
|
+
*/
|
|
88
|
+
rigSetupCheckpoint?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Sentinels loaded for this codon.
|
|
91
|
+
* Set after sentinels load during starting state.
|
|
92
|
+
*/
|
|
93
|
+
sentinels?: {
|
|
94
|
+
loaded: SentinelState[];
|
|
95
|
+
totalCost: number;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Claude process running but no session ID yet.
|
|
100
|
+
* Waiting for init message from Claude.
|
|
101
|
+
*
|
|
102
|
+
* Next states:
|
|
103
|
+
* - running: Got session ID from init message
|
|
104
|
+
* - completed: Process exited cleanly but init message failed validation
|
|
105
|
+
* - failed: Process crashed before init
|
|
106
|
+
* - skipped: User skipped during init
|
|
107
|
+
*/
|
|
108
|
+
export interface InitializingCodon extends BaseCodon {
|
|
109
|
+
status: "initializing";
|
|
110
|
+
rigSetupCheckpoint?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Claude process ID for monitoring/cleanup.
|
|
113
|
+
*
|
|
114
|
+
* Used by: Process manager to kill on skip/shutdown
|
|
115
|
+
* Edge case: Process might already be dead
|
|
116
|
+
*/
|
|
117
|
+
claudePid: number;
|
|
118
|
+
/**
|
|
119
|
+
* Path to Claude's JSONL log file.
|
|
120
|
+
* Relative to .hankweave directory.
|
|
121
|
+
* Example: "runs/1234-abc/codon-research-claude.log"
|
|
122
|
+
*
|
|
123
|
+
* Used by: Log parser, debugging, cleanup
|
|
124
|
+
*/
|
|
125
|
+
claudeLogPath: string;
|
|
126
|
+
/**
|
|
127
|
+
* Session ID from previous codon if continuing.
|
|
128
|
+
* Only set if codon has continueFromPrevious: true.
|
|
129
|
+
*
|
|
130
|
+
* Used by: Claude CLI --resume flag
|
|
131
|
+
*/
|
|
132
|
+
previousSessionId?: SessionId;
|
|
133
|
+
/**
|
|
134
|
+
* Sentinels loaded for this codon.
|
|
135
|
+
* Optional field added during starting state, carried forward to initializing.
|
|
136
|
+
*/
|
|
137
|
+
sentinels?: {
|
|
138
|
+
loaded: SentinelState[];
|
|
139
|
+
totalCost: number;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Claude is actively working.
|
|
144
|
+
* This is where most time is spent.
|
|
145
|
+
*
|
|
146
|
+
* Next states:
|
|
147
|
+
* - completed: Claude process exited cleanly
|
|
148
|
+
* - failed: Timeout, API error, crash
|
|
149
|
+
* - skipped: User skipped
|
|
150
|
+
*/
|
|
151
|
+
export interface RunningCodon extends BaseCodon {
|
|
152
|
+
status: "running";
|
|
153
|
+
rigSetupCheckpoint?: string;
|
|
154
|
+
claudePid: number;
|
|
155
|
+
/**
|
|
156
|
+
* Claude's session UUID from init message.
|
|
157
|
+
* Required for continuation in later codons.
|
|
158
|
+
*
|
|
159
|
+
* Used by: Continue functionality, logs correlation
|
|
160
|
+
*/
|
|
161
|
+
claudeSessionId: SessionId;
|
|
162
|
+
claudeLogPath: string;
|
|
163
|
+
previousSessionId?: SessionId;
|
|
164
|
+
/**
|
|
165
|
+
* Accumulated cost so far in USD.
|
|
166
|
+
* Updated on each token usage message.
|
|
167
|
+
*
|
|
168
|
+
* Used by: Cost display, cost limits (future)
|
|
169
|
+
* Edge case: May be stale if messages delayed
|
|
170
|
+
*/
|
|
171
|
+
currentCost: number;
|
|
172
|
+
/**
|
|
173
|
+
* Accumulated token counts.
|
|
174
|
+
* Updated on each assistant message with usage.
|
|
175
|
+
*
|
|
176
|
+
* Used by: Token display, rate limit tracking
|
|
177
|
+
*/
|
|
178
|
+
currentTokens: TokenUsage;
|
|
179
|
+
/**
|
|
180
|
+
* Number of assistant messages received.
|
|
181
|
+
* Used to determine if Claude has established a conversation.
|
|
182
|
+
* Initialized to 0 when codon enters running state.
|
|
183
|
+
*
|
|
184
|
+
* Used by: Continue functionality to check if session is valid
|
|
185
|
+
*/
|
|
186
|
+
assistantMessageCount: number;
|
|
187
|
+
/**
|
|
188
|
+
* Number of extensions performed so far.
|
|
189
|
+
* 0 initially, increments with each extension.
|
|
190
|
+
* Used for tracking progress and enforcing maxExtensions.
|
|
191
|
+
*/
|
|
192
|
+
extensionCount: number;
|
|
193
|
+
/**
|
|
194
|
+
* Sentinels loaded for this codon.
|
|
195
|
+
* Updated in-place during execution.
|
|
196
|
+
*/
|
|
197
|
+
sentinels?: {
|
|
198
|
+
loaded: SentinelState[];
|
|
199
|
+
totalCost: number;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Codon is completing sentinel work.
|
|
204
|
+
* Transient state between agent completion and final state.
|
|
205
|
+
*
|
|
206
|
+
* This state indicates:
|
|
207
|
+
* - Main Claude agent has finished (process exited)
|
|
208
|
+
* - Sentinel queues are being drained
|
|
209
|
+
* - All pending LLM calls are completing
|
|
210
|
+
* - Output files are being finalized
|
|
211
|
+
*
|
|
212
|
+
* Next states:
|
|
213
|
+
* - completed: All work done successfully
|
|
214
|
+
* - failed: Checkpoint creation failed
|
|
215
|
+
* - skipped: Should not normally happen from this state
|
|
216
|
+
*/
|
|
217
|
+
export interface CompletingSentinelsCodon extends BaseCodon {
|
|
218
|
+
status: "completing-sentinels";
|
|
219
|
+
rigSetupCheckpoint?: string;
|
|
220
|
+
claudePid: number;
|
|
221
|
+
claudeSessionId: SessionId;
|
|
222
|
+
claudeLogPath: string;
|
|
223
|
+
previousSessionId?: SessionId;
|
|
224
|
+
/**
|
|
225
|
+
* Current cost accumulated while Claude was running.
|
|
226
|
+
* Will become finalCost when transitioning to completed.
|
|
227
|
+
*/
|
|
228
|
+
currentCost: number;
|
|
229
|
+
/**
|
|
230
|
+
* Current token counts.
|
|
231
|
+
* Will become finalTokens when transitioning to completed.
|
|
232
|
+
*/
|
|
233
|
+
currentTokens: TokenUsage;
|
|
234
|
+
/**
|
|
235
|
+
* Number of assistant messages received.
|
|
236
|
+
*/
|
|
237
|
+
assistantMessageCount: number;
|
|
238
|
+
/**
|
|
239
|
+
* Extension count from the running state.
|
|
240
|
+
* Preserved during sentinel completion.
|
|
241
|
+
*/
|
|
242
|
+
extensionCount: number;
|
|
243
|
+
/**
|
|
244
|
+
* Sentinels being completed.
|
|
245
|
+
* States are updated in-place as work completes.
|
|
246
|
+
*/
|
|
247
|
+
sentinels?: {
|
|
248
|
+
loaded: SentinelState[];
|
|
249
|
+
totalCost: number;
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Codon completed successfully.
|
|
254
|
+
* This is a terminal state - no further transitions possible.
|
|
255
|
+
*
|
|
256
|
+
* Immutability: All fields are final. To retry, start a new run.
|
|
257
|
+
*/
|
|
258
|
+
export interface CompletedCodon extends BaseCodon {
|
|
259
|
+
status: "completed";
|
|
260
|
+
/**
|
|
261
|
+
* When codon completed. Used for duration calculation.
|
|
262
|
+
*/
|
|
263
|
+
endTime: string;
|
|
264
|
+
claudeSessionId: SessionId;
|
|
265
|
+
claudeLogPath: string;
|
|
266
|
+
previousSessionId?: SessionId;
|
|
267
|
+
/**
|
|
268
|
+
* Always 0 for successful completion.
|
|
269
|
+
*
|
|
270
|
+
* Used by: Success detection
|
|
271
|
+
*/
|
|
272
|
+
exitCode: 0;
|
|
273
|
+
/**
|
|
274
|
+
* Final cost from result message or last token update.
|
|
275
|
+
* This is the authoritative cost for this codon.
|
|
276
|
+
*
|
|
277
|
+
* Used by: Billing, cost reports
|
|
278
|
+
* Edge case: May be from token updates if result message timed out
|
|
279
|
+
*/
|
|
280
|
+
finalCost: number;
|
|
281
|
+
/**
|
|
282
|
+
* Final token counts.
|
|
283
|
+
*
|
|
284
|
+
* Used by: Usage analytics, model comparison
|
|
285
|
+
*/
|
|
286
|
+
finalTokens: TokenUsage;
|
|
287
|
+
/**
|
|
288
|
+
* Whether we got Claude's result message before timeout.
|
|
289
|
+
* False means costs might be slightly off.
|
|
290
|
+
*
|
|
291
|
+
* Used by: Cost accuracy warnings
|
|
292
|
+
*/
|
|
293
|
+
resultMessageReceived: boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Final count of extensions performed.
|
|
296
|
+
* Used for reporting and debugging.
|
|
297
|
+
*/
|
|
298
|
+
extensionCount: number;
|
|
299
|
+
rigSetupCheckpoint?: string;
|
|
300
|
+
/**
|
|
301
|
+
* Git commit after successful completion.
|
|
302
|
+
* Always created for successful codons.
|
|
303
|
+
*
|
|
304
|
+
* Used by: Rollback target points
|
|
305
|
+
*/
|
|
306
|
+
completionCheckpoint: string;
|
|
307
|
+
/**
|
|
308
|
+
* Sentinels that executed during this codon (final state).
|
|
309
|
+
* Field renamed from 'loaded' to 'executed' when codon completes.
|
|
310
|
+
*/
|
|
311
|
+
sentinels?: {
|
|
312
|
+
executed: SentinelState[];
|
|
313
|
+
totalCost: number;
|
|
314
|
+
};
|
|
315
|
+
/** Present when codon was force-completed due to budget limit. */
|
|
316
|
+
budgetExceeded?: BudgetExceededData;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Codon failed with error.
|
|
320
|
+
* Terminal state - must start new run to retry.
|
|
321
|
+
*/
|
|
322
|
+
export interface FailedCodon extends BaseCodon {
|
|
323
|
+
status: "failed";
|
|
324
|
+
endTime: string;
|
|
325
|
+
/**
|
|
326
|
+
* Which state we were in when failure occurred.
|
|
327
|
+
* Helps understand how far we got.
|
|
328
|
+
*
|
|
329
|
+
* Used by: Error analysis, retry strategies
|
|
330
|
+
* Example: "preparing" means rig setup failed
|
|
331
|
+
* Note: Can include "completing-sentinels" if checkpoint creation fails during that codon
|
|
332
|
+
*/
|
|
333
|
+
failedDuring: "preparing" | "starting" | "initializing" | "running" | "completing-sentinels";
|
|
334
|
+
claudePid?: number;
|
|
335
|
+
claudeSessionId?: SessionId;
|
|
336
|
+
claudeLogPath?: string;
|
|
337
|
+
previousSessionId?: SessionId;
|
|
338
|
+
/**
|
|
339
|
+
* Process exit code. 0 means clean exit (shouldn't happen for failed).
|
|
340
|
+
* Common codes:
|
|
341
|
+
* - 1: General error
|
|
342
|
+
* - -1: Killed by signal
|
|
343
|
+
* - 130: Ctrl+C
|
|
344
|
+
*
|
|
345
|
+
* Used by: Debugging, retry decisions
|
|
346
|
+
*/
|
|
347
|
+
exitCode: number;
|
|
348
|
+
/**
|
|
349
|
+
* Structured failure information.
|
|
350
|
+
*
|
|
351
|
+
* Used by: UI error display, retry logic
|
|
352
|
+
*/
|
|
353
|
+
failureReason: FailureReason;
|
|
354
|
+
/**
|
|
355
|
+
* Costs accumulated before failure.
|
|
356
|
+
* Will be 0 if failed before Claude started.
|
|
357
|
+
*
|
|
358
|
+
* Used by: Partial cost tracking
|
|
359
|
+
*/
|
|
360
|
+
partialCost: number;
|
|
361
|
+
partialTokens: TokenUsage;
|
|
362
|
+
/**
|
|
363
|
+
* Number of extensions performed before failure.
|
|
364
|
+
* Only present if codon reached running state and attempted extensions.
|
|
365
|
+
*/
|
|
366
|
+
extensionCount?: number;
|
|
367
|
+
rigSetupCheckpoint?: string;
|
|
368
|
+
/**
|
|
369
|
+
* Error checkpoint if created.
|
|
370
|
+
* On error branch in git.
|
|
371
|
+
*
|
|
372
|
+
* Edge case: Might not exist if git operations failed
|
|
373
|
+
*/
|
|
374
|
+
errorCheckpoint?: string;
|
|
375
|
+
/**
|
|
376
|
+
* Sentinels that executed before failure.
|
|
377
|
+
*/
|
|
378
|
+
sentinels?: {
|
|
379
|
+
executed: SentinelState[];
|
|
380
|
+
totalCost: number;
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Codon was skipped by user.
|
|
385
|
+
* Terminal state - represents user choice to skip.
|
|
386
|
+
*/
|
|
387
|
+
export interface SkippedCodon extends BaseCodon {
|
|
388
|
+
status: "skipped";
|
|
389
|
+
endTime: string;
|
|
390
|
+
/**
|
|
391
|
+
* Which state we were in when skipped.
|
|
392
|
+
*
|
|
393
|
+
* Used by: Understanding skip patterns
|
|
394
|
+
*/
|
|
395
|
+
skippedDuring: "preparing" | "starting" | "initializing" | "running";
|
|
396
|
+
claudePid?: number;
|
|
397
|
+
claudeSessionId?: SessionId;
|
|
398
|
+
claudeLogPath?: string;
|
|
399
|
+
previousSessionId?: SessionId;
|
|
400
|
+
/**
|
|
401
|
+
* Partial cost accumulated before skip.
|
|
402
|
+
* Usually 0, but may have accumulated costs if skipped while running.
|
|
403
|
+
*
|
|
404
|
+
* Used by: Cost calculations, continuation logic
|
|
405
|
+
*/
|
|
406
|
+
partialCost: number;
|
|
407
|
+
/**
|
|
408
|
+
* All zeros - no tokens used for skipped.
|
|
409
|
+
*/
|
|
410
|
+
partialTokens: TokenUsage;
|
|
411
|
+
/**
|
|
412
|
+
* Number of assistant messages received before skip.
|
|
413
|
+
* Used to determine if session can be continued.
|
|
414
|
+
*
|
|
415
|
+
* Used by: Continue functionality
|
|
416
|
+
*/
|
|
417
|
+
assistantMessageCount?: number;
|
|
418
|
+
rigSetupCheckpoint?: string;
|
|
419
|
+
/**
|
|
420
|
+
* Skip checkpoint if any files were being tracked.
|
|
421
|
+
* Even empty commits are created for skip markers.
|
|
422
|
+
*
|
|
423
|
+
* Used by: Skip history in git
|
|
424
|
+
*/
|
|
425
|
+
skipCheckpoint?: string;
|
|
426
|
+
/**
|
|
427
|
+
* Sentinels that executed before skip.
|
|
428
|
+
*/
|
|
429
|
+
sentinels?: {
|
|
430
|
+
executed: SentinelState[];
|
|
431
|
+
totalCost: number;
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Union of all possible codon states.
|
|
436
|
+
* Use discriminated union on `status` field for type narrowing.
|
|
437
|
+
*/
|
|
438
|
+
export type CodonExecution = PreparingCodon | StartingCodon | InitializingCodon | RunningCodon | CompletingSentinelsCodon | CompletedCodon | FailedCodon | SkippedCodon;
|
|
439
|
+
/**
|
|
440
|
+
* Represents one server lifecycle (start → shutdown).
|
|
441
|
+
* Runs form a tree via parent relationships for rollback/retry.
|
|
442
|
+
*/
|
|
443
|
+
export interface Run {
|
|
444
|
+
/**
|
|
445
|
+
* Unique identifier for this run.
|
|
446
|
+
* Also used as git branch name.
|
|
447
|
+
*
|
|
448
|
+
* Used by: State lookups, folder naming, git branches
|
|
449
|
+
*/
|
|
450
|
+
runId: RunId;
|
|
451
|
+
/**
|
|
452
|
+
* Absolute path where run files are stored.
|
|
453
|
+
* Example: "/project/.hankweave/runs/1234-abc"
|
|
454
|
+
*
|
|
455
|
+
* Used by: Log file storage, cleanup operations
|
|
456
|
+
* Edge case: Folder might not exist if run failed early
|
|
457
|
+
*/
|
|
458
|
+
runFolder: string;
|
|
459
|
+
/**
|
|
460
|
+
* Git branch name for this run.
|
|
461
|
+
* Usually same as runId, but explicit for flexibility.
|
|
462
|
+
*
|
|
463
|
+
* Used by: Checkpoint system
|
|
464
|
+
*/
|
|
465
|
+
gitBranch: string;
|
|
466
|
+
/**
|
|
467
|
+
* How this run started - fresh or continuation.
|
|
468
|
+
* Immutable after run creation.
|
|
469
|
+
*
|
|
470
|
+
* Used by: UI to show run relationships, rollback tracking
|
|
471
|
+
*/
|
|
472
|
+
startingConditions: StartingConditions;
|
|
473
|
+
/**
|
|
474
|
+
* Ordered list of codon executions in this run.
|
|
475
|
+
* Append-only - new codons added as they start.
|
|
476
|
+
*
|
|
477
|
+
* Used by: Progress tracking, cost calculation
|
|
478
|
+
* Invariant: Only one codon can be non-terminal at a time
|
|
479
|
+
*/
|
|
480
|
+
codons: CodonExecution[];
|
|
481
|
+
/**
|
|
482
|
+
* Overall run status.
|
|
483
|
+
* - running: Currently executing
|
|
484
|
+
* - completed: All codons done successfully
|
|
485
|
+
* - failed: Stopped due to codon failure
|
|
486
|
+
* - crashed: Detected on recovery
|
|
487
|
+
*
|
|
488
|
+
* Used by: Run selection, cleanup decisions
|
|
489
|
+
*/
|
|
490
|
+
status: "running" | "completed" | "failed" | "crashed";
|
|
491
|
+
/**
|
|
492
|
+
* When server started. Never changes.
|
|
493
|
+
*/
|
|
494
|
+
startTime: string;
|
|
495
|
+
/**
|
|
496
|
+
* When server stopped. Set when status becomes terminal.
|
|
497
|
+
*/
|
|
498
|
+
endTime?: string;
|
|
499
|
+
/**
|
|
500
|
+
* Server process ID for lock file validation.
|
|
501
|
+
*
|
|
502
|
+
* Used by: Detecting stale lock files, crash recovery
|
|
503
|
+
* Edge case: Process might not exist anymore
|
|
504
|
+
*/
|
|
505
|
+
serverPid: number;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* How a run started - fresh project or continuation.
|
|
509
|
+
*/
|
|
510
|
+
export type StartingConditions = {
|
|
511
|
+
type: "fresh";
|
|
512
|
+
initialCheckpointSha?: string;
|
|
513
|
+
} | {
|
|
514
|
+
type: "continuation";
|
|
515
|
+
source: {
|
|
516
|
+
/**
|
|
517
|
+
* Which run we're continuing from.
|
|
518
|
+
*
|
|
519
|
+
* Used by: Building run relationships tree
|
|
520
|
+
*/
|
|
521
|
+
runId: RunId;
|
|
522
|
+
/**
|
|
523
|
+
* Which codon to continue after.
|
|
524
|
+
* null means start from beginning of that run.
|
|
525
|
+
*
|
|
526
|
+
* Example: "codon-2" means start from codon-3
|
|
527
|
+
* Used by: Determining next codon to execute
|
|
528
|
+
*/
|
|
529
|
+
afterCodon: CodonId | null;
|
|
530
|
+
/**
|
|
531
|
+
* Git commit SHA we restored to.
|
|
532
|
+
* This is the exact state we're continuing from.
|
|
533
|
+
*
|
|
534
|
+
* Used by: Verifying correct restoration
|
|
535
|
+
*/
|
|
536
|
+
checkpointSha: string;
|
|
537
|
+
};
|
|
538
|
+
/**
|
|
539
|
+
* Human-readable reason for continuation.
|
|
540
|
+
* Optional metadata for UI/analytics.
|
|
541
|
+
*
|
|
542
|
+
* Used by: Understanding user patterns
|
|
543
|
+
*/
|
|
544
|
+
reason?: "retry" | "rollback" | "continue";
|
|
545
|
+
};
|
|
546
|
+
/**
|
|
547
|
+
* Root state object for Hankweave.
|
|
548
|
+
* Stored in .hankweave/state.json.
|
|
549
|
+
*
|
|
550
|
+
* Design decisions:
|
|
551
|
+
* - Single file instead of per-run for simplicity
|
|
552
|
+
* - No version field per user request
|
|
553
|
+
* - No denormalized costs - computed when needed
|
|
554
|
+
*/
|
|
555
|
+
export interface HankweaveState {
|
|
556
|
+
/**
|
|
557
|
+
* All runs, newest first.
|
|
558
|
+
* Append-only - runs are never removed from history.
|
|
559
|
+
*
|
|
560
|
+
* Used by: History UI, cost calculations, rollback sources
|
|
561
|
+
* Scaling: May need pagination/archival eventually
|
|
562
|
+
*/
|
|
563
|
+
runs: Run[];
|
|
564
|
+
/**
|
|
565
|
+
* Currently active run ID.
|
|
566
|
+
* null when server not running.
|
|
567
|
+
*
|
|
568
|
+
* Used by: State queries, preventing multiple servers
|
|
569
|
+
* Invariant: Only one run can be "running" status
|
|
570
|
+
*/
|
|
571
|
+
currentRunId: RunId | null;
|
|
572
|
+
/**
|
|
573
|
+
* Initial checkpoint SHA from git repository initialization.
|
|
574
|
+
* This is the empty commit created when the checkpoint system starts.
|
|
575
|
+
* Represents the project's clean state before any codons have executed.
|
|
576
|
+
*
|
|
577
|
+
* Used by: Rollback to clean state, project-level rollback commands
|
|
578
|
+
*/
|
|
579
|
+
initialCheckpoint?: string;
|
|
580
|
+
/**
|
|
581
|
+
* Current execution plan with all loop iterations expanded.
|
|
582
|
+
* This is the flattened plan that represents the actual execution sequence.
|
|
583
|
+
* Rebuilt on server start but persisted for crash recovery and debugging.
|
|
584
|
+
*
|
|
585
|
+
* Note: May be empty array during initialization before first run starts,
|
|
586
|
+
* but the field itself is always present.
|
|
587
|
+
*
|
|
588
|
+
* Used by: Codon execution, execution thread analysis, crash recovery
|
|
589
|
+
*/
|
|
590
|
+
executionPlan: import("../execution-planner.js").ExecutionCodonEntry[];
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Defines which status transitions are legal.
|
|
594
|
+
* This is enforced at compile time by the state manager.
|
|
595
|
+
*
|
|
596
|
+
* Key rules:
|
|
597
|
+
* - Can skip to "failed" or "skipped" from any non-terminal state
|
|
598
|
+
* - Terminal states (completed/failed/skipped) have no valid transitions
|
|
599
|
+
* - Must progress through states in order for normal execution
|
|
600
|
+
*/
|
|
601
|
+
export declare const CodonTransitions: Record<CodonStatus, CodonStatus[]>;
|
|
602
|
+
/**
|
|
603
|
+
* All possible state changes in the system.
|
|
604
|
+
* These are the only way to modify state - ensures consistency.
|
|
605
|
+
*
|
|
606
|
+
* Design: Each event captures the minimal data needed for the transition.
|
|
607
|
+
* The state manager computes derived state (like totals) as needed.
|
|
608
|
+
*/
|
|
609
|
+
export type StateTransition =
|
|
610
|
+
/**
|
|
611
|
+
* New run started (fresh or from continuation point).
|
|
612
|
+
* Creates new Run entry with starting codon.
|
|
613
|
+
*
|
|
614
|
+
* Triggered by: Server startup
|
|
615
|
+
* State changes:
|
|
616
|
+
* - Adds new run to runs array
|
|
617
|
+
* - Sets currentRunId
|
|
618
|
+
* - Creates git branch
|
|
619
|
+
*/
|
|
620
|
+
{
|
|
621
|
+
type: "RunStarted";
|
|
622
|
+
data: {
|
|
623
|
+
runId: RunId;
|
|
624
|
+
runFolder: string;
|
|
625
|
+
gitBranch: string;
|
|
626
|
+
startingConditions: StartingConditions;
|
|
627
|
+
serverPid: number;
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Run completed successfully (all codons done).
|
|
632
|
+
*
|
|
633
|
+
* Triggered by: Last codon completing successfully
|
|
634
|
+
* State changes:
|
|
635
|
+
* - Sets run.status = "completed"
|
|
636
|
+
* - Sets run.endTime
|
|
637
|
+
* - Clears currentRunId
|
|
638
|
+
*/
|
|
639
|
+
| {
|
|
640
|
+
type: "RunCompleted";
|
|
641
|
+
data: {
|
|
642
|
+
runId: RunId;
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Run failed (codon failed and server shutting down).
|
|
647
|
+
*
|
|
648
|
+
* Triggered by: Codon failure, fatal error
|
|
649
|
+
* State changes:
|
|
650
|
+
* - Sets run.status = "failed"
|
|
651
|
+
* - Sets run.endTime
|
|
652
|
+
* - Clears currentRunId
|
|
653
|
+
*/
|
|
654
|
+
| {
|
|
655
|
+
type: "RunFailed";
|
|
656
|
+
data: {
|
|
657
|
+
runId: RunId;
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Run crashed (detected on recovery).
|
|
662
|
+
*
|
|
663
|
+
* Triggered by: Stale lock file detection
|
|
664
|
+
* State changes:
|
|
665
|
+
* - Sets run.status = "crashed"
|
|
666
|
+
* - Sets run.endTime
|
|
667
|
+
* - Marks running codons as failed
|
|
668
|
+
*/
|
|
669
|
+
| {
|
|
670
|
+
type: "RunCrashed";
|
|
671
|
+
data: {
|
|
672
|
+
runId: RunId;
|
|
673
|
+
detectedAt: string;
|
|
674
|
+
lastCodonStatus: CodonStatus;
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* New codon starting in current run.
|
|
679
|
+
*
|
|
680
|
+
* Triggered by: User command or auto-advance
|
|
681
|
+
* State changes:
|
|
682
|
+
* - Adds new PreparingCodon to run.codons
|
|
683
|
+
* Validation: No other codon currently running
|
|
684
|
+
*/
|
|
685
|
+
| {
|
|
686
|
+
type: "CodonStarted";
|
|
687
|
+
data: {
|
|
688
|
+
runId: RunId;
|
|
689
|
+
codonId: CodonId;
|
|
690
|
+
loopContext?: {
|
|
691
|
+
loopId: CodonId;
|
|
692
|
+
iteration: number;
|
|
693
|
+
codonIndexInLoop: number;
|
|
694
|
+
};
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Codon status changed (main state machine).
|
|
699
|
+
*
|
|
700
|
+
* Triggered by: Various codon lifecycle events
|
|
701
|
+
* State changes:
|
|
702
|
+
* - Updates codon status
|
|
703
|
+
* - Sets relevant fields based on transition
|
|
704
|
+
* Validation: Transition must be in CodonTransitions map
|
|
705
|
+
*/
|
|
706
|
+
| {
|
|
707
|
+
type: "CodonTransitioned";
|
|
708
|
+
data: {
|
|
709
|
+
runId: RunId;
|
|
710
|
+
codonId: CodonId;
|
|
711
|
+
from: CodonStatus;
|
|
712
|
+
to: CodonStatus;
|
|
713
|
+
metadata?: {
|
|
714
|
+
claudePid?: number;
|
|
715
|
+
claudeLogPath?: string;
|
|
716
|
+
previousSessionId?: SessionId;
|
|
717
|
+
claudeSessionId?: SessionId;
|
|
718
|
+
exitCode?: number;
|
|
719
|
+
failureReason?: FailureReason;
|
|
720
|
+
failedDuring?: CodonStatus;
|
|
721
|
+
skippedDuring?: CodonStatus;
|
|
722
|
+
resultMessageReceived?: boolean;
|
|
723
|
+
sentinelCount?: number;
|
|
724
|
+
sentinelIds?: string[];
|
|
725
|
+
checkpointSha?: string;
|
|
726
|
+
checkpointBranch?: string;
|
|
727
|
+
contextExceeded?: boolean;
|
|
728
|
+
extensionCount?: number;
|
|
729
|
+
budgetExceeded?: BudgetExceededData;
|
|
730
|
+
};
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Token usage update from Claude.
|
|
735
|
+
* Can happen frequently during execution.
|
|
736
|
+
*
|
|
737
|
+
* Triggered by: Assistant messages with usage
|
|
738
|
+
* State changes:
|
|
739
|
+
* - Updates currentCost/currentTokens (if running)
|
|
740
|
+
* - Updates finalCost/finalTokens (if completing)
|
|
741
|
+
*/
|
|
742
|
+
| {
|
|
743
|
+
type: "CostsUpdated";
|
|
744
|
+
data: {
|
|
745
|
+
runId: RunId;
|
|
746
|
+
codonId: CodonId;
|
|
747
|
+
cost: number;
|
|
748
|
+
tokens: TokenUsage;
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Incremental token usage update from Claude.
|
|
753
|
+
* More resilient to race conditions than CostsUpdated.
|
|
754
|
+
*
|
|
755
|
+
* Triggered by: Assistant messages with usage (incremental approach)
|
|
756
|
+
* State changes:
|
|
757
|
+
* - Adds costDelta to currentCost (if running)
|
|
758
|
+
* - Adds tokensDelta to currentTokens (if running)
|
|
759
|
+
*/
|
|
760
|
+
| {
|
|
761
|
+
type: "CostsIncremented";
|
|
762
|
+
data: {
|
|
763
|
+
runId: RunId;
|
|
764
|
+
codonId: CodonId;
|
|
765
|
+
costDelta: number;
|
|
766
|
+
tokensDelta: TokenUsage;
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Assistant message count update.
|
|
771
|
+
* Incremented when Claude sends a message.
|
|
772
|
+
*
|
|
773
|
+
* Triggered by: Assistant messages in Claude logs
|
|
774
|
+
* State changes:
|
|
775
|
+
* - Increments assistantMessageCount (if running/completing)
|
|
776
|
+
*/
|
|
777
|
+
| {
|
|
778
|
+
type: "AssistantMessageCountUpdated";
|
|
779
|
+
data: {
|
|
780
|
+
runId: RunId;
|
|
781
|
+
codonId: CodonId;
|
|
782
|
+
newCount: number;
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Extension count update.
|
|
787
|
+
* Incremented when a codon extends.
|
|
788
|
+
*
|
|
789
|
+
* Triggered by: Extension trigger in hankweave-runtime
|
|
790
|
+
* State changes:
|
|
791
|
+
* - Updates extensionCount on RunningCodon
|
|
792
|
+
*/
|
|
793
|
+
| {
|
|
794
|
+
type: "ExtensionCountUpdated";
|
|
795
|
+
data: {
|
|
796
|
+
runId: RunId;
|
|
797
|
+
codonId: CodonId;
|
|
798
|
+
extensionCount: number;
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Git checkpoint created.
|
|
803
|
+
*
|
|
804
|
+
* Triggered by: Rig setup, completion, error, skip
|
|
805
|
+
* State changes:
|
|
806
|
+
* - Sets relevant checkpoint field in codon
|
|
807
|
+
*/
|
|
808
|
+
| {
|
|
809
|
+
type: "CheckpointCreated";
|
|
810
|
+
data: {
|
|
811
|
+
runId: RunId;
|
|
812
|
+
codonId: CodonId;
|
|
813
|
+
checkpointType: "rig-setup" | "completed" | "error" | "skipped";
|
|
814
|
+
sha: string;
|
|
815
|
+
branch: string;
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Initial checkpoint set for the project.
|
|
820
|
+
*
|
|
821
|
+
* Triggered by: Git repository initialization
|
|
822
|
+
* State changes:
|
|
823
|
+
* - Sets state.initialCheckpoint
|
|
824
|
+
*/
|
|
825
|
+
| {
|
|
826
|
+
type: "InitialCheckpointSet";
|
|
827
|
+
data: {
|
|
828
|
+
sha: string;
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Codon final cost set from Claude's result message.
|
|
833
|
+
* This ensures the authoritative cost from Claude's result message
|
|
834
|
+
* is stored before the codon completes.
|
|
835
|
+
*
|
|
836
|
+
* Triggered by: Claude result message with final cost
|
|
837
|
+
* State changes:
|
|
838
|
+
* - Updates currentCost and currentTokens in running codon
|
|
839
|
+
*/
|
|
840
|
+
| {
|
|
841
|
+
type: "CodonFinalCostSet";
|
|
842
|
+
data: {
|
|
843
|
+
runId: RunId;
|
|
844
|
+
codonId: CodonId;
|
|
845
|
+
finalCost: number;
|
|
846
|
+
finalTokens: TokenUsage;
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Sentinel states updated/initialized for a codon.
|
|
851
|
+
* Sets the initial sentinel state when sentinels load,
|
|
852
|
+
* or updates states before codon completion.
|
|
853
|
+
*
|
|
854
|
+
* Triggered by: After sentinels load, before completing-sentinels transition
|
|
855
|
+
* State changes:
|
|
856
|
+
* - Sets/updates RunningCodon.sentinels field
|
|
857
|
+
* - Updates CompletingSentinelsCodon.sentinels field
|
|
858
|
+
*/
|
|
859
|
+
| {
|
|
860
|
+
type: "SentinelStatesUpdated";
|
|
861
|
+
data: {
|
|
862
|
+
runId: RunId;
|
|
863
|
+
codonId: CodonId;
|
|
864
|
+
sentinelStates: SentinelState[];
|
|
865
|
+
totalCost: number;
|
|
866
|
+
};
|
|
867
|
+
};
|
|
868
|
+
/**
|
|
869
|
+
* Extract the type field from StateTransition for use in schemas.
|
|
870
|
+
* This ensures type safety when creating state transition events.
|
|
871
|
+
*/
|
|
872
|
+
export type StateTransitionType = StateTransition["type"];
|
|
873
|
+
/**
|
|
874
|
+
* Central state management for Hankweave.
|
|
875
|
+
* All state modifications go through this interface.
|
|
876
|
+
*
|
|
877
|
+
* Implementation notes:
|
|
878
|
+
* - Single instance per server
|
|
879
|
+
* - Persists to disk after each transition
|
|
880
|
+
* - Validates all transitions before applying
|
|
881
|
+
* - Provides type-safe queries
|
|
882
|
+
*/
|
|
883
|
+
export interface StateManager {
|
|
884
|
+
/**
|
|
885
|
+
* Load state from disk or create new.
|
|
886
|
+
* Called once on server startup.
|
|
887
|
+
*
|
|
888
|
+
* Recovery logic:
|
|
889
|
+
* 1. Try to load state.json
|
|
890
|
+
* 2. If corrupted, try state.json.bak
|
|
891
|
+
* 3. If both fail, start fresh
|
|
892
|
+
* 4. Detect any crashed runs
|
|
893
|
+
*/
|
|
894
|
+
initialize(): Promise<void>;
|
|
895
|
+
/**
|
|
896
|
+
* Get current state snapshot (immutable).
|
|
897
|
+
* This is the primary way to read state.
|
|
898
|
+
*
|
|
899
|
+
* Usage: const { runs, currentRunId } = stateManager.getState();
|
|
900
|
+
*/
|
|
901
|
+
getState(): Readonly<HankweaveState>;
|
|
902
|
+
/**
|
|
903
|
+
* Apply a state transition.
|
|
904
|
+
* This is the ONLY way to modify state.
|
|
905
|
+
*
|
|
906
|
+
* Process:
|
|
907
|
+
* 1. Validate transition is legal
|
|
908
|
+
* 2. Apply transition (pure function)
|
|
909
|
+
* 3. Persist to disk atomically
|
|
910
|
+
* 4. Emit change event
|
|
911
|
+
*
|
|
912
|
+
* @throws {InvalidTransitionError} if transition is invalid
|
|
913
|
+
* @throws {PersistenceError} if save fails
|
|
914
|
+
*/
|
|
915
|
+
transition(event: StateTransition): void;
|
|
916
|
+
/**
|
|
917
|
+
* Get the currently active run.
|
|
918
|
+
* @returns null if no server running
|
|
919
|
+
*/
|
|
920
|
+
getCurrentRun(): Run | null;
|
|
921
|
+
/**
|
|
922
|
+
* Get the currently executing codon.
|
|
923
|
+
* @returns null if between codons or no run active
|
|
924
|
+
*/
|
|
925
|
+
getCurrentlyRunningCodon(): CodonExecution | null;
|
|
926
|
+
/**
|
|
927
|
+
* Get specific codon in current run.
|
|
928
|
+
* Useful for checking if codon already executed.
|
|
929
|
+
*
|
|
930
|
+
* @param codonId - Codon to look for
|
|
931
|
+
* @returns null if codon not found or no current run
|
|
932
|
+
*/
|
|
933
|
+
getCodonInCurrentRun(codonId: CodonId): CodonExecution | null;
|
|
934
|
+
/**
|
|
935
|
+
* Determine which codon should execute next.
|
|
936
|
+
* Handles both fresh runs and continuations.
|
|
937
|
+
*
|
|
938
|
+
* Logic:
|
|
939
|
+
* - For fresh runs: First codon in config
|
|
940
|
+
* - For continuations: Codon after the continuation point
|
|
941
|
+
* - If all codons complete: null
|
|
942
|
+
*
|
|
943
|
+
* @returns null if all codons completed
|
|
944
|
+
*/
|
|
945
|
+
getNextCodonToExecute(): Promise<CodonId | null>;
|
|
946
|
+
/**
|
|
947
|
+
* Get any run by ID.
|
|
948
|
+
* Useful for rollback sources, history display.
|
|
949
|
+
*
|
|
950
|
+
* @returns null if run not found
|
|
951
|
+
*/
|
|
952
|
+
getRun(runId: RunId): Run | null;
|
|
953
|
+
/**
|
|
954
|
+
* Calculate total cost of current run.
|
|
955
|
+
* Includes all codons (successful, failed, partial).
|
|
956
|
+
*
|
|
957
|
+
* @returns 0 if no current run
|
|
958
|
+
*/
|
|
959
|
+
getCurrentRunCost(): number;
|
|
960
|
+
/**
|
|
961
|
+
* Calculate total cost across all runs.
|
|
962
|
+
* This is the "all time" cost.
|
|
963
|
+
*
|
|
964
|
+
* Note: Computed on demand, not stored
|
|
965
|
+
*/
|
|
966
|
+
getTotalCost(): number;
|
|
967
|
+
/**
|
|
968
|
+
* Calculate cost from a specific run onwards.
|
|
969
|
+
* Useful for "cost since last success" queries.
|
|
970
|
+
*
|
|
971
|
+
* @param runId - Starting run (inclusive)
|
|
972
|
+
* @returns Total cost from that run to now
|
|
973
|
+
*/
|
|
974
|
+
getCostSince(runId: RunId): number;
|
|
975
|
+
/**
|
|
976
|
+
* Check if we can continue from a specific point.
|
|
977
|
+
* Validates that the source run and codon exist.
|
|
978
|
+
*
|
|
979
|
+
* @param runId - Run to continue from
|
|
980
|
+
* @param afterCodon - Codon to continue after (null = from beginning)
|
|
981
|
+
* @returns true if valid continuation point
|
|
982
|
+
*/
|
|
983
|
+
canContinueFrom(runId: RunId, afterCodon: CodonId | null): boolean;
|
|
984
|
+
/**
|
|
985
|
+
* Get the checkpoint SHA for a continuation point.
|
|
986
|
+
* This is what git should restore to.
|
|
987
|
+
*
|
|
988
|
+
* @returns null if invalid continuation point
|
|
989
|
+
*/
|
|
990
|
+
getCheckpointForContinuation(runId: RunId, afterCodon: CodonId | null): string | null;
|
|
991
|
+
/**
|
|
992
|
+
* Force save current state to disk.
|
|
993
|
+
* Normally automatic after transitions.
|
|
994
|
+
*
|
|
995
|
+
* Process:
|
|
996
|
+
* 1. Copy current to .bak
|
|
997
|
+
* 2. Write to .tmp
|
|
998
|
+
* 3. Atomic rename to state.json
|
|
999
|
+
*
|
|
1000
|
+
* Note: fs.renameSync is atomic on POSIX systems
|
|
1001
|
+
*/
|
|
1002
|
+
save(): Promise<void>;
|
|
1003
|
+
/**
|
|
1004
|
+
* Validate state file integrity.
|
|
1005
|
+
* Checks for corruption, invalid references, etc.
|
|
1006
|
+
*
|
|
1007
|
+
* @returns Validation results with any issues found
|
|
1008
|
+
*/
|
|
1009
|
+
validate(state: unknown): StateValidation;
|
|
1010
|
+
/**
|
|
1011
|
+
* Detect and mark crashed runs on startup.
|
|
1012
|
+
* Finds runs with status="running" but server not running.
|
|
1013
|
+
*
|
|
1014
|
+
* Side effects:
|
|
1015
|
+
* - Transitions crashed runs to "crashed" status
|
|
1016
|
+
* - Marks running codons as failed
|
|
1017
|
+
*
|
|
1018
|
+
* Recovery strategy:
|
|
1019
|
+
* - Check for orphaned run folders not in state
|
|
1020
|
+
* - Validate PIDs in lock files
|
|
1021
|
+
* - Handle partial state writes (check for .tmp files)
|
|
1022
|
+
*/
|
|
1023
|
+
detectCrashedRuns(): Promise<void>;
|
|
1024
|
+
/**
|
|
1025
|
+
* Attempt recovery from corrupted state.
|
|
1026
|
+
* Last resort if both state.json and backup fail.
|
|
1027
|
+
*
|
|
1028
|
+
* Options:
|
|
1029
|
+
* - Start fresh (data loss)
|
|
1030
|
+
* - Rebuild from Claude logs (deprecated)
|
|
1031
|
+
*
|
|
1032
|
+
* @returns Recovery results
|
|
1033
|
+
*/
|
|
1034
|
+
recover(): Promise<RecoveryResult>;
|
|
1035
|
+
/**
|
|
1036
|
+
* Wait for all pending transitions during shutdown
|
|
1037
|
+
*/
|
|
1038
|
+
waitForPendingTransitions(): Promise<void>;
|
|
1039
|
+
}
|
|
1040
|
+
export interface StateValidation {
|
|
1041
|
+
valid: boolean;
|
|
1042
|
+
errors: ValidationError[];
|
|
1043
|
+
warnings: ValidationWarning[];
|
|
1044
|
+
}
|
|
1045
|
+
export interface ValidationError {
|
|
1046
|
+
type: "missing_run" | "invalid_codon" | "corrupted_data";
|
|
1047
|
+
message: string;
|
|
1048
|
+
context?: unknown;
|
|
1049
|
+
}
|
|
1050
|
+
export interface ValidationWarning {
|
|
1051
|
+
type: "orphaned_folder" | "missing_checkpoint" | "cost_mismatch";
|
|
1052
|
+
message: string;
|
|
1053
|
+
}
|
|
1054
|
+
export interface RecoveryResult {
|
|
1055
|
+
success: boolean;
|
|
1056
|
+
method: "backup" | "fresh" | "logs";
|
|
1057
|
+
dataLoss: boolean;
|
|
1058
|
+
message: string;
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Information about the latest codon execution.
|
|
1062
|
+
* Used to determine the current position in the workflow.
|
|
1063
|
+
*/
|
|
1064
|
+
export interface LatestCodonInfo {
|
|
1065
|
+
/**
|
|
1066
|
+
* The codon execution object containing all codon details
|
|
1067
|
+
*/
|
|
1068
|
+
codon: CodonExecution;
|
|
1069
|
+
/**
|
|
1070
|
+
* Which run this codon belongs to
|
|
1071
|
+
*/
|
|
1072
|
+
runId: RunId;
|
|
1073
|
+
/**
|
|
1074
|
+
* Current status of the codon (convenience field)
|
|
1075
|
+
*/
|
|
1076
|
+
status: CodonStatus;
|
|
1077
|
+
/**
|
|
1078
|
+
* The next codon that should be executed (if any).
|
|
1079
|
+
* null means all codons are complete or a new run is needed.
|
|
1080
|
+
*/
|
|
1081
|
+
nextCodonId: CodonId | null;
|
|
1082
|
+
/**
|
|
1083
|
+
* Whether to continue execution in the current run.
|
|
1084
|
+
* false means a new run needs to be started (e.g., after rollback).
|
|
1085
|
+
*/
|
|
1086
|
+
continueInCurrentRun: boolean;
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Check if a codon status is terminal (no further transitions possible)
|
|
1090
|
+
*/
|
|
1091
|
+
export declare function isTerminalCodonStatus(status: CodonStatus): boolean;
|
|
1092
|
+
/**
|
|
1093
|
+
* Calculate codon cost based on its status
|
|
1094
|
+
*/
|
|
1095
|
+
export declare function getCodonCost(codon: CodonExecution): number;
|
|
1096
|
+
/**
|
|
1097
|
+
* Calculate codon tokens based on its status
|
|
1098
|
+
*/
|
|
1099
|
+
export declare function getCodonTokens(codon: CodonExecution): TokenUsage;
|