zelari-code 1.17.0 → 1.17.1

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.
@@ -28622,7 +28622,7 @@ function composeProjectContext(input) {
28622
28622
  default: 3e3,
28623
28623
  min: 200
28624
28624
  });
28625
- const wantDurable = input.includeDurableState ?? (input.mode === "council" || input.mode === "zelari");
28625
+ const wantDurable = input.includeDurableState ?? (process.env.ZELARI_STATE !== "0" && (input.mode === "council" || input.mode === "zelari" || input.mode === "agent"));
28626
28626
  let durableRaw = input.durableState?.trim() ?? "";
28627
28627
  if (!durableRaw && wantDurable) {
28628
28628
  durableRaw = readDurableHeadSync(cwd);
@@ -28712,6 +28712,42 @@ var init_planDetect = __esm({
28712
28712
  }
28713
28713
  });
28714
28714
 
28715
+ // src/cli/state/loadDurableContext.ts
28716
+ var loadDurableContext_exports = {};
28717
+ __export(loadDurableContext_exports, {
28718
+ clearDurableContextCache: () => clearDurableContextCache,
28719
+ loadDurableContext: () => loadDurableContext
28720
+ });
28721
+ function clearDurableContextCache() {
28722
+ cache = null;
28723
+ }
28724
+ async function loadDurableContext(projectRoot, opts) {
28725
+ const env = opts?.env ?? process.env;
28726
+ if (!isStateEnabled(env)) return "";
28727
+ const cacheMs = opts?.cacheMs ?? DEFAULT_CACHE_MS;
28728
+ const now = Date.now();
28729
+ if (cache && cache.projectRoot === projectRoot && now - cache.at < cacheMs) {
28730
+ return cache.text;
28731
+ }
28732
+ try {
28733
+ const store = await getStateStore(projectRoot, env);
28734
+ const text = await store.materializeContext(void 0, opts?.maxChars);
28735
+ cache = { text: text || "", at: now, projectRoot };
28736
+ return cache.text;
28737
+ } catch {
28738
+ return "";
28739
+ }
28740
+ }
28741
+ var DEFAULT_CACHE_MS, cache;
28742
+ var init_loadDurableContext = __esm({
28743
+ "src/cli/state/loadDurableContext.ts"() {
28744
+ "use strict";
28745
+ init_fileStateStore();
28746
+ DEFAULT_CACHE_MS = 2e3;
28747
+ cache = null;
28748
+ }
28749
+ });
28750
+
28715
28751
  // src/cli/workspace/storage.ts
28716
28752
  var storage_exports = {};
