opencode-swarm 6.30.0 → 6.30.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.
- package/dist/cli/index.js +2 -1
- package/dist/index.js +93 -41
- package/dist/session/snapshot-reader.d.ts +1 -1
- package/dist/state.d.ts +4 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -17453,7 +17453,8 @@ var swarmState = {
|
|
|
17453
17453
|
delegationChains: new Map,
|
|
17454
17454
|
pendingEvents: 0,
|
|
17455
17455
|
lastBudgetPct: 0,
|
|
17456
|
-
agentSessions: new Map
|
|
17456
|
+
agentSessions: new Map,
|
|
17457
|
+
pendingRehydrations: new Set
|
|
17457
17458
|
};
|
|
17458
17459
|
function getAgentSession(sessionId) {
|
|
17459
17460
|
return swarmState.agentSessions.get(sessionId);
|
package/dist/index.js
CHANGED
|
@@ -39377,9 +39377,10 @@ var swarmState = {
|
|
|
39377
39377
|
delegationChains: new Map,
|
|
39378
39378
|
pendingEvents: 0,
|
|
39379
39379
|
lastBudgetPct: 0,
|
|
39380
|
-
agentSessions: new Map
|
|
39380
|
+
agentSessions: new Map,
|
|
39381
|
+
pendingRehydrations: new Set
|
|
39381
39382
|
};
|
|
39382
|
-
function startAgentSession(sessionId, agentName, staleDurationMs = 7200000,
|
|
39383
|
+
function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, directory) {
|
|
39383
39384
|
const now = Date.now();
|
|
39384
39385
|
const staleIds = [];
|
|
39385
39386
|
for (const [id, session] of swarmState.agentSessions) {
|
|
@@ -39428,11 +39429,18 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, _dir
|
|
|
39428
39429
|
swarmState.agentSessions.set(sessionId, sessionState);
|
|
39429
39430
|
swarmState.activeAgent.set(sessionId, agentName);
|
|
39430
39431
|
applyRehydrationCache(sessionState);
|
|
39432
|
+
if (directory) {
|
|
39433
|
+
let rehydrationPromise;
|
|
39434
|
+
rehydrationPromise = rehydrateSessionFromDisk(directory, sessionState).catch(() => {}).finally(() => {
|
|
39435
|
+
swarmState.pendingRehydrations.delete(rehydrationPromise);
|
|
39436
|
+
});
|
|
39437
|
+
swarmState.pendingRehydrations.add(rehydrationPromise);
|
|
39438
|
+
}
|
|
39431
39439
|
}
|
|
39432
39440
|
function getAgentSession(sessionId) {
|
|
39433
39441
|
return swarmState.agentSessions.get(sessionId);
|
|
39434
39442
|
}
|
|
39435
|
-
function ensureAgentSession(sessionId, agentName,
|
|
39443
|
+
function ensureAgentSession(sessionId, agentName, directory) {
|
|
39436
39444
|
const now = Date.now();
|
|
39437
39445
|
let session = swarmState.agentSessions.get(sessionId);
|
|
39438
39446
|
if (session) {
|
|
@@ -39532,7 +39540,7 @@ function ensureAgentSession(sessionId, agentName, _directory) {
|
|
|
39532
39540
|
session.lastToolCallTime = now;
|
|
39533
39541
|
return session;
|
|
39534
39542
|
}
|
|
39535
|
-
startAgentSession(sessionId, agentName ?? "unknown", 7200000);
|
|
39543
|
+
startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
|
|
39536
39544
|
session = swarmState.agentSessions.get(sessionId);
|
|
39537
39545
|
if (!session) {
|
|
39538
39546
|
throw new Error(`Failed to create guardrail session for ${sessionId}`);
|
|
@@ -39761,6 +39769,10 @@ function applyRehydrationCache(session) {
|
|
|
39761
39769
|
}
|
|
39762
39770
|
}
|
|
39763
39771
|
}
|
|
39772
|
+
async function rehydrateSessionFromDisk(directory, session) {
|
|
39773
|
+
await buildRehydrationCache(directory);
|
|
39774
|
+
applyRehydrationCache(session);
|
|
39775
|
+
}
|
|
39764
39776
|
function hasActiveTurboMode() {
|
|
39765
39777
|
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
39766
39778
|
if (session.turboMode === true) {
|
|
@@ -49897,6 +49909,8 @@ ${joined}
|
|
|
49897
49909
|
` + textPart2.text;
|
|
49898
49910
|
}
|
|
49899
49911
|
session.pendingAdvisoryMessages = [];
|
|
49912
|
+
} else if (!isArchitectSession && session && (session.pendingAdvisoryMessages?.length ?? 0) > 0) {
|
|
49913
|
+
session.pendingAdvisoryMessages = [];
|
|
49900
49914
|
}
|
|
49901
49915
|
if (isArchitectSession && session && session.architectWriteCount > session.selfCodingWarnedAtCount) {
|
|
49902
49916
|
let targetSystemMessage = systemMessages[0];
|
|
@@ -52565,19 +52579,38 @@ import * as path33 from "path";
|
|
|
52565
52579
|
|
|
52566
52580
|
// src/hooks/spawn-helper.ts
|
|
52567
52581
|
import { spawn } from "child_process";
|
|
52582
|
+
var WIN32_CMD_BINARIES = new Set(["npm", "npx", "pnpm", "yarn"]);
|
|
52568
52583
|
function spawnAsync(command, cwd, timeoutMs) {
|
|
52569
52584
|
return new Promise((resolve11) => {
|
|
52570
52585
|
try {
|
|
52571
|
-
const [
|
|
52586
|
+
const [rawCmd, ...args2] = command;
|
|
52587
|
+
const cmd = process.platform === "win32" && WIN32_CMD_BINARIES.has(rawCmd) && !rawCmd.includes(".") ? `${rawCmd}.cmd` : rawCmd;
|
|
52572
52588
|
const proc = spawn(cmd, args2, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
52573
52589
|
let stdout = "";
|
|
52574
52590
|
let stderr = "";
|
|
52575
52591
|
let done = false;
|
|
52592
|
+
const MAX_OUTPUT = 512 * 1024;
|
|
52576
52593
|
proc.stdout.on("data", (d) => {
|
|
52577
|
-
stdout
|
|
52594
|
+
if (stdout.length < MAX_OUTPUT) {
|
|
52595
|
+
stdout += d;
|
|
52596
|
+
if (stdout.length >= MAX_OUTPUT) {
|
|
52597
|
+
stdout = stdout.slice(0, MAX_OUTPUT);
|
|
52598
|
+
try {
|
|
52599
|
+
proc.stdout.destroy();
|
|
52600
|
+
} catch {}
|
|
52601
|
+
}
|
|
52602
|
+
}
|
|
52578
52603
|
});
|
|
52579
52604
|
proc.stderr.on("data", (d) => {
|
|
52580
|
-
stderr
|
|
52605
|
+
if (stderr.length < MAX_OUTPUT) {
|
|
52606
|
+
stderr += d;
|
|
52607
|
+
if (stderr.length >= MAX_OUTPUT) {
|
|
52608
|
+
stderr = stderr.slice(0, MAX_OUTPUT);
|
|
52609
|
+
try {
|
|
52610
|
+
proc.stderr.destroy();
|
|
52611
|
+
} catch {}
|
|
52612
|
+
}
|
|
52613
|
+
}
|
|
52581
52614
|
});
|
|
52582
52615
|
const timer = setTimeout(() => {
|
|
52583
52616
|
if (done)
|
|
@@ -52616,19 +52649,31 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
52616
52649
|
|
|
52617
52650
|
// src/hooks/incremental-verify.ts
|
|
52618
52651
|
var emittedSkipAdvisories = new Set;
|
|
52652
|
+
function detectPackageManager(projectDir) {
|
|
52653
|
+
if (fs20.existsSync(path33.join(projectDir, "bun.lockb")))
|
|
52654
|
+
return "bun";
|
|
52655
|
+
if (fs20.existsSync(path33.join(projectDir, "pnpm-lock.yaml")))
|
|
52656
|
+
return "pnpm";
|
|
52657
|
+
if (fs20.existsSync(path33.join(projectDir, "yarn.lock")))
|
|
52658
|
+
return "yarn";
|
|
52659
|
+
if (fs20.existsSync(path33.join(projectDir, "package-lock.json")))
|
|
52660
|
+
return "npm";
|
|
52661
|
+
return "bun";
|
|
52662
|
+
}
|
|
52619
52663
|
function detectTypecheckCommand(projectDir) {
|
|
52620
52664
|
const pkgPath = path33.join(projectDir, "package.json");
|
|
52621
52665
|
if (fs20.existsSync(pkgPath)) {
|
|
52622
52666
|
try {
|
|
52623
52667
|
const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf8"));
|
|
52624
52668
|
const scripts = pkg.scripts;
|
|
52625
|
-
if (scripts?.typecheck)
|
|
52626
|
-
|
|
52627
|
-
|
|
52628
|
-
|
|
52629
|
-
|
|
52630
|
-
|
|
52631
|
-
};
|
|
52669
|
+
if (scripts?.typecheck) {
|
|
52670
|
+
const pm = detectPackageManager(projectDir);
|
|
52671
|
+
return { command: [pm, "run", "typecheck"], language: "typescript" };
|
|
52672
|
+
}
|
|
52673
|
+
if (scripts?.["type-check"]) {
|
|
52674
|
+
const pm = detectPackageManager(projectDir);
|
|
52675
|
+
return { command: [pm, "run", "type-check"], language: "typescript" };
|
|
52676
|
+
}
|
|
52632
52677
|
const deps = {
|
|
52633
52678
|
...pkg.dependencies,
|
|
52634
52679
|
...pkg.devDependencies
|
|
@@ -52683,7 +52728,11 @@ function createIncrementalVerifyHook(config3, projectDir, injectMessage) {
|
|
|
52683
52728
|
}
|
|
52684
52729
|
let commandToRun = null;
|
|
52685
52730
|
if (config3.command != null) {
|
|
52686
|
-
|
|
52731
|
+
if (Array.isArray(config3.command)) {
|
|
52732
|
+
commandToRun = config3.command;
|
|
52733
|
+
} else {
|
|
52734
|
+
commandToRun = config3.command.split(" ");
|
|
52735
|
+
}
|
|
52687
52736
|
} else {
|
|
52688
52737
|
const detected = detectTypecheckCommand(projectDir);
|
|
52689
52738
|
if (detected === null) {
|
|
@@ -53954,7 +54003,10 @@ async function readSnapshot(directory) {
|
|
|
53954
54003
|
return null;
|
|
53955
54004
|
}
|
|
53956
54005
|
}
|
|
53957
|
-
function rehydrateState(snapshot) {
|
|
54006
|
+
async function rehydrateState(snapshot) {
|
|
54007
|
+
if (swarmState.pendingRehydrations.size > 0) {
|
|
54008
|
+
await Promise.allSettled([...swarmState.pendingRehydrations]);
|
|
54009
|
+
}
|
|
53958
54010
|
swarmState.toolAggregates.clear();
|
|
53959
54011
|
swarmState.activeAgent.clear();
|
|
53960
54012
|
swarmState.delegationChains.clear();
|
|
@@ -53985,7 +54037,7 @@ async function loadSnapshot(directory) {
|
|
|
53985
54037
|
await buildRehydrationCache(directory);
|
|
53986
54038
|
const snapshot = await readSnapshot(directory);
|
|
53987
54039
|
if (snapshot !== null) {
|
|
53988
|
-
rehydrateState(snapshot);
|
|
54040
|
+
await rehydrateState(snapshot);
|
|
53989
54041
|
for (const session of swarmState.agentSessions.values()) {
|
|
53990
54042
|
applyRehydrationCache(session);
|
|
53991
54043
|
}
|
|
@@ -56643,32 +56695,32 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56643
56695
|
]
|
|
56644
56696
|
}, null, 2);
|
|
56645
56697
|
}
|
|
56698
|
+
const knowledgeConfig = {
|
|
56699
|
+
enabled: true,
|
|
56700
|
+
swarm_max_entries: 100,
|
|
56701
|
+
hive_max_entries: 200,
|
|
56702
|
+
auto_promote_days: 90,
|
|
56703
|
+
max_inject_count: 5,
|
|
56704
|
+
dedup_threshold: 0.6,
|
|
56705
|
+
scope_filter: ["global"],
|
|
56706
|
+
hive_enabled: true,
|
|
56707
|
+
rejected_max_entries: 20,
|
|
56708
|
+
validation_enabled: true,
|
|
56709
|
+
evergreen_confidence: 0.9,
|
|
56710
|
+
evergreen_utility: 0.8,
|
|
56711
|
+
low_utility_threshold: 0.3,
|
|
56712
|
+
min_retrievals_for_utility: 3,
|
|
56713
|
+
schema_version: 1,
|
|
56714
|
+
same_project_weight: 1,
|
|
56715
|
+
cross_project_weight: 0.5,
|
|
56716
|
+
min_encounter_score: 0.1,
|
|
56717
|
+
initial_encounter_score: 1,
|
|
56718
|
+
encounter_increment: 0.1,
|
|
56719
|
+
max_encounter_score: 10
|
|
56720
|
+
};
|
|
56646
56721
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
56647
56722
|
try {
|
|
56648
56723
|
const projectName = path44.basename(dir);
|
|
56649
|
-
const knowledgeConfig = {
|
|
56650
|
-
enabled: true,
|
|
56651
|
-
swarm_max_entries: 100,
|
|
56652
|
-
hive_max_entries: 200,
|
|
56653
|
-
auto_promote_days: 90,
|
|
56654
|
-
max_inject_count: 5,
|
|
56655
|
-
dedup_threshold: 0.6,
|
|
56656
|
-
scope_filter: ["global"],
|
|
56657
|
-
hive_enabled: true,
|
|
56658
|
-
rejected_max_entries: 20,
|
|
56659
|
-
validation_enabled: true,
|
|
56660
|
-
evergreen_confidence: 0.9,
|
|
56661
|
-
evergreen_utility: 0.8,
|
|
56662
|
-
low_utility_threshold: 0.3,
|
|
56663
|
-
min_retrievals_for_utility: 3,
|
|
56664
|
-
schema_version: 1,
|
|
56665
|
-
same_project_weight: 1,
|
|
56666
|
-
cross_project_weight: 0.5,
|
|
56667
|
-
min_encounter_score: 0.1,
|
|
56668
|
-
initial_encounter_score: 1,
|
|
56669
|
-
encounter_increment: 0.1,
|
|
56670
|
-
max_encounter_score: 10
|
|
56671
|
-
};
|
|
56672
56724
|
await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
56673
56725
|
} catch (error93) {
|
|
56674
56726
|
safeWarn("[phase_complete] Failed to curate lessons from retrospective:", error93);
|
|
@@ -56679,7 +56731,7 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56679
56731
|
const curatorConfig = CuratorConfigSchema.parse(config3.curator ?? {});
|
|
56680
56732
|
if (curatorConfig.enabled && curatorConfig.phase_enabled) {
|
|
56681
56733
|
const curatorResult = await runCuratorPhase(dir, phase, agentsDispatched, curatorConfig, {});
|
|
56682
|
-
await applyCuratorKnowledgeUpdates(dir, curatorResult.knowledge_recommendations,
|
|
56734
|
+
await applyCuratorKnowledgeUpdates(dir, curatorResult.knowledge_recommendations, knowledgeConfig);
|
|
56683
56735
|
await runCriticDriftCheck(dir, phase, curatorResult, curatorConfig);
|
|
56684
56736
|
if (curatorResult.compliance.length > 0 && !curatorConfig.suppress_warnings) {
|
|
56685
56737
|
const complianceLines = curatorResult.compliance.map((obs) => `[${obs.severity.toUpperCase()}] ${obs.description}`).slice(0, 5);
|
|
@@ -20,7 +20,7 @@ export declare function readSnapshot(directory: string): Promise<SnapshotData |
|
|
|
20
20
|
* Clears existing maps first, then populates from snapshot.
|
|
21
21
|
* Does NOT touch activeToolCalls or pendingEvents (remain at defaults).
|
|
22
22
|
*/
|
|
23
|
-
export declare function rehydrateState(snapshot: SnapshotData): void
|
|
23
|
+
export declare function rehydrateState(snapshot: SnapshotData): Promise<void>;
|
|
24
24
|
/**
|
|
25
25
|
* Load snapshot from disk and rehydrate swarmState.
|
|
26
26
|
* Called on plugin init to restore state from previous session.
|
package/dist/state.d.ts
CHANGED
|
@@ -181,6 +181,8 @@ export declare const swarmState: {
|
|
|
181
181
|
lastBudgetPct: number;
|
|
182
182
|
/** Per-session guardrail state — keyed by sessionID */
|
|
183
183
|
agentSessions: Map<string, AgentSessionState>;
|
|
184
|
+
/** In-flight rehydration promises — awaited by rehydrateState before clearing agentSessions */
|
|
185
|
+
pendingRehydrations: Set<Promise<void>>;
|
|
184
186
|
};
|
|
185
187
|
/**
|
|
186
188
|
* Reset all state to initial values - useful for testing
|
|
@@ -194,7 +196,7 @@ export declare function resetSwarmState(): void;
|
|
|
194
196
|
* @param staleDurationMs - Age threshold for stale session eviction (default: 120 min)
|
|
195
197
|
* @param directory - Optional project directory for rehydrating workflow state from disk
|
|
196
198
|
*/
|
|
197
|
-
export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number,
|
|
199
|
+
export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number, directory?: string): void;
|
|
198
200
|
/**
|
|
199
201
|
* End an agent session by removing it from the state.
|
|
200
202
|
* NOTE: Currently unused in production — no session lifecycle teardown is wired up.
|
|
@@ -218,7 +220,7 @@ export declare function getAgentSession(sessionId: string): AgentSessionState |
|
|
|
218
220
|
* @param agentName - Optional agent name (if known)
|
|
219
221
|
* @returns The AgentSessionState
|
|
220
222
|
*/
|
|
221
|
-
export declare function ensureAgentSession(sessionId: string, agentName?: string,
|
|
223
|
+
export declare function ensureAgentSession(sessionId: string, agentName?: string, directory?: string): AgentSessionState;
|
|
222
224
|
/**
|
|
223
225
|
* Update only the agent event timestamp (for stale detection).
|
|
224
226
|
* Does NOT change agent name or reset guardrail state.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "6.30.
|
|
3
|
+
"version": "6.30.1",
|
|
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",
|