pantheon-opencode 1.5.0-beta.1 → 1.5.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +44 -15
  2. package/README.pt-BR.md +39 -12
  3. package/package.json +7 -3
  4. package/plugin.json +1 -1
  5. package/pyproject.toml +57 -0
  6. package/scripts/code_mode_server.py +101 -36
  7. package/scripts/cost.mjs +30 -14
  8. package/scripts/install/opencode.mjs +6 -0
  9. package/scripts/install/plugin.mjs +3 -33
  10. package/scripts/manifest-inventory.mjs +410 -0
  11. package/scripts/mcp_persistence_server.py +518 -128
  12. package/scripts/package-evidence.mjs +242 -0
  13. package/scripts/probe-context-rehydrate.mjs +240 -0
  14. package/scripts/probe-pantheon-cost.mjs +304 -0
  15. package/scripts/release-beta-version.mjs +61 -60
  16. package/scripts/sync-tui.mjs +5 -27
  17. package/scripts/test-opencode-v1-v2-sandbox.sh +367 -96
  18. package/scripts/validation-policy.mjs +7 -7
  19. package/scripts/version-check.mjs +113 -108
  20. package/scripts/versioning.mjs +131 -88
  21. package/src/mcp/code_mode_server.py +101 -36
  22. package/src/mcp/mcp_persistence_server.py +518 -128
  23. package/src/pantheon/compaction-handoff.ts +304 -0
  24. package/src/pantheon/cost-command.ts +49 -32
  25. package/src/pantheon/delegate-manager.ts +285 -0
  26. package/src/pantheon/provider-capabilities.ts +221 -0
  27. package/src/pantheon/provider-stream-tracker.ts +182 -0
  28. package/src/pantheon/token-opt.ts +237 -11
  29. package/src/plugin-v2.ts +2 -14
  30. package/src/plugin.ts +3 -8
  31. package/src/plugins/tui/package-lock.json +2 -2
  32. package/src/plugins/tui/package.json +1 -1
  33. package/.pantheon/code-mode/.gitkeep +0 -0
  34. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-1.json +0 -8
  35. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-10.json +0 -8
  36. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-11.json +0 -8
  37. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-2.json +0 -8
  38. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-3.json +0 -8
  39. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-4.json +0 -8
  40. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-5.json +0 -8
  41. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-6.json +0 -8
  42. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-7.json +0 -8
  43. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-8.json +0 -8
  44. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-9.json +0 -8
  45. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/heartbeat.json +0 -8
  46. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/session.json +0 -11
  47. package/src/pantheon/delegate-task-adapter.ts +0 -444
@@ -173,7 +173,7 @@ export function applyGate(
173
173
  }
174
174
 
175
175
  /** Kill-switch: `PANTHEON_TOKEN_OPT=off` disables the whole WS3 layer. */