28717
28753
  __export(storage_exports, {
@@ -31539,8 +31575,8 @@ __export(commitHelpers_exports, {
31539
31575
  async function tryStateCommit(args) {
31540
31576
  try {
31541
31577
  const store = args.store ?? await getStateStore(args.projectRoot, args.env);
31542
- let workspaceCheckpointId;
31543
- if (args.withCheckpoint && (args.env ?? process.env).ZELARI_CHECKPOINT !== "0") {
31578
+ let workspaceCheckpointId = args.workspaceCheckpointId;
31579
+ if (!workspaceCheckpointId && args.withCheckpoint && (args.env ?? process.env).ZELARI_CHECKPOINT !== "0") {
31544
31580
  const cp = await createCheckpoint(
31545
31581
  args.projectRoot,
31546
31582
  `state ${args.layer ?? args.label}`.slice(0, 80)
@@ -31556,9 +31592,15 @@ async function tryStateCommit(args) {
31556
31592
  verification: args.verification,
31557
31593
  changedPaths: args.changedPaths,
31558
31594
  discoveries: args.discoveries,
31595
+ stablePromptHash: args.stablePromptHash,
31559
31596
  force: args.force
31560
31597
  });
31561
31598
  if (!meta3.id) return { ok: false, error: "noop store", checkpointId: workspaceCheckpointId };
31599
+ try {
31600
+ const { clearDurableContextCache: clearDurableContextCache2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
31601
+ clearDurableContextCache2();
31602
+ } catch {
31603
+ }
31562
31604
  return { ok: true, meta: meta3, checkpointId: workspaceCheckpointId };
31563
31605
  } catch (err) {
31564
31606
  return {
@@ -31840,14 +31882,7 @@ async function runZelariMission(userMessage, brief, deps) {
31840
31882
  limit: 8,
31841
31883
  metadataFilter: { projectRoot: deps.projectRoot }
31842
31884
  });
31843
- let durableBlock = "";
31844
- try {
31845
- durableBlock = await stateStore.materializeContext();
31846
- } catch {
31847
- durableBlock = "";
31848
- }
31849
- const memBlock = formatMemoryHits(hits);
31850
- const ragContext = [durableBlock, memBlock].filter(Boolean).join("\n\n");
31885
+ const ragContext = formatMemoryHits(hits);
31851
31886
  const promptIter = runMode === "implementation" ? implStep : 1;
31852
31887
  const slicePrompt = buildSlicePrompt(brief, userMessage, runMode, promptIter);
31853
31888
  const implementerRetry = runMode === "implementation" && implStep > 1;
@@ -31919,7 +31954,9 @@ async function runZelariMission(userMessage, brief, deps) {
31919
31954
  sessionId: missionId,
31920
31955
  verification: { ok: hard, ran: result.ran },
31921
31956
  force: !hard,
31922
- withCheckpoint: hard,
31957
+ // Prefer linking the mission-start checkpoint (no explosion).
31958
+ workspaceCheckpointId: missionCheckpointId,
31959
+ withCheckpoint: hard && !missionCheckpointId,
31923
31960
  discoveries: discoveriesFromOutcome({
31924
31961
  stepId: `${missionId}-${step}`,
31925
31962
  synthesis: result.synthesisText,
@@ -31930,7 +31967,7 @@ async function runZelariMission(userMessage, brief, deps) {
31930
31967
  if (commitRes.ok && commitRes.meta?.id) {
31931
31968
  if (hard) {
31932
31969
  state2.lastGoodCommitId = commitRes.meta.id;
31933
- if (commitRes.checkpointId) {
31970
+ if (commitRes.checkpointId && !missionCheckpointId) {
31934
31971
  missionCheckpointId = commitRes.checkpointId;
31935
31972
  }
31936
31973
  }
@@ -36673,6 +36710,48 @@ function finalizeStreamingAssistant(setMessages) {
36673
36710
  // src/cli/hooks/useChatTurn.ts
36674
36711
  init_conversationContext();
36675
36712
 
36713
+ // src/cli/state/promptCacheStats.ts
36714
+ function emptyPromptCacheStats() {
36715
+ return {
36716
+ promptTokens: 0,
36717
+ cachedTokens: 0,
36718
+ premiumTokens: 0,
36719
+ hitRate: 0,
36720
+ estimatedCostUsd: 0,
36721
+ stableBustCount: 0,
36722
+ turns: 0
36723
+ };
36724
+ }
36725
+ function accumulatePromptCacheStats(prev2, turn) {
36726
+ const promptTokens = prev2.promptTokens + Math.max(0, turn.promptTokens);
36727
+ const cachedTokens = prev2.cachedTokens + Math.max(0, turn.cachedTokens);
36728
+ const premiumDelta = Math.max(0, turn.promptTokens - turn.cachedTokens);
36729
+ const premiumTokens = prev2.premiumTokens + premiumDelta;
36730
+ const hitRate = promptTokens > 0 ? cachedTokens / promptTokens : 0;
36731
+ let stableBustCount = prev2.stableBustCount;
36732
+ let lastStableHash = prev2.lastStableHash;
36733
+ if (turn.stableHash) {
36734
+ if (lastStableHash && lastStableHash !== turn.stableHash) {
36735
+ stableBustCount += 1;
36736
+ }
36737
+ lastStableHash = turn.stableHash;
36738
+ }
36739
+ return {
36740
+ promptTokens,
36741
+ cachedTokens,
36742
+ premiumTokens,
36743
+ hitRate,
36744
+ estimatedCostUsd: prev2.estimatedCostUsd + (turn.costUsd ?? 0),
36745
+ lastStableHash,
36746
+ stableBustCount,
36747
+ turns: prev2.turns + 1
36748
+ };
36749
+ }
36750
+ function formatCacheStatsLine(stats) {
36751
+ const pct = stats.promptTokens > 0 ? Math.round(stats.hitRate * 100) : 0;
36752
+ return `cache hit ${pct}% \xB7 premium ${stats.premiumTokens} \xB7 cached ${stats.cachedTokens} \xB7 stable busts ${stats.stableBustCount} \xB7 turns ${stats.turns}`;
36753
+ }
36754
+
36676
36755
  // src/cli/hooks/chatStats.ts
36677
36756
  function computeSessionStatsDelta(realUsage, userText, assistantContent, model, prev2, opts) {
36678
36757
  const promptTokens = realUsage ? realUsage.promptTokens : Math.ceil(userText.length / 4);
@@ -36680,31 +36759,41 @@ function computeSessionStatsDelta(realUsage, userText, assistantContent, model,
36680
36759
  const cachedPromptTokens = realUsage?.cachedPromptTokens ?? 0;
36681
36760
  const turnCost = calculateCost(model, promptTokens, completionTokens, cachedPromptTokens);
36682
36761
  const contextTokens = realUsage ? realUsage.totalTokens || promptTokens + completionTokens : promptTokens + completionTokens;
36683
- const nextCached = (prev2.cachedTokens ?? 0) + cachedPromptTokens;
36684
- const nextPrompt = (prev2.promptTokens ?? 0) + promptTokens;
36685
- const premiumDelta = Math.max(0, promptTokens - cachedPromptTokens);
36686
- const nextPremium = (prev2.premiumTokens ?? 0) + premiumDelta;
36687
- const cacheHitRate = nextPrompt > 0 ? nextCached / nextPrompt : 0;
36688
- let stableBustCount = prev2.stableBustCount ?? 0;
36689
- let lastStableHash = prev2.lastStableHash;
36690
- if (opts?.stableHash) {
36691
- if (lastStableHash && lastStableHash !== opts.stableHash) {
36692
- stableBustCount += 1;
36693
- }
36694
- lastStableHash = opts.stableHash;
36695
- }
36762
+ const prevCache = {
36763
+ ...emptyPromptCacheStats(),
36764
+ promptTokens: prev2.promptTokens ?? 0,
36765
+ cachedTokens: prev2.cachedTokens ?? 0,
36766
+ premiumTokens: prev2.premiumTokens ?? 0,
36767
+ hitRate: prev2.cacheHitRate ?? 0,
36768
+ estimatedCostUsd: prev2.totalCostUsd,
36769
+ lastStableHash: prev2.lastStableHash,
36770
+ stableBustCount: prev2.stableBustCount ?? 0,
36771
+ turns: 0
36772
+ };
36773
+ const nextCache = accumulatePromptCacheStats(prevCache, {
36774
+ promptTokens,
36775
+ cachedTokens: cachedPromptTokens,
36776
+ costUsd: turnCost,
36777
+ stableHash: opts?.stableHash
36778
+ });
36696
36779
  return {
36697
36780
  totalTokens: prev2.totalTokens + promptTokens + completionTokens,
36698
36781
  totalCostUsd: prev2.totalCostUsd + turnCost,
36699
- cachedTokens: nextCached,
36782
+ cachedTokens: nextCache.cachedTokens,
36700
36783
  contextTokens,
36701
- premiumTokens: nextPremium,
36702
- cacheHitRate,
36703
- promptTokens: nextPrompt,
36704
- lastStableHash,
36705
- stableBustCount
36784
+ premiumTokens: nextCache.premiumTokens,
36785
+ cacheHitRate: nextCache.hitRate,
36786
+ promptTokens: nextCache.promptTokens,
36787
+ lastStableHash: nextCache.lastStableHash,
36788
+ stableBustCount: nextCache.stableBustCount
36706
36789
  };
36707
36790
  }
36791
+ function resolvePromptCacheTtl(env = process.env) {
36792
+ const raw = (env.ZELARI_PROMPT_CACHE_TTL ?? "auto").toLowerCase().trim();
36793
+ if (raw === "1h" || raw === "1hour" || raw === "long") return "1h";
36794
+ if (raw === "5m" || raw === "5min" || raw === "short") return "5m";
36795
+ return "auto";
36796
+ }
36708
36797
 
36709
36798
  // src/cli/hooks/useChatTurn.ts
36710
36799
  init_envNumber();
@@ -36901,14 +36990,22 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
36901
36990
  const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
36902
36991
  const { hasWorkspacePlan: hasWorkspacePlan2 } = await Promise.resolve().then(() => (init_planDetect(), planDetect_exports));
36903
36992
  hasPlan = hasWorkspacePlan2(cwd);
36993
+ const { loadDurableContext: loadDurableContext2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
36994
+ const durableState = await loadDurableContext2(cwd);
36904
36995
  const composed = composeProjectContext2({
36905
36996
  mode: "agent",
36906
36997
  cwd,
36907
36998
  userMessage: userText,
36908
- includeLessons: false
36999
+ includeLessons: false,
37000
+ durableState: durableState || void 0,
37001
+ // Pre-loaded async — skip sync fallback double-read.
37002
+ includeDurableState: false
36909
37003
  });
36910
37004
  composedWorkspace = composed.workspaceContext;
36911
37005
  composedInstructions = composed.projectInstructions;
37006
+ if (composed.ragContext) {
37007
+ composedWorkspace = [composedWorkspace, composed.ragContext].filter(Boolean).join("\n\n");
37008
+ }
36912
37009
  for (const w of composed.warnings) {
36913
37010
  appendSystem(setMessages, w, Date.now());
36914
37011
  }
@@ -37514,6 +37611,35 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
37514
37611
  let sliceRan = false;
37515
37612
  let sliceDegraded = false;
37516
37613
  const PROVIDER_ERROR_ABORT_THRESHOLD = 2;
37614
+ let councilCompose = { workspaceContext: formatHistoryForCouncil(4) || "" };
37615
+ try {
37616
+ const { loadDurableContext: loadDurableContext2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
37617
+ const durableState = await loadDurableContext2(process.cwd());
37618
+ const composed = composeProjectContext2({
37619
+ mode: overrides.ragContext ? "zelari" : "council",
37620
+ cwd: process.cwd(),
37621
+ userMessage: effectiveText,
37622
+ memoryHits: overrides.ragContext,
37623
+ durableState: durableState || void 0,
37624
+ historySnippet: formatHistoryForCouncil(4) || void 0,
37625
+ includeLessons: true,
37626
+ includeDurableState: false
37627
+ });
37628
+ for (const w of composed.warnings) {
37629
+ appendSystem(setMessages, w, Date.now());
37630
+ }
37631
+ councilCompose = {
37632
+ workspaceContext: composed.workspaceContext,
37633
+ ...composed.ragContext ? { ragContext: composed.ragContext } : {}
37634
+ };
37635
+ } catch {
37636
+ if (overrides.ragContext) {
37637
+ councilCompose = {
37638
+ workspaceContext: formatHistoryForCouncil(4) || "",
37639
+ ragContext: overrides.ragContext
37640
+ };
37641
+ }
37642
+ }
37517
37643
  try {
37518
37644
  for await (const event of dispatchCouncil2(effectiveText, {
37519
37645
  apiKey: envConfig.apiKey,
@@ -37523,33 +37649,8 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
37523
37649
  sessionId,
37524
37650
  tools: councilToolRegistry,
37525
37651
  feedbackStore: councilFeedbackStore,
37526
- // v1.16: unified compose — product truth + draft plan ops + design index
37527
- // (not full vault). Memory RAG only via overrides.ragContext.
37528
- // Fail-soft: never block a council run if compose throws in tests/odd cwd.
37529
- ...(() => {
37530
- try {
37531
- const composed = composeProjectContext2({
37532
- mode: overrides.ragContext ? "zelari" : "council",
37533
- cwd: process.cwd(),
37534
- userMessage: effectiveText,
37535
- memoryHits: overrides.ragContext,
37536
- historySnippet: formatHistoryForCouncil(4) || void 0,
37537
- includeLessons: true
37538
- });
37539
- for (const w of composed.warnings) {
37540
- appendSystem(setMessages, w, Date.now());
37541
- }
37542
- return {
37543
- workspaceContext: composed.workspaceContext,
37544
- ...composed.ragContext ? { ragContext: composed.ragContext } : {}
37545
- };
37546
- } catch {
37547
- return {
37548
- workspaceContext: formatHistoryForCouncil(4) || "",
37549
- ...overrides.ragContext ? { ragContext: overrides.ragContext } : {}
37550
- };
37551
- }
37552
- })(),
37652
+ workspaceContext: councilCompose.workspaceContext,
37653
+ ...councilCompose.ragContext ? { ragContext: councilCompose.ragContext } : {},
37553
37654
  maxToolCallsPerTurn: councilMaxToolCalls,
37554
37655
  maxToolLoopIterations: councilMaxToolLoop,
37555
37656
  ...councilMaxToolLoopHard > 0 ? { maxToolLoopHardCap: councilMaxToolLoopHard } : {},
@@ -38848,20 +38949,28 @@ async function handleStateStatus(ctx) {
38848
38949
  if (!head) {
38849
38950
  appendSystem(
38850
38951
  ctx.setMessages,
38851
- "[state] no durable commits yet. Run a verified Zelari slice or `/state commit [label]`."
38952
+ "[state] no durable commits yet. Run a verified Zelari slice or `/state commit [label]`.\n Kill switch: ZELARI_STATE=0 disables the store."
38852
38953
  );
38853
38954
  return;
38854
38955
  }
38855
- const recent = await store.list(5);
38956
+ const discoveries = await store.loadDiscoveries(head.id);
38957
+ const reusable = discoveries.filter((d) => d.reusable).length;
38958
+ const recent = await store.list(8);
38856
38959
  const lines = recent.map((c, i) => {
38857
- const ver = c.verification.ran ? c.verification.ok ? "ok" : "fail" : "n/a";
38858
- return ` ${i === 0 ? "\u2192" : " "} ${c.id} ${ago2(c.createdAt)} ${c.label} ver=${ver}` + (c.layer ? ` [${c.layer}]` : "");
38960
+ const ver2 = c.verification.ran ? c.verification.ok ? "ok" : "fail" : "n/a";
38961
+ return ` ${i === 0 ? "\u2192" : " "} ${c.id} ${ago2(c.createdAt)} ${c.label} ver=${ver2}` + (c.layer ? ` [${c.layer}]` : "") + (c.stablePromptHash ? ` hash=${c.stablePromptHash.slice(0, 8)}` : "");
38859
38962
  });
38963
+ const ver = head.verification;
38860
38964
  appendSystem(
38861
38965
  ctx.setMessages,
38862
- `[state] HEAD ${head.id} \xB7 ${head.discoveryCount} discoveries \xB7 mode ${head.mode}
38863
- ` + (head.workspaceCheckpointId ? `linked checkpoint: ${head.workspaceCheckpointId}
38864
- ` : "") + lines.join("\n")
38966
+ `[state] HEAD ${head.id} \xB7 mode ${head.mode}` + (head.layer ? ` \xB7 layer ${head.layer}` : "") + `
38967
+ discoveries: ${head.discoveryCount} total, ${reusable} reusable
38968
+ verification: ran=${ver.ran} ok=${ver.ok}` + (ver.reportPath ? ` report=${ver.reportPath}` : "") + (head.parentId ? `
38969
+ parent: ${head.parentId}` : "") + (head.workspaceCheckpointId ? `
38970
+ workspaceCheckpoint: ${head.workspaceCheckpointId}` : "") + (head.stablePromptHash ? `
38971
+ stablePromptHash: ${head.stablePromptHash}` : "") + `
38972
+ created: ${ago2(head.createdAt)}
38973
+ ` + lines.join("\n")
38865
38974
  );
38866
38975
  }
38867
38976
  async function handleStateCommit(ctx, label) {
@@ -38916,19 +39025,16 @@ async function handleStateRestore(ctx, id, opts) {
38916
39025
  appendSystem(ctx.setMessages, res.message);
38917
39026
  }
38918
39027
 
38919
- // src/cli/state/promptCacheStats.ts
38920
- function formatCacheStatsLine(stats) {
38921
- const pct = stats.promptTokens > 0 ? Math.round(stats.hitRate * 100) : 0;
38922
- return `cache hit ${pct}% \xB7 premium ${stats.premiumTokens} \xB7 cached ${stats.cachedTokens} \xB7 stable busts ${stats.stableBustCount} \xB7 turns ${stats.turns}`;
38923
- }
38924
-
38925
39028
  // src/cli/slashHandlers/cache.ts
38926
39029
  function handleCacheStats(ctx) {
39030
+ const ttl = resolvePromptCacheTtl();
38927
39031
  const s = ctx.sessionStats;
38928
39032
  if (!s || !(s.promptTokens || s.cachedTokens || s.totalTokens)) {
38929
39033
  appendSystem(
38930
39034
  ctx.setMessages,
38931
- "[cache] no session usage yet. Complete a model turn to see hit rate.\n Tip: stable prompt (identity+tools) should stay byte-stable; workspace/plan is volatile.\n Env: ZELARI_PROMPT_CACHE_TTL=1h|5m|auto (Anthropic path when available)."
39035
+ `[cache] no session usage yet. Complete a model turn to see hit rate.
39036
+ Tip: stable prompt (identity+tools) should stay byte-stable; workspace/plan is volatile.
39037
+ ZELARI_PROMPT_CACHE_TTL=${ttl} (OpenAI-compat: automatic prefix cache; TTL is a preference for future Anthropic markers).`
38932
39038
  );
38933
39039
  return;
38934
39040
  }
@@ -38938,15 +39044,18 @@ function handleCacheStats(ctx) {
38938
39044
  premiumTokens: s.premiumTokens ?? Math.max(0, (s.promptTokens ?? 0) - (s.cachedTokens ?? 0)),
38939
39045
  hitRate: s.cacheHitRate ?? 0,
38940
39046
  estimatedCostUsd: s.totalCostUsd ?? 0,
39047
+ lastStableHash: s.lastStableHash,
38941
39048
  stableBustCount: s.stableBustCount ?? 0,
38942
39049
  turns: 0
38943
39050
  };
38944
39051
  const pct = stats.promptTokens > 0 ? Math.round(stats.hitRate * 100) : 0;
39052
+ const hashShort = stats.lastStableHash ? stats.lastStableHash.slice(0, 8) : "\u2014";
38945
39053
  appendSystem(
38946
39054
  ctx.setMessages,
38947
39055
  `[cache] ${formatCacheStatsLine(stats)}
38948
- hit rate: ${pct}% \xB7 cost ~$${stats.estimatedCostUsd.toFixed(4)}
38949
- (OpenAI-compat: automatic prefix cache; keep system stable prefix free of plan/memory churn.)`
39056
+ hit rate: ${pct}% \xB7 premium ${stats.premiumTokens} \xB7 cached ${stats.cachedTokens}
39057
+ cost ~$${stats.estimatedCostUsd.toFixed(4)} \xB7 stable hash ${hashShort} \xB7 busts ${stats.stableBustCount}
39058
+ TTL pref: ${ttl} (OpenAI-compat path uses automatic prefix caching; keep stable prefix free of plan/memory churn.)`
38950
39059
  );
38951
39060
  }
38952
39061
 
@@ -40702,7 +40811,8 @@ function App() {
40702
40811
  premiumTokens: 0,
40703
40812
  cacheHitRate: 0,
40704
40813
  promptTokens: 0,
40705
- stableBustCount: 0
40814
+ stableBustCount: 0,
40815
+ lastStableHash: void 0
40706
40816
  });
40707
40817
  const [clearEpoch, setClearEpoch] = useState8(0);
40708
40818
  const [mode, setMode] = useState8("agent");
@@ -41816,11 +41926,16 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
41816
41926
  ].join("\n")
41817
41927
  };
41818
41928
  const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
41929
+ const { loadDurableContext: loadDurableContext2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
41930
+ const cwd = process.cwd();
41931
+ const durableState = await loadDurableContext2(cwd);
41819
41932
  const composed = composeProjectContext2({
41820
41933
  mode: "agent",
41821
- cwd: process.cwd(),
41934
+ cwd,
41822
41935
  userMessage: opts.task,
41823
- includeLessons: false
41936
+ includeLessons: false,
41937
+ durableState: durableState || void 0,
41938
+ includeDurableState: false
41824
41939
  });
41825
41940
  let sshBlock = "";
41826
41941
  try {
@@ -41829,6 +41944,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
41829
41944
  } catch {
41830
41945
  }
41831
41946
  const rolePrompt = [headlessRole.systemPrompt, sshBlock].filter(Boolean).join("\n\n");
41947
+ const agentWorkspace = [composed.workspaceContext, composed.ragContext].filter(Boolean).join("\n\n");
41832
41948
  systemPrompt = buildSystemPrompt(
41833
41949
  { ...headlessRole, systemPrompt: rolePrompt },
41834
41950
  {
@@ -41836,7 +41952,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
41836
41952
  toolNames,
41837
41953
  mode: "agent",
41838
41954
  projectInstructions: composed.projectInstructions || void 0,
41839
- workspaceContext: composed.workspaceContext || void 0,
41955
+ workspaceContext: agentWorkspace || void 0,
41840
41956
  // Plan lives in workspaceContext as draft ops — never as RAG.
41841
41957
  ragContext: void 0,
41842
41958
  aiConfig: {
@@ -42104,11 +42220,16 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
42104
42220
  let currentAssistantText = "";
42105
42221
  try {
42106
42222
  const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
42223
+ const { loadDurableContext: loadDurableContext2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
42224
+ const cwd = process.cwd();
42225
+ const durableState = await loadDurableContext2(cwd);
42107
42226
  const composed = composeProjectContext2({
42108
42227
  mode: "council",
42109
- cwd: process.cwd(),
42228
+ cwd,
42110
42229
  userMessage: opts.task,
42111
- includeLessons: true
42230
+ includeLessons: true,
42231
+ durableState: durableState || void 0,
42232
+ includeDurableState: false
42112
42233
  });
42113
42234
  for await (const event of dispatchCouncil2(effectiveTask, {
42114
42235
  apiKey: "REDACTED",
@@ -42249,13 +42370,17 @@ ${ragContext}` : slicePrompt;
42249
42370
  let membersCompleted = 0;
42250
42371
  const scrub = createStreamScrubber();
42251
42372
  const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
42373
+ const { loadDurableContext: loadDurableContext2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
42252
42374
  const memOnly = ragContext?.trim() ? ragContext : void 0;
42375
+ const durableState = await loadDurableContext2(projectRoot);
42253
42376
  const composed = composeProjectContext2({
42254
42377
  mode: "zelari",
42255
42378
  cwd: projectRoot,
42256
42379
  userMessage: slicePrompt,
42257
42380
  memoryHits: memOnly,
42258
- includeLessons: true
42381
+ durableState: durableState || void 0,
42382
+ includeLessons: true,
42383
+ includeDurableState: false
42259
42384
  });
42260
42385
  for await (const event of dispatchCouncil2(fullPrompt, {
42261
42386
  apiKey: "REDACTED",