opencode-swarm 7.51.2 → 7.51.4
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 +82 -51
- 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 +304 -274
- package/dist/lang/runtime.d.ts +8 -0
- package/package.json +1 -1
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.4",
|
|
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",
|
|
@@ -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
|
}
|
|
@@ -91100,6 +91101,7 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
91100
91101
|
// src/lang/runtime.ts
|
|
91101
91102
|
var exports_runtime = {};
|
|
91102
91103
|
__export(exports_runtime, {
|
|
91104
|
+
resolveGrammarsDir: () => resolveGrammarsDir,
|
|
91103
91105
|
parserCache: () => parserCache,
|
|
91104
91106
|
loadGrammar: () => loadGrammar,
|
|
91105
91107
|
isGrammarAvailable: () => isGrammarAvailable,
|
|
@@ -91146,13 +91148,16 @@ function getWasmFileName(languageId) {
|
|
|
91146
91148
|
}
|
|
91147
91149
|
return `tree-sitter-${sanitized}.wasm`;
|
|
91148
91150
|
}
|
|
91149
|
-
function
|
|
91150
|
-
const thisDir = path92.dirname(fileURLToPath4(import.meta.url));
|
|
91151
|
+
function resolveGrammarsDir(thisDir) {
|
|
91151
91152
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
91152
91153
|
const isSource = normalized.endsWith("/src/lang");
|
|
91153
91154
|
const isCliBundle = normalized.endsWith("/cli");
|
|
91154
91155
|
return isSource ? path92.join(thisDir, "grammars") : isCliBundle ? path92.join(thisDir, "..", "lang", "grammars") : path92.join(thisDir, "lang", "grammars");
|
|
91155
91156
|
}
|
|
91157
|
+
function getGrammarsDirAbsolute() {
|
|
91158
|
+
const thisDir = path92.dirname(fileURLToPath4(import.meta.url));
|
|
91159
|
+
return resolveGrammarsDir(thisDir);
|
|
91160
|
+
}
|
|
91156
91161
|
async function loadGrammar(languageId) {
|
|
91157
91162
|
if (typeof languageId !== "string" || languageId.length > 100) {
|
|
91158
91163
|
throw new Error(`Invalid languageId: must be a string of at most 100 characters`);
|
|
@@ -91269,7 +91274,7 @@ import {
|
|
|
91269
91274
|
readFile as readFile16,
|
|
91270
91275
|
realpath as realpath3,
|
|
91271
91276
|
stat as stat7,
|
|
91272
|
-
writeFile as
|
|
91277
|
+
writeFile as writeFile12
|
|
91273
91278
|
} from "node:fs/promises";
|
|
91274
91279
|
import * as path94 from "node:path";
|
|
91275
91280
|
function normalizeSeparators(filePath) {
|
|
@@ -91467,7 +91472,7 @@ async function scanDocIndex(directory) {
|
|
|
91467
91472
|
};
|
|
91468
91473
|
try {
|
|
91469
91474
|
await mkdir16(path94.dirname(manifestPath), { recursive: true });
|
|
91470
|
-
await
|
|
91475
|
+
await writeFile12(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
91471
91476
|
} catch {}
|
|
91472
91477
|
return { manifest, cached: false };
|
|
91473
91478
|
}
|
|
@@ -91681,7 +91686,7 @@ var init_doc_scan = __esm(() => {
|
|
|
91681
91686
|
|
|
91682
91687
|
// src/hooks/knowledge-reader.ts
|
|
91683
91688
|
import { existsSync as existsSync51 } from "node:fs";
|
|
91684
|
-
import {
|
|
91689
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
91685
91690
|
import * as path95 from "node:path";
|
|
91686
91691
|
function inferCategoriesFromPhase(phaseDescription) {
|
|
91687
91692
|
const lower = phaseDescription.toLowerCase();
|
|
@@ -91726,19 +91731,32 @@ function inferCategoriesFromPhase(phaseDescription) {
|
|
|
91726
91731
|
}
|
|
91727
91732
|
return ["process", "tooling"];
|
|
91728
91733
|
}
|
|
91734
|
+
async function transactShownFile(shownFile, mutate) {
|
|
91735
|
+
return transactFile(shownFile, async (filePath) => {
|
|
91736
|
+
if (!existsSync51(filePath))
|
|
91737
|
+
return {};
|
|
91738
|
+
try {
|
|
91739
|
+
const content = await readFile17(filePath, "utf-8");
|
|
91740
|
+
return JSON.parse(content);
|
|
91741
|
+
} catch {
|
|
91742
|
+
return {};
|
|
91743
|
+
}
|
|
91744
|
+
}, async (filePath, data) => {
|
|
91745
|
+
await atomicWriteFile(filePath, JSON.stringify(data, null, 2));
|
|
91746
|
+
}, mutate);
|
|
91747
|
+
}
|
|
91729
91748
|
async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
91730
91749
|
const shownFile = path95.join(directory, ".swarm", ".knowledge-shown.json");
|
|
91731
91750
|
try {
|
|
91732
|
-
let shownData = {};
|
|
91733
|
-
if (existsSync51(shownFile)) {
|
|
91734
|
-
const content = await readFile17(shownFile, "utf-8");
|
|
91735
|
-
shownData = JSON.parse(content);
|
|
91736
|
-
}
|
|
91737
91751
|
const phaseMatch = /^Phase\s+(\d+)/i.exec(currentPhase);
|
|
91738
91752
|
const canonicalKey = phaseMatch ? `Phase ${phaseMatch[1]}` : currentPhase;
|
|
91739
|
-
|
|
91740
|
-
|
|
91741
|
-
|
|
91753
|
+
const ok = await transactShownFile(shownFile, (shownData) => {
|
|
91754
|
+
shownData[canonicalKey] = lessonIds;
|
|
91755
|
+
return shownData;
|
|
91756
|
+
});
|
|
91757
|
+
if (!ok) {
|
|
91758
|
+
warn("[swarm] Knowledge: failed to record shown lessons");
|
|
91759
|
+
}
|
|
91742
91760
|
} catch {
|
|
91743
91761
|
warn("[swarm] Knowledge: failed to record shown lessons");
|
|
91744
91762
|
}
|
|
@@ -91843,56 +91861,58 @@ async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
|
91843
91861
|
if (!existsSync51(shownFile)) {
|
|
91844
91862
|
return;
|
|
91845
91863
|
}
|
|
91846
|
-
|
|
91847
|
-
|
|
91848
|
-
|
|
91864
|
+
let shownIds;
|
|
91865
|
+
try {
|
|
91866
|
+
const content = await readFile17(shownFile, "utf-8");
|
|
91867
|
+
const shownData = JSON.parse(content);
|
|
91868
|
+
shownIds = shownData[phaseInfo];
|
|
91869
|
+
} catch {
|
|
91870
|
+
return;
|
|
91871
|
+
}
|
|
91849
91872
|
if (!shownIds || shownIds.length === 0) {
|
|
91850
91873
|
return;
|
|
91851
91874
|
}
|
|
91852
91875
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
91853
|
-
const entries = await readKnowledge(swarmPath);
|
|
91854
|
-
let updated = false;
|
|
91855
91876
|
const foundInSwarm = new Set;
|
|
91856
|
-
|
|
91857
|
-
|
|
91858
|
-
|
|
91859
|
-
if (
|
|
91860
|
-
ro
|
|
91861
|
-
|
|
91862
|
-
|
|
91877
|
+
await transactKnowledge(swarmPath, (entries) => {
|
|
91878
|
+
let mutated = false;
|
|
91879
|
+
for (const entry of entries) {
|
|
91880
|
+
if (shownIds.includes(entry.id)) {
|
|
91881
|
+
const ro = entry.retrieval_outcomes;
|
|
91882
|
+
if (phaseSucceeded) {
|
|
91883
|
+
ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
|
|
91884
|
+
} else {
|
|
91885
|
+
ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
|
|
91886
|
+
}
|
|
91887
|
+
mutated = true;
|
|
91888
|
+
foundInSwarm.add(entry.id);
|
|
91863
91889
|
}
|
|
91864
|
-
updated = true;
|
|
91865
|
-
foundInSwarm.add(entry.id);
|
|
91866
91890
|
}
|
|
91867
|
-
|
|
91868
|
-
|
|
91869
|
-
await rewriteKnowledge(swarmPath, entries);
|
|
91870
|
-
}
|
|
91891
|
+
return mutated ? entries : null;
|
|
91892
|
+
});
|
|
91871
91893
|
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;
|
|
91894
|
+
if (remainingIds.length > 0) {
|
|
91895
|
+
const hivePath = resolveHiveKnowledgePath();
|
|
91896
|
+
await transactKnowledge(hivePath, (hiveEntries) => {
|
|
91897
|
+
let mutated = false;
|
|
91898
|
+
for (const entry of hiveEntries) {
|
|
91899
|
+
if (remainingIds.includes(entry.id)) {
|
|
91900
|
+
const ro = entry.retrieval_outcomes;
|
|
91901
|
+
if (phaseSucceeded) {
|
|
91902
|
+
ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
|
|
91903
|
+
} else {
|
|
91904
|
+
ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
|
|
91905
|
+
}
|
|
91906
|
+
mutated = true;
|
|
91907
|
+
}
|
|
91887
91908
|
}
|
|
91888
|
-
|
|
91889
|
-
}
|
|
91890
|
-
}
|
|
91891
|
-
if (hiveUpdated) {
|
|
91892
|
-
await rewriteKnowledge(hivePath, hiveEntries);
|
|
91909
|
+
return mutated ? hiveEntries : null;
|
|
91910
|
+
});
|
|
91893
91911
|
}
|
|
91894
|
-
|
|
91895
|
-
|
|
91912
|
+
await transactShownFile(shownFile, (data) => {
|
|
91913
|
+
delete data[phaseInfo];
|
|
91914
|
+
return data;
|
|
91915
|
+
});
|
|
91896
91916
|
} catch {
|
|
91897
91917
|
warn("[swarm] Knowledge: failed to update retrieval outcomes");
|
|
91898
91918
|
}
|
|
@@ -91956,6 +91976,7 @@ function scoreDirectiveAgainstContext(entry, ctx) {
|
|
|
91956
91976
|
}
|
|
91957
91977
|
var JACCARD_THRESHOLD2 = 0.6, HIVE_TIER_BOOST = 0.05, SAME_PROJECT_PENALTY = -0.05, NORMAL_RETRIEVAL_STATUSES;
|
|
91958
91978
|
var init_knowledge_reader = __esm(() => {
|
|
91979
|
+
init_task_file();
|
|
91959
91980
|
init_logger();
|
|
91960
91981
|
init_knowledge_store();
|
|
91961
91982
|
NORMAL_RETRIEVAL_STATUSES = new Set(["established", "promoted"]);
|
|
@@ -95318,9 +95339,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner, dele
|
|
|
95318
95339
|
const initResult = await runner(directory, curatorConfig, llmDelegate);
|
|
95319
95340
|
if (initResult.briefing) {
|
|
95320
95341
|
const briefingPath = path78.join(directory, ".swarm", "curator-briefing.md");
|
|
95321
|
-
const { mkdir: mkdir14, writeFile:
|
|
95342
|
+
const { mkdir: mkdir14, writeFile: writeFile11 } = await import("node:fs/promises");
|
|
95322
95343
|
await mkdir14(path78.dirname(briefingPath), { recursive: true });
|
|
95323
|
-
await
|
|
95344
|
+
await writeFile11(briefingPath, initResult.briefing, "utf-8");
|
|
95324
95345
|
const { buildApprovedReceipt: buildApprovedReceipt2, persistReviewReceipt: persistReviewReceipt2 } = await Promise.resolve().then(() => (init_review_receipt(), exports_review_receipt));
|
|
95325
95346
|
const initReceipt = buildApprovedReceipt2({
|
|
95326
95347
|
agent: "curator",
|
|
@@ -99971,6 +99992,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
99971
99992
|
let tryInject = function(text) {
|
|
99972
99993
|
const tokens = estimateTokens(text);
|
|
99973
99994
|
if (injectedTokens + tokens > maxInjectionTokens) {
|
|
99995
|
+
warn(`system-enhancer: injection budget exceeded (${injectedTokens + tokens} > ${maxInjectionTokens} tokens) — truncating system prompt content`);
|
|
99974
99996
|
return;
|
|
99975
99997
|
}
|
|
99976
99998
|
output.system.push(text);
|
|
@@ -102948,7 +102970,7 @@ ${errorSummary}`);
|
|
|
102948
102970
|
init_schema();
|
|
102949
102971
|
init_state();
|
|
102950
102972
|
init_logger();
|
|
102951
|
-
import { appendFile as appendFile10, mkdir as
|
|
102973
|
+
import { appendFile as appendFile10, mkdir as mkdir18 } from "node:fs/promises";
|
|
102952
102974
|
import * as path100 from "node:path";
|
|
102953
102975
|
|
|
102954
102976
|
// src/hooks/knowledge-application.ts
|
|
@@ -102956,7 +102978,7 @@ init_logger();
|
|
|
102956
102978
|
init_knowledge_store();
|
|
102957
102979
|
var import_proper_lockfile8 = __toESM(require_proper_lockfile(), 1);
|
|
102958
102980
|
import { existsSync as existsSync55 } from "node:fs";
|
|
102959
|
-
import { appendFile as appendFile9, mkdir as
|
|
102981
|
+
import { appendFile as appendFile9, mkdir as mkdir17, readFile as readFile18 } from "node:fs/promises";
|
|
102960
102982
|
import * as path99 from "node:path";
|
|
102961
102983
|
function resolveApplicationLogPath(directory) {
|
|
102962
102984
|
return path99.join(directory, ".swarm", "knowledge-application.jsonl");
|
|
@@ -102977,7 +102999,7 @@ function parseAcknowledgments(text) {
|
|
|
102977
102999
|
}
|
|
102978
103000
|
async function appendAudit(directory, record3) {
|
|
102979
103001
|
const filePath = resolveApplicationLogPath(directory);
|
|
102980
|
-
await
|
|
103002
|
+
await mkdir17(path99.dirname(filePath), { recursive: true });
|
|
102981
103003
|
await appendFile9(filePath, `${JSON.stringify(record3)}
|
|
102982
103004
|
`, "utf-8");
|
|
102983
103005
|
}
|
|
@@ -103158,7 +103180,7 @@ async function knowledgeApplicationGateBefore(directory, input, config3) {
|
|
|
103158
103180
|
}
|
|
103159
103181
|
async function writeWarnEvent(directory, record3) {
|
|
103160
103182
|
const filePath = path100.join(directory, ".swarm", "events.jsonl");
|
|
103161
|
-
await
|
|
103183
|
+
await mkdir18(path100.dirname(filePath), { recursive: true });
|
|
103162
103184
|
await appendFile10(filePath, `${JSON.stringify(record3)}
|
|
103163
103185
|
`, "utf-8");
|
|
103164
103186
|
}
|
|
@@ -103214,10 +103236,20 @@ init_manager();
|
|
|
103214
103236
|
import { createHash as createHash9 } from "node:crypto";
|
|
103215
103237
|
|
|
103216
103238
|
// src/services/run-memory.ts
|
|
103217
|
-
init_utils2();
|
|
103218
|
-
init_path_security();
|
|
103219
103239
|
import * as crypto10 from "node:crypto";
|
|
103220
103240
|
import * as fs63 from "node:fs/promises";
|
|
103241
|
+
|
|
103242
|
+
// src/hooks/context-sanitizer.ts
|
|
103243
|
+
function sanitizeContextText(text) {
|
|
103244
|
+
return text.split("").filter((char) => {
|
|
103245
|
+
const code = char.charCodeAt(0);
|
|
103246
|
+
return code === 9 || code === 10 || code === 13 || code > 31 && code !== 127;
|
|
103247
|
+
}).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]");
|
|
103248
|
+
}
|
|
103249
|
+
|
|
103250
|
+
// src/services/run-memory.ts
|
|
103251
|
+
init_utils2();
|
|
103252
|
+
init_path_security();
|
|
103221
103253
|
var RUN_MEMORY_FILENAME = "run-memory.jsonl";
|
|
103222
103254
|
var MAX_SUMMARY_TOKENS = 500;
|
|
103223
103255
|
function generateTaskFingerprint(taskId, fileTargets) {
|
|
@@ -103297,9 +103329,11 @@ function summarizeTask(taskId, entries) {
|
|
|
103297
103329
|
if (lastPass) {
|
|
103298
103330
|
const passAttempt = lastPass.attemptNumber;
|
|
103299
103331
|
const failAttempt = lastFailure.attemptNumber;
|
|
103300
|
-
|
|
103332
|
+
const reason = sanitizeContextText(lastFailure.failureReason || "unknown");
|
|
103333
|
+
return `Task ${taskId}: FAILED attempt ${failAttempt} — ${reason}. Passed on attempt ${passAttempt}.`;
|
|
103301
103334
|
} else {
|
|
103302
|
-
|
|
103335
|
+
const reason = sanitizeContextText(lastFailure.failureReason || "unknown");
|
|
103336
|
+
return `Task ${taskId}: FAILED ${failCount} times — last: ${reason}. Still failing.`;
|
|
103303
103337
|
}
|
|
103304
103338
|
}
|
|
103305
103339
|
async function getRunMemorySummary(directory) {
|
|
@@ -103458,12 +103492,7 @@ function buildDirectiveBlock(entries, charBudget, cfg) {
|
|
|
103458
103492
|
return null;
|
|
103459
103493
|
return block;
|
|
103460
103494
|
}
|
|
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
|
-
}
|
|
103495
|
+
var sanitizeLessonForContext = sanitizeContextText;
|
|
103467
103496
|
function isOrchestratorAgent(agentName) {
|
|
103468
103497
|
const stripped = stripKnownSwarmPrefix(agentName);
|
|
103469
103498
|
return stripped.toLowerCase() === "architect";
|
|
@@ -103576,14 +103605,14 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
103576
103605
|
const latestReport = driftReports[driftReports.length - 1];
|
|
103577
103606
|
const driftText = buildDriftInjectionText(latestReport, 500);
|
|
103578
103607
|
if (driftText) {
|
|
103579
|
-
freshPreamble = driftText;
|
|
103608
|
+
freshPreamble = sanitizeContextText(driftText);
|
|
103580
103609
|
}
|
|
103581
103610
|
}
|
|
103582
103611
|
} catch {}
|
|
103583
103612
|
try {
|
|
103584
103613
|
const briefingContent = await readSwarmFileAsync(directory, "curator-briefing.md");
|
|
103585
103614
|
if (briefingContent) {
|
|
103586
|
-
const truncatedBriefing = briefingContent.slice(0, 500);
|
|
103615
|
+
const truncatedBriefing = sanitizeContextText(briefingContent).slice(0, 500);
|
|
103587
103616
|
freshPreamble = freshPreamble ? `<curator_briefing>${truncatedBriefing}</curator_briefing>
|
|
103588
103617
|
|
|
103589
103618
|
${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
|
|
@@ -103614,8 +103643,9 @@ ${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
|
|
|
103614
103643
|
remaining -= lessonBlock.length;
|
|
103615
103644
|
}
|
|
103616
103645
|
if (runMemory && remaining > 300) {
|
|
103617
|
-
|
|
103618
|
-
|
|
103646
|
+
const sanitizedRunMemory = sanitizeContextText(runMemory);
|
|
103647
|
+
parts2.push(sanitizedRunMemory);
|
|
103648
|
+
remaining -= sanitizedRunMemory.length;
|
|
103619
103649
|
}
|
|
103620
103650
|
if (freshPreamble && remaining > 200) {
|
|
103621
103651
|
let preambleToUse = freshPreamble;
|
|
@@ -112519,6 +112549,7 @@ init_config();
|
|
|
112519
112549
|
init_knowledge_store();
|
|
112520
112550
|
init_knowledge_validator();
|
|
112521
112551
|
init_manager();
|
|
112552
|
+
init_utils();
|
|
112522
112553
|
init_create_tool();
|
|
112523
112554
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
112524
112555
|
var VALID_CATEGORIES2 = [
|
|
@@ -112641,7 +112672,9 @@ var knowledge_add = createSwarmTool({
|
|
|
112641
112672
|
message: "near-duplicate of existing entry"
|
|
112642
112673
|
});
|
|
112643
112674
|
}
|
|
112644
|
-
} catch {
|
|
112675
|
+
} catch (err2) {
|
|
112676
|
+
warn("knowledge_add: dedup check failed — skipping near-duplicate detection", err2);
|
|
112677
|
+
}
|
|
112645
112678
|
try {
|
|
112646
112679
|
await appendKnowledge(resolveSwarmKnowledgePath(directory), entry);
|
|
112647
112680
|
} catch (err2) {
|
|
@@ -113186,9 +113219,17 @@ var knowledge_remove = createSwarmTool({
|
|
|
113186
113219
|
}
|
|
113187
113220
|
const id = idInput;
|
|
113188
113221
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
113189
|
-
let
|
|
113222
|
+
let found = false;
|
|
113223
|
+
let remaining = 0;
|
|
113190
113224
|
try {
|
|
113191
|
-
|
|
113225
|
+
await transactKnowledge(swarmPath, (entries) => {
|
|
113226
|
+
const filtered = entries.filter((entry) => entry.id !== id);
|
|
113227
|
+
if (filtered.length === entries.length)
|
|
113228
|
+
return null;
|
|
113229
|
+
found = true;
|
|
113230
|
+
remaining = filtered.length;
|
|
113231
|
+
return filtered;
|
|
113232
|
+
});
|
|
113192
113233
|
} catch (err2) {
|
|
113193
113234
|
const message = err2 instanceof Error ? err2.message : "Unknown error";
|
|
113194
113235
|
return JSON.stringify({
|
|
@@ -113196,27 +113237,16 @@ var knowledge_remove = createSwarmTool({
|
|
|
113196
113237
|
error: message
|
|
113197
113238
|
});
|
|
113198
113239
|
}
|
|
113199
|
-
|
|
113200
|
-
entries = entries.filter((entry) => entry.id !== id);
|
|
113201
|
-
if (entries.length === originalCount) {
|
|
113240
|
+
if (!found) {
|
|
113202
113241
|
return JSON.stringify({
|
|
113203
113242
|
success: false,
|
|
113204
113243
|
message: "entry not found"
|
|
113205
113244
|
});
|
|
113206
113245
|
}
|
|
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
113246
|
return JSON.stringify({
|
|
113217
113247
|
success: true,
|
|
113218
113248
|
removed: 1,
|
|
113219
|
-
remaining
|
|
113249
|
+
remaining
|
|
113220
113250
|
});
|
|
113221
113251
|
}
|
|
113222
113252
|
});
|
|
@@ -125063,7 +125093,7 @@ init_zod();
|
|
|
125063
125093
|
init_config();
|
|
125064
125094
|
init_schema();
|
|
125065
125095
|
init_create_tool();
|
|
125066
|
-
import { mkdir as
|
|
125096
|
+
import { mkdir as mkdir23, rename as rename10, writeFile as writeFile16 } from "node:fs/promises";
|
|
125067
125097
|
import * as path152 from "node:path";
|
|
125068
125098
|
var MAX_SPEC_BYTES = 256 * 1024;
|
|
125069
125099
|
var spec_write = createSwarmTool({
|
|
@@ -125106,7 +125136,7 @@ var spec_write = createSwarmTool({
|
|
|
125106
125136
|
}, null, 2);
|
|
125107
125137
|
}
|
|
125108
125138
|
const target = path152.join(directory, ".swarm", "spec.md");
|
|
125109
|
-
await
|
|
125139
|
+
await mkdir23(path152.dirname(target), { recursive: true });
|
|
125110
125140
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
125111
125141
|
let finalContent = content;
|
|
125112
125142
|
if (mode === "append") {
|
|
@@ -125125,7 +125155,7 @@ ${content}
|
|
|
125125
125155
|
}
|
|
125126
125156
|
} catch {}
|
|
125127
125157
|
}
|
|
125128
|
-
await
|
|
125158
|
+
await writeFile16(tmp, finalContent, "utf-8");
|
|
125129
125159
|
await rename10(tmp, target);
|
|
125130
125160
|
return JSON.stringify({ written: true, path: target, bytes: finalContent.length }, null, 2);
|
|
125131
125161
|
}
|
|
@@ -127798,7 +127828,7 @@ function createWebSearchProvider(config3) {
|
|
|
127798
127828
|
init_utils2();
|
|
127799
127829
|
init_redaction();
|
|
127800
127830
|
import { createHash as createHash12 } from "node:crypto";
|
|
127801
|
-
import { appendFile as appendFile14, mkdir as
|
|
127831
|
+
import { appendFile as appendFile14, mkdir as mkdir24 } from "node:fs/promises";
|
|
127802
127832
|
import * as path161 from "node:path";
|
|
127803
127833
|
var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
|
|
127804
127834
|
var MAX_EVIDENCE_TEXT_LENGTH = 4000;
|
|
@@ -127807,7 +127837,7 @@ async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
|
127807
127837
|
const capturedAt = now().toISOString();
|
|
127808
127838
|
const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
|
|
127809
127839
|
if (records.length > 0) {
|
|
127810
|
-
await
|
|
127840
|
+
await mkdir24(path161.dirname(filePath), { recursive: true });
|
|
127811
127841
|
await appendFile14(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
|
|
127812
127842
|
`)}
|
|
127813
127843
|
`, "utf-8");
|