176
- export function isTokenOptEnabled(env: Record<string, string | undefined> = {}): boolean {
176
+ export function isTokenOptEnabled(env: Readonly<Record<string, string | undefined>> = {}): boolean {
177
177
  return env.PANTHEON_TOKEN_OPT !== 'off'
178
178
  }
179
179
 
@@ -193,12 +193,24 @@ export interface C9Chunk {
193
193
  text: string
194
194
  }
195
195
 
196
+ /** Immutable input batch for the safe C9 context-preparation contract. */
197
+ export interface C9CandidateBatch {
198
+ query: string
199
+ candidates: readonly C9Chunk[]
200
+ }
201
+
196
202
  /** Per-category override of top-k / cutoff. */
197
203
  export interface C9CategoryConfig {
198
204
  topK?: number
199
205
  cutoff?: number
200
206
  }
201
207
 
208
+ /** Optional query used only to activate the explicit low-score fallback. */
209
+ export interface C9FilterOptions {
210
+ perCategory?: Readonly<Record<string, C9CategoryConfig>>
211
+ query?: string
212
+ }
213
+
202
214
  /** Result of C9 filtering with debited injection cost. */
203
215
  export interface C9FilterResult {
204
216
  selected: C9Chunk[]
@@ -210,10 +222,15 @@ export interface C9FilterResult {
210
222
  * - `ok` — at least one chunk selected;
211
223
  * - `empty-input` — no chunks retrieved at all (fallback: proceed without
212
224
  * injected context, caller should log `notice`);
213
- * - `all-dropped` — chunks existed but none survived cutoff/top-k
214
- * (fallback: relax cutoff/top-k or proceed without context).
225
+ * - `all-dropped` — chunks existed but none survived cutoff/top-k and no
226
+ * lexical query fallback was available;
227
+ * - `fallback-relative` — the absolute cutoff rejected every chunk, but a
228
+ * query-matching lexical/relative ranking selected auditable low-score
229
+ * chunks;
230
+ * - `nonsense` — a supplied query had no lexical overlap, so nothing is
231
+ * injected.
215
232
  */
216
- signal: 'ok' | 'empty-input' | 'all-dropped'
233
+ signal: 'ok' | 'empty-input' | 'all-dropped' | 'fallback-relative' | 'nonsense'
217
234
  /** Human-readable alert for the non-`ok` signals (null when `ok`). */
218
235
  notice: string | null
219
236
  /**
@@ -228,12 +245,27 @@ export interface C9FilterResult {
228
245
 
229
246
  /**
230
247
  * Filter scored chunks per category: drop below cutoff, keep top-k by
231
- * score desc. The injected context cost is debited (`injectedTokens`).
248
+ * score desc. An optional query enables only the explicit low-score fallback.
249
+ * The injected context cost is debited (`injectedTokens`).
232
250
  */
233
251
  export function c9Filter(
234
- chunks: C9Chunk[],
235
- perCategory?: Record<string, C9CategoryConfig>,
252
+ chunks: readonly C9Chunk[],
253
+ perCategoryOrOptions?: Readonly<Record<string, C9CategoryConfig>> | C9FilterOptions | string,
254
+ query?: string,
236
255
  ): C9FilterResult {
256
+ const isOptions = isC9FilterOptions(perCategoryOrOptions)
257
+ const perCategory =
258
+ typeof perCategoryOrOptions === 'string'
259
+ ? undefined
260
+ : isOptions
261
+ ? perCategoryOrOptions.perCategory
262
+ : perCategoryOrOptions
263
+ const filterQuery =
264
+ typeof perCategoryOrOptions === 'string'
265
+ ? (query ?? perCategoryOrOptions)
266
+ : isOptions
267
+ ? (query ?? perCategoryOrOptions.query)
268
+ : query
237
269
  const byCategory = new Map<string, C9Chunk[]>()
238
270
  for (const chunk of chunks) {
239
271
  const group = byCategory.get(chunk.category)
@@ -256,15 +288,42 @@ export function c9Filter(
256
288
  dropped.push(...group.filter((c) => c.score < cutoff))
257
289
  dropped.push(...eligible.slice(topK))
258
290
  }
259
- const context = buildC9Context(selected)
260
- const signal: C9FilterResult['signal'] =
291
+ let signal: C9FilterResult['signal'] =
261
292
  chunks.length === 0 ? 'empty-input' : selected.length === 0 ? 'all-dropped' : 'ok'
262
- const notice =
293
+ let notice =
263
294
  signal === 'empty-input'
264
295
  ? 'C9: empty input — no chunks retrieved; fallback: proceed without injected context'
265
296
  : signal === 'all-dropped'
266
297
  ? 'C9: all chunks dropped by cutoff/top-k; fallback: relax cutoff/top-k or proceed without context'
267
298
  : null
299
+
300
+ // Keep the absolute cutoff intact. This fallback is deliberately entered
301
+ // only after it rejects every chunk, and only lexical overlap can authorize
302
+ // injecting one of those low-score chunks.
303
+ if (chunks.length > 0 && selected.length === 0 && filterQuery !== undefined) {
304
+ const queryTerms = lexicalTerms(filterQuery)
305
+ const fallbackSelected =
306
+ queryTerms.length > 0 ? relativeLexicalSelection(byCategory, perCategory, queryTerms) : []
307
+ if (fallbackSelected.length > 0) {
308
+ selected.push(...fallbackSelected)
309
+ signal = 'fallback-relative'
310
+ notice =
311
+ `C9: absolute cutoff ${C9_DEFAULT_CUTOFF} yielded no eligible chunks; ` +
312
+ `lexical/relative fallback selected ${fallbackSelected.length} auditable ` +
313
+ `low-score chunk(s) (${queryTerms.length} query term(s)); selected scores remain below cutoff`
314
+ } else if (filterQuery.trim().length > 0) {
315
+ signal = 'nonsense'
316
+ notice =
317
+ 'C9: query has no lexical overlap with low-score chunks; fallback returned zero and no context was injected'
318
+ }
319
+ }
320
+
321
+ if (selected.length > 0 && signal === 'fallback-relative') {
322
+ const selectedSet = new Set(selected)
323
+ dropped.length = 0
324
+ dropped.push(...chunks.filter((chunk) => !selectedSet.has(chunk)))
325
+ }
326
+ const context = buildC9Context(selected)
268
327
  return {
269
328
  selected,
270
329
  dropped,
@@ -276,8 +335,175 @@ export function c9Filter(
276
335
  }
277
336
  }
278
337
 
338
+ /** Configuration for the pure C9 context-preparation boundary. */
339
+ export interface C9ContextOptions {
340
+ env?: Readonly<Record<string, string | undefined>>
341
+ perCategory?: Readonly<Record<string, C9CategoryConfig>>
342
+ }
343
+
344
+ /** Metrics emitted by C9; deliberately contains no candidate or context text. */
345
+ export interface C9Telemetry {
346
+ signal: C9FilterResult['signal'] | 'disabled' | 'empty-query'
347
+ counts: {
348
+ candidates: number
349
+ selected: number
350
+ dropped: number
351
+ }
352
+ recall: number
353
+ injectedChars: number
354
+ injectedTokens: number
355
+ }
356
+
357
+ /** C9 result with the kill-switch state available as a type discriminator. */
358
+ export type C9ContextResult =
359
+ | {
360
+ enabled: true
361
+ context: string
362
+ telemetry: C9Telemetry
363
+ }
364
+ | {
365
+ enabled: false
366
+ context: ''
367
+ telemetry: C9Telemetry
368
+ }
369
+
370
+ function telemetry(
371
+ signal: C9Telemetry['signal'],
372
+ candidates: number,
373
+ selected: number,
374
+ dropped: number,
375
+ recall: number,
376
+ context = '',
377
+ ): C9Telemetry {
378
+ return {
379
+ signal,
380
+ counts: { candidates, selected, dropped },
381
+ recall,
382
+ injectedChars: context.length,
383
+ injectedTokens: estimateTokens(context),
384
+ }
385
+ }
386
+
387
+ function hasLexicalOverlap(query: string, chunks: readonly C9Chunk[]): boolean {
388
+ const queryTerms = lexicalTerms(query)
389
+ if (queryTerms.length === 0) return false
390
+ return chunks.some((chunk) => {
391
+ const chunkTerms = new Set(lexicalTerms(chunk.text))
392
+ return queryTerms.some((term) => chunkTerms.has(term))
393
+ })
394
+ }
395
+
396
+ /**
397
+ * Prepare auditable context without performing retrieval or side effects.
398
+ *
399
+ * The caller supplies the query and candidates already retrieved. The
400
+ * kill-switch is read only from the supplied environment object, so this
401
+ * boundary remains deterministic and testable. C9 always receives the batch
402
+ * query explicitly; no option can replace it with an implicit query.
403
+ */
404
+ export function prepareC9Context(
405
+ batch: C9CandidateBatch,
406
+ options: C9ContextOptions = {},
407
+ ): C9ContextResult {
408
+ const candidateCount = batch.candidates.length
409
+ if (!isTokenOptEnabled(options.env)) {
410
+ return {
411
+ enabled: false,
412
+ context: '',
413
+ telemetry: telemetry('disabled', candidateCount, 0, 0, 0),
414
+ }
415
+ }
416
+
417
+ const filtered = c9Filter(batch.candidates, options.perCategory, batch.query)
418
+ if (batch.query.trim().length === 0) {
419
+ return {
420
+ enabled: true,
421
+ context: '',
422
+ telemetry: telemetry(
423
+ 'empty-query',
424
+ candidateCount,
425
+ 0,
426
+ candidateCount,
427
+ candidateCount === 0 ? filtered.recall : 0,
428
+ ),
429
+ }
430
+ }
431
+
432
+ const context =
433
+ filtered.signal === 'nonsense' ||
434
+ (filtered.signal === 'ok' && !hasLexicalOverlap(batch.query, filtered.selected))
435
+ ? ''
436
+ : buildC9Context(filtered.selected)
437
+ const signal =
438
+ context.length === 0 && filtered.signal === 'ok' ? ('nonsense' as const) : filtered.signal
439
+ const selectedCount = context.length === 0 ? 0 : filtered.selected.length
440
+ const droppedCount = context.length === 0 ? candidateCount : filtered.dropped.length
441
+ const recall = context.length === 0 && filtered.signal === 'ok' ? 0 : filtered.recall
442
+ return {
443
+ enabled: true,
444
+ context,
445
+ telemetry: telemetry(signal, candidateCount, selectedCount, droppedCount, recall, context),
446
+ }
447
+ }
448
+
449
+ /** Normalize query/text terms without introducing a semantic or runtime dependency. */
450
+ function lexicalTerms(value: string): string[] {
451
+ return [
452
+ ...new Set(
453
+ value
454
+ .normalize('NFKD')
455
+ .replace(/\p{M}/gu, '')
456
+ .toLowerCase()
457
+ .match(/[\p{L}\p{N}]+/gu)
458
+ ?.filter((term) => term.length > 1) ?? [],
459
+ ),
460
+ ]
461
+ }
462
+
463
+ /** Select only query-matching low-score chunks, ranked lexically then relatively. */
464
+ function relativeLexicalSelection(
465
+ byCategory: Map<string, C9Chunk[]>,
466
+ perCategory: Readonly<Record<string, C9CategoryConfig>> | undefined,
467
+ queryTerms: string[],
468
+ ): C9Chunk[] {
469
+ const selected: C9Chunk[] = []
470
+ for (const [category, group] of byCategory) {
471
+ const config = perCategory?.[category]
472
+ const topK = config?.topK ?? C9_DEFAULT_TOP_K
473
+ const maxScore = Math.max(...group.map((chunk) => chunk.score), 0)
474
+ const ranked = group
475
+ .map((chunk, index) => {
476
+ const textSet = new Set(lexicalTerms(chunk.text))
477
+ const overlap = queryTerms.filter((term) => textSet.has(term)).length
478
+ const lexicalScore = overlap / queryTerms.length
479
+ const relativeScore = maxScore > 0 ? chunk.score / maxScore : 0
480
+ return { chunk, index, lexicalScore, relativeScore }
481
+ })
482
+ .filter((entry) => entry.lexicalScore > 0)
483
+ .sort(
484
+ (left, right) =>
485
+ right.lexicalScore - left.lexicalScore ||
486
+ right.relativeScore - left.relativeScore ||
487
+ right.chunk.score - left.chunk.score ||
488
+ left.index - right.index,
489
+ )
490
+ selected.push(...ranked.slice(0, topK).map((entry) => entry.chunk))
491
+ }
492
+ return selected
493
+ }
494
+
495
+ function isC9FilterOptions(
496
+ value: Readonly<Record<string, C9CategoryConfig>> | C9FilterOptions | string | undefined,
497
+ ): value is C9FilterOptions {
498
+ return (
499
+ value !== undefined &&
500
+ typeof value !== 'string' &&
501
+ ('perCategory' in value || ('query' in value && typeof value.query === 'string'))
502
+ )
503
+ }
504
+
279
505
  /** Build the injected context: only auditable chunks (id + score + text). */
280
- export function buildC9Context(selected: C9Chunk[]): string {
506
+ export function buildC9Context(selected: readonly C9Chunk[]): string {
281
507
  return selected.map((c) => `[${c.category}:${c.id}|${c.score}] ${c.text}`).join('\n')
282
508
  }
283
509
 
package/src/plugin-v2.ts CHANGED
@@ -612,18 +612,6 @@ export interface V2ToolResult {
612
612
  output: string
613
613
  }
614
614
 
615
- /**
616
- * Wrap raw tool text into the object shape the V2 beta host requires.
617
- * Never throws (fail-open): non-string input degrades to String(input).
618
- */
619
- export function toV2ToolResult(text: unknown): V2ToolResult {
620
- try {
621
- return { output: typeof text === 'string' ? text : String(text) }
622
- } catch {
623
- return { output: '[pantheon] tool output unavailable' }
624
- }
625
- }
626
-
627
615
  /**
628
616
  * A V2 tool definition ready for registration.
629
617
  */
@@ -698,9 +686,9 @@ function createV2ToolDefinitionsFromContext(_context: PluginContext): V2ToolDef[
698
686
  // costCommand/goalTools) once V1 infrastructure is resolvable in the V2
699
687
  // standalone context. The before/after factories in v2-hooks.ts:216-282
700
688
  // are likewise unwired. Until then, placeholders resolve to the object
701
- // shape via toV2ToolResult so the beta host never sees a bare string.
689
+ // shape so the beta host never sees a bare string.
702
690
  execute: async (_input: Record<string, unknown>, _context: unknown): Promise<V2ToolResult> => {
703
- return toV2ToolResult(`${name}: ${v2UnavailableMessage}`)
691
+ return { output: `${name}: ${v2UnavailableMessage}` }
704
692
  },
705
693
  }))
706
694
  }
package/src/plugin.ts CHANGED
@@ -12,11 +12,7 @@ import {
12
12
  DEFAULT_LIMITS as SANDBOX_DEFAULT_LIMITS,
13
13
  } from './pantheon/context-sandbox.ts'
14
14
  import { createCostCommand } from './pantheon/cost-command.ts'
15
- import {
16
- buildPluginNativeDelegation,
17
- resolveDelegateMode,
18
- withDelegationKillSwitch,
19
- } from './pantheon/delegate-task-adapter.ts'
15
+ import { buildPluginNativeDelegation, resolveDelegateMode } from './pantheon/delegate-manager.ts'
20
16
  import {
21
17
  collectRootSessionIDs,
22
18
  createDelegationTools,
@@ -375,8 +371,7 @@ const plugin: Plugin = async (input: PluginInput) => {
375
371
  // WS1 (PR #94): delegation backend gate. Default = legacy (the V1
376
372
  // fire-and-forget toolset, intact); PANTHEON_DELEGATE_MODE=native selects
377
373
  // the thin manager over native task() semantics. Kill-switch
378
- // PANTHEON_DELEGATION=off covers BOTH modes (native guards internally;
379
- // legacy via withDelegationKillSwitch). finalizeDelegation always stays on
374
+ // PANTHEON_DELEGATION=off covers the native manager; finalizeDelegation stays on
380
375
  // the legacy observer: it works on the shared board in both modes and must
381
376
  // never be kill-switched, so children never orphan. The idle hook below is
382
377
  // untouched.
@@ -428,7 +423,7 @@ const plugin: Plugin = async (input: PluginInput) => {
428
423
  ...(wallClockTimeoutMs !== undefined ? { wallClockTimeoutMs } : {}),
429
424
  finalizeDelegation: legacyDelegation.finalizeDelegation,
430
425
  })
431
- : withDelegationKillSwitch(legacyDelegation)
426
+ : legacyDelegation
432
427
 
433
428
  // Proactive idle-child scan (Fix 2): finalize children that are idle on the
434
429
  // board but have no MD report on disk — eliminates the phantom "running"
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pantheon-tui",
3
- "version": "1.5.0",
3
+ "version": "1.5.0-beta.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pantheon-tui",
9
- "version": "1.5.0",
9
+ "version": "1.5.0-beta.3",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@opencode-ai/plugin": ">=1.14.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pantheon-tui",
3
3
  "type": "module",
4
- "version": "1.5.0-beta.1",
4
+ "version": "1.5.0-beta.3",
5
5
  "description": "Pantheon TUI plugin — sidebar (version, preset, sessions, real-time delegations) + AI subscription usage gauges incl. OpenCode Go/Zen dollar limits (vendored, MIT)",
6
6
  "license": "MIT",
7
7
  "exports": {
File without changes
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 1,
5
- "timestamp": "2026-07-24T10:57:09.398807+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 10,
5
- "timestamp": "2026-07-24T11:14:15.230136+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 11,
5
- "timestamp": "2026-07-24T11:21:25.938170+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 2,
5
- "timestamp": "2026-07-24T11:00:35.522164+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 3,
5
- "timestamp": "2026-07-24T11:01:21.558497+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 4,
5
- "timestamp": "2026-07-24T11:02:18.695362+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 5,
5
- "timestamp": "2026-07-24T11:04:13.337080+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 6,
5
- "timestamp": "2026-07-24T11:07:03.322884+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 7,
5
- "timestamp": "2026-07-24T11:08:30.280736+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 8,
5
- "timestamp": "2026-07-24T11:10:03.409420+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "phase": 0,
4
- "turn_count": 9,
5
- "timestamp": "2026-07-24T11:12:14.924527+00:00",
6
- "context_hash": "",
7
- "version": 2
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "slug": "initial-token-40k",
3
- "last_action": "2026-07-24T11:21:25.938170+00:00",
4
- "turn_count": 11,
5
- "current_phase": 0,
6
- "status": "alive",
7
- "next_action": "checkpoint saved"
8
- }
@@ -1,11 +0,0 @@
1
- {
2
- "task_id": "initial-token-40k",
3
- "mode": "deepwork",
4
- "start_time": "2026-07-24T10:57:06.212552+00:00",
5
- "last_activity": "2026-07-24T11:21:25.938170+00:00",
6
- "status": "in_progress",
7
- "gate_history": [],
8
- "stop_reason": null,
9
- "stopped_at": null,
10
- "turn_count": 11
11
- }