opencode-swarm 6.29.4 → 6.29.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -31005,6 +31005,7 @@ function serializeAgentSession(s) {
31005
31005
  lastCompletedPhaseAgentsDispatched,
31006
31006
  qaSkipCount: s.qaSkipCount ?? 0,
31007
31007
  qaSkipTaskIds: s.qaSkipTaskIds ?? [],
31008
+ pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? [],
31008
31009
  taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
31009
31010
  ...s.scopeViolationDetected !== undefined && {
31010
31011
  scopeViolationDetected: s.scopeViolationDetected
package/dist/index.js CHANGED
@@ -39369,6 +39369,7 @@ init_plan_schema();
39369
39369
  init_schema();
39370
39370
  import * as fs3 from "fs/promises";
39371
39371
  import * as path2 from "path";
39372
+ var _rehydrationCache = null;
39372
39373
  var swarmState = {
39373
39374
  activeToolCalls: new Map,
39374
39375
  toolAggregates: new Map,
@@ -39378,7 +39379,7 @@ var swarmState = {
39378
39379
  lastBudgetPct: 0,
39379
39380
  agentSessions: new Map
39380
39381
  };
39381
- function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, directory) {
39382
+ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, _directory) {
39382
39383
  const now = Date.now();
39383
39384
  const staleIds = [];
39384
39385
  for (const [id, session] of swarmState.agentSessions) {
@@ -39426,14 +39427,12 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, dire
39426
39427
  };
39427
39428
  swarmState.agentSessions.set(sessionId, sessionState);
39428
39429
  swarmState.activeAgent.set(sessionId, agentName);
39429
- if (directory) {
39430
- rehydrateSessionFromDisk(directory, sessionState).catch(() => {});
39431
- }
39430
+ applyRehydrationCache(sessionState);
39432
39431
  }
39433
39432
  function getAgentSession(sessionId) {
39434
39433
  return swarmState.agentSessions.get(sessionId);
39435
39434
  }
39436
- function ensureAgentSession(sessionId, agentName, directory) {
39435
+ function ensureAgentSession(sessionId, agentName, _directory) {
39437
39436
  const now = Date.now();
39438
39437
  let session = swarmState.agentSessions.get(sessionId);
39439
39438
  if (session) {
@@ -39533,7 +39532,7 @@ function ensureAgentSession(sessionId, agentName, directory) {
39533
39532
  session.lastToolCallTime = now;
39534
39533
  return session;
39535
39534
  }
39536
- startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
39535
+ startAgentSession(sessionId, agentName ?? "unknown", 7200000);
39537
39536
  session = swarmState.agentSessions.get(sessionId);
39538
39537
  if (!session) {
39539
39538
  throw new Error(`Failed to create guardrail session for ${sessionId}`);
@@ -39718,43 +39717,47 @@ async function readEvidenceFromDisk(directory) {
39718
39717
  } catch {}
39719
39718
  return evidenceMap;
39720
39719
  }
39721
- async function rehydrateSessionFromDisk(directory, session) {
39722
- if (!session.taskWorkflowStates) {
39723
- session.taskWorkflowStates = new Map;
39724
- }
39725
- const plan = await readPlanFromDisk(directory);
39726
- if (!plan) {
39727
- return;
39728
- }
39720
+ async function buildRehydrationCache(directory) {
39729
39721
  const planTaskStates = new Map;
39730
- for (const phase of plan.phases ?? []) {
39731
- for (const task of phase.tasks ?? []) {
39732
- const taskState = planStatusToWorkflowState(task.status);
39733
- planTaskStates.set(task.id, taskState);
39722
+ const plan = await readPlanFromDisk(directory);
39723
+ if (plan) {
39724
+ for (const phase of plan.phases ?? []) {
39725
+ for (const task of phase.tasks ?? []) {
39726
+ planTaskStates.set(task.id, planStatusToWorkflowState(task.status));
39727
+ }
39734
39728
  }
39735
39729
  }
39736
39730
  const evidenceMap = await readEvidenceFromDisk(directory);
39731
+ _rehydrationCache = { planTaskStates, evidenceMap };
39732
+ }
39733
+ function applyRehydrationCache(session) {
39734
+ if (!_rehydrationCache) {
39735
+ return;
39736
+ }
39737
+ if (!session.taskWorkflowStates) {
39738
+ session.taskWorkflowStates = new Map;
39739
+ }
39740
+ const { planTaskStates, evidenceMap } = _rehydrationCache;
39741
+ const STATE_ORDER = [
39742
+ "idle",
39743
+ "coder_delegated",
39744
+ "pre_check_passed",
39745
+ "reviewer_run",
39746
+ "tests_run",
39747
+ "complete"
39748
+ ];
39737
39749
  for (const [taskId, planState] of planTaskStates) {
39738
39750
  const existingState = session.taskWorkflowStates.get(taskId);
39739
39751
  const evidence = evidenceMap.get(taskId);
39740
- let derivedState;
39741
39752
  if (evidence) {
39742
- derivedState = evidenceToWorkflowState(evidence);
39743
- } else {
39744
- derivedState = planState;
39745
- }
39746
- const STATE_ORDER = [
39747
- "idle",
39748
- "coder_delegated",
39749
- "pre_check_passed",
39750
- "reviewer_run",
39751
- "tests_run",
39752
- "complete"
39753
- ];
39754
- const existingIndex = existingState ? STATE_ORDER.indexOf(existingState) : -1;
39755
- const derivedIndex = STATE_ORDER.indexOf(derivedState);
39756
- if (derivedIndex > existingIndex) {
39753
+ const derivedState = evidenceToWorkflowState(evidence);
39757
39754
  session.taskWorkflowStates.set(taskId, derivedState);
39755
+ } else {
39756
+ const existingIndex = existingState ? STATE_ORDER.indexOf(existingState) : -1;
39757
+ const derivedIndex = STATE_ORDER.indexOf(planState);
39758
+ if (derivedIndex > existingIndex) {
39759
+ session.taskWorkflowStates.set(taskId, planState);
39760
+ }
39758
39761
  }
39759
39762
  }
39760
39763
  }
@@ -46385,6 +46388,7 @@ function serializeAgentSession(s) {
46385
46388
  lastCompletedPhaseAgentsDispatched,
46386
46389
  qaSkipCount: s.qaSkipCount ?? 0,
46387
46390
  qaSkipTaskIds: s.qaSkipTaskIds ?? [],
46391
+ pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? [],
46388
46392
  taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
46389
46393
  ...s.scopeViolationDetected !== undefined && {
46390
46394
  scopeViolationDetected: s.scopeViolationDetected
@@ -49871,7 +49875,7 @@ ${pending.message}
49871
49875
  }
49872
49876
  }
49873
49877
  if (isArchitectSession && (session?.pendingAdvisoryMessages?.length ?? 0) > 0) {
49874
- const advisories = session.pendingAdvisoryMessages;
49878
+ const advisories = session.pendingAdvisoryMessages ?? [];
49875
49879
  let targetMsg = systemMessages[0];
49876
49880
  if (!targetMsg) {
49877
49881
  const newMsg = {
@@ -50819,9 +50823,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner = run
50819
50823
  const initResult = await curatorRunner(directory, curatorConfig);
50820
50824
  if (initResult.briefing) {
50821
50825
  const briefingPath = path31.join(directory, ".swarm", "curator-briefing.md");
50822
- const fs18 = await import("fs");
50823
- fs18.mkdirSync(path31.dirname(briefingPath), { recursive: true });
50824
- fs18.writeFileSync(briefingPath, initResult.briefing, "utf-8");
50826
+ const { mkdir: mkdir4, writeFile: writeFile4 } = await import("fs/promises");
50827
+ await mkdir4(path31.dirname(briefingPath), { recursive: true });
50828
+ await writeFile4(briefingPath, initResult.briefing, "utf-8");
50825
50829
  }
50826
50830
  }
50827
50831
  } catch {}
@@ -53569,15 +53573,14 @@ function createKnowledgeInjectorHook(directory, config3) {
53569
53573
  currentPhase: phaseDescription
53570
53574
  };
53571
53575
  const entries = await readMergedKnowledge(directory, config3, context);
53576
+ let freshPreamble = null;
53572
53577
  try {
53573
53578
  const driftReports = await readPriorDriftReports(directory);
53574
53579
  if (driftReports.length > 0) {
53575
53580
  const latestReport = driftReports[driftReports.length - 1];
53576
53581
  const driftText = buildDriftInjectionText(latestReport, 500);
53577
53582
  if (driftText) {
53578
- cachedInjectionText = cachedInjectionText ? `${driftText}
53579
-
53580
- ${cachedInjectionText}` : driftText;
53583
+ freshPreamble = driftText;
53581
53584
  }
53582
53585
  }
53583
53586
  } catch {}
@@ -53585,14 +53588,15 @@ ${cachedInjectionText}` : driftText;
53585
53588
  const briefingContent = await readSwarmFileAsync(directory, "curator-briefing.md");
53586
53589
  if (briefingContent) {
53587
53590
  const truncatedBriefing = briefingContent.slice(0, 500);
53588
- cachedInjectionText = cachedInjectionText ? `<curator_briefing>${truncatedBriefing}</curator_briefing>
53591
+ freshPreamble = freshPreamble ? `<curator_briefing>${truncatedBriefing}</curator_briefing>
53589
53592
 
53590
- ${cachedInjectionText}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
53593
+ ${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
53591
53594
  }
53592
53595
  } catch {}
53593
53596
  if (entries.length === 0) {
53594
- if (cachedInjectionText === null)
53597
+ if (freshPreamble === null)
53595
53598
  return;
53599
+ cachedInjectionText = freshPreamble;
53596
53600
  injectKnowledgeMessage(output, cachedInjectionText);
53597
53601
  return;
53598
53602
  }
@@ -53614,7 +53618,7 @@ ${cachedInjectionText}` : `<curator_briefing>${truncatedBriefing}</curator_brief
53614
53618
  "These are lessons learned from this project and past projects. Consider them as context but use your judgment \u2014 they may not all apply."
53615
53619
  ].join(`
53616
53620
  `);
53617
- let injectionText = cachedInjectionText ? `${cachedInjectionText}
53621
+ let injectionText = freshPreamble ? `${freshPreamble}
53618
53622
 
53619
53623
  ${knowledgeSection}` : knowledgeSection;
53620
53624
  if (runMemory) {
@@ -53926,7 +53930,8 @@ function deserializeAgentSession(s) {
53926
53930
  declaredCoderScope: null,
53927
53931
  lastScopeViolation: null,
53928
53932
  scopeViolationDetected: s.scopeViolationDetected,
53929
- modifiedFilesThisCoderTask: []
53933
+ modifiedFilesThisCoderTask: [],
53934
+ pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? []
53930
53935
  };
53931
53936
  }
53932
53937
  async function readSnapshot(directory) {
@@ -54019,9 +54024,13 @@ async function reconcileTaskStatesFromPlan(directory) {
54019
54024
  }
54020
54025
  async function loadSnapshot(directory) {
54021
54026
  try {
54027
+ await buildRehydrationCache(directory);
54022
54028
  const snapshot = await readSnapshot(directory);
54023
54029
  if (snapshot !== null) {
54024
54030
  rehydrateState(snapshot);
54031
+ for (const session of swarmState.agentSessions.values()) {
54032
+ applyRehydrationCache(session);
54033
+ }
54025
54034
  await reconcileTaskStatesFromPlan(directory);
54026
54035
  }
54027
54036
  } catch {}
@@ -37,6 +37,7 @@ export interface SerializedAgentSession {
37
37
  lastCompletedPhaseAgentsDispatched: string[];
38
38
  qaSkipCount: number;
39
39
  qaSkipTaskIds: string[];
40
+ pendingAdvisoryMessages: string[];
40
41
  taskWorkflowStates?: Record<string, string>;
41
42
  /** Flag for one-shot scope violation warning injection (omitted when undefined for additive-only schema) */
42
43
  scopeViolationDetected?: boolean;
package/dist/state.d.ts CHANGED
@@ -194,7 +194,7 @@ export declare function resetSwarmState(): void;
194
194
  * @param staleDurationMs - Age threshold for stale session eviction (default: 120 min)
195
195
  * @param directory - Optional project directory for rehydrating workflow state from disk
196
196
  */
197
- export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number, directory?: string): void;
197
+ export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number, _directory?: string): void;
198
198
  /**
199
199
  * End an agent session by removing it from the state.
200
200
  * NOTE: Currently unused in production — no session lifecycle teardown is wired up.
@@ -216,10 +216,9 @@ export declare function getAgentSession(sessionId: string): AgentSessionState |
216
216
  * Always updates lastToolCallTime.
217
217
  * @param sessionId - The session identifier
218
218
  * @param agentName - Optional agent name (if known)
219
- * @param directory - Optional project directory for rehydrating workflow state from disk
220
219
  * @returns The AgentSessionState
221
220
  */
222
- export declare function ensureAgentSession(sessionId: string, agentName?: string, directory?: string): AgentSessionState;
221
+ export declare function ensureAgentSession(sessionId: string, agentName?: string, _directory?: string): AgentSessionState;
223
222
  /**
224
223
  * Update only the agent event timestamp (for stale detection).
225
224
  * Does NOT change agent name or reset guardrail state.
@@ -301,6 +300,25 @@ export declare function getTaskState(session: AgentSessionState, taskId: string)
301
300
  * @param directory - Project root containing .swarm/ subdirectory
302
301
  * @param session - Target AgentSessionState to merge rehydrated state into
303
302
  */
303
+ /**
304
+ * Reads plan.json + evidence/*.json from the project directory and populates the
305
+ * module-level _rehydrationCache. Called once at plugin init by loadSnapshot().
306
+ * Non-fatal: missing/malformed files leave an empty cache.
307
+ */
308
+ export declare function buildRehydrationCache(directory: string): Promise<void>;
309
+ /**
310
+ * Synchronously applies the cached plan+evidence data to a session.
311
+ * Merge rules:
312
+ * - evidence-derived state: always applied (replaces snapshot state, even if lower)
313
+ * - plan-only derived state: only applied if it advances past existing state
314
+ * No-op when the cache has not been built yet.
315
+ */
316
+ export declare function applyRehydrationCache(session: AgentSessionState): void;
317
+ /**
318
+ * Rehydrates session workflow state from durable swarm files.
319
+ * Builds (or refreshes) the rehydration cache from disk, then applies it
320
+ * to the target session.
321
+ */
304
322
  export declare function rehydrateSessionFromDisk(directory: string, session: AgentSessionState): Promise<void>;
305
323
  /**
306
324
  * Check if ANY active session has Turbo Mode enabled.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.29.4",
3
+ "version": "6.29.6",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",