opencode-swarm 7.51.1 → 7.51.3
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 +83 -52
- package/dist/hooks/context-sanitizer.d.ts +25 -0
- package/dist/hooks/curator.d.ts +1 -1
- package/dist/hooks/knowledge-reader.d.ts +3 -0
- package/dist/hooks/knowledge-store.d.ts +3 -0
- package/dist/index.js +294 -272
- package/package.json +2 -2
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.51.
|
|
72
|
+
version: "7.51.3",
|
|
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",
|
|
@@ -116,7 +116,7 @@ var init_package = __esm(() => {
|
|
|
116
116
|
check: "biome check --write .",
|
|
117
117
|
dev: "bun run build && opencode",
|
|
118
118
|
"package:smoke": "node scripts/package-smoke.mjs",
|
|
119
|
-
|
|
119
|
+
prepare: "bun run build",
|
|
120
120
|
"repro:704": "node scripts/repro-704.mjs"
|
|
121
121
|
},
|
|
122
122
|
dependencies: {
|
|
@@ -56604,7 +56604,7 @@ var init_event_bus = __esm(() => {
|
|
|
56604
56604
|
|
|
56605
56605
|
// src/hooks/knowledge-store.ts
|
|
56606
56606
|
import { existsSync as existsSync12 } from "node:fs";
|
|
56607
|
-
import { appendFile as appendFile3, mkdir as mkdir3, readFile as readFile5
|
|
56607
|
+
import { appendFile as appendFile3, mkdir as mkdir3, readFile as readFile5 } from "node:fs/promises";
|
|
56608
56608
|
import * as os8 from "node:os";
|
|
56609
56609
|
import * as path22 from "node:path";
|
|
56610
56610
|
function resolveSwarmKnowledgePath(directory) {
|
|
@@ -56767,23 +56767,25 @@ async function rewriteKnowledge(filePath, entries) {
|
|
|
56767
56767
|
}
|
|
56768
56768
|
}
|
|
56769
56769
|
}
|
|
56770
|
-
async function
|
|
56771
|
-
|
|
56770
|
+
async function transactFile(filePath, read, write, mutate) {
|
|
56771
|
+
const dir = path22.dirname(filePath);
|
|
56772
56772
|
try {
|
|
56773
|
-
const dir = path22.dirname(filePath);
|
|
56774
56773
|
await mkdir3(dir, { recursive: true });
|
|
56774
|
+
} catch {
|
|
56775
|
+
return false;
|
|
56776
|
+
}
|
|
56777
|
+
let release = null;
|
|
56778
|
+
try {
|
|
56775
56779
|
release = await import_proper_lockfile3.default.lock(dir, {
|
|
56776
56780
|
retries: { retries: 5, minTimeout: 100, maxTimeout: 500 },
|
|
56777
56781
|
stale: 5000
|
|
56778
56782
|
});
|
|
56779
|
-
const
|
|
56780
|
-
|
|
56781
|
-
|
|
56782
|
-
|
|
56783
|
-
|
|
56784
|
-
|
|
56785
|
-
await writeFile3(filePath, content, "utf-8");
|
|
56786
|
-
}
|
|
56783
|
+
const data = await read(filePath);
|
|
56784
|
+
const result = mutate(data);
|
|
56785
|
+
if (result === null)
|
|
56786
|
+
return false;
|
|
56787
|
+
await write(filePath, result);
|
|
56788
|
+
return true;
|
|
56787
56789
|
} finally {
|
|
56788
56790
|
if (release) {
|
|
56789
56791
|
try {
|
|
@@ -56792,25 +56794,33 @@ async function enforceKnowledgeCap(filePath, maxEntries) {
|
|
|
56792
56794
|
}
|
|
56793
56795
|
}
|
|
56794
56796
|
}
|
|
56797
|
+
async function transactKnowledge(filePath, mutate) {
|
|
56798
|
+
return transactFile(filePath, readKnowledge, async (fp, entries) => {
|
|
56799
|
+
const content = entries.map((e) => JSON.stringify(e)).join(`
|
|
56800
|
+
`) + (entries.length > 0 ? `
|
|
56801
|
+
` : "");
|
|
56802
|
+
await atomicWriteFile(fp, content);
|
|
56803
|
+
}, mutate);
|
|
56804
|
+
}
|
|
56805
|
+
async function enforceKnowledgeCap(filePath, maxEntries) {
|
|
56806
|
+
await transactKnowledge(filePath, (entries) => {
|
|
56807
|
+
if (entries.length <= maxEntries)
|
|
56808
|
+
return null;
|
|
56809
|
+
return entries.slice(entries.length - maxEntries);
|
|
56810
|
+
});
|
|
56811
|
+
}
|
|
56795
56812
|
async function sweepAgedEntries(filePath, defaultMaxPhases) {
|
|
56796
|
-
|
|
56797
|
-
|
|
56798
|
-
|
|
56799
|
-
|
|
56800
|
-
|
|
56801
|
-
|
|
56802
|
-
|
|
56803
|
-
|
|
56804
|
-
|
|
56805
|
-
const result = {
|
|
56806
|
-
scanned: entries.length,
|
|
56807
|
-
aged: 0,
|
|
56808
|
-
archived: 0,
|
|
56809
|
-
removed: 0,
|
|
56810
|
-
skipped_promoted: 0
|
|
56811
|
-
};
|
|
56813
|
+
const result = {
|
|
56814
|
+
scanned: 0,
|
|
56815
|
+
aged: 0,
|
|
56816
|
+
archived: 0,
|
|
56817
|
+
removed: 0,
|
|
56818
|
+
skipped_promoted: 0
|
|
56819
|
+
};
|
|
56820
|
+
await transactKnowledge(filePath, (entries) => {
|
|
56821
|
+
result.scanned = entries.length;
|
|
56812
56822
|
if (entries.length === 0)
|
|
56813
|
-
return
|
|
56823
|
+
return null;
|
|
56814
56824
|
const now = new Date().toISOString();
|
|
56815
56825
|
let mutated = false;
|
|
56816
56826
|
for (const entry of entries) {
|
|
@@ -56830,40 +56840,22 @@ async function sweepAgedEntries(filePath, defaultMaxPhases) {
|
|
|
56830
56840
|
result.archived++;
|
|
56831
56841
|
}
|
|
56832
56842
|
}
|
|
56833
|
-
|
|
56834
|
-
|
|
56835
|
-
|
|
56836
|
-
` : "");
|
|
56837
|
-
await writeFile3(filePath, content, "utf-8");
|
|
56838
|
-
}
|
|
56839
|
-
return result;
|
|
56840
|
-
} finally {
|
|
56841
|
-
if (release) {
|
|
56842
|
-
try {
|
|
56843
|
-
await release();
|
|
56844
|
-
} catch {}
|
|
56845
|
-
}
|
|
56846
|
-
}
|
|
56843
|
+
return mutated ? entries : null;
|
|
56844
|
+
});
|
|
56845
|
+
return result;
|
|
56847
56846
|
}
|
|
56848
56847
|
async function sweepStaleTodos(filePath, todoMaxPhases) {
|
|
56849
|
-
|
|
56850
|
-
|
|
56851
|
-
|
|
56852
|
-
|
|
56853
|
-
|
|
56854
|
-
|
|
56855
|
-
|
|
56856
|
-
|
|
56857
|
-
|
|
56858
|
-
const result = {
|
|
56859
|
-
scanned: entries.length,
|
|
56860
|
-
aged: 0,
|
|
56861
|
-
archived: 0,
|
|
56862
|
-
removed: 0,
|
|
56863
|
-
skipped_promoted: 0
|
|
56864
|
-
};
|
|
56848
|
+
const result = {
|
|
56849
|
+
scanned: 0,
|
|
56850
|
+
aged: 0,
|
|
56851
|
+
archived: 0,
|
|
56852
|
+
removed: 0,
|
|
56853
|
+
skipped_promoted: 0
|
|
56854
|
+
};
|
|
56855
|
+
await transactKnowledge(filePath, (entries) => {
|
|
56856
|
+
result.scanned = entries.length;
|
|
56865
56857
|
if (entries.length === 0)
|
|
56866
|
-
return
|
|
56858
|
+
return null;
|
|
56867
56859
|
const kept = entries.filter((e) => {
|
|
56868
56860
|
if (e.category !== "todo" || e.status === "promoted")
|
|
56869
56861
|
return true;
|
|
@@ -56874,32 +56866,20 @@ async function sweepStaleTodos(filePath, todoMaxPhases) {
|
|
|
56874
56866
|
}
|
|
56875
56867
|
return true;
|
|
56876
56868
|
});
|
|
56877
|
-
|
|
56878
|
-
|
|
56879
|
-
|
|
56880
|
-
` : "");
|
|
56881
|
-
await writeFile3(filePath, content, "utf-8");
|
|
56882
|
-
}
|
|
56883
|
-
return result;
|
|
56884
|
-
} finally {
|
|
56885
|
-
if (release) {
|
|
56886
|
-
try {
|
|
56887
|
-
await release();
|
|
56888
|
-
} catch {}
|
|
56889
|
-
}
|
|
56890
|
-
}
|
|
56869
|
+
return result.removed > 0 ? kept : null;
|
|
56870
|
+
});
|
|
56871
|
+
return result;
|
|
56891
56872
|
}
|
|
56892
56873
|
async function appendRejectedLesson(directory, lesson) {
|
|
56893
56874
|
const filePath = resolveSwarmRejectedPath(directory);
|
|
56894
|
-
const existing = await readRejectedLessons(directory);
|
|
56895
56875
|
const MAX = 20;
|
|
56896
|
-
|
|
56897
|
-
|
|
56898
|
-
|
|
56899
|
-
|
|
56900
|
-
|
|
56901
|
-
|
|
56902
|
-
}
|
|
56876
|
+
await transactKnowledge(filePath, (existing) => {
|
|
56877
|
+
const updated = [...existing, lesson];
|
|
56878
|
+
if (updated.length > MAX) {
|
|
56879
|
+
return updated.slice(updated.length - MAX);
|
|
56880
|
+
}
|
|
56881
|
+
return updated;
|
|
56882
|
+
});
|
|
56903
56883
|
}
|
|
56904
56884
|
function normalize4(text) {
|
|
56905
56885
|
const s = typeof text === "string" ? text : String(text ?? "");
|
|
@@ -57028,7 +57008,7 @@ async function applyConfidenceDeltas(filePath, deltas) {
|
|
|
57028
57008
|
const content = entries.map((e) => JSON.stringify(e)).join(`
|
|
57029
57009
|
`) + (entries.length > 0 ? `
|
|
57030
57010
|
` : "");
|
|
57031
|
-
await
|
|
57011
|
+
await atomicWriteFile(filePath, content);
|
|
57032
57012
|
}
|
|
57033
57013
|
} catch (err2) {
|
|
57034
57014
|
console.warn(`[knowledge-store] applyConfidenceDeltas failed on ${filePath} (fail-open):`, err2 instanceof Error ? err2.message : String(err2));
|
|
@@ -57047,7 +57027,7 @@ var init_knowledge_store = __esm(() => {
|
|
|
57047
57027
|
});
|
|
57048
57028
|
|
|
57049
57029
|
// src/hooks/knowledge-validator.ts
|
|
57050
|
-
import { appendFile as appendFile4, mkdir as mkdir4
|
|
57030
|
+
import { appendFile as appendFile4, mkdir as mkdir4 } from "node:fs/promises";
|
|
57051
57031
|
import * as path23 from "node:path";
|
|
57052
57032
|
function normalizeText(text) {
|
|
57053
57033
|
return text.normalize("NFKC").toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -57224,7 +57204,8 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
57224
57204
|
let release;
|
|
57225
57205
|
try {
|
|
57226
57206
|
release = await import_proper_lockfile4.default.lock(swarmDir, {
|
|
57227
|
-
retries: { retries:
|
|
57207
|
+
retries: { retries: 5, minTimeout: 100, maxTimeout: 500 },
|
|
57208
|
+
stale: 5000
|
|
57228
57209
|
});
|
|
57229
57210
|
const entries = await readKnowledge(knowledgePath);
|
|
57230
57211
|
const entry = entries.find((e) => e.id === entryId);
|
|
@@ -57243,7 +57224,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
57243
57224
|
const jsonlContent = remaining.length > 0 ? `${remaining.map((e) => JSON.stringify(e)).join(`
|
|
57244
57225
|
`)}
|
|
57245
57226
|
` : "";
|
|
57246
|
-
await
|
|
57227
|
+
await atomicWriteFile(knowledgePath, jsonlContent);
|
|
57247
57228
|
await appendFile4(quarantinePath, `${JSON.stringify(quarantined)}
|
|
57248
57229
|
`, "utf-8");
|
|
57249
57230
|
const quarantinedEntries = await readKnowledge(quarantinePath);
|
|
@@ -57252,7 +57233,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
57252
57233
|
const capContent = trimmed.length > 0 ? `${trimmed.map((e) => JSON.stringify(e)).join(`
|
|
57253
57234
|
`)}
|
|
57254
57235
|
` : "";
|
|
57255
|
-
await
|
|
57236
|
+
await atomicWriteFile(quarantinePath, capContent);
|
|
57256
57237
|
}
|
|
57257
57238
|
const rejectedRecord = {
|
|
57258
57239
|
id: entryId,
|
|
@@ -57287,7 +57268,8 @@ async function restoreEntry(directory, entryId) {
|
|
|
57287
57268
|
let release;
|
|
57288
57269
|
try {
|
|
57289
57270
|
release = await import_proper_lockfile4.default.lock(swarmDir, {
|
|
57290
|
-
retries: { retries:
|
|
57271
|
+
retries: { retries: 5, minTimeout: 100, maxTimeout: 500 },
|
|
57272
|
+
stale: 5000
|
|
57291
57273
|
});
|
|
57292
57274
|
const quarantinedEntries = await readKnowledge(quarantinePath);
|
|
57293
57275
|
const entryToRestore = quarantinedEntries.find((e) => e.id === entryId);
|
|
@@ -57316,7 +57298,7 @@ async function restoreEntry(directory, entryId) {
|
|
|
57316
57298
|
const jsonlContent = remaining.length > 0 ? `${remaining.map((e) => JSON.stringify(e)).join(`
|
|
57317
57299
|
`)}
|
|
57318
57300
|
` : "";
|
|
57319
|
-
await
|
|
57301
|
+
await atomicWriteFile(quarantinePath, jsonlContent);
|
|
57320
57302
|
await appendFile4(knowledgePath, `${JSON.stringify(original)}
|
|
57321
57303
|
`, "utf-8");
|
|
57322
57304
|
const rejectedEntries = await readKnowledge(rejectedPath);
|
|
@@ -57324,7 +57306,7 @@ async function restoreEntry(directory, entryId) {
|
|
|
57324
57306
|
const rejectedContent = filtered.length > 0 ? `${filtered.map((e) => JSON.stringify(e)).join(`
|
|
57325
57307
|
`)}
|
|
57326
57308
|
` : "";
|
|
57327
|
-
await
|
|
57309
|
+
await atomicWriteFile(rejectedPath, rejectedContent);
|
|
57328
57310
|
} finally {
|
|
57329
57311
|
if (release) {
|
|
57330
57312
|
await release();
|
|
@@ -57333,6 +57315,7 @@ async function restoreEntry(directory, entryId) {
|
|
|
57333
57315
|
}
|
|
57334
57316
|
var import_proper_lockfile4, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS, ALLOWED_SKILL_PATH_PREFIXES, VALID_DIRECTIVE_PRIORITIES;
|
|
57335
57317
|
var init_knowledge_validator = __esm(() => {
|
|
57318
|
+
init_task_file();
|
|
57336
57319
|
init_logger();
|
|
57337
57320
|
init_knowledge_store();
|
|
57338
57321
|
import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
|
|
@@ -57470,7 +57453,7 @@ __export(exports_skill_generator, {
|
|
|
57470
57453
|
_internals: () => _internals18
|
|
57471
57454
|
});
|
|
57472
57455
|
import { existsSync as existsSync13, unlinkSync as unlinkSync5 } from "node:fs";
|
|
57473
|
-
import { mkdir as mkdir5, readFile as readFile6, rename as rename3, writeFile as
|
|
57456
|
+
import { mkdir as mkdir5, readFile as readFile6, rename as rename3, writeFile as writeFile3 } from "node:fs/promises";
|
|
57474
57457
|
import * as path24 from "node:path";
|
|
57475
57458
|
function sanitizeSlug(input) {
|
|
57476
57459
|
const lc = input.toLowerCase().trim();
|
|
@@ -57662,7 +57645,7 @@ function escapeMarkdown(s) {
|
|
|
57662
57645
|
async function atomicWrite2(p, content) {
|
|
57663
57646
|
await mkdir5(path24.dirname(p), { recursive: true });
|
|
57664
57647
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
57665
|
-
await
|
|
57648
|
+
await writeFile3(tmp, content, "utf-8");
|
|
57666
57649
|
await rename3(tmp, p);
|
|
57667
57650
|
}
|
|
57668
57651
|
async function generateSkills(req) {
|
|
@@ -57976,7 +57959,7 @@ async function retireSkill(directory, slug, reason) {
|
|
|
57976
57959
|
reason: reason ?? "manual_retire"
|
|
57977
57960
|
});
|
|
57978
57961
|
await mkdir5(markerDir, { recursive: true });
|
|
57979
|
-
await
|
|
57962
|
+
await writeFile3(markerPath, markerContent, "utf-8");
|
|
57980
57963
|
return {
|
|
57981
57964
|
retired: true,
|
|
57982
57965
|
path: skillPath,
|
|
@@ -59195,77 +59178,83 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
59195
59178
|
}
|
|
59196
59179
|
const validRecommendations = recommendations.filter((rec) => rec != null);
|
|
59197
59180
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
59198
|
-
const entries = await readKnowledge(knowledgePath);
|
|
59199
|
-
let modified = false;
|
|
59200
59181
|
const appliedIds = new Set;
|
|
59201
|
-
const
|
|
59202
|
-
|
|
59203
|
-
|
|
59204
|
-
|
|
59205
|
-
|
|
59206
|
-
|
|
59207
|
-
|
|
59208
|
-
|
|
59209
|
-
|
|
59210
|
-
|
|
59211
|
-
|
|
59212
|
-
|
|
59213
|
-
|
|
59214
|
-
|
|
59215
|
-
|
|
59216
|
-
|
|
59217
|
-
|
|
59218
|
-
|
|
59219
|
-
|
|
59220
|
-
|
|
59221
|
-
|
|
59222
|
-
|
|
59223
|
-
|
|
59224
|
-
|
|
59225
|
-
|
|
59226
|
-
|
|
59227
|
-
|
|
59228
|
-
|
|
59229
|
-
|
|
59230
|
-
|
|
59231
|
-
|
|
59232
|
-
|
|
59233
|
-
|
|
59234
|
-
|
|
59235
|
-
|
|
59236
|
-
|
|
59237
|
-
|
|
59238
|
-
|
|
59239
|
-
|
|
59240
|
-
|
|
59182
|
+
const foundIds = new Set;
|
|
59183
|
+
await transactKnowledge(knowledgePath, (entries) => {
|
|
59184
|
+
appliedIds.clear();
|
|
59185
|
+
foundIds.clear();
|
|
59186
|
+
let txApplied = 0;
|
|
59187
|
+
let modified = false;
|
|
59188
|
+
for (const e of entries)
|
|
59189
|
+
foundIds.add(e.id);
|
|
59190
|
+
const updatedEntries = entries.map((entry) => {
|
|
59191
|
+
const rec = validRecommendations.find((r) => r.entry_id === entry.id);
|
|
59192
|
+
if (!rec)
|
|
59193
|
+
return entry;
|
|
59194
|
+
switch (rec.action) {
|
|
59195
|
+
case "promote":
|
|
59196
|
+
appliedIds.add(entry.id);
|
|
59197
|
+
txApplied++;
|
|
59198
|
+
modified = true;
|
|
59199
|
+
return {
|
|
59200
|
+
...entry,
|
|
59201
|
+
hive_eligible: true,
|
|
59202
|
+
confidence: Math.min(1, (entry.confidence ?? 0) + 0.1),
|
|
59203
|
+
updated_at: new Date().toISOString()
|
|
59204
|
+
};
|
|
59205
|
+
case "archive":
|
|
59206
|
+
appliedIds.add(entry.id);
|
|
59207
|
+
txApplied++;
|
|
59208
|
+
modified = true;
|
|
59209
|
+
return {
|
|
59210
|
+
...entry,
|
|
59211
|
+
status: "archived",
|
|
59212
|
+
updated_at: new Date().toISOString()
|
|
59213
|
+
};
|
|
59214
|
+
case "flag_contradiction":
|
|
59215
|
+
appliedIds.add(entry.id);
|
|
59216
|
+
txApplied++;
|
|
59217
|
+
modified = true;
|
|
59218
|
+
return {
|
|
59219
|
+
...entry,
|
|
59220
|
+
tags: [
|
|
59221
|
+
...entry.tags ?? [],
|
|
59222
|
+
`contradiction:${(rec.reason ?? "").slice(0, 50)}`
|
|
59223
|
+
],
|
|
59224
|
+
updated_at: new Date().toISOString()
|
|
59225
|
+
};
|
|
59226
|
+
case "rewrite": {
|
|
59227
|
+
const newLesson = (rec.lesson ?? "").trim();
|
|
59228
|
+
if (newLesson.length < 15 || newLesson.length > 280) {
|
|
59229
|
+
return entry;
|
|
59230
|
+
}
|
|
59231
|
+
appliedIds.add(entry.id);
|
|
59232
|
+
txApplied++;
|
|
59233
|
+
modified = true;
|
|
59234
|
+
return {
|
|
59235
|
+
...entry,
|
|
59236
|
+
lesson: newLesson,
|
|
59237
|
+
updated_at: new Date().toISOString(),
|
|
59238
|
+
confidence: Math.max(0.1, (entry.confidence ?? 0.5) - 0.05)
|
|
59239
|
+
};
|
|
59241
59240
|
}
|
|
59242
|
-
|
|
59243
|
-
|
|
59244
|
-
modified = true;
|
|
59245
|
-
return {
|
|
59246
|
-
...entry,
|
|
59247
|
-
lesson: newLesson,
|
|
59248
|
-
updated_at: new Date().toISOString(),
|
|
59249
|
-
confidence: Math.max(0.1, (entry.confidence ?? 0.5) - 0.05)
|
|
59250
|
-
};
|
|
59241
|
+
default:
|
|
59242
|
+
return entry;
|
|
59251
59243
|
}
|
|
59252
|
-
|
|
59253
|
-
|
|
59254
|
-
|
|
59244
|
+
});
|
|
59245
|
+
applied += txApplied;
|
|
59246
|
+
return modified ? updatedEntries : null;
|
|
59255
59247
|
});
|
|
59256
59248
|
for (const rec of validRecommendations) {
|
|
59257
59249
|
if (rec.entry_id !== undefined && !appliedIds.has(rec.entry_id)) {
|
|
59258
|
-
|
|
59259
|
-
if (!found) {
|
|
59250
|
+
if (!foundIds.has(rec.entry_id)) {
|
|
59260
59251
|
warn(`[curator] applyCuratorKnowledgeUpdates: entry_id '${rec.entry_id}' not found — skipping`);
|
|
59261
59252
|
}
|
|
59262
59253
|
skipped++;
|
|
59263
59254
|
}
|
|
59264
59255
|
}
|
|
59265
|
-
|
|
59266
|
-
|
|
59267
|
-
}
|
|
59268
|
-
const existingLessons = entries.map((e) => e.lesson);
|
|
59256
|
+
const currentEntries = await readKnowledge(knowledgePath);
|
|
59257
|
+
const currentLessons = currentEntries.map((e) => e.lesson);
|
|
59269
59258
|
for (const rec of validRecommendations) {
|
|
59270
59259
|
if (rec.entry_id !== undefined)
|
|
59271
59260
|
continue;
|
|
@@ -59278,12 +59267,12 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
59278
59267
|
skipped++;
|
|
59279
59268
|
continue;
|
|
59280
59269
|
}
|
|
59281
|
-
if (
|
|
59270
|
+
if (currentLessons.some((el) => el.toLowerCase() === lesson.toLowerCase())) {
|
|
59282
59271
|
skipped++;
|
|
59283
59272
|
continue;
|
|
59284
59273
|
}
|
|
59285
59274
|
if (knowledgeConfig.validation_enabled !== false) {
|
|
59286
|
-
const validation = validateLesson(lesson,
|
|
59275
|
+
const validation = validateLesson(lesson, currentLessons, {
|
|
59287
59276
|
category: rec.category ?? "other",
|
|
59288
59277
|
scope: "global",
|
|
59289
59278
|
confidence: rec.confidence ?? 0.5
|
|
@@ -59317,7 +59306,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
59317
59306
|
};
|
|
59318
59307
|
await appendKnowledge(knowledgePath, newEntry);
|
|
59319
59308
|
applied++;
|
|
59320
|
-
|
|
59309
|
+
currentLessons.push(lesson);
|
|
59321
59310
|
}
|
|
59322
59311
|
return { applied, skipped };
|
|
59323
59312
|
}
|
|
@@ -59613,7 +59602,7 @@ var init_hive_promoter = __esm(() => {
|
|
|
59613
59602
|
// src/hooks/knowledge-events.ts
|
|
59614
59603
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
59615
59604
|
import { existsSync as existsSync16 } from "node:fs";
|
|
59616
|
-
import { appendFile as appendFile5, mkdir as mkdir6, readFile as readFile7, writeFile as
|
|
59605
|
+
import { appendFile as appendFile5, mkdir as mkdir6, readFile as readFile7, writeFile as writeFile4 } from "node:fs/promises";
|
|
59617
59606
|
import * as path28 from "node:path";
|
|
59618
59607
|
function resolveKnowledgeEventsPath(directory) {
|
|
59619
59608
|
return path28.join(directory, ".swarm", "knowledge-events.jsonl");
|
|
@@ -59653,7 +59642,7 @@ async function appendKnowledgeEvent(directory, event) {
|
|
|
59653
59642
|
`).filter((line) => line.trim().length > 0);
|
|
59654
59643
|
if (lines.length > MAX_EVENT_LOG_ENTRIES) {
|
|
59655
59644
|
const trimmed = lines.slice(lines.length - MAX_EVENT_LOG_ENTRIES);
|
|
59656
|
-
await
|
|
59645
|
+
await writeFile4(filePath, `${trimmed.join(`
|
|
59657
59646
|
`)}
|
|
59658
59647
|
`, "utf-8");
|
|
59659
59648
|
}
|
|
@@ -60001,8 +59990,7 @@ async function processRetractions(retractions, directory) {
|
|
|
60001
59990
|
}
|
|
60002
59991
|
async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, config3, options) {
|
|
60003
59992
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
60004
|
-
const
|
|
60005
|
-
let stored = 0;
|
|
59993
|
+
const snapshot = await readKnowledge(knowledgePath) ?? [];
|
|
60006
59994
|
let skipped = 0;
|
|
60007
59995
|
let rejected = 0;
|
|
60008
59996
|
const categoryByTag = new Map([
|
|
@@ -60017,6 +60005,8 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
|
|
|
60017
60005
|
["other", "other"],
|
|
60018
60006
|
["todo", "todo"]
|
|
60019
60007
|
]);
|
|
60008
|
+
const snapshotPlusNew = [...snapshot];
|
|
60009
|
+
const toAdd = [];
|
|
60020
60010
|
for (const lesson of lessons) {
|
|
60021
60011
|
const tags = inferTags(lesson);
|
|
60022
60012
|
let category = "process";
|
|
@@ -60031,7 +60021,7 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
|
|
|
60031
60021
|
scope: "global",
|
|
60032
60022
|
confidence: computeConfidence(0, true)
|
|
60033
60023
|
};
|
|
60034
|
-
const result = validateLesson(lesson,
|
|
60024
|
+
const result = validateLesson(lesson, snapshotPlusNew.map((e) => e.lesson), meta3);
|
|
60035
60025
|
if (result.valid === false || result.severity === "error") {
|
|
60036
60026
|
const rejectedLesson = {
|
|
60037
60027
|
id: crypto.randomUUID(),
|
|
@@ -60044,7 +60034,7 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
|
|
|
60044
60034
|
rejected++;
|
|
60045
60035
|
continue;
|
|
60046
60036
|
}
|
|
60047
|
-
const duplicate = findNearDuplicate(lesson,
|
|
60037
|
+
const duplicate = findNearDuplicate(lesson, snapshotPlusNew, config3.dedup_threshold);
|
|
60048
60038
|
if (duplicate) {
|
|
60049
60039
|
skipped++;
|
|
60050
60040
|
continue;
|
|
@@ -60076,9 +60066,20 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
|
|
|
60076
60066
|
project_name: projectName,
|
|
60077
60067
|
auto_generated: true
|
|
60078
60068
|
};
|
|
60079
|
-
|
|
60080
|
-
|
|
60081
|
-
|
|
60069
|
+
toAdd.push(entry);
|
|
60070
|
+
snapshotPlusNew.push(entry);
|
|
60071
|
+
}
|
|
60072
|
+
let stored = 0;
|
|
60073
|
+
if (toAdd.length > 0) {
|
|
60074
|
+
await transactKnowledge(knowledgePath, (current) => {
|
|
60075
|
+
const trulyNew = toAdd.filter((e) => !findNearDuplicate(e.lesson, current, config3.dedup_threshold));
|
|
60076
|
+
const extraDups = toAdd.length - trulyNew.length;
|
|
60077
|
+
skipped += extraDups;
|
|
60078
|
+
if (trulyNew.length === 0)
|
|
60079
|
+
return null;
|
|
60080
|
+
stored = trulyNew.length;
|
|
60081
|
+
return [...current, ...trulyNew];
|
|
60082
|
+
});
|
|
60082
60083
|
}
|
|
60083
60084
|
await enforceKnowledgeCap(knowledgePath, config3.swarm_max_entries);
|
|
60084
60085
|
if (!options?.skipAutoPromotion) {
|
|
@@ -60320,7 +60321,7 @@ var init_skill_improver_llm_factory = __esm(() => {
|
|
|
60320
60321
|
|
|
60321
60322
|
// src/services/skill-improver-quota.ts
|
|
60322
60323
|
import { existsSync as existsSync17 } from "node:fs";
|
|
60323
|
-
import { mkdir as mkdir7, readFile as readFile8, rename as rename4, writeFile as
|
|
60324
|
+
import { mkdir as mkdir7, readFile as readFile8, rename as rename4, writeFile as writeFile5 } from "node:fs/promises";
|
|
60324
60325
|
import * as path29 from "node:path";
|
|
60325
60326
|
async function acquireLock(dir) {
|
|
60326
60327
|
const acquire = import_proper_lockfile6.default.lock(dir, LOCK_RETRY_OPTS);
|
|
@@ -60367,7 +60368,7 @@ async function readState(filePath) {
|
|
|
60367
60368
|
async function writeState(filePath, state) {
|
|
60368
60369
|
await mkdir7(path29.dirname(filePath), { recursive: true });
|
|
60369
60370
|
const tmp = `${filePath}.tmp-${process.pid}`;
|
|
60370
|
-
await
|
|
60371
|
+
await writeFile5(tmp, JSON.stringify(state, null, 2), "utf-8");
|
|
60371
60372
|
await rename4(tmp, filePath);
|
|
60372
60373
|
}
|
|
60373
60374
|
async function getQuotaState(directory, opts) {
|
|
@@ -60454,7 +60455,7 @@ var init_skill_improver_quota = __esm(() => {
|
|
|
60454
60455
|
|
|
60455
60456
|
// src/services/skill-improver.ts
|
|
60456
60457
|
import { existsSync as existsSync18 } from "node:fs";
|
|
60457
|
-
import { mkdir as mkdir8, rename as rename5, writeFile as
|
|
60458
|
+
import { mkdir as mkdir8, rename as rename5, writeFile as writeFile6 } from "node:fs/promises";
|
|
60458
60459
|
import * as path30 from "node:path";
|
|
60459
60460
|
function timestampSlug(d) {
|
|
60460
60461
|
return d.toISOString().replace(/[:.]/g, "-");
|
|
@@ -60462,7 +60463,7 @@ function timestampSlug(d) {
|
|
|
60462
60463
|
async function atomicWrite3(p, content) {
|
|
60463
60464
|
await mkdir8(path30.dirname(p), { recursive: true });
|
|
60464
60465
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
60465
|
-
await
|
|
60466
|
+
await writeFile6(tmp, content, "utf-8");
|
|
60466
60467
|
await rename5(tmp, p);
|
|
60467
60468
|
}
|
|
60468
60469
|
async function gatherInventory(directory) {
|
|
@@ -68292,7 +68293,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
68292
68293
|
// src/hooks/knowledge-migrator.ts
|
|
68293
68294
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
68294
68295
|
import { existsSync as existsSync25, readFileSync as readFileSync13 } from "node:fs";
|
|
68295
|
-
import { mkdir as mkdir9, readFile as readFile11, writeFile as
|
|
68296
|
+
import { mkdir as mkdir9, readFile as readFile11, writeFile as writeFile7 } from "node:fs/promises";
|
|
68296
68297
|
import * as path41 from "node:path";
|
|
68297
68298
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
68298
68299
|
return {
|
|
@@ -68523,7 +68524,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
68523
68524
|
migration_tool: "knowledge-migrator.ts"
|
|
68524
68525
|
};
|
|
68525
68526
|
await mkdir9(path41.dirname(sentinelPath), { recursive: true });
|
|
68526
|
-
await
|
|
68527
|
+
await writeFile7(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
68527
68528
|
}
|
|
68528
68529
|
var _internals29;
|
|
68529
68530
|
var init_knowledge_migrator = __esm(() => {
|
|
@@ -69605,7 +69606,7 @@ import {
|
|
|
69605
69606
|
mkdir as mkdir10,
|
|
69606
69607
|
readFile as readFile12,
|
|
69607
69608
|
rename as rename6,
|
|
69608
|
-
writeFile as
|
|
69609
|
+
writeFile as writeFile8
|
|
69609
69610
|
} from "node:fs/promises";
|
|
69610
69611
|
import * as path42 from "node:path";
|
|
69611
69612
|
|
|
@@ -70016,7 +70017,7 @@ async function writeJsonlAtomic(filePath, values) {
|
|
|
70016
70017
|
const content = values.map((value) => JSON.stringify(value)).join(`
|
|
70017
70018
|
`) + (values.length > 0 ? `
|
|
70018
70019
|
` : "");
|
|
70019
|
-
await
|
|
70020
|
+
await writeFile8(tmp, content, "utf-8");
|
|
70020
70021
|
await rename6(tmp, filePath);
|
|
70021
70022
|
}
|
|
70022
70023
|
var init_local_jsonl_provider = __esm(() => {
|
|
@@ -70111,7 +70112,7 @@ var init_prompt_block = __esm(() => {
|
|
|
70111
70112
|
|
|
70112
70113
|
// src/memory/jsonl-migration.ts
|
|
70113
70114
|
import { existsSync as existsSync27 } from "node:fs";
|
|
70114
|
-
import { copyFile, mkdir as mkdir11, readFile as readFile13, stat as stat4, writeFile as
|
|
70115
|
+
import { copyFile, mkdir as mkdir11, readFile as readFile13, stat as stat4, writeFile as writeFile9 } from "node:fs/promises";
|
|
70115
70116
|
import * as path43 from "node:path";
|
|
70116
70117
|
function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
|
|
70117
70118
|
const resolved = resolveConfig(config3);
|
|
@@ -70159,14 +70160,14 @@ async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
|
|
|
70159
70160
|
await mkdir11(exportDir, { recursive: true });
|
|
70160
70161
|
const memoriesPath = path43.join(exportDir, "memories.jsonl");
|
|
70161
70162
|
const proposalsPath = path43.join(exportDir, "proposals.jsonl");
|
|
70162
|
-
await
|
|
70163
|
-
await
|
|
70163
|
+
await writeFile9(memoriesPath, toJsonl(memories), "utf-8");
|
|
70164
|
+
await writeFile9(proposalsPath, toJsonl(proposals), "utf-8");
|
|
70164
70165
|
return { directory: exportDir, memoriesPath, proposalsPath };
|
|
70165
70166
|
}
|
|
70166
70167
|
async function writeMigrationReport(rootDirectory, report, config3 = {}) {
|
|
70167
70168
|
const reportPath = path43.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
70168
70169
|
await mkdir11(path43.dirname(reportPath), { recursive: true });
|
|
70169
|
-
await
|
|
70170
|
+
await writeFile9(reportPath, `${JSON.stringify(report, null, 2)}
|
|
70170
70171
|
`, "utf-8");
|
|
70171
70172
|
return reportPath;
|
|
70172
70173
|
}
|
|
@@ -86306,7 +86307,7 @@ COVERAGE REPORTING:
|
|
|
86306
86307
|
`;
|
|
86307
86308
|
|
|
86308
86309
|
// src/agents/index.ts
|
|
86309
|
-
import { mkdir as mkdir13, writeFile as
|
|
86310
|
+
import { mkdir as mkdir13, writeFile as writeFile10 } from "node:fs/promises";
|
|
86310
86311
|
import * as path70 from "node:path";
|
|
86311
86312
|
function stripSwarmPrefix(agentName, swarmPrefix) {
|
|
86312
86313
|
if (!swarmPrefix || !agentName)
|
|
@@ -86728,7 +86729,7 @@ function getAgentConfigs(config3, directory, sessionId, projectContext) {
|
|
|
86728
86729
|
generatedAt: new Date().toISOString(),
|
|
86729
86730
|
agents: agentToolSnapshot
|
|
86730
86731
|
}, null, 2);
|
|
86731
|
-
mkdir13(evidenceDir, { recursive: true }).then(() =>
|
|
86732
|
+
mkdir13(evidenceDir, { recursive: true }).then(() => writeFile10(path70.join(evidenceDir, filename), snapshotData)).catch(() => {});
|
|
86732
86733
|
}
|
|
86733
86734
|
return result;
|
|
86734
86735
|
}
|
|
@@ -91269,7 +91270,7 @@ import {
|
|
|
91269
91270
|
readFile as readFile16,
|
|
91270
91271
|
realpath as realpath3,
|
|
91271
91272
|
stat as stat7,
|
|
91272
|
-
writeFile as
|
|
91273
|
+
writeFile as writeFile12
|
|
91273
91274
|
} from "node:fs/promises";
|
|
91274
91275
|
import * as path94 from "node:path";
|
|
91275
91276
|
function normalizeSeparators(filePath) {
|
|
@@ -91467,7 +91468,7 @@ async function scanDocIndex(directory) {
|
|
|
91467
91468
|
};
|
|
91468
91469
|
try {
|
|
91469
91470
|
await mkdir16(path94.dirname(manifestPath), { recursive: true });
|
|
91470
|
-
await
|
|
91471
|
+
await writeFile12(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
91471
91472
|
} catch {}
|
|
91472
91473
|
return { manifest, cached: false };
|
|
91473
91474
|
}
|
|
@@ -91681,7 +91682,7 @@ var init_doc_scan = __esm(() => {
|
|
|
91681
91682
|
|
|
91682
91683
|
// src/hooks/knowledge-reader.ts
|
|
91683
91684
|
import { existsSync as existsSync51 } from "node:fs";
|
|
91684
|
-
import {
|
|
91685
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
91685
91686
|
import * as path95 from "node:path";
|
|
91686
91687
|
function inferCategoriesFromPhase(phaseDescription) {
|
|
91687
91688
|
const lower = phaseDescription.toLowerCase();
|
|
@@ -91726,19 +91727,32 @@ function inferCategoriesFromPhase(phaseDescription) {
|
|
|
91726
91727
|
}
|
|
91727
91728
|
return ["process", "tooling"];
|
|
91728
91729
|
}
|
|
91730
|
+
async function transactShownFile(shownFile, mutate) {
|
|
91731
|
+
return transactFile(shownFile, async (filePath) => {
|
|
91732
|
+
if (!existsSync51(filePath))
|
|
91733
|
+
return {};
|
|
91734
|
+
try {
|
|
91735
|
+
const content = await readFile17(filePath, "utf-8");
|
|
91736
|
+
return JSON.parse(content);
|
|
91737
|
+
} catch {
|
|
91738
|
+
return {};
|
|
91739
|
+
}
|
|
91740
|
+
}, async (filePath, data) => {
|
|
91741
|
+
await atomicWriteFile(filePath, JSON.stringify(data, null, 2));
|
|
91742
|
+
}, mutate);
|
|
91743
|
+
}
|
|
91729
91744
|
async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
91730
91745
|
const shownFile = path95.join(directory, ".swarm", ".knowledge-shown.json");
|
|
91731
91746
|
try {
|
|
91732
|
-
let shownData = {};
|
|
91733
|
-
if (existsSync51(shownFile)) {
|
|
91734
|
-
const content = await readFile17(shownFile, "utf-8");
|
|
91735
|
-
shownData = JSON.parse(content);
|
|
91736
|
-
}
|
|
91737
91747
|
const phaseMatch = /^Phase\s+(\d+)/i.exec(currentPhase);
|
|
91738
91748
|
const canonicalKey = phaseMatch ? `Phase ${phaseMatch[1]}` : currentPhase;
|
|
91739
|
-
|
|
91740
|
-
|
|
91741
|
-
|
|
91749
|
+
const ok = await transactShownFile(shownFile, (shownData) => {
|
|
91750
|
+
shownData[canonicalKey] = lessonIds;
|
|
91751
|
+
return shownData;
|
|
91752
|
+
});
|
|
91753
|
+
if (!ok) {
|
|
91754
|
+
warn("[swarm] Knowledge: failed to record shown lessons");
|
|
91755
|
+
}
|
|
91742
91756
|
} catch {
|
|
91743
91757
|
warn("[swarm] Knowledge: failed to record shown lessons");
|
|
91744
91758
|
}
|
|
@@ -91843,56 +91857,58 @@ async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
|
91843
91857
|
if (!existsSync51(shownFile)) {
|
|
91844
91858
|
return;
|
|
91845
91859
|
}
|
|
91846
|
-
|
|
91847
|
-
|
|
91848
|
-
|
|
91860
|
+
let shownIds;
|
|
91861
|
+
try {
|
|
91862
|
+
const content = await readFile17(shownFile, "utf-8");
|
|
91863
|
+
const shownData = JSON.parse(content);
|
|
91864
|
+
shownIds = shownData[phaseInfo];
|
|
91865
|
+
} catch {
|
|
91866
|
+
return;
|
|
91867
|
+
}
|
|
91849
91868
|
if (!shownIds || shownIds.length === 0) {
|
|
91850
91869
|
return;
|
|
91851
91870
|
}
|
|
91852
91871
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
91853
|
-
const entries = await readKnowledge(swarmPath);
|
|
91854
|
-
let updated = false;
|
|
91855
91872
|
const foundInSwarm = new Set;
|
|
91856
|
-
|
|
91857
|
-
|
|
91858
|
-
|
|
91859
|
-
if (
|
|
91860
|
-
ro
|
|
91861
|
-
|
|
91862
|
-
|
|
91873
|
+
await transactKnowledge(swarmPath, (entries) => {
|
|
91874
|
+
let mutated = false;
|
|
91875
|
+
for (const entry of entries) {
|
|
91876
|
+
if (shownIds.includes(entry.id)) {
|
|
91877
|
+
const ro = entry.retrieval_outcomes;
|
|
91878
|
+
if (phaseSucceeded) {
|
|
91879
|
+
ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
|
|
91880
|
+
} else {
|
|
91881
|
+
ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
|
|
91882
|
+
}
|
|
91883
|
+
mutated = true;
|
|
91884
|
+
foundInSwarm.add(entry.id);
|
|
91863
91885
|
}
|
|
91864
|
-
updated = true;
|
|
91865
|
-
foundInSwarm.add(entry.id);
|
|
91866
91886
|
}
|
|
91867
|
-
|
|
91868
|
-
|
|
91869
|
-
await rewriteKnowledge(swarmPath, entries);
|
|
91870
|
-
}
|
|
91887
|
+
return mutated ? entries : null;
|
|
91888
|
+
});
|
|
91871
91889
|
const remainingIds = shownIds.filter((id) => !foundInSwarm.has(id));
|
|
91872
|
-
if (remainingIds.length
|
|
91873
|
-
|
|
91874
|
-
await
|
|
91875
|
-
|
|
91876
|
-
|
|
91877
|
-
|
|
91878
|
-
|
|
91879
|
-
|
|
91880
|
-
|
|
91881
|
-
|
|
91882
|
-
|
|
91883
|
-
|
|
91884
|
-
|
|
91885
|
-
|
|
91886
|
-
ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
|
|
91890
|
+
if (remainingIds.length > 0) {
|
|
91891
|
+
const hivePath = resolveHiveKnowledgePath();
|
|
91892
|
+
await transactKnowledge(hivePath, (hiveEntries) => {
|
|
91893
|
+
let mutated = false;
|
|
91894
|
+
for (const entry of hiveEntries) {
|
|
91895
|
+
if (remainingIds.includes(entry.id)) {
|
|
91896
|
+
const ro = entry.retrieval_outcomes;
|
|
91897
|
+
if (phaseSucceeded) {
|
|
91898
|
+
ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
|
|
91899
|
+
} else {
|
|
91900
|
+
ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
|
|
91901
|
+
}
|
|
91902
|
+
mutated = true;
|
|
91903
|
+
}
|
|
91887
91904
|
}
|
|
91888
|
-
|
|
91889
|
-
}
|
|
91890
|
-
}
|
|
91891
|
-
if (hiveUpdated) {
|
|
91892
|
-
await rewriteKnowledge(hivePath, hiveEntries);
|
|
91905
|
+
return mutated ? hiveEntries : null;
|
|
91906
|
+
});
|
|
91893
91907
|
}
|
|
91894
|
-
|
|
91895
|
-
|
|
91908
|
+
await transactShownFile(shownFile, (data) => {
|
|
91909
|
+
delete data[phaseInfo];
|
|
91910
|
+
return data;
|
|
91911
|
+
});
|
|
91896
91912
|
} catch {
|
|
91897
91913
|
warn("[swarm] Knowledge: failed to update retrieval outcomes");
|
|
91898
91914
|
}
|
|
@@ -91956,6 +91972,7 @@ function scoreDirectiveAgainstContext(entry, ctx) {
|
|
|
91956
91972
|
}
|
|
91957
91973
|
var JACCARD_THRESHOLD2 = 0.6, HIVE_TIER_BOOST = 0.05, SAME_PROJECT_PENALTY = -0.05, NORMAL_RETRIEVAL_STATUSES;
|
|
91958
91974
|
var init_knowledge_reader = __esm(() => {
|
|
91975
|
+
init_task_file();
|
|
91959
91976
|
init_logger();
|
|
91960
91977
|
init_knowledge_store();
|
|
91961
91978
|
NORMAL_RETRIEVAL_STATUSES = new Set(["established", "promoted"]);
|
|
@@ -95318,9 +95335,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner, dele
|
|
|
95318
95335
|
const initResult = await runner(directory, curatorConfig, llmDelegate);
|
|
95319
95336
|
if (initResult.briefing) {
|
|
95320
95337
|
const briefingPath = path78.join(directory, ".swarm", "curator-briefing.md");
|
|
95321
|
-
const { mkdir: mkdir14, writeFile:
|
|
95338
|
+
const { mkdir: mkdir14, writeFile: writeFile11 } = await import("node:fs/promises");
|
|
95322
95339
|
await mkdir14(path78.dirname(briefingPath), { recursive: true });
|
|
95323
|
-
await
|
|
95340
|
+
await writeFile11(briefingPath, initResult.briefing, "utf-8");
|
|
95324
95341
|
const { buildApprovedReceipt: buildApprovedReceipt2, persistReviewReceipt: persistReviewReceipt2 } = await Promise.resolve().then(() => (init_review_receipt(), exports_review_receipt));
|
|
95325
95342
|
const initReceipt = buildApprovedReceipt2({
|
|
95326
95343
|
agent: "curator",
|
|
@@ -102948,7 +102965,7 @@ ${errorSummary}`);
|
|
|
102948
102965
|
init_schema();
|
|
102949
102966
|
init_state();
|
|
102950
102967
|
init_logger();
|
|
102951
|
-
import { appendFile as appendFile10, mkdir as
|
|
102968
|
+
import { appendFile as appendFile10, mkdir as mkdir18 } from "node:fs/promises";
|
|
102952
102969
|
import * as path100 from "node:path";
|
|
102953
102970
|
|
|
102954
102971
|
// src/hooks/knowledge-application.ts
|
|
@@ -102956,7 +102973,7 @@ init_logger();
|
|
|
102956
102973
|
init_knowledge_store();
|
|
102957
102974
|
var import_proper_lockfile8 = __toESM(require_proper_lockfile(), 1);
|
|
102958
102975
|
import { existsSync as existsSync55 } from "node:fs";
|
|
102959
|
-
import { appendFile as appendFile9, mkdir as
|
|
102976
|
+
import { appendFile as appendFile9, mkdir as mkdir17, readFile as readFile18 } from "node:fs/promises";
|
|
102960
102977
|
import * as path99 from "node:path";
|
|
102961
102978
|
function resolveApplicationLogPath(directory) {
|
|
102962
102979
|
return path99.join(directory, ".swarm", "knowledge-application.jsonl");
|
|
@@ -102977,7 +102994,7 @@ function parseAcknowledgments(text) {
|
|
|
102977
102994
|
}
|
|
102978
102995
|
async function appendAudit(directory, record3) {
|
|
102979
102996
|
const filePath = resolveApplicationLogPath(directory);
|
|
102980
|
-
await
|
|
102997
|
+
await mkdir17(path99.dirname(filePath), { recursive: true });
|
|
102981
102998
|
await appendFile9(filePath, `${JSON.stringify(record3)}
|
|
102982
102999
|
`, "utf-8");
|
|
102983
103000
|
}
|
|
@@ -103158,7 +103175,7 @@ async function knowledgeApplicationGateBefore(directory, input, config3) {
|
|
|
103158
103175
|
}
|
|
103159
103176
|
async function writeWarnEvent(directory, record3) {
|
|
103160
103177
|
const filePath = path100.join(directory, ".swarm", "events.jsonl");
|
|
103161
|
-
await
|
|
103178
|
+
await mkdir18(path100.dirname(filePath), { recursive: true });
|
|
103162
103179
|
await appendFile10(filePath, `${JSON.stringify(record3)}
|
|
103163
103180
|
`, "utf-8");
|
|
103164
103181
|
}
|
|
@@ -103214,10 +103231,20 @@ init_manager();
|
|
|
103214
103231
|
import { createHash as createHash9 } from "node:crypto";
|
|
103215
103232
|
|
|
103216
103233
|
// src/services/run-memory.ts
|
|
103217
|
-
init_utils2();
|
|
103218
|
-
init_path_security();
|
|
103219
103234
|
import * as crypto10 from "node:crypto";
|
|
103220
103235
|
import * as fs63 from "node:fs/promises";
|
|
103236
|
+
|
|
103237
|
+
// src/hooks/context-sanitizer.ts
|
|
103238
|
+
function sanitizeContextText(text) {
|
|
103239
|
+
return text.split("").filter((char) => {
|
|
103240
|
+
const code = char.charCodeAt(0);
|
|
103241
|
+
return code === 9 || code === 10 || code === 13 || code > 31 && code !== 127;
|
|
103242
|
+
}).join("").replace(/[\u200B-\u200D\uFEFF]/g, "").replace(/[\u202A-\u202E\u2066-\u2069]/g, "").replace(/```/g, "` ` `").replace(/^system\s*:/gim, "[BLOCKED]:").replace(/<system\b[^>]*>/gi, "[BLOCKED-TAG]").replace(/<\/system>/gi, "[/BLOCKED-TAG]").replace(/<tool_call\b[^>]*>/gi, "[BLOCKED-TOOL]").replace(/<\/tool_call>/gi, "[/BLOCKED-TOOL]").replace(/<\/\w+>/g, "[/BLOCKED-TAG]");
|
|
103243
|
+
}
|
|
103244
|
+
|
|
103245
|
+
// src/services/run-memory.ts
|
|
103246
|
+
init_utils2();
|
|
103247
|
+
init_path_security();
|
|
103221
103248
|
var RUN_MEMORY_FILENAME = "run-memory.jsonl";
|
|
103222
103249
|
var MAX_SUMMARY_TOKENS = 500;
|
|
103223
103250
|
function generateTaskFingerprint(taskId, fileTargets) {
|
|
@@ -103297,9 +103324,11 @@ function summarizeTask(taskId, entries) {
|
|
|
103297
103324
|
if (lastPass) {
|
|
103298
103325
|
const passAttempt = lastPass.attemptNumber;
|
|
103299
103326
|
const failAttempt = lastFailure.attemptNumber;
|
|
103300
|
-
|
|
103327
|
+
const reason = sanitizeContextText(lastFailure.failureReason || "unknown");
|
|
103328
|
+
return `Task ${taskId}: FAILED attempt ${failAttempt} — ${reason}. Passed on attempt ${passAttempt}.`;
|
|
103301
103329
|
} else {
|
|
103302
|
-
|
|
103330
|
+
const reason = sanitizeContextText(lastFailure.failureReason || "unknown");
|
|
103331
|
+
return `Task ${taskId}: FAILED ${failCount} times — last: ${reason}. Still failing.`;
|
|
103303
103332
|
}
|
|
103304
103333
|
}
|
|
103305
103334
|
async function getRunMemorySummary(directory) {
|
|
@@ -103458,12 +103487,7 @@ function buildDirectiveBlock(entries, charBudget, cfg) {
|
|
|
103458
103487
|
return null;
|
|
103459
103488
|
return block;
|
|
103460
103489
|
}
|
|
103461
|
-
|
|
103462
|
-
return text.split("").filter((char) => {
|
|
103463
|
-
const code = char.charCodeAt(0);
|
|
103464
|
-
return code === 9 || code === 10 || code === 13 || code > 31 && code !== 127;
|
|
103465
|
-
}).join("").replace(/[\u200B-\u200D\uFEFF]/g, "").replace(/[\u202A-\u202E\u2066-\u2069]/g, "").replace(/```/g, "` ` `").replace(/^system\s*:/gim, "[BLOCKED]:");
|
|
103466
|
-
}
|
|
103490
|
+
var sanitizeLessonForContext = sanitizeContextText;
|
|
103467
103491
|
function isOrchestratorAgent(agentName) {
|
|
103468
103492
|
const stripped = stripKnownSwarmPrefix(agentName);
|
|
103469
103493
|
return stripped.toLowerCase() === "architect";
|
|
@@ -103576,14 +103600,14 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
103576
103600
|
const latestReport = driftReports[driftReports.length - 1];
|
|
103577
103601
|
const driftText = buildDriftInjectionText(latestReport, 500);
|
|
103578
103602
|
if (driftText) {
|
|
103579
|
-
freshPreamble = driftText;
|
|
103603
|
+
freshPreamble = sanitizeContextText(driftText);
|
|
103580
103604
|
}
|
|
103581
103605
|
}
|
|
103582
103606
|
} catch {}
|
|
103583
103607
|
try {
|
|
103584
103608
|
const briefingContent = await readSwarmFileAsync(directory, "curator-briefing.md");
|
|
103585
103609
|
if (briefingContent) {
|
|
103586
|
-
const truncatedBriefing = briefingContent.slice(0, 500);
|
|
103610
|
+
const truncatedBriefing = sanitizeContextText(briefingContent).slice(0, 500);
|
|
103587
103611
|
freshPreamble = freshPreamble ? `<curator_briefing>${truncatedBriefing}</curator_briefing>
|
|
103588
103612
|
|
|
103589
103613
|
${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
|
|
@@ -103614,8 +103638,9 @@ ${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
|
|
|
103614
103638
|
remaining -= lessonBlock.length;
|
|
103615
103639
|
}
|
|
103616
103640
|
if (runMemory && remaining > 300) {
|
|
103617
|
-
|
|
103618
|
-
|
|
103641
|
+
const sanitizedRunMemory = sanitizeContextText(runMemory);
|
|
103642
|
+
parts2.push(sanitizedRunMemory);
|
|
103643
|
+
remaining -= sanitizedRunMemory.length;
|
|
103619
103644
|
}
|
|
103620
103645
|
if (freshPreamble && remaining > 200) {
|
|
103621
103646
|
let preambleToUse = freshPreamble;
|
|
@@ -113186,9 +113211,17 @@ var knowledge_remove = createSwarmTool({
|
|
|
113186
113211
|
}
|
|
113187
113212
|
const id = idInput;
|
|
113188
113213
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
113189
|
-
let
|
|
113214
|
+
let found = false;
|
|
113215
|
+
let remaining = 0;
|
|
113190
113216
|
try {
|
|
113191
|
-
|
|
113217
|
+
await transactKnowledge(swarmPath, (entries) => {
|
|
113218
|
+
const filtered = entries.filter((entry) => entry.id !== id);
|
|
113219
|
+
if (filtered.length === entries.length)
|
|
113220
|
+
return null;
|
|
113221
|
+
found = true;
|
|
113222
|
+
remaining = filtered.length;
|
|
113223
|
+
return filtered;
|
|
113224
|
+
});
|
|
113192
113225
|
} catch (err2) {
|
|
113193
113226
|
const message = err2 instanceof Error ? err2.message : "Unknown error";
|
|
113194
113227
|
return JSON.stringify({
|
|
@@ -113196,27 +113229,16 @@ var knowledge_remove = createSwarmTool({
|
|
|
113196
113229
|
error: message
|
|
113197
113230
|
});
|
|
113198
113231
|
}
|
|
113199
|
-
|
|
113200
|
-
entries = entries.filter((entry) => entry.id !== id);
|
|
113201
|
-
if (entries.length === originalCount) {
|
|
113232
|
+
if (!found) {
|
|
113202
113233
|
return JSON.stringify({
|
|
113203
113234
|
success: false,
|
|
113204
113235
|
message: "entry not found"
|
|
113205
113236
|
});
|
|
113206
113237
|
}
|
|
113207
|
-
try {
|
|
113208
|
-
await rewriteKnowledge(swarmPath, entries);
|
|
113209
|
-
} catch (err2) {
|
|
113210
|
-
const message = err2 instanceof Error ? err2.message : "Unknown error";
|
|
113211
|
-
return JSON.stringify({
|
|
113212
|
-
success: false,
|
|
113213
|
-
error: message
|
|
113214
|
-
});
|
|
113215
|
-
}
|
|
113216
113238
|
return JSON.stringify({
|
|
113217
113239
|
success: true,
|
|
113218
113240
|
removed: 1,
|
|
113219
|
-
remaining
|
|
113241
|
+
remaining
|
|
113220
113242
|
});
|
|
113221
113243
|
}
|
|
113222
113244
|
});
|
|
@@ -125063,7 +125085,7 @@ init_zod();
|
|
|
125063
125085
|
init_config();
|
|
125064
125086
|
init_schema();
|
|
125065
125087
|
init_create_tool();
|
|
125066
|
-
import { mkdir as
|
|
125088
|
+
import { mkdir as mkdir23, rename as rename10, writeFile as writeFile16 } from "node:fs/promises";
|
|
125067
125089
|
import * as path152 from "node:path";
|
|
125068
125090
|
var MAX_SPEC_BYTES = 256 * 1024;
|
|
125069
125091
|
var spec_write = createSwarmTool({
|
|
@@ -125106,7 +125128,7 @@ var spec_write = createSwarmTool({
|
|
|
125106
125128
|
}, null, 2);
|
|
125107
125129
|
}
|
|
125108
125130
|
const target = path152.join(directory, ".swarm", "spec.md");
|
|
125109
|
-
await
|
|
125131
|
+
await mkdir23(path152.dirname(target), { recursive: true });
|
|
125110
125132
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
125111
125133
|
let finalContent = content;
|
|
125112
125134
|
if (mode === "append") {
|
|
@@ -125125,7 +125147,7 @@ ${content}
|
|
|
125125
125147
|
}
|
|
125126
125148
|
} catch {}
|
|
125127
125149
|
}
|
|
125128
|
-
await
|
|
125150
|
+
await writeFile16(tmp, finalContent, "utf-8");
|
|
125129
125151
|
await rename10(tmp, target);
|
|
125130
125152
|
return JSON.stringify({ written: true, path: target, bytes: finalContent.length }, null, 2);
|
|
125131
125153
|
}
|
|
@@ -127798,7 +127820,7 @@ function createWebSearchProvider(config3) {
|
|
|
127798
127820
|
init_utils2();
|
|
127799
127821
|
init_redaction();
|
|
127800
127822
|
import { createHash as createHash12 } from "node:crypto";
|
|
127801
|
-
import { appendFile as appendFile14, mkdir as
|
|
127823
|
+
import { appendFile as appendFile14, mkdir as mkdir24 } from "node:fs/promises";
|
|
127802
127824
|
import * as path161 from "node:path";
|
|
127803
127825
|
var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
|
|
127804
127826
|
var MAX_EVIDENCE_TEXT_LENGTH = 4000;
|
|
@@ -127807,7 +127829,7 @@ async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
|
127807
127829
|
const capturedAt = now().toISOString();
|
|
127808
127830
|
const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
|
|
127809
127831
|
if (records.length > 0) {
|
|
127810
|
-
await
|
|
127832
|
+
await mkdir24(path161.dirname(filePath), { recursive: true });
|
|
127811
127833
|
await appendFile14(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
|
|
127812
127834
|
`)}
|
|
127813
127835
|
`, "utf-8");
|