opencode-swarm-plugin 0.1.0 → 0.2.0
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/.beads/issues.jsonl +308 -0
- package/README.md +157 -11
- package/dist/index.js +804 -23
- package/dist/plugin.js +443 -23
- package/package.json +7 -3
- package/src/agent-mail.ts +46 -3
- package/src/index.ts +60 -0
- package/src/learning.integration.test.ts +326 -1
- package/src/storage.integration.test.ts +341 -0
- package/src/storage.ts +679 -0
- package/src/swarm.integration.test.ts +194 -3
- package/src/swarm.ts +185 -32
- package/src/tool-availability.ts +389 -0
package/dist/index.js
CHANGED
|
@@ -12879,6 +12879,242 @@ var beadsTools = {
|
|
|
12879
12879
|
beads_link_thread
|
|
12880
12880
|
};
|
|
12881
12881
|
|
|
12882
|
+
// src/tool-availability.ts
|
|
12883
|
+
var toolCache = new Map;
|
|
12884
|
+
var warningsLogged = new Set;
|
|
12885
|
+
async function commandExists(cmd) {
|
|
12886
|
+
try {
|
|
12887
|
+
const result = await Bun.$`which ${cmd}`.quiet().nothrow();
|
|
12888
|
+
return result.exitCode === 0;
|
|
12889
|
+
} catch {
|
|
12890
|
+
return false;
|
|
12891
|
+
}
|
|
12892
|
+
}
|
|
12893
|
+
async function urlReachable(url2, timeoutMs = 1000) {
|
|
12894
|
+
try {
|
|
12895
|
+
const controller = new AbortController;
|
|
12896
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
12897
|
+
const response = await fetch(url2, {
|
|
12898
|
+
method: "HEAD",
|
|
12899
|
+
signal: controller.signal
|
|
12900
|
+
});
|
|
12901
|
+
clearTimeout(timeout);
|
|
12902
|
+
return response.ok;
|
|
12903
|
+
} catch {
|
|
12904
|
+
return false;
|
|
12905
|
+
}
|
|
12906
|
+
}
|
|
12907
|
+
var toolCheckers = {
|
|
12908
|
+
"semantic-memory": async () => {
|
|
12909
|
+
const nativeExists = await commandExists("semantic-memory");
|
|
12910
|
+
if (nativeExists) {
|
|
12911
|
+
try {
|
|
12912
|
+
const result = await Bun.$`semantic-memory stats`.quiet().nothrow();
|
|
12913
|
+
return {
|
|
12914
|
+
available: result.exitCode === 0,
|
|
12915
|
+
checkedAt: new Date().toISOString(),
|
|
12916
|
+
version: "native"
|
|
12917
|
+
};
|
|
12918
|
+
} catch (e) {
|
|
12919
|
+
return {
|
|
12920
|
+
available: false,
|
|
12921
|
+
checkedAt: new Date().toISOString(),
|
|
12922
|
+
error: String(e)
|
|
12923
|
+
};
|
|
12924
|
+
}
|
|
12925
|
+
}
|
|
12926
|
+
try {
|
|
12927
|
+
const proc = Bun.spawn(["bunx", "semantic-memory", "stats"], {
|
|
12928
|
+
stdout: "pipe",
|
|
12929
|
+
stderr: "pipe"
|
|
12930
|
+
});
|
|
12931
|
+
const timeout = setTimeout(() => proc.kill(), 1e4);
|
|
12932
|
+
const exitCode = await proc.exited;
|
|
12933
|
+
clearTimeout(timeout);
|
|
12934
|
+
return {
|
|
12935
|
+
available: exitCode === 0,
|
|
12936
|
+
checkedAt: new Date().toISOString(),
|
|
12937
|
+
version: "bunx"
|
|
12938
|
+
};
|
|
12939
|
+
} catch (e) {
|
|
12940
|
+
return {
|
|
12941
|
+
available: false,
|
|
12942
|
+
checkedAt: new Date().toISOString(),
|
|
12943
|
+
error: String(e)
|
|
12944
|
+
};
|
|
12945
|
+
}
|
|
12946
|
+
},
|
|
12947
|
+
cass: async () => {
|
|
12948
|
+
const exists = await commandExists("cass");
|
|
12949
|
+
if (!exists) {
|
|
12950
|
+
return {
|
|
12951
|
+
available: false,
|
|
12952
|
+
checkedAt: new Date().toISOString(),
|
|
12953
|
+
error: "cass command not found"
|
|
12954
|
+
};
|
|
12955
|
+
}
|
|
12956
|
+
try {
|
|
12957
|
+
const result = await Bun.$`cass health`.quiet().nothrow();
|
|
12958
|
+
return {
|
|
12959
|
+
available: result.exitCode === 0,
|
|
12960
|
+
checkedAt: new Date().toISOString()
|
|
12961
|
+
};
|
|
12962
|
+
} catch (e) {
|
|
12963
|
+
return {
|
|
12964
|
+
available: false,
|
|
12965
|
+
checkedAt: new Date().toISOString(),
|
|
12966
|
+
error: String(e)
|
|
12967
|
+
};
|
|
12968
|
+
}
|
|
12969
|
+
},
|
|
12970
|
+
ubs: async () => {
|
|
12971
|
+
const exists = await commandExists("ubs");
|
|
12972
|
+
if (!exists) {
|
|
12973
|
+
return {
|
|
12974
|
+
available: false,
|
|
12975
|
+
checkedAt: new Date().toISOString(),
|
|
12976
|
+
error: "ubs command not found"
|
|
12977
|
+
};
|
|
12978
|
+
}
|
|
12979
|
+
try {
|
|
12980
|
+
const result = await Bun.$`ubs doctor`.quiet().nothrow();
|
|
12981
|
+
return {
|
|
12982
|
+
available: result.exitCode === 0,
|
|
12983
|
+
checkedAt: new Date().toISOString()
|
|
12984
|
+
};
|
|
12985
|
+
} catch (e) {
|
|
12986
|
+
return {
|
|
12987
|
+
available: false,
|
|
12988
|
+
checkedAt: new Date().toISOString(),
|
|
12989
|
+
error: String(e)
|
|
12990
|
+
};
|
|
12991
|
+
}
|
|
12992
|
+
},
|
|
12993
|
+
beads: async () => {
|
|
12994
|
+
const exists = await commandExists("bd");
|
|
12995
|
+
if (!exists) {
|
|
12996
|
+
return {
|
|
12997
|
+
available: false,
|
|
12998
|
+
checkedAt: new Date().toISOString(),
|
|
12999
|
+
error: "bd command not found"
|
|
13000
|
+
};
|
|
13001
|
+
}
|
|
13002
|
+
try {
|
|
13003
|
+
const result = await Bun.$`bd --version`.quiet().nothrow();
|
|
13004
|
+
return {
|
|
13005
|
+
available: result.exitCode === 0,
|
|
13006
|
+
checkedAt: new Date().toISOString()
|
|
13007
|
+
};
|
|
13008
|
+
} catch (e) {
|
|
13009
|
+
return {
|
|
13010
|
+
available: false,
|
|
13011
|
+
checkedAt: new Date().toISOString(),
|
|
13012
|
+
error: String(e)
|
|
13013
|
+
};
|
|
13014
|
+
}
|
|
13015
|
+
},
|
|
13016
|
+
"agent-mail": async () => {
|
|
13017
|
+
const reachable = await urlReachable("http://127.0.0.1:8765/health/liveness");
|
|
13018
|
+
return {
|
|
13019
|
+
available: reachable,
|
|
13020
|
+
checkedAt: new Date().toISOString(),
|
|
13021
|
+
error: reachable ? undefined : "Agent Mail server not reachable at :8765"
|
|
13022
|
+
};
|
|
13023
|
+
}
|
|
13024
|
+
};
|
|
13025
|
+
var fallbackBehaviors = {
|
|
13026
|
+
"semantic-memory": "Learning data stored in-memory only (lost on session end)",
|
|
13027
|
+
cass: "Decomposition proceeds without historical context from past sessions",
|
|
13028
|
+
ubs: "Subtask completion skips bug scanning - manual review recommended",
|
|
13029
|
+
beads: "Swarm cannot track issues - task coordination will be less reliable",
|
|
13030
|
+
"agent-mail": "Multi-agent coordination disabled - file conflicts possible if multiple agents active"
|
|
13031
|
+
};
|
|
13032
|
+
async function checkTool(tool3) {
|
|
13033
|
+
const cached2 = toolCache.get(tool3);
|
|
13034
|
+
if (cached2) {
|
|
13035
|
+
return cached2;
|
|
13036
|
+
}
|
|
13037
|
+
const checker = toolCheckers[tool3];
|
|
13038
|
+
const status = await checker();
|
|
13039
|
+
toolCache.set(tool3, status);
|
|
13040
|
+
return status;
|
|
13041
|
+
}
|
|
13042
|
+
async function isToolAvailable(tool3) {
|
|
13043
|
+
const status = await checkTool(tool3);
|
|
13044
|
+
return status.available;
|
|
13045
|
+
}
|
|
13046
|
+
async function getToolAvailability(tool3) {
|
|
13047
|
+
const status = await checkTool(tool3);
|
|
13048
|
+
return {
|
|
13049
|
+
tool: tool3,
|
|
13050
|
+
status,
|
|
13051
|
+
fallbackBehavior: fallbackBehaviors[tool3]
|
|
13052
|
+
};
|
|
13053
|
+
}
|
|
13054
|
+
async function checkAllTools() {
|
|
13055
|
+
const tools = [
|
|
13056
|
+
"semantic-memory",
|
|
13057
|
+
"cass",
|
|
13058
|
+
"ubs",
|
|
13059
|
+
"beads",
|
|
13060
|
+
"agent-mail"
|
|
13061
|
+
];
|
|
13062
|
+
const results = new Map;
|
|
13063
|
+
const checks3 = await Promise.all(tools.map(async (tool3) => ({
|
|
13064
|
+
tool: tool3,
|
|
13065
|
+
availability: await getToolAvailability(tool3)
|
|
13066
|
+
})));
|
|
13067
|
+
for (const { tool: tool3, availability } of checks3) {
|
|
13068
|
+
results.set(tool3, availability);
|
|
13069
|
+
}
|
|
13070
|
+
return results;
|
|
13071
|
+
}
|
|
13072
|
+
function warnMissingTool(tool3) {
|
|
13073
|
+
if (warningsLogged.has(tool3)) {
|
|
13074
|
+
return;
|
|
13075
|
+
}
|
|
13076
|
+
warningsLogged.add(tool3);
|
|
13077
|
+
const fallback = fallbackBehaviors[tool3];
|
|
13078
|
+
console.warn(`[swarm] ${tool3} not available: ${fallback}`);
|
|
13079
|
+
}
|
|
13080
|
+
async function requireTool(tool3) {
|
|
13081
|
+
const status = await checkTool(tool3);
|
|
13082
|
+
if (!status.available) {
|
|
13083
|
+
throw new Error(`Required tool '${tool3}' is not available: ${status.error || "unknown error"}`);
|
|
13084
|
+
}
|
|
13085
|
+
}
|
|
13086
|
+
async function withToolFallback(tool3, action, fallback) {
|
|
13087
|
+
const available = await isToolAvailable(tool3);
|
|
13088
|
+
if (available) {
|
|
13089
|
+
return action();
|
|
13090
|
+
}
|
|
13091
|
+
warnMissingTool(tool3);
|
|
13092
|
+
return fallback();
|
|
13093
|
+
}
|
|
13094
|
+
async function ifToolAvailable(tool3, action) {
|
|
13095
|
+
const available = await isToolAvailable(tool3);
|
|
13096
|
+
if (available) {
|
|
13097
|
+
return action();
|
|
13098
|
+
}
|
|
13099
|
+
warnMissingTool(tool3);
|
|
13100
|
+
return;
|
|
13101
|
+
}
|
|
13102
|
+
function resetToolCache() {
|
|
13103
|
+
toolCache.clear();
|
|
13104
|
+
warningsLogged.clear();
|
|
13105
|
+
}
|
|
13106
|
+
function formatToolAvailability(availability) {
|
|
13107
|
+
const lines = ["Tool Availability:"];
|
|
13108
|
+
for (const [tool3, info] of availability) {
|
|
13109
|
+
const status = info.status.available ? "\u2713" : "\u2717";
|
|
13110
|
+
const version2 = info.status.version ? ` (${info.status.version})` : "";
|
|
13111
|
+
const fallback = info.status.available ? "" : ` \u2192 ${info.fallbackBehavior}`;
|
|
13112
|
+
lines.push(` ${status} ${tool3}${version2}${fallback}`);
|
|
13113
|
+
}
|
|
13114
|
+
return lines.join(`
|
|
13115
|
+
`);
|
|
13116
|
+
}
|
|
13117
|
+
|
|
12882
13118
|
// src/agent-mail.ts
|
|
12883
13119
|
var AGENT_MAIL_URL = "http://127.0.0.1:8765";
|
|
12884
13120
|
var DEFAULT_TTL_SECONDS = 3600;
|
|
@@ -12913,6 +13149,14 @@ class FileReservationConflictError extends Error {
|
|
|
12913
13149
|
this.name = "FileReservationConflictError";
|
|
12914
13150
|
}
|
|
12915
13151
|
}
|
|
13152
|
+
var agentMailAvailable = null;
|
|
13153
|
+
async function checkAgentMailAvailable() {
|
|
13154
|
+
if (agentMailAvailable !== null) {
|
|
13155
|
+
return agentMailAvailable;
|
|
13156
|
+
}
|
|
13157
|
+
agentMailAvailable = await isToolAvailable("agent-mail");
|
|
13158
|
+
return agentMailAvailable;
|
|
13159
|
+
}
|
|
12916
13160
|
async function mcpCall(toolName, args) {
|
|
12917
13161
|
const response = await fetch(`${AGENT_MAIL_URL}/mcp/`, {
|
|
12918
13162
|
method: "POST",
|
|
@@ -12962,6 +13206,16 @@ var agentmail_init = tool({
|
|
|
12962
13206
|
task_description: tool.schema.string().optional().describe("Description of current task")
|
|
12963
13207
|
},
|
|
12964
13208
|
async execute(args, ctx) {
|
|
13209
|
+
const available = await checkAgentMailAvailable();
|
|
13210
|
+
if (!available) {
|
|
13211
|
+
warnMissingTool("agent-mail");
|
|
13212
|
+
return JSON.stringify({
|
|
13213
|
+
error: "Agent Mail server not available",
|
|
13214
|
+
available: false,
|
|
13215
|
+
hint: "Start Agent Mail with: agent-mail serve",
|
|
13216
|
+
fallback: "Swarm will continue without multi-agent coordination. File conflicts possible if multiple agents active."
|
|
13217
|
+
}, null, 2);
|
|
13218
|
+
}
|
|
12965
13219
|
const project = await mcpCall("ensure_project", {
|
|
12966
13220
|
human_key: args.project_path
|
|
12967
13221
|
});
|
|
@@ -12979,7 +13233,7 @@ var agentmail_init = tool({
|
|
|
12979
13233
|
startedAt: new Date().toISOString()
|
|
12980
13234
|
};
|
|
12981
13235
|
setState(ctx.sessionID, state);
|
|
12982
|
-
return JSON.stringify({ project, agent }, null, 2);
|
|
13236
|
+
return JSON.stringify({ project, agent, available: true }, null, 2);
|
|
12983
13237
|
}
|
|
12984
13238
|
});
|
|
12985
13239
|
var agentmail_send = tool({
|
|
@@ -13670,6 +13924,21 @@ function outcomeToFeedback(outcome, criterion) {
|
|
|
13670
13924
|
raw_value: outcome.decayed_value
|
|
13671
13925
|
};
|
|
13672
13926
|
}
|
|
13927
|
+
class InMemoryFeedbackStorage {
|
|
13928
|
+
events = [];
|
|
13929
|
+
async store(event) {
|
|
13930
|
+
this.events.push(event);
|
|
13931
|
+
}
|
|
13932
|
+
async getByCriterion(criterion) {
|
|
13933
|
+
return this.events.filter((e) => e.criterion === criterion);
|
|
13934
|
+
}
|
|
13935
|
+
async getByBead(beadId) {
|
|
13936
|
+
return this.events.filter((e) => e.bead_id === beadId);
|
|
13937
|
+
}
|
|
13938
|
+
async getAll() {
|
|
13939
|
+
return [...this.events];
|
|
13940
|
+
}
|
|
13941
|
+
}
|
|
13673
13942
|
|
|
13674
13943
|
// src/swarm.ts
|
|
13675
13944
|
var POSITIVE_MARKERS = [
|
|
@@ -13762,6 +14031,18 @@ var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subta
|
|
|
13762
14031
|
|
|
13763
14032
|
{context_section}
|
|
13764
14033
|
|
|
14034
|
+
## MANDATORY: Beads Issue Tracking
|
|
14035
|
+
|
|
14036
|
+
**Every subtask MUST become a bead.** This is non-negotiable.
|
|
14037
|
+
|
|
14038
|
+
After decomposition, the coordinator will:
|
|
14039
|
+
1. Create an epic bead for the overall task
|
|
14040
|
+
2. Create child beads for each subtask
|
|
14041
|
+
3. Track progress through bead status updates
|
|
14042
|
+
4. Close beads with summaries when complete
|
|
14043
|
+
|
|
14044
|
+
Agents MUST update their bead status as they work. No silent progress.
|
|
14045
|
+
|
|
13765
14046
|
## Requirements
|
|
13766
14047
|
|
|
13767
14048
|
1. **Break into 2-{max_subtasks} independent subtasks** that can run in parallel
|
|
@@ -13769,6 +14050,7 @@ var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subta
|
|
|
13769
14050
|
3. **No file overlap** - files cannot appear in multiple subtasks (they get exclusive locks)
|
|
13770
14051
|
4. **Order by dependency** - if subtask B needs subtask A's output, A must come first in the array
|
|
13771
14052
|
5. **Estimate complexity** - 1 (trivial) to 5 (complex)
|
|
14053
|
+
6. **Plan aggressively** - break down more than you think necessary, smaller is better
|
|
13772
14054
|
|
|
13773
14055
|
## Response Format
|
|
13774
14056
|
|
|
@@ -13795,10 +14077,12 @@ Respond with a JSON object matching this schema:
|
|
|
13795
14077
|
|
|
13796
14078
|
## Guidelines
|
|
13797
14079
|
|
|
14080
|
+
- **Plan aggressively** - when in doubt, split further. 3 small tasks > 1 medium task
|
|
13798
14081
|
- **Prefer smaller, focused subtasks** over large complex ones
|
|
13799
14082
|
- **Include test files** in the same subtask as the code they test
|
|
13800
14083
|
- **Consider shared types** - if multiple files share types, handle that first
|
|
13801
14084
|
- **Think about imports** - changes to exported APIs affect downstream files
|
|
14085
|
+
- **Explicit > implicit** - spell out what each subtask should do, don't assume
|
|
13802
14086
|
|
|
13803
14087
|
## File Assignment Examples
|
|
13804
14088
|
|
|
@@ -13829,19 +14113,49 @@ send a message to the coordinator requesting the change.
|
|
|
13829
14113
|
## Shared Context
|
|
13830
14114
|
{shared_context}
|
|
13831
14115
|
|
|
14116
|
+
## MANDATORY: Beads Tracking
|
|
14117
|
+
|
|
14118
|
+
You MUST keep your bead updated as you work:
|
|
14119
|
+
|
|
14120
|
+
1. **Your bead is already in_progress** - don't change this unless blocked
|
|
14121
|
+
2. **If blocked**: \`bd update {bead_id} --status blocked\` and message coordinator
|
|
14122
|
+
3. **When done**: Use \`swarm_complete\` - it closes your bead automatically
|
|
14123
|
+
4. **Discovered issues**: Create new beads with \`bd create "issue" -t bug\`
|
|
14124
|
+
|
|
14125
|
+
**Never work silently.** Your bead status is how the swarm tracks progress.
|
|
14126
|
+
|
|
14127
|
+
## MANDATORY: Agent Mail Communication
|
|
14128
|
+
|
|
14129
|
+
You MUST communicate with other agents:
|
|
14130
|
+
|
|
14131
|
+
1. **Report progress** every significant milestone (not just at the end)
|
|
14132
|
+
2. **Ask questions** if requirements are unclear - don't guess
|
|
14133
|
+
3. **Announce blockers** immediately - don't spin trying to fix alone
|
|
14134
|
+
4. **Coordinate on shared concerns** - if you see something affecting other agents, say so
|
|
14135
|
+
|
|
14136
|
+
Use Agent Mail for all communication:
|
|
14137
|
+
\`\`\`
|
|
14138
|
+
agentmail_send(
|
|
14139
|
+
to: ["coordinator" or specific agent],
|
|
14140
|
+
subject: "Brief subject",
|
|
14141
|
+
body: "Message content",
|
|
14142
|
+
thread_id: "{epic_id}"
|
|
14143
|
+
)
|
|
14144
|
+
\`\`\`
|
|
14145
|
+
|
|
13832
14146
|
## Coordination Protocol
|
|
13833
14147
|
|
|
13834
14148
|
1. **Start**: Your bead is already marked in_progress
|
|
13835
|
-
2. **Progress**: Use
|
|
13836
|
-
3. **Blocked**:
|
|
13837
|
-
4. **Complete**: Use
|
|
14149
|
+
2. **Progress**: Use swarm_progress to report status updates
|
|
14150
|
+
3. **Blocked**: Report immediately via Agent Mail - don't spin
|
|
14151
|
+
4. **Complete**: Use swarm_complete when done - it handles:
|
|
13838
14152
|
- Closing your bead with a summary
|
|
13839
14153
|
- Releasing file reservations
|
|
13840
14154
|
- Notifying the coordinator
|
|
13841
14155
|
|
|
13842
14156
|
## Self-Evaluation
|
|
13843
14157
|
|
|
13844
|
-
Before calling
|
|
14158
|
+
Before calling swarm_complete, evaluate your work:
|
|
13845
14159
|
- Type safety: Does it compile without errors?
|
|
13846
14160
|
- No obvious bugs: Did you handle edge cases?
|
|
13847
14161
|
- Follows patterns: Does it match existing code style?
|
|
@@ -13849,17 +14163,13 @@ Before calling swarm:complete, evaluate your work:
|
|
|
13849
14163
|
|
|
13850
14164
|
If evaluation fails, fix the issues before completing.
|
|
13851
14165
|
|
|
13852
|
-
##
|
|
14166
|
+
## Planning Your Work
|
|
13853
14167
|
|
|
13854
|
-
|
|
13855
|
-
|
|
13856
|
-
|
|
13857
|
-
|
|
13858
|
-
|
|
13859
|
-
body: "Message content",
|
|
13860
|
-
thread_id: "{epic_id}"
|
|
13861
|
-
)
|
|
13862
|
-
\`\`\`
|
|
14168
|
+
Before writing code:
|
|
14169
|
+
1. **Read the files** you're assigned to understand current state
|
|
14170
|
+
2. **Plan your approach** - what changes, in what order?
|
|
14171
|
+
3. **Identify risks** - what could go wrong? What dependencies?
|
|
14172
|
+
4. **Communicate your plan** via Agent Mail if non-trivial
|
|
13863
14173
|
|
|
13864
14174
|
Begin work on your subtask now.`;
|
|
13865
14175
|
var EVALUATION_PROMPT = `Evaluate the work completed for this subtask.
|
|
@@ -13934,21 +14244,32 @@ function formatEvaluationPrompt(params) {
|
|
|
13934
14244
|
return EVALUATION_PROMPT.replace("{bead_id}", params.bead_id).replace("{subtask_title}", params.subtask_title).replace("{files_touched}", filesList || "(no files recorded)");
|
|
13935
14245
|
}
|
|
13936
14246
|
async function queryEpicSubtasks(epicId) {
|
|
14247
|
+
const beadsAvailable = await isToolAvailable("beads");
|
|
14248
|
+
if (!beadsAvailable) {
|
|
14249
|
+
warnMissingTool("beads");
|
|
14250
|
+
return [];
|
|
14251
|
+
}
|
|
13937
14252
|
const result = await Bun.$`bd list --parent ${epicId} --json`.quiet().nothrow();
|
|
13938
14253
|
if (result.exitCode !== 0) {
|
|
13939
|
-
|
|
14254
|
+
console.warn(`[swarm] Failed to query subtasks: ${result.stderr.toString()}`);
|
|
14255
|
+
return [];
|
|
13940
14256
|
}
|
|
13941
14257
|
try {
|
|
13942
14258
|
const parsed = JSON.parse(result.stdout.toString());
|
|
13943
14259
|
return exports_external.array(BeadSchema).parse(parsed);
|
|
13944
14260
|
} catch (error45) {
|
|
13945
14261
|
if (error45 instanceof exports_external.ZodError) {
|
|
13946
|
-
|
|
14262
|
+
console.warn(`[swarm] Invalid bead data: ${error45.message}`);
|
|
14263
|
+
return [];
|
|
13947
14264
|
}
|
|
13948
14265
|
throw error45;
|
|
13949
14266
|
}
|
|
13950
14267
|
}
|
|
13951
14268
|
async function querySwarmMessages(projectKey, threadId) {
|
|
14269
|
+
const agentMailAvailable2 = await isToolAvailable("agent-mail");
|
|
14270
|
+
if (!agentMailAvailable2) {
|
|
14271
|
+
return 0;
|
|
14272
|
+
}
|
|
13952
14273
|
try {
|
|
13953
14274
|
const summary = await mcpCall("summarize_thread", {
|
|
13954
14275
|
project_key: projectKey,
|
|
@@ -13977,11 +14298,13 @@ ${progress.blockers.map((b) => `- ${b}`).join(`
|
|
|
13977
14298
|
`);
|
|
13978
14299
|
}
|
|
13979
14300
|
async function queryCassHistory(task, limit = 3) {
|
|
14301
|
+
const cassAvailable = await isToolAvailable("cass");
|
|
14302
|
+
if (!cassAvailable) {
|
|
14303
|
+
warnMissingTool("cass");
|
|
14304
|
+
return null;
|
|
14305
|
+
}
|
|
13980
14306
|
try {
|
|
13981
14307
|
const result = await Bun.$`cass search ${task} --limit ${limit} --json`.quiet().nothrow();
|
|
13982
|
-
if (result.exitCode === 127) {
|
|
13983
|
-
return null;
|
|
13984
|
-
}
|
|
13985
14308
|
if (result.exitCode !== 0) {
|
|
13986
14309
|
return null;
|
|
13987
14310
|
}
|
|
@@ -14241,11 +14564,13 @@ async function runUbsScan(files) {
|
|
|
14241
14564
|
if (files.length === 0) {
|
|
14242
14565
|
return null;
|
|
14243
14566
|
}
|
|
14567
|
+
const ubsAvailable = await isToolAvailable("ubs");
|
|
14568
|
+
if (!ubsAvailable) {
|
|
14569
|
+
warnMissingTool("ubs");
|
|
14570
|
+
return null;
|
|
14571
|
+
}
|
|
14244
14572
|
try {
|
|
14245
14573
|
const result = await Bun.$`ubs scan ${files.join(" ")} --json`.quiet().nothrow();
|
|
14246
|
-
if (result.exitCode === 127) {
|
|
14247
|
-
return null;
|
|
14248
|
-
}
|
|
14249
14574
|
const output = result.stdout.toString();
|
|
14250
14575
|
if (!output.trim()) {
|
|
14251
14576
|
return {
|
|
@@ -14476,7 +14801,56 @@ var swarm_evaluation_prompt = tool({
|
|
|
14476
14801
|
}, null, 2);
|
|
14477
14802
|
}
|
|
14478
14803
|
});
|
|
14804
|
+
var swarm_init = tool({
|
|
14805
|
+
description: "Initialize swarm session and check tool availability. Call at swarm start to see what features are available.",
|
|
14806
|
+
args: {
|
|
14807
|
+
project_path: tool.schema.string().optional().describe("Project path (for Agent Mail init)")
|
|
14808
|
+
},
|
|
14809
|
+
async execute(args) {
|
|
14810
|
+
const availability = await checkAllTools();
|
|
14811
|
+
const report = formatToolAvailability(availability);
|
|
14812
|
+
const beadsAvailable = availability.get("beads")?.status.available ?? false;
|
|
14813
|
+
const agentMailAvailable2 = availability.get("agent-mail")?.status.available ?? false;
|
|
14814
|
+
const warnings = [];
|
|
14815
|
+
const degradedFeatures = [];
|
|
14816
|
+
if (!beadsAvailable) {
|
|
14817
|
+
warnings.push("\u26A0\uFE0F beads (bd) not available - issue tracking disabled, swarm coordination will be limited");
|
|
14818
|
+
degradedFeatures.push("issue tracking", "progress persistence");
|
|
14819
|
+
}
|
|
14820
|
+
if (!agentMailAvailable2) {
|
|
14821
|
+
warnings.push("\u26A0\uFE0F agent-mail not available - multi-agent communication disabled");
|
|
14822
|
+
degradedFeatures.push("agent communication", "file reservations");
|
|
14823
|
+
}
|
|
14824
|
+
if (!availability.get("cass")?.status.available) {
|
|
14825
|
+
degradedFeatures.push("historical context from past sessions");
|
|
14826
|
+
}
|
|
14827
|
+
if (!availability.get("ubs")?.status.available) {
|
|
14828
|
+
degradedFeatures.push("pre-completion bug scanning");
|
|
14829
|
+
}
|
|
14830
|
+
if (!availability.get("semantic-memory")?.status.available) {
|
|
14831
|
+
degradedFeatures.push("persistent learning (using in-memory fallback)");
|
|
14832
|
+
}
|
|
14833
|
+
return JSON.stringify({
|
|
14834
|
+
ready: true,
|
|
14835
|
+
tool_availability: Object.fromEntries(Array.from(availability.entries()).map(([k, v]) => [
|
|
14836
|
+
k,
|
|
14837
|
+
{
|
|
14838
|
+
available: v.status.available,
|
|
14839
|
+
fallback: v.status.available ? null : v.fallbackBehavior
|
|
14840
|
+
}
|
|
14841
|
+
])),
|
|
14842
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
14843
|
+
degraded_features: degradedFeatures.length > 0 ? degradedFeatures : undefined,
|
|
14844
|
+
recommendations: {
|
|
14845
|
+
beads: beadsAvailable ? "\u2713 Use beads for all task tracking" : "Install beads: npm i -g @joelhooks/beads",
|
|
14846
|
+
agent_mail: agentMailAvailable2 ? "\u2713 Use Agent Mail for coordination" : "Start Agent Mail: agent-mail serve"
|
|
14847
|
+
},
|
|
14848
|
+
report
|
|
14849
|
+
}, null, 2);
|
|
14850
|
+
}
|
|
14851
|
+
});
|
|
14479
14852
|
var swarmTools = {
|
|
14853
|
+
swarm_init,
|
|
14480
14854
|
swarm_decompose,
|
|
14481
14855
|
swarm_validate_decomposition,
|
|
14482
14856
|
swarm_status,
|
|
@@ -14486,6 +14860,394 @@ var swarmTools = {
|
|
|
14486
14860
|
swarm_subtask_prompt,
|
|
14487
14861
|
swarm_evaluation_prompt
|
|
14488
14862
|
};
|
|
14863
|
+
// src/anti-patterns.ts
|
|
14864
|
+
var PatternKindSchema = exports_external.enum(["pattern", "anti_pattern"]);
|
|
14865
|
+
var DecompositionPatternSchema = exports_external.object({
|
|
14866
|
+
id: exports_external.string(),
|
|
14867
|
+
content: exports_external.string(),
|
|
14868
|
+
kind: PatternKindSchema,
|
|
14869
|
+
is_negative: exports_external.boolean(),
|
|
14870
|
+
success_count: exports_external.number().int().min(0).default(0),
|
|
14871
|
+
failure_count: exports_external.number().int().min(0).default(0),
|
|
14872
|
+
created_at: exports_external.string(),
|
|
14873
|
+
updated_at: exports_external.string(),
|
|
14874
|
+
reason: exports_external.string().optional(),
|
|
14875
|
+
tags: exports_external.array(exports_external.string()).default([]),
|
|
14876
|
+
example_beads: exports_external.array(exports_external.string()).default([])
|
|
14877
|
+
});
|
|
14878
|
+
var PatternInversionResultSchema = exports_external.object({
|
|
14879
|
+
original: DecompositionPatternSchema,
|
|
14880
|
+
inverted: DecompositionPatternSchema,
|
|
14881
|
+
reason: exports_external.string()
|
|
14882
|
+
});
|
|
14883
|
+
class InMemoryPatternStorage {
|
|
14884
|
+
patterns = new Map;
|
|
14885
|
+
async store(pattern) {
|
|
14886
|
+
this.patterns.set(pattern.id, pattern);
|
|
14887
|
+
}
|
|
14888
|
+
async get(id) {
|
|
14889
|
+
return this.patterns.get(id) ?? null;
|
|
14890
|
+
}
|
|
14891
|
+
async getAll() {
|
|
14892
|
+
return Array.from(this.patterns.values());
|
|
14893
|
+
}
|
|
14894
|
+
async getAntiPatterns() {
|
|
14895
|
+
return Array.from(this.patterns.values()).filter((p) => p.kind === "anti_pattern");
|
|
14896
|
+
}
|
|
14897
|
+
async getByTag(tag) {
|
|
14898
|
+
return Array.from(this.patterns.values()).filter((p) => p.tags.includes(tag));
|
|
14899
|
+
}
|
|
14900
|
+
async findByContent(content) {
|
|
14901
|
+
const lower = content.toLowerCase();
|
|
14902
|
+
return Array.from(this.patterns.values()).filter((p) => p.content.toLowerCase().includes(lower));
|
|
14903
|
+
}
|
|
14904
|
+
}
|
|
14905
|
+
|
|
14906
|
+
// src/pattern-maturity.ts
|
|
14907
|
+
var MaturityStateSchema = exports_external.enum([
|
|
14908
|
+
"candidate",
|
|
14909
|
+
"established",
|
|
14910
|
+
"proven",
|
|
14911
|
+
"deprecated"
|
|
14912
|
+
]);
|
|
14913
|
+
var PatternMaturitySchema = exports_external.object({
|
|
14914
|
+
pattern_id: exports_external.string(),
|
|
14915
|
+
state: MaturityStateSchema,
|
|
14916
|
+
helpful_count: exports_external.number().int().min(0),
|
|
14917
|
+
harmful_count: exports_external.number().int().min(0),
|
|
14918
|
+
last_validated: exports_external.string(),
|
|
14919
|
+
promoted_at: exports_external.string().optional(),
|
|
14920
|
+
deprecated_at: exports_external.string().optional()
|
|
14921
|
+
});
|
|
14922
|
+
var MaturityFeedbackSchema = exports_external.object({
|
|
14923
|
+
pattern_id: exports_external.string(),
|
|
14924
|
+
type: exports_external.enum(["helpful", "harmful"]),
|
|
14925
|
+
timestamp: exports_external.string(),
|
|
14926
|
+
weight: exports_external.number().min(0).max(1).default(1)
|
|
14927
|
+
});
|
|
14928
|
+
class InMemoryMaturityStorage {
|
|
14929
|
+
maturities = new Map;
|
|
14930
|
+
feedback = [];
|
|
14931
|
+
async store(maturity) {
|
|
14932
|
+
this.maturities.set(maturity.pattern_id, maturity);
|
|
14933
|
+
}
|
|
14934
|
+
async get(patternId) {
|
|
14935
|
+
return this.maturities.get(patternId) ?? null;
|
|
14936
|
+
}
|
|
14937
|
+
async getAll() {
|
|
14938
|
+
return Array.from(this.maturities.values());
|
|
14939
|
+
}
|
|
14940
|
+
async getByState(state) {
|
|
14941
|
+
return Array.from(this.maturities.values()).filter((m) => m.state === state);
|
|
14942
|
+
}
|
|
14943
|
+
async storeFeedback(feedback) {
|
|
14944
|
+
this.feedback.push(feedback);
|
|
14945
|
+
}
|
|
14946
|
+
async getFeedback(patternId) {
|
|
14947
|
+
return this.feedback.filter((f) => f.pattern_id === patternId);
|
|
14948
|
+
}
|
|
14949
|
+
}
|
|
14950
|
+
|
|
14951
|
+
// src/storage.ts
|
|
14952
|
+
var cachedCommand = null;
|
|
14953
|
+
async function resolveSemanticMemoryCommand() {
|
|
14954
|
+
if (cachedCommand)
|
|
14955
|
+
return cachedCommand;
|
|
14956
|
+
const nativeResult = await Bun.$`which semantic-memory`.quiet().nothrow();
|
|
14957
|
+
if (nativeResult.exitCode === 0) {
|
|
14958
|
+
cachedCommand = ["semantic-memory"];
|
|
14959
|
+
return cachedCommand;
|
|
14960
|
+
}
|
|
14961
|
+
cachedCommand = ["bunx", "semantic-memory"];
|
|
14962
|
+
return cachedCommand;
|
|
14963
|
+
}
|
|
14964
|
+
async function execSemanticMemory(args) {
|
|
14965
|
+
const cmd = await resolveSemanticMemoryCommand();
|
|
14966
|
+
const fullCmd = [...cmd, ...args];
|
|
14967
|
+
const proc = Bun.spawn(fullCmd, {
|
|
14968
|
+
stdout: "pipe",
|
|
14969
|
+
stderr: "pipe"
|
|
14970
|
+
});
|
|
14971
|
+
const stdout = Buffer.from(await new Response(proc.stdout).arrayBuffer());
|
|
14972
|
+
const stderr = Buffer.from(await new Response(proc.stderr).arrayBuffer());
|
|
14973
|
+
const exitCode = await proc.exited;
|
|
14974
|
+
return { exitCode, stdout, stderr };
|
|
14975
|
+
}
|
|
14976
|
+
var DEFAULT_STORAGE_CONFIG = {
|
|
14977
|
+
backend: "semantic-memory",
|
|
14978
|
+
collections: {
|
|
14979
|
+
feedback: "swarm-feedback",
|
|
14980
|
+
patterns: "swarm-patterns",
|
|
14981
|
+
maturity: "swarm-maturity"
|
|
14982
|
+
},
|
|
14983
|
+
useSemanticSearch: true
|
|
14984
|
+
};
|
|
14985
|
+
|
|
14986
|
+
class SemanticMemoryStorage {
|
|
14987
|
+
config;
|
|
14988
|
+
constructor(config2 = {}) {
|
|
14989
|
+
this.config = { ...DEFAULT_STORAGE_CONFIG, ...config2 };
|
|
14990
|
+
}
|
|
14991
|
+
async store(collection, data, metadata) {
|
|
14992
|
+
const content = typeof data === "string" ? data : JSON.stringify(data);
|
|
14993
|
+
const args = ["store", content, "--collection", collection];
|
|
14994
|
+
if (metadata) {
|
|
14995
|
+
args.push("--metadata", JSON.stringify(metadata));
|
|
14996
|
+
}
|
|
14997
|
+
await execSemanticMemory(args);
|
|
14998
|
+
}
|
|
14999
|
+
async find(collection, query, limit = 10, useFts = false) {
|
|
15000
|
+
const args = [
|
|
15001
|
+
"find",
|
|
15002
|
+
query,
|
|
15003
|
+
"--collection",
|
|
15004
|
+
collection,
|
|
15005
|
+
"--limit",
|
|
15006
|
+
String(limit),
|
|
15007
|
+
"--json"
|
|
15008
|
+
];
|
|
15009
|
+
if (useFts) {
|
|
15010
|
+
args.push("--fts");
|
|
15011
|
+
}
|
|
15012
|
+
const result = await execSemanticMemory(args);
|
|
15013
|
+
if (result.exitCode !== 0) {
|
|
15014
|
+
return [];
|
|
15015
|
+
}
|
|
15016
|
+
try {
|
|
15017
|
+
const output = result.stdout.toString().trim();
|
|
15018
|
+
if (!output)
|
|
15019
|
+
return [];
|
|
15020
|
+
const parsed = JSON.parse(output);
|
|
15021
|
+
const results = Array.isArray(parsed) ? parsed : parsed.results || [];
|
|
15022
|
+
return results.map((r) => {
|
|
15023
|
+
const content = r.content || r.information || "";
|
|
15024
|
+
try {
|
|
15025
|
+
return JSON.parse(content);
|
|
15026
|
+
} catch {
|
|
15027
|
+
return content;
|
|
15028
|
+
}
|
|
15029
|
+
});
|
|
15030
|
+
} catch {
|
|
15031
|
+
return [];
|
|
15032
|
+
}
|
|
15033
|
+
}
|
|
15034
|
+
async list(collection) {
|
|
15035
|
+
const result = await execSemanticMemory([
|
|
15036
|
+
"list",
|
|
15037
|
+
"--collection",
|
|
15038
|
+
collection,
|
|
15039
|
+
"--json"
|
|
15040
|
+
]);
|
|
15041
|
+
if (result.exitCode !== 0) {
|
|
15042
|
+
return [];
|
|
15043
|
+
}
|
|
15044
|
+
try {
|
|
15045
|
+
const output = result.stdout.toString().trim();
|
|
15046
|
+
if (!output)
|
|
15047
|
+
return [];
|
|
15048
|
+
const parsed = JSON.parse(output);
|
|
15049
|
+
const items = Array.isArray(parsed) ? parsed : parsed.items || [];
|
|
15050
|
+
return items.map((item) => {
|
|
15051
|
+
const content = item.content || item.information || "";
|
|
15052
|
+
try {
|
|
15053
|
+
return JSON.parse(content);
|
|
15054
|
+
} catch {
|
|
15055
|
+
return content;
|
|
15056
|
+
}
|
|
15057
|
+
});
|
|
15058
|
+
} catch {
|
|
15059
|
+
return [];
|
|
15060
|
+
}
|
|
15061
|
+
}
|
|
15062
|
+
async storeFeedback(event) {
|
|
15063
|
+
await this.store(this.config.collections.feedback, event, {
|
|
15064
|
+
criterion: event.criterion,
|
|
15065
|
+
type: event.type,
|
|
15066
|
+
bead_id: event.bead_id || "",
|
|
15067
|
+
timestamp: event.timestamp
|
|
15068
|
+
});
|
|
15069
|
+
}
|
|
15070
|
+
async getFeedbackByCriterion(criterion) {
|
|
15071
|
+
return this.find(this.config.collections.feedback, criterion, 100, true);
|
|
15072
|
+
}
|
|
15073
|
+
async getFeedbackByBead(beadId) {
|
|
15074
|
+
return this.find(this.config.collections.feedback, beadId, 100, true);
|
|
15075
|
+
}
|
|
15076
|
+
async getAllFeedback() {
|
|
15077
|
+
return this.list(this.config.collections.feedback);
|
|
15078
|
+
}
|
|
15079
|
+
async findSimilarFeedback(query, limit = 10) {
|
|
15080
|
+
return this.find(this.config.collections.feedback, query, limit, !this.config.useSemanticSearch);
|
|
15081
|
+
}
|
|
15082
|
+
async storePattern(pattern) {
|
|
15083
|
+
await this.store(this.config.collections.patterns, pattern, {
|
|
15084
|
+
id: pattern.id,
|
|
15085
|
+
kind: pattern.kind,
|
|
15086
|
+
is_negative: pattern.is_negative,
|
|
15087
|
+
tags: pattern.tags.join(",")
|
|
15088
|
+
});
|
|
15089
|
+
}
|
|
15090
|
+
async getPattern(id) {
|
|
15091
|
+
const all = await this.list(this.config.collections.patterns);
|
|
15092
|
+
return all.find((p) => p.id === id) || null;
|
|
15093
|
+
}
|
|
15094
|
+
async getAllPatterns() {
|
|
15095
|
+
return this.list(this.config.collections.patterns);
|
|
15096
|
+
}
|
|
15097
|
+
async getAntiPatterns() {
|
|
15098
|
+
const all = await this.getAllPatterns();
|
|
15099
|
+
return all.filter((p) => p.kind === "anti_pattern");
|
|
15100
|
+
}
|
|
15101
|
+
async getPatternsByTag(tag) {
|
|
15102
|
+
const results = await this.find(this.config.collections.patterns, tag, 100, true);
|
|
15103
|
+
return results.filter((p) => p.tags.includes(tag));
|
|
15104
|
+
}
|
|
15105
|
+
async findSimilarPatterns(query, limit = 10) {
|
|
15106
|
+
return this.find(this.config.collections.patterns, query, limit, !this.config.useSemanticSearch);
|
|
15107
|
+
}
|
|
15108
|
+
async storeMaturity(maturity) {
|
|
15109
|
+
await this.store(this.config.collections.maturity, maturity, {
|
|
15110
|
+
pattern_id: maturity.pattern_id,
|
|
15111
|
+
state: maturity.state
|
|
15112
|
+
});
|
|
15113
|
+
}
|
|
15114
|
+
async getMaturity(patternId) {
|
|
15115
|
+
const all = await this.list(this.config.collections.maturity);
|
|
15116
|
+
return all.find((m) => m.pattern_id === patternId) || null;
|
|
15117
|
+
}
|
|
15118
|
+
async getAllMaturity() {
|
|
15119
|
+
return this.list(this.config.collections.maturity);
|
|
15120
|
+
}
|
|
15121
|
+
async getMaturityByState(state) {
|
|
15122
|
+
const all = await this.getAllMaturity();
|
|
15123
|
+
return all.filter((m) => m.state === state);
|
|
15124
|
+
}
|
|
15125
|
+
async storeMaturityFeedback(feedback) {
|
|
15126
|
+
await this.store(this.config.collections.maturity + "-feedback", feedback, {
|
|
15127
|
+
pattern_id: feedback.pattern_id,
|
|
15128
|
+
type: feedback.type,
|
|
15129
|
+
timestamp: feedback.timestamp
|
|
15130
|
+
});
|
|
15131
|
+
}
|
|
15132
|
+
async getMaturityFeedback(patternId) {
|
|
15133
|
+
const all = await this.list(this.config.collections.maturity + "-feedback");
|
|
15134
|
+
return all.filter((f) => f.pattern_id === patternId);
|
|
15135
|
+
}
|
|
15136
|
+
async close() {}
|
|
15137
|
+
}
|
|
15138
|
+
|
|
15139
|
+
class InMemoryStorage {
|
|
15140
|
+
feedback;
|
|
15141
|
+
patterns;
|
|
15142
|
+
maturity;
|
|
15143
|
+
constructor() {
|
|
15144
|
+
this.feedback = new InMemoryFeedbackStorage;
|
|
15145
|
+
this.patterns = new InMemoryPatternStorage;
|
|
15146
|
+
this.maturity = new InMemoryMaturityStorage;
|
|
15147
|
+
}
|
|
15148
|
+
async storeFeedback(event) {
|
|
15149
|
+
return this.feedback.store(event);
|
|
15150
|
+
}
|
|
15151
|
+
async getFeedbackByCriterion(criterion) {
|
|
15152
|
+
return this.feedback.getByCriterion(criterion);
|
|
15153
|
+
}
|
|
15154
|
+
async getFeedbackByBead(beadId) {
|
|
15155
|
+
return this.feedback.getByBead(beadId);
|
|
15156
|
+
}
|
|
15157
|
+
async getAllFeedback() {
|
|
15158
|
+
return this.feedback.getAll();
|
|
15159
|
+
}
|
|
15160
|
+
async findSimilarFeedback(query, limit = 10) {
|
|
15161
|
+
const all = await this.feedback.getAll();
|
|
15162
|
+
const lowerQuery = query.toLowerCase();
|
|
15163
|
+
const filtered = all.filter((event) => event.criterion.toLowerCase().includes(lowerQuery) || event.bead_id && event.bead_id.toLowerCase().includes(lowerQuery) || event.context && event.context.toLowerCase().includes(lowerQuery));
|
|
15164
|
+
return filtered.slice(0, limit);
|
|
15165
|
+
}
|
|
15166
|
+
async storePattern(pattern) {
|
|
15167
|
+
return this.patterns.store(pattern);
|
|
15168
|
+
}
|
|
15169
|
+
async getPattern(id) {
|
|
15170
|
+
return this.patterns.get(id);
|
|
15171
|
+
}
|
|
15172
|
+
async getAllPatterns() {
|
|
15173
|
+
return this.patterns.getAll();
|
|
15174
|
+
}
|
|
15175
|
+
async getAntiPatterns() {
|
|
15176
|
+
return this.patterns.getAntiPatterns();
|
|
15177
|
+
}
|
|
15178
|
+
async getPatternsByTag(tag) {
|
|
15179
|
+
return this.patterns.getByTag(tag);
|
|
15180
|
+
}
|
|
15181
|
+
async findSimilarPatterns(query, limit = 10) {
|
|
15182
|
+
const results = await this.patterns.findByContent(query);
|
|
15183
|
+
return results.slice(0, limit);
|
|
15184
|
+
}
|
|
15185
|
+
async storeMaturity(maturity) {
|
|
15186
|
+
return this.maturity.store(maturity);
|
|
15187
|
+
}
|
|
15188
|
+
async getMaturity(patternId) {
|
|
15189
|
+
return this.maturity.get(patternId);
|
|
15190
|
+
}
|
|
15191
|
+
async getAllMaturity() {
|
|
15192
|
+
return this.maturity.getAll();
|
|
15193
|
+
}
|
|
15194
|
+
async getMaturityByState(state) {
|
|
15195
|
+
return this.maturity.getByState(state);
|
|
15196
|
+
}
|
|
15197
|
+
async storeMaturityFeedback(feedback) {
|
|
15198
|
+
return this.maturity.storeFeedback(feedback);
|
|
15199
|
+
}
|
|
15200
|
+
async getMaturityFeedback(patternId) {
|
|
15201
|
+
return this.maturity.getFeedback(patternId);
|
|
15202
|
+
}
|
|
15203
|
+
async close() {}
|
|
15204
|
+
}
|
|
15205
|
+
function createStorage(config2 = {}) {
|
|
15206
|
+
const fullConfig = { ...DEFAULT_STORAGE_CONFIG, ...config2 };
|
|
15207
|
+
switch (fullConfig.backend) {
|
|
15208
|
+
case "semantic-memory":
|
|
15209
|
+
return new SemanticMemoryStorage(fullConfig);
|
|
15210
|
+
case "memory":
|
|
15211
|
+
return new InMemoryStorage;
|
|
15212
|
+
default:
|
|
15213
|
+
throw new Error(`Unknown storage backend: ${fullConfig.backend}`);
|
|
15214
|
+
}
|
|
15215
|
+
}
|
|
15216
|
+
async function isSemanticMemoryAvailable() {
|
|
15217
|
+
try {
|
|
15218
|
+
const result = await execSemanticMemory(["stats"]);
|
|
15219
|
+
return result.exitCode === 0;
|
|
15220
|
+
} catch {
|
|
15221
|
+
return false;
|
|
15222
|
+
}
|
|
15223
|
+
}
|
|
15224
|
+
async function createStorageWithFallback(config2 = {}) {
|
|
15225
|
+
if (config2.backend === "memory") {
|
|
15226
|
+
return new InMemoryStorage;
|
|
15227
|
+
}
|
|
15228
|
+
const available = await isSemanticMemoryAvailable();
|
|
15229
|
+
if (available) {
|
|
15230
|
+
return new SemanticMemoryStorage(config2);
|
|
15231
|
+
}
|
|
15232
|
+
console.warn("semantic-memory not available, falling back to in-memory storage");
|
|
15233
|
+
return new InMemoryStorage;
|
|
15234
|
+
}
|
|
15235
|
+
var globalStorage = null;
|
|
15236
|
+
async function getStorage() {
|
|
15237
|
+
if (!globalStorage) {
|
|
15238
|
+
globalStorage = await createStorageWithFallback();
|
|
15239
|
+
}
|
|
15240
|
+
return globalStorage;
|
|
15241
|
+
}
|
|
15242
|
+
function setStorage(storage) {
|
|
15243
|
+
globalStorage = storage;
|
|
15244
|
+
}
|
|
15245
|
+
async function resetStorage() {
|
|
15246
|
+
if (globalStorage) {
|
|
15247
|
+
await globalStorage.close();
|
|
15248
|
+
globalStorage = null;
|
|
15249
|
+
}
|
|
15250
|
+
}
|
|
14489
15251
|
|
|
14490
15252
|
// src/index.ts
|
|
14491
15253
|
var SwarmPlugin = async (input) => {
|
|
@@ -14567,14 +15329,30 @@ var SwarmPlugin = async (input) => {
|
|
|
14567
15329
|
};
|
|
14568
15330
|
var src_default = SwarmPlugin;
|
|
14569
15331
|
export {
|
|
15332
|
+
withToolFallback,
|
|
15333
|
+
warnMissingTool,
|
|
14570
15334
|
swarmTools,
|
|
14571
15335
|
structuredTools,
|
|
15336
|
+
setStorage,
|
|
15337
|
+
resetToolCache,
|
|
15338
|
+
resetStorage,
|
|
15339
|
+
requireTool,
|
|
15340
|
+
isToolAvailable,
|
|
15341
|
+
isSemanticMemoryAvailable,
|
|
15342
|
+
ifToolAvailable,
|
|
15343
|
+
getToolAvailability,
|
|
15344
|
+
getStorage,
|
|
14572
15345
|
getSchemaByName,
|
|
14573
15346
|
formatZodErrors,
|
|
15347
|
+
formatToolAvailability,
|
|
14574
15348
|
formatSubtaskPrompt,
|
|
14575
15349
|
formatEvaluationPrompt,
|
|
14576
15350
|
extractJsonFromText,
|
|
14577
15351
|
src_default as default,
|
|
15352
|
+
createStorageWithFallback,
|
|
15353
|
+
createStorage,
|
|
15354
|
+
checkTool,
|
|
15355
|
+
checkAllTools,
|
|
14578
15356
|
beads_update,
|
|
14579
15357
|
beads_sync,
|
|
14580
15358
|
beads_start,
|
|
@@ -14598,6 +15376,8 @@ export {
|
|
|
14598
15376
|
SubtaskSpecSchema,
|
|
14599
15377
|
SubtaskDependencySchema,
|
|
14600
15378
|
SpawnedAgentSchema,
|
|
15379
|
+
SemanticMemoryStorage,
|
|
15380
|
+
InMemoryStorage,
|
|
14601
15381
|
FileReservationConflictError,
|
|
14602
15382
|
EvaluationSchema,
|
|
14603
15383
|
EvaluationRequestSchema,
|
|
@@ -14608,6 +15388,7 @@ export {
|
|
|
14608
15388
|
DecompositionError,
|
|
14609
15389
|
DecomposedSubtaskSchema,
|
|
14610
15390
|
DecomposeArgsSchema,
|
|
15391
|
+
DEFAULT_STORAGE_CONFIG,
|
|
14611
15392
|
DEFAULT_CRITERIA,
|
|
14612
15393
|
CriterionEvaluationSchema,
|
|
14613
15394
|
BeadValidationError,
|