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 +1 -0
- package/dist/index.js +55 -46
- package/dist/session/snapshot-writer.d.ts +1 -0
- package/dist/state.d.ts +21 -3
- package/package.json +1 -1
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,
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
39731
|
-
|
|
39732
|
-
|
|
39733
|
-
|
|
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
|
|
50823
|
-
|
|
50824
|
-
|
|
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
|
-
|
|
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
|
-
|
|
53591
|
+
freshPreamble = freshPreamble ? `<curator_briefing>${truncatedBriefing}</curator_briefing>
|
|
53589
53592
|
|
|
53590
|
-
${
|
|
53593
|
+
${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
|
|
53591
53594
|
}
|
|
53592
53595
|
} catch {}
|
|
53593
53596
|
if (entries.length === 0) {
|
|
53594
|
-
if (
|
|
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 =
|
|
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,
|
|
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,
|
|
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.
|
|
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",
|