opencode-swarm 7.98.1 → 7.98.2
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/{evidence-summary-service-g4x5e3e3.js → evidence-summary-service-559nas1m.js} +2 -2
- package/dist/cli/{guardrail-explain-cm08h4mt.js → guardrail-explain-xktjjh53.js} +5 -5
- package/dist/cli/{index-zgba613y.js → index-72k57f21.js} +18 -10
- package/dist/cli/{index-sf08zj91.js → index-a0dv2c7k.js} +1 -1
- package/dist/cli/{index-attgb1ma.js → index-chan9mkv.js} +5 -5
- package/dist/cli/{index-0rgde8qc.js → index-rvweaxsd.js} +1 -1
- package/dist/cli/{index-gn8n22th.js → index-we94wkty.js} +19 -3
- package/dist/cli/{index-4c5jpmn9.js → index-yrzfbqqh.js} +8 -8
- package/dist/cli/index.js +4 -4
- package/dist/cli/{pending-delegations-shqbvfjc.js → pending-delegations-8b2js1vq.js} +1 -1
- package/dist/cli/{pr-subscriptions-2565fpsc.js → pr-subscriptions-ttvr1ta9.js} +2 -2
- package/dist/commands/close.d.ts +2 -1
- package/dist/hooks/system-enhancer.d.ts +1 -1
- package/dist/hooks/utils.d.ts +3 -1
- package/dist/index.js +46 -24
- package/dist/plan/manager.d.ts +1 -1
- package/dist/state.d.ts +3 -3
- package/package.json +1 -1
package/dist/cli/{evidence-summary-service-g4x5e3e3.js → evidence-summary-service-559nas1m.js}
RENAMED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
loadPlanJsonOnly,
|
|
7
7
|
mergeDurableGateEntriesFromEvidence,
|
|
8
8
|
readDurableGateEvidence
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-yrzfbqqh.js";
|
|
10
10
|
import"./index-mh1ej70w.js";
|
|
11
11
|
import"./index-kv4dd5c5.js";
|
|
12
|
-
import"./index-
|
|
12
|
+
import"./index-we94wkty.js";
|
|
13
13
|
import"./index-jtqkh8jf.js";
|
|
14
14
|
import"./index-5e4e2hvv.js";
|
|
15
15
|
import"./index-p0arc26j.js";
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-rvweaxsd.js";
|
|
5
|
+
import"./index-72k57f21.js";
|
|
6
6
|
import"./index-5z2e78tv.js";
|
|
7
7
|
import"./index-2a6ppa65.js";
|
|
8
8
|
import"./index-fjxjb66n.js";
|
|
9
9
|
import"./index-hb10a2g8.js";
|
|
10
10
|
import"./index-zy22fg5h.js";
|
|
11
11
|
import"./index-471qxz9g.js";
|
|
12
|
-
import"./index-
|
|
12
|
+
import"./index-yrzfbqqh.js";
|
|
13
13
|
import"./index-adz3nk9b.js";
|
|
14
14
|
import"./index-v4fcn4tr.js";
|
|
15
15
|
import"./index-mh1ej70w.js";
|
|
16
16
|
import"./index-kv4dd5c5.js";
|
|
17
|
-
import"./index-
|
|
18
|
-
import"./index-
|
|
17
|
+
import"./index-a0dv2c7k.js";
|
|
18
|
+
import"./index-we94wkty.js";
|
|
19
19
|
import"./index-jtqkh8jf.js";
|
|
20
20
|
import"./index-5e4e2hvv.js";
|
|
21
21
|
import"./index-p0arc26j.js";
|
|
@@ -114,7 +114,7 @@ import {
|
|
|
114
114
|
transientBackoff,
|
|
115
115
|
validateProjectRoot,
|
|
116
116
|
writeProjectedSpecSync
|
|
117
|
-
} from "./index-
|
|
117
|
+
} from "./index-yrzfbqqh.js";
|
|
118
118
|
import {
|
|
119
119
|
_internals as _internals2,
|
|
120
120
|
_internals1 as _internals3,
|
|
@@ -138,12 +138,12 @@ import {
|
|
|
138
138
|
listActive,
|
|
139
139
|
subscribe,
|
|
140
140
|
unsubscribe
|
|
141
|
-
} from "./index-
|
|
141
|
+
} from "./index-a0dv2c7k.js";
|
|
142
142
|
import {
|
|
143
143
|
readSwarmFileAsync,
|
|
144
144
|
safeHook,
|
|
145
145
|
validateSwarmPath
|
|
146
|
-
} from "./index-
|
|
146
|
+
} from "./index-we94wkty.js";
|
|
147
147
|
import {
|
|
148
148
|
deepMerge
|
|
149
149
|
} from "./index-p0arc26j.js";
|
|
@@ -909,7 +909,7 @@ var init_executor = __esm(() => {
|
|
|
909
909
|
// package.json
|
|
910
910
|
var package_default = {
|
|
911
911
|
name: "opencode-swarm",
|
|
912
|
-
version: "7.98.
|
|
912
|
+
version: "7.98.2",
|
|
913
913
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
914
914
|
main: "dist/index.js",
|
|
915
915
|
types: "dist/index.d.ts",
|
|
@@ -5474,6 +5474,9 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, dire
|
|
|
5474
5474
|
swarmState.pendingRehydrations.add(rehydrationPromise);
|
|
5475
5475
|
}
|
|
5476
5476
|
}
|
|
5477
|
+
function endAgentSession(sessionId) {
|
|
5478
|
+
swarmState.agentSessions.delete(sessionId);
|
|
5479
|
+
}
|
|
5477
5480
|
function getAgentSession(sessionId) {
|
|
5478
5481
|
return swarmState.agentSessions.get(sessionId);
|
|
5479
5482
|
}
|
|
@@ -5978,7 +5981,7 @@ function hasActiveEpicMode(sessionID) {
|
|
|
5978
5981
|
async function rehydratePrSubscriptions(sessionID, directory) {
|
|
5979
5982
|
const map = new Map;
|
|
5980
5983
|
try {
|
|
5981
|
-
const { listActive: listActive2 } = await import("./pr-subscriptions-
|
|
5984
|
+
const { listActive: listActive2 } = await import("./pr-subscriptions-ttvr1ta9.js");
|
|
5982
5985
|
const records = await listActive2(directory);
|
|
5983
5986
|
for (const record of records) {
|
|
5984
5987
|
if (record.sessionID !== sessionID)
|
|
@@ -13652,6 +13655,10 @@ This project was already finalized in a previous /swarm close run. The plan has
|
|
|
13652
13655
|
ctx.warnings.push(`Failed to write close-summary.md: ${msg}`);
|
|
13653
13656
|
console.warn("[close-command] Failed to write close-summary.md:", error2);
|
|
13654
13657
|
}
|
|
13658
|
+
const sessionIdsToEnd = [...swarmState.agentSessions.keys()];
|
|
13659
|
+
for (const sessionId of sessionIdsToEnd) {
|
|
13660
|
+
_internals20.endAgentSession(sessionId);
|
|
13661
|
+
}
|
|
13655
13662
|
_internals20.resetSwarmStatePreservingSingletons();
|
|
13656
13663
|
const retroWarnings = ctx.warnings.filter((w) => w.includes("Retrospective write") || w.includes("retrospective write") || w.includes("Session retrospective"));
|
|
13657
13664
|
const otherWarnings = ctx.warnings.filter((w) => !w.includes("Retrospective write") && !w.includes("retrospective write") && !w.includes("Session retrospective"));
|
|
@@ -13744,7 +13751,8 @@ var _internals20 = {
|
|
|
13744
13751
|
runCleanStage,
|
|
13745
13752
|
runAlignStage,
|
|
13746
13753
|
archiveEvidence,
|
|
13747
|
-
closePlanTerminalState
|
|
13754
|
+
closePlanTerminalState,
|
|
13755
|
+
endAgentSession
|
|
13748
13756
|
};
|
|
13749
13757
|
|
|
13750
13758
|
// src/commands/codebase-review.ts
|
|
@@ -17605,7 +17613,7 @@ async function handleEvidenceCommand(directory, args) {
|
|
|
17605
17613
|
return formatTaskEvidenceMarkdown(evidenceData);
|
|
17606
17614
|
}
|
|
17607
17615
|
async function handleEvidenceSummaryCommand(directory) {
|
|
17608
|
-
const { buildEvidenceSummary } = await import("./evidence-summary-service-
|
|
17616
|
+
const { buildEvidenceSummary } = await import("./evidence-summary-service-559nas1m.js");
|
|
17609
17617
|
const artifact = await buildEvidenceSummary(directory);
|
|
17610
17618
|
if (!artifact) {
|
|
17611
17619
|
return "No plan found. Run `/swarm plan` to check plan status.";
|
|
@@ -31856,7 +31864,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
31856
31864
|
async function handleHelpCommand(ctx) {
|
|
31857
31865
|
const targetCommand = ctx.args.join(" ");
|
|
31858
31866
|
if (!targetCommand) {
|
|
31859
|
-
const { buildHelpText } = await import("./index-
|
|
31867
|
+
const { buildHelpText } = await import("./index-chan9mkv.js");
|
|
31860
31868
|
return buildHelpText();
|
|
31861
31869
|
}
|
|
31862
31870
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -31865,7 +31873,7 @@ async function handleHelpCommand(ctx) {
|
|
|
31865
31873
|
return _internals45.buildDetailedHelp(resolved.key, resolved.entry);
|
|
31866
31874
|
}
|
|
31867
31875
|
const similar = _internals45.findSimilarCommands(targetCommand);
|
|
31868
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
31876
|
+
const { buildHelpText: fullHelp } = await import("./index-chan9mkv.js");
|
|
31869
31877
|
if (similar.length > 0) {
|
|
31870
31878
|
return `Command '/swarm ${targetCommand}' not found.
|
|
31871
31879
|
|
|
@@ -31998,7 +32006,7 @@ var COMMAND_REGISTRY = {
|
|
|
31998
32006
|
},
|
|
31999
32007
|
"guardrail explain": {
|
|
32000
32008
|
handler: async (ctx) => {
|
|
32001
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
32009
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-xktjjh53.js");
|
|
32002
32010
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
32003
32011
|
},
|
|
32004
32012
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-rvweaxsd.js";
|
|
5
5
|
import {
|
|
6
6
|
handleGuardrailLog
|
|
7
7
|
} from "./index-gnd1280x.js";
|
|
@@ -78,7 +78,7 @@ import {
|
|
|
78
78
|
handleWriteRetroCommand,
|
|
79
79
|
normalizeSwarmCommandInput,
|
|
80
80
|
resolveCommand
|
|
81
|
-
} from "./index-
|
|
81
|
+
} from "./index-72k57f21.js";
|
|
82
82
|
import"./index-5z2e78tv.js";
|
|
83
83
|
import"./index-2a6ppa65.js";
|
|
84
84
|
import"./index-fjxjb66n.js";
|
|
@@ -89,13 +89,13 @@ import {
|
|
|
89
89
|
ORCHESTRATOR_NAME,
|
|
90
90
|
stripKnownSwarmPrefix
|
|
91
91
|
} from "./index-471qxz9g.js";
|
|
92
|
-
import"./index-
|
|
92
|
+
import"./index-yrzfbqqh.js";
|
|
93
93
|
import"./index-adz3nk9b.js";
|
|
94
94
|
import"./index-v4fcn4tr.js";
|
|
95
95
|
import"./index-mh1ej70w.js";
|
|
96
96
|
import"./index-kv4dd5c5.js";
|
|
97
|
-
import"./index-
|
|
98
|
-
import"./index-
|
|
97
|
+
import"./index-a0dv2c7k.js";
|
|
98
|
+
import"./index-we94wkty.js";
|
|
99
99
|
import"./index-jtqkh8jf.js";
|
|
100
100
|
import"./index-5e4e2hvv.js";
|
|
101
101
|
import"./index-p0arc26j.js";
|
|
@@ -14,7 +14,13 @@ import {
|
|
|
14
14
|
|
|
15
15
|
// src/hooks/utils.ts
|
|
16
16
|
import * as path from "path";
|
|
17
|
-
var _internals = {
|
|
17
|
+
var _internals = {
|
|
18
|
+
safeHook,
|
|
19
|
+
composeHandlers,
|
|
20
|
+
validateSwarmPath,
|
|
21
|
+
readSwarmFileAsync,
|
|
22
|
+
readCachedTextFile
|
|
23
|
+
};
|
|
18
24
|
function safeHook(fn) {
|
|
19
25
|
return async (input, output) => {
|
|
20
26
|
try {
|
|
@@ -67,13 +73,23 @@ function validateSwarmPath(directory, filename) {
|
|
|
67
73
|
}
|
|
68
74
|
return resolved;
|
|
69
75
|
}
|
|
70
|
-
async function readSwarmFileAsync(directory, filename) {
|
|
76
|
+
async function readSwarmFileAsync(directory, filename, cache) {
|
|
77
|
+
if (cache !== undefined) {
|
|
78
|
+
const key = `${directory}::${filename}`;
|
|
79
|
+
const cached = cache.get(key);
|
|
80
|
+
if (cached !== undefined) {
|
|
81
|
+
return cached;
|
|
82
|
+
}
|
|
83
|
+
const promise = readSwarmFileAsync(directory, filename);
|
|
84
|
+
cache.set(key, promise);
|
|
85
|
+
return promise;
|
|
86
|
+
}
|
|
71
87
|
const maxAttempts = 5;
|
|
72
88
|
const retryDelayMs = 10;
|
|
73
89
|
for (let attempt = 0;attempt < maxAttempts; attempt++) {
|
|
74
90
|
try {
|
|
75
91
|
const resolvedPath = _internals.validateSwarmPath(directory, filename);
|
|
76
|
-
return await readCachedTextFile(resolvedPath, async () => {
|
|
92
|
+
return await _internals.readCachedTextFile(resolvedPath, async () => {
|
|
77
93
|
const file = bunFile(resolvedPath);
|
|
78
94
|
return await file.text();
|
|
79
95
|
});
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
readSwarmFileAsync,
|
|
10
10
|
validateSwarmPath
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-we94wkty.js";
|
|
12
12
|
import {
|
|
13
13
|
readCachedParsedFile
|
|
14
14
|
} from "./index-jtqkh8jf.js";
|
|
@@ -2162,8 +2162,8 @@ function extractPlanHashFromMarkdown(markdown) {
|
|
|
2162
2162
|
const match = markdown.match(/<!--\s*PLAN_HASH:\s*(\S+)\s*-->/);
|
|
2163
2163
|
return match ? match[1] : null;
|
|
2164
2164
|
}
|
|
2165
|
-
async function isPlanMdInSync(directory, plan) {
|
|
2166
|
-
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
2165
|
+
async function isPlanMdInSync(directory, plan, cache) {
|
|
2166
|
+
const planMdContent = await readSwarmFileAsync(directory, "plan.md", cache);
|
|
2167
2167
|
if (planMdContent === null) {
|
|
2168
2168
|
return false;
|
|
2169
2169
|
}
|
|
@@ -2197,8 +2197,8 @@ ${markdown}`;
|
|
|
2197
2197
|
} catch {}
|
|
2198
2198
|
}
|
|
2199
2199
|
}
|
|
2200
|
-
async function loadPlan(directory) {
|
|
2201
|
-
const planJsonContent = await readSwarmFileAsync(directory, "plan.json");
|
|
2200
|
+
async function loadPlan(directory, cache) {
|
|
2201
|
+
const planJsonContent = await readSwarmFileAsync(directory, "plan.json", cache);
|
|
2202
2202
|
if (planJsonContent !== null) {
|
|
2203
2203
|
if (planJsonContent.includes("\x00") || planJsonContent.includes("\uFFFD")) {
|
|
2204
2204
|
warn("Plan rejected: .swarm/plan.json contains null bytes or invalid encoding");
|
|
@@ -2208,7 +2208,7 @@ async function loadPlan(directory) {
|
|
|
2208
2208
|
if (validated === null) {
|
|
2209
2209
|
warn("[loadPlan] plan.json disappeared during cached parse. Falling back to plan.md migration or ledger recovery.");
|
|
2210
2210
|
} else {
|
|
2211
|
-
const inSync = await isPlanMdInSync(directory, validated);
|
|
2211
|
+
const inSync = await isPlanMdInSync(directory, validated, cache);
|
|
2212
2212
|
if (!inSync) {
|
|
2213
2213
|
try {
|
|
2214
2214
|
await _internals4.regeneratePlanMarkdown(directory, validated);
|
|
@@ -2331,7 +2331,7 @@ async function loadPlan(directory) {
|
|
|
2331
2331
|
}
|
|
2332
2332
|
}
|
|
2333
2333
|
}
|
|
2334
|
-
const planMdContent2 = await readSwarmFileAsync(directory, "plan.md");
|
|
2334
|
+
const planMdContent2 = await readSwarmFileAsync(directory, "plan.md", cache);
|
|
2335
2335
|
if (planMdContent2 !== null) {
|
|
2336
2336
|
const migrated = migrateLegacyPlan(planMdContent2);
|
|
2337
2337
|
const { removedCount } = await savePlanWithAutoAcknowledgedRemovals(directory, migrated, "load_plan_migration_from_md", "migrate legacy plan.md to plan.json");
|
|
@@ -2346,7 +2346,7 @@ async function loadPlan(directory) {
|
|
|
2346
2346
|
}
|
|
2347
2347
|
}
|
|
2348
2348
|
}
|
|
2349
|
-
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
2349
|
+
const planMdContent = await readSwarmFileAsync(directory, "plan.md", cache);
|
|
2350
2350
|
if (planMdContent !== null) {
|
|
2351
2351
|
const migrated = migrateLegacyPlan(planMdContent);
|
|
2352
2352
|
await savePlan(directory, migrated);
|
package/dist/cli/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getPluginLockFilePaths,
|
|
8
8
|
package_default,
|
|
9
9
|
resolveCommand
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-72k57f21.js";
|
|
11
11
|
import"./index-5z2e78tv.js";
|
|
12
12
|
import"./index-2a6ppa65.js";
|
|
13
13
|
import"./index-fjxjb66n.js";
|
|
@@ -16,13 +16,13 @@ import"./index-zy22fg5h.js";
|
|
|
16
16
|
import {
|
|
17
17
|
DEFAULT_AGENT_CONFIGS
|
|
18
18
|
} from "./index-471qxz9g.js";
|
|
19
|
-
import"./index-
|
|
19
|
+
import"./index-yrzfbqqh.js";
|
|
20
20
|
import"./index-adz3nk9b.js";
|
|
21
21
|
import"./index-v4fcn4tr.js";
|
|
22
22
|
import"./index-mh1ej70w.js";
|
|
23
23
|
import"./index-kv4dd5c5.js";
|
|
24
|
-
import"./index-
|
|
25
|
-
import"./index-
|
|
24
|
+
import"./index-a0dv2c7k.js";
|
|
25
|
+
import"./index-we94wkty.js";
|
|
26
26
|
import"./index-jtqkh8jf.js";
|
|
27
27
|
import"./index-5e4e2hvv.js";
|
|
28
28
|
import"./index-p0arc26j.js";
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
sweepStale,
|
|
10
10
|
unsubscribe,
|
|
11
11
|
updateSnapshot
|
|
12
|
-
} from "./index-
|
|
13
|
-
import"./index-
|
|
12
|
+
} from "./index-a0dv2c7k.js";
|
|
13
|
+
import"./index-we94wkty.js";
|
|
14
14
|
import"./index-jtqkh8jf.js";
|
|
15
15
|
import"./index-5e4e2hvv.js";
|
|
16
16
|
import"./index-p0arc26j.js";
|
package/dist/commands/close.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { checkHivePromotions } from '../hooks/hive-promoter';
|
|
|
8
8
|
import { curateAndStoreSwarm } from '../hooks/knowledge-curator';
|
|
9
9
|
import { closePlanTerminalState } from '../plan/manager';
|
|
10
10
|
import { type SessionReflectionResult } from '../services/session-reflection';
|
|
11
|
-
import { resetSwarmStatePreservingSingletons } from '../state';
|
|
11
|
+
import { endAgentSession, resetSwarmStatePreservingSingletons } from '../state';
|
|
12
12
|
interface PlanPhase {
|
|
13
13
|
id: number;
|
|
14
14
|
name: string;
|
|
@@ -197,5 +197,6 @@ export declare const _internals: {
|
|
|
197
197
|
runAlignStage: typeof runAlignStage;
|
|
198
198
|
archiveEvidence: typeof archiveEvidence;
|
|
199
199
|
closePlanTerminalState: typeof closePlanTerminalState;
|
|
200
|
+
endAgentSession: typeof endAgentSession;
|
|
200
201
|
};
|
|
201
202
|
export {};
|
|
@@ -46,4 +46,4 @@ export type ArchitectMode = 'DISCOVER' | 'PLAN' | 'EXECUTE' | 'PHASE-WRAP' | 'UN
|
|
|
46
46
|
* @param directory - The project directory to check
|
|
47
47
|
* @returns The current architect mode based on plan state
|
|
48
48
|
*/
|
|
49
|
-
export declare function detectArchitectMode(directory: string): Promise<ArchitectMode>;
|
|
49
|
+
export declare function detectArchitectMode(directory: string, cache?: Map<string, Promise<string | null>>): Promise<ArchitectMode>;
|
package/dist/hooks/utils.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* including error handling, handler composition, file I/O, and
|
|
6
6
|
* token estimation for swarm-related operations.
|
|
7
7
|
*/
|
|
8
|
+
import { readCachedTextFile } from '../utils/swarm-artifact-cache';
|
|
8
9
|
/**
|
|
9
10
|
* Test-only dependency-injection seam. Production code calls
|
|
10
11
|
* `_internals.<fn>(...)` so tests can replace the function on this object
|
|
@@ -18,6 +19,7 @@ export declare const _internals: {
|
|
|
18
19
|
composeHandlers: typeof composeHandlers;
|
|
19
20
|
validateSwarmPath: typeof validateSwarmPath;
|
|
20
21
|
readSwarmFileAsync: typeof readSwarmFileAsync;
|
|
22
|
+
readCachedTextFile: typeof readCachedTextFile;
|
|
21
23
|
};
|
|
22
24
|
export declare function safeHook<I, O>(fn: (input: I, output: O) => Promise<void>): (input: I, output: O) => Promise<void>;
|
|
23
25
|
/**
|
|
@@ -70,5 +72,5 @@ export declare function composeBlockingHandlers<I, O>(...fns: Array<(input: I, o
|
|
|
70
72
|
* @throws Error if the filename is invalid or attempts path traversal
|
|
71
73
|
*/
|
|
72
74
|
export declare function validateSwarmPath(directory: string, filename: string): string;
|
|
73
|
-
export declare function readSwarmFileAsync(directory: string, filename: string): Promise<string | null>;
|
|
75
|
+
export declare function readSwarmFileAsync(directory: string, filename: string, cache?: Map<string, Promise<string | null>>): Promise<string | null>;
|
|
74
76
|
export declare function estimateTokens(text: string): number;
|
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ var package_default;
|
|
|
69
69
|
var init_package = __esm(() => {
|
|
70
70
|
package_default = {
|
|
71
71
|
name: "opencode-swarm",
|
|
72
|
-
version: "7.98.
|
|
72
|
+
version: "7.98.2",
|
|
73
73
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
74
74
|
main: "dist/index.js",
|
|
75
75
|
types: "dist/index.d.ts",
|
|
@@ -18167,13 +18167,23 @@ function validateSwarmPath(directory, filename) {
|
|
|
18167
18167
|
}
|
|
18168
18168
|
return resolved;
|
|
18169
18169
|
}
|
|
18170
|
-
async function readSwarmFileAsync(directory, filename) {
|
|
18170
|
+
async function readSwarmFileAsync(directory, filename, cache) {
|
|
18171
|
+
if (cache !== undefined) {
|
|
18172
|
+
const key = `${directory}::${filename}`;
|
|
18173
|
+
const cached2 = cache.get(key);
|
|
18174
|
+
if (cached2 !== undefined) {
|
|
18175
|
+
return cached2;
|
|
18176
|
+
}
|
|
18177
|
+
const promise2 = readSwarmFileAsync(directory, filename);
|
|
18178
|
+
cache.set(key, promise2);
|
|
18179
|
+
return promise2;
|
|
18180
|
+
}
|
|
18171
18181
|
const maxAttempts = 5;
|
|
18172
18182
|
const retryDelayMs = 10;
|
|
18173
18183
|
for (let attempt = 0;attempt < maxAttempts; attempt++) {
|
|
18174
18184
|
try {
|
|
18175
18185
|
const resolvedPath = _internals3.validateSwarmPath(directory, filename);
|
|
18176
|
-
return await readCachedTextFile(resolvedPath, async () => {
|
|
18186
|
+
return await _internals3.readCachedTextFile(resolvedPath, async () => {
|
|
18177
18187
|
const file2 = bunFile(resolvedPath);
|
|
18178
18188
|
return await file2.text();
|
|
18179
18189
|
});
|
|
@@ -18198,7 +18208,13 @@ var init_utils2 = __esm(() => {
|
|
|
18198
18208
|
init_utils();
|
|
18199
18209
|
init_bun_compat();
|
|
18200
18210
|
init_swarm_artifact_cache();
|
|
18201
|
-
_internals3 = {
|
|
18211
|
+
_internals3 = {
|
|
18212
|
+
safeHook,
|
|
18213
|
+
composeHandlers,
|
|
18214
|
+
validateSwarmPath,
|
|
18215
|
+
readSwarmFileAsync,
|
|
18216
|
+
readCachedTextFile
|
|
18217
|
+
};
|
|
18202
18218
|
});
|
|
18203
18219
|
|
|
18204
18220
|
// src/utils/git-binary-missing-error.ts
|
|
@@ -20452,8 +20468,8 @@ function extractPlanHashFromMarkdown(markdown) {
|
|
|
20452
20468
|
const match = markdown.match(/<!--\s*PLAN_HASH:\s*(\S+)\s*-->/);
|
|
20453
20469
|
return match ? match[1] : null;
|
|
20454
20470
|
}
|
|
20455
|
-
async function isPlanMdInSync(directory, plan) {
|
|
20456
|
-
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
20471
|
+
async function isPlanMdInSync(directory, plan, cache) {
|
|
20472
|
+
const planMdContent = await readSwarmFileAsync(directory, "plan.md", cache);
|
|
20457
20473
|
if (planMdContent === null) {
|
|
20458
20474
|
return false;
|
|
20459
20475
|
}
|
|
@@ -20487,8 +20503,8 @@ ${markdown}`;
|
|
|
20487
20503
|
} catch {}
|
|
20488
20504
|
}
|
|
20489
20505
|
}
|
|
20490
|
-
async function loadPlan(directory) {
|
|
20491
|
-
const planJsonContent = await readSwarmFileAsync(directory, "plan.json");
|
|
20506
|
+
async function loadPlan(directory, cache) {
|
|
20507
|
+
const planJsonContent = await readSwarmFileAsync(directory, "plan.json", cache);
|
|
20492
20508
|
if (planJsonContent !== null) {
|
|
20493
20509
|
if (planJsonContent.includes("\x00") || planJsonContent.includes("�")) {
|
|
20494
20510
|
warn("Plan rejected: .swarm/plan.json contains null bytes or invalid encoding");
|
|
@@ -20498,7 +20514,7 @@ async function loadPlan(directory) {
|
|
|
20498
20514
|
if (validated === null) {
|
|
20499
20515
|
warn("[loadPlan] plan.json disappeared during cached parse. Falling back to plan.md migration or ledger recovery.");
|
|
20500
20516
|
} else {
|
|
20501
|
-
const inSync = await isPlanMdInSync(directory, validated);
|
|
20517
|
+
const inSync = await isPlanMdInSync(directory, validated, cache);
|
|
20502
20518
|
if (!inSync) {
|
|
20503
20519
|
try {
|
|
20504
20520
|
await _internals8.regeneratePlanMarkdown(directory, validated);
|
|
@@ -20621,7 +20637,7 @@ async function loadPlan(directory) {
|
|
|
20621
20637
|
}
|
|
20622
20638
|
}
|
|
20623
20639
|
}
|
|
20624
|
-
const planMdContent2 = await readSwarmFileAsync(directory, "plan.md");
|
|
20640
|
+
const planMdContent2 = await readSwarmFileAsync(directory, "plan.md", cache);
|
|
20625
20641
|
if (planMdContent2 !== null) {
|
|
20626
20642
|
const migrated = migrateLegacyPlan(planMdContent2);
|
|
20627
20643
|
const { removedCount } = await savePlanWithAutoAcknowledgedRemovals(directory, migrated, "load_plan_migration_from_md", "migrate legacy plan.md to plan.json");
|
|
@@ -20636,7 +20652,7 @@ async function loadPlan(directory) {
|
|
|
20636
20652
|
}
|
|
20637
20653
|
}
|
|
20638
20654
|
}
|
|
20639
|
-
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
20655
|
+
const planMdContent = await readSwarmFileAsync(directory, "plan.md", cache);
|
|
20640
20656
|
if (planMdContent !== null) {
|
|
20641
20657
|
const migrated = migrateLegacyPlan(planMdContent);
|
|
20642
20658
|
await savePlan(directory, migrated);
|
|
@@ -73875,6 +73891,10 @@ This project was already finalized in a previous /swarm close run. The plan has
|
|
|
73875
73891
|
ctx.warnings.push(`Failed to write close-summary.md: ${msg}`);
|
|
73876
73892
|
console.warn("[close-command] Failed to write close-summary.md:", error93);
|
|
73877
73893
|
}
|
|
73894
|
+
const sessionIdsToEnd = [...swarmState.agentSessions.keys()];
|
|
73895
|
+
for (const sessionId of sessionIdsToEnd) {
|
|
73896
|
+
_internals38.endAgentSession(sessionId);
|
|
73897
|
+
}
|
|
73878
73898
|
_internals38.resetSwarmStatePreservingSingletons();
|
|
73879
73899
|
const retroWarnings = ctx.warnings.filter((w) => w.includes("Retrospective write") || w.includes("retrospective write") || w.includes("Session retrospective"));
|
|
73880
73900
|
const otherWarnings = ctx.warnings.filter((w) => !w.includes("Retrospective write") && !w.includes("retrospective write") && !w.includes("Session retrospective"));
|
|
@@ -74041,7 +74061,8 @@ var init_close = __esm(() => {
|
|
|
74041
74061
|
runCleanStage,
|
|
74042
74062
|
runAlignStage,
|
|
74043
74063
|
archiveEvidence,
|
|
74044
|
-
closePlanTerminalState
|
|
74064
|
+
closePlanTerminalState,
|
|
74065
|
+
endAgentSession
|
|
74045
74066
|
};
|
|
74046
74067
|
});
|
|
74047
74068
|
|
|
@@ -119725,6 +119746,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
119725
119746
|
return;
|
|
119726
119747
|
}
|
|
119727
119748
|
}
|
|
119749
|
+
const planReadCache = new Map;
|
|
119728
119750
|
const maxInjectionTokens = config3.context_budget?.max_injection_tokens ?? 4000;
|
|
119729
119751
|
let injectedTokens = 0;
|
|
119730
119752
|
let actualDemand = 0;
|
|
@@ -119739,7 +119761,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
119739
119761
|
} else {
|
|
119740
119762
|
seAllocation = maxInjectionTokens;
|
|
119741
119763
|
}
|
|
119742
|
-
const contextContent = await readSwarmFileAsync(directory, "context.md");
|
|
119764
|
+
const contextContent = await readSwarmFileAsync(directory, "context.md", planReadCache);
|
|
119743
119765
|
try {
|
|
119744
119766
|
const { scanDocIndex: scanDocIndex2 } = await Promise.resolve().then(() => (init_doc_scan(), exports_doc_scan));
|
|
119745
119767
|
const { manifest, cached: cached3 } = await scanDocIndex2(directory);
|
|
@@ -119799,19 +119821,19 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
119799
119821
|
if (!scoringEnabled) {
|
|
119800
119822
|
let plan2 = null;
|
|
119801
119823
|
try {
|
|
119802
|
-
plan2 = await loadPlan(directory);
|
|
119824
|
+
plan2 = await loadPlan(directory, planReadCache);
|
|
119803
119825
|
} catch (error93) {
|
|
119804
119826
|
warn(`Failed to load plan: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
119805
119827
|
}
|
|
119806
119828
|
maybeAppendSpecDriftAdvisory(output, directory, plan2);
|
|
119807
|
-
const mode = await detectArchitectMode(directory);
|
|
119829
|
+
const mode = await detectArchitectMode(directory, planReadCache);
|
|
119808
119830
|
let planContent = null;
|
|
119809
119831
|
let phaseHeader = "";
|
|
119810
119832
|
if (plan2 && plan2.migration_status !== "migration_failed") {
|
|
119811
119833
|
phaseHeader = extractCurrentPhaseFromPlan(plan2) || "";
|
|
119812
|
-
planContent = await readSwarmFileAsync(directory, "plan.md");
|
|
119834
|
+
planContent = await readSwarmFileAsync(directory, "plan.md", planReadCache);
|
|
119813
119835
|
} else {
|
|
119814
|
-
planContent = await readSwarmFileAsync(directory, "plan.md");
|
|
119836
|
+
planContent = await readSwarmFileAsync(directory, "plan.md", planReadCache);
|
|
119815
119837
|
phaseHeader = planContent ? extractCurrentPhase(planContent) || "" : "";
|
|
119816
119838
|
}
|
|
119817
119839
|
if (phaseHeader) {
|
|
@@ -119823,7 +119845,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
119823
119845
|
}
|
|
119824
119846
|
if (mode !== "DISCOVER") {
|
|
119825
119847
|
try {
|
|
119826
|
-
const handoffContent = await readSwarmFileAsync(directory, "handoff.md");
|
|
119848
|
+
const handoffContent = await readSwarmFileAsync(directory, "handoff.md", planReadCache);
|
|
119827
119849
|
if (handoffContent) {
|
|
119828
119850
|
const handoffPath = validateSwarmPath(directory, "handoff.md");
|
|
119829
119851
|
const consumedPath = validateSwarmPath(directory, "handoff-consumed.md");
|
|
@@ -120187,7 +120209,7 @@ ${budgetWarning}`);
|
|
|
120187
120209
|
} else {}
|
|
120188
120210
|
return;
|
|
120189
120211
|
}
|
|
120190
|
-
const mode_b = await detectArchitectMode(directory);
|
|
120212
|
+
const mode_b = await detectArchitectMode(directory, planReadCache);
|
|
120191
120213
|
const userScoringConfig = config3.context_budget?.scoring;
|
|
120192
120214
|
const candidates = [];
|
|
120193
120215
|
let idCounter = 0;
|
|
@@ -120199,7 +120221,7 @@ ${budgetWarning}`);
|
|
|
120199
120221
|
} : DEFAULT_SCORING_CONFIG;
|
|
120200
120222
|
let plan = null;
|
|
120201
120223
|
try {
|
|
120202
|
-
plan = await loadPlan(directory);
|
|
120224
|
+
plan = await loadPlan(directory, planReadCache);
|
|
120203
120225
|
} catch (error93) {
|
|
120204
120226
|
warn(`Failed to load plan: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
120205
120227
|
}
|
|
@@ -120210,7 +120232,7 @@ ${budgetWarning}`);
|
|
|
120210
120232
|
currentPhase = extractCurrentPhaseFromPlan(plan);
|
|
120211
120233
|
currentTask = extractCurrentTaskFromPlan(plan);
|
|
120212
120234
|
} else {
|
|
120213
|
-
planContentForCursor = await readSwarmFileAsync(directory, "plan.md");
|
|
120235
|
+
planContentForCursor = await readSwarmFileAsync(directory, "plan.md", planReadCache);
|
|
120214
120236
|
if (planContentForCursor) {
|
|
120215
120237
|
currentPhase = extractCurrentPhase(planContentForCursor);
|
|
120216
120238
|
currentTask = extractCurrentTask(planContentForCursor);
|
|
@@ -120254,7 +120276,7 @@ ${budgetWarning}`);
|
|
|
120254
120276
|
}
|
|
120255
120277
|
if (mode_b !== "DISCOVER") {
|
|
120256
120278
|
try {
|
|
120257
|
-
const handoffContent = await readSwarmFileAsync(directory, "handoff.md");
|
|
120279
|
+
const handoffContent = await readSwarmFileAsync(directory, "handoff.md", planReadCache);
|
|
120258
120280
|
if (handoffContent) {
|
|
120259
120281
|
const handoffPath = validateSwarmPath(directory, "handoff.md");
|
|
120260
120282
|
const consumedPath = validateSwarmPath(directory, "handoff-consumed.md");
|
|
@@ -120753,9 +120775,9 @@ ${activitySection}`;
|
|
|
120753
120775
|
}
|
|
120754
120776
|
return contextSummary;
|
|
120755
120777
|
}
|
|
120756
|
-
async function detectArchitectMode(directory) {
|
|
120778
|
+
async function detectArchitectMode(directory, cache4) {
|
|
120757
120779
|
try {
|
|
120758
|
-
const plan = await loadPlan(directory);
|
|
120780
|
+
const plan = await loadPlan(directory, cache4);
|
|
120759
120781
|
if (!plan) {
|
|
120760
120782
|
return "DISCOVER";
|
|
120761
120783
|
}
|
package/dist/plan/manager.d.ts
CHANGED
|
@@ -108,7 +108,7 @@ export declare function regeneratePlanMarkdown(directory: string, plan: Plan): P
|
|
|
108
108
|
* 3. .swarm/plan.md exists only -> migrate from plan.md, save both files, return Plan
|
|
109
109
|
* 4. Neither exists -> return null
|
|
110
110
|
*/
|
|
111
|
-
export declare function loadPlan(directory: string): Promise<RuntimePlan | null>;
|
|
111
|
+
export declare function loadPlan(directory: string, cache?: Map<string, Promise<string | null>>): Promise<RuntimePlan | null>;
|
|
112
112
|
/**
|
|
113
113
|
* Recovery-path helper for callers that legitimately need to replace the
|
|
114
114
|
* plan task set without explicit per-id acknowledgement (e.g. rebuilding
|
package/dist/state.d.ts
CHANGED
|
@@ -391,9 +391,9 @@ export declare function resetSwarmStatePreservingSingletons(): void;
|
|
|
391
391
|
export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number, directory?: string): void;
|
|
392
392
|
/**
|
|
393
393
|
* End an agent session by removing it from the state.
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
* a
|
|
394
|
+
* Called at session terminal state transitions (task completion, error, or session
|
|
395
|
+
* teardown) to prevent unbounded Map growth. Double-calls are safe: Map.delete is
|
|
396
|
+
* a no-op for missing keys (FR-010).
|
|
397
397
|
* @param sessionId - The session identifier to remove
|
|
398
398
|
*/
|
|
399
399
|
export declare function endAgentSession(sessionId: string): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.98.
|
|
3
|
+
"version": "7.98.2",
|
|
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",
|