opencode-swarm 7.74.0 → 7.74.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +474 -192
- package/dist/config/schema.d.ts +14 -0
- package/dist/hooks/knowledge-application.d.ts +1 -0
- package/dist/hooks/knowledge-curator.d.ts +7 -2
- package/dist/hooks/knowledge-events.d.ts +16 -9
- package/dist/hooks/knowledge-injector.d.ts +1 -1
- package/dist/hooks/knowledge-reader.d.ts +1 -0
- package/dist/hooks/knowledge-store.d.ts +3 -0
- package/dist/hooks/knowledge-types.d.ts +5 -0
- package/dist/hooks/knowledge-validator.d.ts +5 -6
- package/dist/hooks/micro-reflector.d.ts +2 -1
- package/dist/hooks/skill-scoring.d.ts +1 -1
- package/dist/hooks/skill-usage-log.d.ts +7 -2
- package/dist/index.js +684 -309
- package/dist/services/external-skill-validator.d.ts +3 -0
- package/dist/services/skill-generator.d.ts +5 -0
- package/dist/services/skill-improver-quota.d.ts +6 -4
- package/dist/services/skill-improver.d.ts +6 -2
- package/dist/services/unactionable-hardening.d.ts +2 -2
- package/package.json +1 -1
- package/dist/skills/index.d.ts +0 -30
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.74.
|
|
72
|
+
version: "7.74.1",
|
|
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",
|
|
@@ -648,7 +648,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
648
648
|
agents: ["architect", "coder"]
|
|
649
649
|
},
|
|
650
650
|
knowledge_archive: {
|
|
651
|
-
description: "archive (default), quarantine, or purge a swarm knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",
|
|
651
|
+
description: "archive (default), quarantine, or purge a swarm or hive knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",
|
|
652
652
|
agents: ["architect"]
|
|
653
653
|
},
|
|
654
654
|
swarm_memory_recall: {
|
|
@@ -15921,7 +15921,11 @@ var init_schema = __esm(() => {
|
|
|
15921
15921
|
cold_start_max_age_phases: exports_external.number().int().min(0).max(100).default(3),
|
|
15922
15922
|
synonym_min_cooccurrence: exports_external.number().int().min(1).max(100).default(3),
|
|
15923
15923
|
synonym_map_max_pairs: exports_external.number().int().min(1).max(1e4).default(500)
|
|
15924
|
-
}).optional()
|
|
15924
|
+
}).optional(),
|
|
15925
|
+
enrichment: exports_external.object({
|
|
15926
|
+
max_calls_per_day: exports_external.number().int().min(0).max(1000).default(30),
|
|
15927
|
+
quota_window: exports_external.enum(["utc", "local"]).default("utc")
|
|
15928
|
+
}).default({ max_calls_per_day: 30, quota_window: "utc" })
|
|
15925
15929
|
});
|
|
15926
15930
|
MemoryConfigSchema = exports_external.object({
|
|
15927
15931
|
enabled: exports_external.boolean().default(false),
|
|
@@ -15988,7 +15992,7 @@ var init_schema = __esm(() => {
|
|
|
15988
15992
|
llm_timeout_ms: exports_external.number().int().min(5000).max(600000).default(300000),
|
|
15989
15993
|
skill_generation_enabled: exports_external.boolean().default(true),
|
|
15990
15994
|
skill_generation_mode: exports_external.enum(["draft", "active"]).default("draft"),
|
|
15991
|
-
min_skill_confidence: exports_external.number().min(0).max(1).default(0.
|
|
15995
|
+
min_skill_confidence: exports_external.number().min(0).max(1).default(0.7),
|
|
15992
15996
|
min_skill_confirmations: exports_external.number().int().min(1).max(50).default(2)
|
|
15993
15997
|
});
|
|
15994
15998
|
ArchitecturalSupervisionConfigSchema = exports_external.object({
|
|
@@ -59523,7 +59527,7 @@ async function appendKnowledgeWithCapEnforcement(filePath, entry, maxEntries) {
|
|
|
59523
59527
|
return transactKnowledge(filePath, (entries) => {
|
|
59524
59528
|
const updated = [...entries, entry];
|
|
59525
59529
|
if (updated.length > maxEntries) {
|
|
59526
|
-
return
|
|
59530
|
+
return selectKnowledgeCapSurvivors(updated, maxEntries);
|
|
59527
59531
|
}
|
|
59528
59532
|
return updated;
|
|
59529
59533
|
});
|
|
@@ -59532,9 +59536,46 @@ async function enforceKnowledgeCap(filePath, maxEntries) {
|
|
|
59532
59536
|
await transactKnowledge(filePath, (entries) => {
|
|
59533
59537
|
if (entries.length <= maxEntries)
|
|
59534
59538
|
return null;
|
|
59535
|
-
return
|
|
59539
|
+
return selectKnowledgeCapSurvivors(entries, maxEntries);
|
|
59536
59540
|
});
|
|
59537
59541
|
}
|
|
59542
|
+
function selectKnowledgeCapSurvivors(entries, maxEntries) {
|
|
59543
|
+
if (entries.length <= maxEntries)
|
|
59544
|
+
return entries;
|
|
59545
|
+
if (maxEntries <= 0)
|
|
59546
|
+
return [];
|
|
59547
|
+
const candidates = entries.map((entry, index) => {
|
|
59548
|
+
const maybeKnowledge = entry;
|
|
59549
|
+
return {
|
|
59550
|
+
entry,
|
|
59551
|
+
index,
|
|
59552
|
+
status: maybeKnowledge.status,
|
|
59553
|
+
outcomeSignal: computeOutcomeSignal(maybeKnowledge.retrieval_outcomes)
|
|
59554
|
+
};
|
|
59555
|
+
});
|
|
59556
|
+
const allPromoted = candidates.every((c) => c.status === "promoted");
|
|
59557
|
+
const evictable = allPromoted ? candidates : candidates.filter((c) => c.status !== "promoted");
|
|
59558
|
+
const targetDropCount = entries.length - maxEntries;
|
|
59559
|
+
const dropCount = Math.min(targetDropCount, evictable.length);
|
|
59560
|
+
if (dropCount <= 0)
|
|
59561
|
+
return entries;
|
|
59562
|
+
const drop = new Set([...evictable].sort((a, b) => {
|
|
59563
|
+
const inactiveDelta = getKnowledgeCapStatusPriority(a.status) - getKnowledgeCapStatusPriority(b.status);
|
|
59564
|
+
if (inactiveDelta !== 0)
|
|
59565
|
+
return inactiveDelta;
|
|
59566
|
+
const signalDelta = a.outcomeSignal - b.outcomeSignal;
|
|
59567
|
+
if (signalDelta !== 0)
|
|
59568
|
+
return signalDelta;
|
|
59569
|
+
return a.index - b.index;
|
|
59570
|
+
}).slice(0, dropCount).map((c) => c.index));
|
|
59571
|
+
return candidates.filter((c) => !drop.has(c.index)).map((c) => c.entry);
|
|
59572
|
+
}
|
|
59573
|
+
function getKnowledgeCapStatusPriority(status) {
|
|
59574
|
+
if (status === "archived" || status === "quarantined" || status === "quarantined_unactionable") {
|
|
59575
|
+
return 0;
|
|
59576
|
+
}
|
|
59577
|
+
return 1;
|
|
59578
|
+
}
|
|
59538
59579
|
async function sweepAgedEntries(filePath, defaultMaxPhases) {
|
|
59539
59580
|
const result = {
|
|
59540
59581
|
scanned: 0,
|
|
@@ -59770,6 +59811,7 @@ var init_knowledge_store = __esm(() => {
|
|
|
59770
59811
|
findNearDuplicate,
|
|
59771
59812
|
computeConfidence,
|
|
59772
59813
|
computeOutcomeSignal,
|
|
59814
|
+
selectKnowledgeCapSurvivors,
|
|
59773
59815
|
inferTags,
|
|
59774
59816
|
bumpKnowledgeConfidenceBatch
|
|
59775
59817
|
};
|
|
@@ -59780,6 +59822,7 @@ var exports_knowledge_events = {};
|
|
|
59780
59822
|
__export(exports_knowledge_events, {
|
|
59781
59823
|
resolveLegacyApplicationLogPath: () => resolveLegacyApplicationLogPath,
|
|
59782
59824
|
resolveKnowledgeEventsPath: () => resolveKnowledgeEventsPath,
|
|
59825
|
+
resolveKnowledgeCounterBaselinePath: () => resolveKnowledgeCounterBaselinePath,
|
|
59783
59826
|
recordKnowledgeEvent: () => recordKnowledgeEvent,
|
|
59784
59827
|
recomputeCounters: () => recomputeCounters,
|
|
59785
59828
|
readLegacyApplicationRecords: () => readLegacyApplicationRecords,
|
|
@@ -59800,11 +59843,14 @@ __export(exports_knowledge_events, {
|
|
|
59800
59843
|
});
|
|
59801
59844
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
59802
59845
|
import { existsSync as existsSync15 } from "node:fs";
|
|
59803
|
-
import { appendFile as appendFile4, mkdir as mkdir4, readFile as readFile5,
|
|
59846
|
+
import { appendFile as appendFile4, mkdir as mkdir4, readFile as readFile5, stat as stat3 } from "node:fs/promises";
|
|
59804
59847
|
import * as path32 from "node:path";
|
|
59805
59848
|
function resolveKnowledgeEventsPath(directory) {
|
|
59806
59849
|
return path32.join(directory, ".swarm", "knowledge-events.jsonl");
|
|
59807
59850
|
}
|
|
59851
|
+
function resolveKnowledgeCounterBaselinePath(directory) {
|
|
59852
|
+
return path32.join(directory, ".swarm", "knowledge-counter-baseline.json");
|
|
59853
|
+
}
|
|
59808
59854
|
function resolveLegacyApplicationLogPath(directory) {
|
|
59809
59855
|
return path32.join(directory, ".swarm", "knowledge-application.jsonl");
|
|
59810
59856
|
}
|
|
@@ -59839,10 +59885,12 @@ async function appendKnowledgeEvent(directory, event) {
|
|
|
59839
59885
|
const lines = content.split(`
|
|
59840
59886
|
`).filter((line) => line.trim().length > 0);
|
|
59841
59887
|
if (lines.length > MAX_EVENT_LOG_ENTRIES) {
|
|
59888
|
+
const evicted = lines.slice(0, lines.length - MAX_EVENT_LOG_ENTRIES);
|
|
59842
59889
|
const trimmed = lines.slice(lines.length - MAX_EVENT_LOG_ENTRIES);
|
|
59843
|
-
await
|
|
59890
|
+
await foldEvictedEventsIntoBaseline(directory, evicted, filePath);
|
|
59891
|
+
await atomicWriteFile(filePath, `${trimmed.join(`
|
|
59844
59892
|
`)}
|
|
59845
|
-
|
|
59893
|
+
`);
|
|
59846
59894
|
}
|
|
59847
59895
|
} catch (err2) {
|
|
59848
59896
|
warn(`[knowledge-events] local cap trim failed (non-fatal): ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
@@ -59866,19 +59914,8 @@ async function readKnowledgeEvents(directory) {
|
|
|
59866
59914
|
if (!existsSync15(filePath))
|
|
59867
59915
|
return [];
|
|
59868
59916
|
const content = await readFile5(filePath, "utf-8");
|
|
59869
|
-
|
|
59870
|
-
|
|
59871
|
-
`)) {
|
|
59872
|
-
const trimmed = line.trim();
|
|
59873
|
-
if (!trimmed)
|
|
59874
|
-
continue;
|
|
59875
|
-
try {
|
|
59876
|
-
out2.push(JSON.parse(trimmed));
|
|
59877
|
-
} catch {
|
|
59878
|
-
warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
|
|
59879
|
-
}
|
|
59880
|
-
}
|
|
59881
|
-
return out2;
|
|
59917
|
+
return parseEventLines(content.split(`
|
|
59918
|
+
`), filePath);
|
|
59882
59919
|
}
|
|
59883
59920
|
async function readLegacyApplicationRecords(directory) {
|
|
59884
59921
|
const filePath = resolveLegacyApplicationLogPath(directory);
|
|
@@ -59914,6 +59951,49 @@ function emptyRollup() {
|
|
|
59914
59951
|
violation_timestamps: []
|
|
59915
59952
|
};
|
|
59916
59953
|
}
|
|
59954
|
+
function cloneRollup(input) {
|
|
59955
|
+
return {
|
|
59956
|
+
...emptyRollup(),
|
|
59957
|
+
...input,
|
|
59958
|
+
violation_timestamps: [...input.violation_timestamps ?? []]
|
|
59959
|
+
};
|
|
59960
|
+
}
|
|
59961
|
+
function cloneRollupMap(input) {
|
|
59962
|
+
const out2 = new Map;
|
|
59963
|
+
for (const [id, rollup] of input) {
|
|
59964
|
+
out2.set(id, cloneRollup(rollup));
|
|
59965
|
+
}
|
|
59966
|
+
return out2;
|
|
59967
|
+
}
|
|
59968
|
+
function normalizeRollupTimestamps(rollup) {
|
|
59969
|
+
if (rollup.violation_timestamps.length > 1) {
|
|
59970
|
+
rollup.violation_timestamps.sort((a, b) => a < b ? 1 : a > b ? -1 : 0);
|
|
59971
|
+
}
|
|
59972
|
+
if (rollup.violation_timestamps.length > MAX_VIOLATION_TIMESTAMPS) {
|
|
59973
|
+
rollup.violation_timestamps = rollup.violation_timestamps.slice(0, MAX_VIOLATION_TIMESTAMPS);
|
|
59974
|
+
}
|
|
59975
|
+
return rollup;
|
|
59976
|
+
}
|
|
59977
|
+
function mergeRollupInto(target, source) {
|
|
59978
|
+
target.shown_count += source.shown_count ?? 0;
|
|
59979
|
+
target.acknowledged_count += source.acknowledged_count ?? 0;
|
|
59980
|
+
target.applied_explicit_count += source.applied_explicit_count ?? 0;
|
|
59981
|
+
target.ignored_count += source.ignored_count ?? 0;
|
|
59982
|
+
target.violated_count += source.violated_count ?? 0;
|
|
59983
|
+
target.contradicted_count += source.contradicted_count ?? 0;
|
|
59984
|
+
target.n_a_count += source.n_a_count ?? 0;
|
|
59985
|
+
target.succeeded_after_shown_count += source.succeeded_after_shown_count ?? 0;
|
|
59986
|
+
target.failed_after_shown_count += source.failed_after_shown_count ?? 0;
|
|
59987
|
+
target.partial_after_shown_count += source.partial_after_shown_count ?? 0;
|
|
59988
|
+
if (source.last_applied_at) {
|
|
59989
|
+
target.last_applied_at = maxIso(target.last_applied_at, source.last_applied_at);
|
|
59990
|
+
}
|
|
59991
|
+
if (source.last_acknowledged_at) {
|
|
59992
|
+
target.last_acknowledged_at = maxIso(target.last_acknowledged_at, source.last_acknowledged_at);
|
|
59993
|
+
}
|
|
59994
|
+
target.violation_timestamps.push(...source.violation_timestamps ?? []);
|
|
59995
|
+
normalizeRollupTimestamps(target);
|
|
59996
|
+
}
|
|
59917
59997
|
function get(map3, id) {
|
|
59918
59998
|
let r = map3.get(id);
|
|
59919
59999
|
if (!r) {
|
|
@@ -59927,9 +60007,91 @@ function maxIso(current, candidate) {
|
|
|
59927
60007
|
return candidate;
|
|
59928
60008
|
return candidate > current ? candidate : current;
|
|
59929
60009
|
}
|
|
59930
|
-
function
|
|
60010
|
+
async function readCounterBaseline(directory) {
|
|
60011
|
+
const filePath = resolveKnowledgeCounterBaselinePath(directory);
|
|
60012
|
+
if (!existsSync15(filePath))
|
|
60013
|
+
return new Map;
|
|
60014
|
+
const raw = JSON.parse(await readFile5(filePath, "utf-8"));
|
|
60015
|
+
const map3 = new Map;
|
|
60016
|
+
for (const [id, rollup] of Object.entries(raw)) {
|
|
60017
|
+
map3.set(id, normalizeRollupTimestamps(cloneRollup(rollup)));
|
|
60018
|
+
}
|
|
60019
|
+
return map3;
|
|
60020
|
+
}
|
|
60021
|
+
async function writeCounterBaseline(directory, baseline) {
|
|
60022
|
+
const filePath = resolveKnowledgeCounterBaselinePath(directory);
|
|
60023
|
+
const out2 = {};
|
|
60024
|
+
for (const [id, rollup] of [...baseline.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
60025
|
+
out2[id] = normalizeRollupTimestamps(cloneRollup(rollup));
|
|
60026
|
+
}
|
|
60027
|
+
await atomicWriteFile(filePath, `${JSON.stringify(out2, null, 2)}
|
|
60028
|
+
`);
|
|
60029
|
+
}
|
|
60030
|
+
async function statCacheKey(filePath) {
|
|
60031
|
+
try {
|
|
60032
|
+
const fileStat = await stat3(filePath);
|
|
60033
|
+
return `${fileStat.mtimeMs}:${fileStat.ctimeMs}:${fileStat.size}`;
|
|
60034
|
+
} catch (err2) {
|
|
60035
|
+
if (err2?.code === "ENOENT")
|
|
60036
|
+
return "missing";
|
|
60037
|
+
throw err2;
|
|
60038
|
+
}
|
|
60039
|
+
}
|
|
60040
|
+
async function buildCounterRollupCacheKey(directory) {
|
|
60041
|
+
const [eventsKey, legacyKey, baselineKey] = await Promise.all([
|
|
60042
|
+
statCacheKey(resolveKnowledgeEventsPath(directory)),
|
|
60043
|
+
statCacheKey(resolveLegacyApplicationLogPath(directory)),
|
|
60044
|
+
statCacheKey(resolveKnowledgeCounterBaselinePath(directory))
|
|
60045
|
+
]);
|
|
60046
|
+
return `${eventsKey}|${legacyKey}|${baselineKey}`;
|
|
60047
|
+
}
|
|
60048
|
+
function setCounterRollupCache(directory, key, rollups) {
|
|
60049
|
+
if (counterRollupCache.has(directory)) {
|
|
60050
|
+
counterRollupCache.delete(directory);
|
|
60051
|
+
}
|
|
60052
|
+
counterRollupCache.set(directory, {
|
|
60053
|
+
key,
|
|
60054
|
+
rollups: cloneRollupMap(rollups)
|
|
60055
|
+
});
|
|
60056
|
+
while (counterRollupCache.size > MAX_COUNTER_ROLLUP_CACHE_DIRS) {
|
|
60057
|
+
const oldestKey = counterRollupCache.keys().next().value;
|
|
60058
|
+
if (oldestKey === undefined)
|
|
60059
|
+
break;
|
|
60060
|
+
counterRollupCache.delete(oldestKey);
|
|
60061
|
+
}
|
|
60062
|
+
}
|
|
60063
|
+
function parseEventLines(lines, filePath) {
|
|
60064
|
+
const out2 = [];
|
|
60065
|
+
for (const line of lines) {
|
|
60066
|
+
const trimmed = line.trim();
|
|
60067
|
+
if (!trimmed)
|
|
60068
|
+
continue;
|
|
60069
|
+
try {
|
|
60070
|
+
out2.push(JSON.parse(trimmed));
|
|
60071
|
+
} catch {
|
|
60072
|
+
warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
|
|
60073
|
+
}
|
|
60074
|
+
}
|
|
60075
|
+
return out2;
|
|
60076
|
+
}
|
|
60077
|
+
async function foldEvictedEventsIntoBaseline(directory, evictedLines, filePath) {
|
|
60078
|
+
const evictedEvents = parseEventLines(evictedLines, filePath);
|
|
60079
|
+
if (evictedEvents.length === 0)
|
|
60080
|
+
return;
|
|
60081
|
+
const baseline = await readCounterBaseline(directory);
|
|
60082
|
+
for (const [id, rollup] of recomputeCounters(evictedEvents)) {
|
|
60083
|
+
mergeRollupInto(get(baseline, id), rollup);
|
|
60084
|
+
}
|
|
60085
|
+
await writeCounterBaseline(directory, baseline);
|
|
60086
|
+
}
|
|
60087
|
+
function recomputeCounters(events, legacyRecords = [], baseline = new Map) {
|
|
59931
60088
|
const map3 = new Map;
|
|
59932
60089
|
const retrievedIds = new Set;
|
|
60090
|
+
for (const [id, rollup] of baseline) {
|
|
60091
|
+
map3.set(id, cloneRollup(rollup));
|
|
60092
|
+
if ((rollup.shown_count ?? 0) > 0)
|
|
60093
|
+
retrievedIds.add(id);
|
|
60094
|
+
}
|
|
59933
60095
|
for (const e of events) {
|
|
59934
60096
|
switch (e.type) {
|
|
59935
60097
|
case "retrieved": {
|
|
@@ -60005,12 +60167,7 @@ function recomputeCounters(events, legacyRecords = []) {
|
|
|
60005
60167
|
}
|
|
60006
60168
|
}
|
|
60007
60169
|
for (const r of map3.values()) {
|
|
60008
|
-
|
|
60009
|
-
r.violation_timestamps.sort((a, b) => a < b ? 1 : a > b ? -1 : 0);
|
|
60010
|
-
}
|
|
60011
|
-
if (r.violation_timestamps.length > MAX_VIOLATION_TIMESTAMPS) {
|
|
60012
|
-
r.violation_timestamps = r.violation_timestamps.slice(0, MAX_VIOLATION_TIMESTAMPS);
|
|
60013
|
-
}
|
|
60170
|
+
normalizeRollupTimestamps(r);
|
|
60014
60171
|
}
|
|
60015
60172
|
return map3;
|
|
60016
60173
|
}
|
|
@@ -60053,11 +60210,21 @@ async function countEntryViolationsInWindow(directory, entryId, windowDays, now
|
|
|
60053
60210
|
}
|
|
60054
60211
|
async function readKnowledgeCounterRollups(directory) {
|
|
60055
60212
|
try {
|
|
60056
|
-
const
|
|
60213
|
+
const cacheKey = await buildCounterRollupCacheKey(directory);
|
|
60214
|
+
const cached3 = counterRollupCache.get(directory);
|
|
60215
|
+
if (cached3?.key === cacheKey) {
|
|
60216
|
+
counterRollupCache.delete(directory);
|
|
60217
|
+
counterRollupCache.set(directory, cached3);
|
|
60218
|
+
return cloneRollupMap(cached3.rollups);
|
|
60219
|
+
}
|
|
60220
|
+
const [events, legacyRecords, baseline] = await Promise.all([
|
|
60057
60221
|
readKnowledgeEvents(directory),
|
|
60058
|
-
readLegacyApplicationRecords(directory)
|
|
60222
|
+
readLegacyApplicationRecords(directory),
|
|
60223
|
+
readCounterBaseline(directory)
|
|
60059
60224
|
]);
|
|
60060
|
-
|
|
60225
|
+
const rollups = recomputeCounters(events, legacyRecords, baseline);
|
|
60226
|
+
setCounterRollupCache(directory, cacheKey, rollups);
|
|
60227
|
+
return cloneRollupMap(rollups);
|
|
60061
60228
|
} catch (err2) {
|
|
60062
60229
|
warn(`[knowledge-events] readKnowledgeCounterRollups failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
60063
60230
|
return new Map;
|
|
@@ -60124,10 +60291,12 @@ async function applyKnowledgeVerdictFeedback(directory, options) {
|
|
|
60124
60291
|
return { processed: 0, bumps: 0 };
|
|
60125
60292
|
}
|
|
60126
60293
|
}
|
|
60127
|
-
var import_proper_lockfile4, KNOWLEDGE_EVENT_SCHEMA_VERSION = 1, MAX_EVENT_LOG_ENTRIES = 5000, RECEIPT_EVENT_TYPES, MAX_VIOLATION_TIMESTAMPS = 10, VERDICT_CONFIDENCE_BOOST = 0.03, VERDICT_CONFIDENCE_DECAY = 0.05, _internals23;
|
|
60294
|
+
var import_proper_lockfile4, KNOWLEDGE_EVENT_SCHEMA_VERSION = 1, MAX_EVENT_LOG_ENTRIES = 5000, counterRollupCache, MAX_COUNTER_ROLLUP_CACHE_DIRS = 32, RECEIPT_EVENT_TYPES, MAX_VIOLATION_TIMESTAMPS = 10, VERDICT_CONFIDENCE_BOOST = 0.03, VERDICT_CONFIDENCE_DECAY = 0.05, _internals23;
|
|
60128
60295
|
var init_knowledge_events = __esm(() => {
|
|
60296
|
+
init_task_file();
|
|
60129
60297
|
init_logger();
|
|
60130
60298
|
import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
|
|
60299
|
+
counterRollupCache = new Map;
|
|
60131
60300
|
RECEIPT_EVENT_TYPES = new Set([
|
|
60132
60301
|
"acknowledged",
|
|
60133
60302
|
"applied",
|
|
@@ -60139,9 +60308,11 @@ var init_knowledge_events = __esm(() => {
|
|
|
60139
60308
|
]);
|
|
60140
60309
|
_internals23 = {
|
|
60141
60310
|
resolveKnowledgeEventsPath,
|
|
60311
|
+
resolveKnowledgeCounterBaselinePath,
|
|
60142
60312
|
appendKnowledgeEvent,
|
|
60143
60313
|
recordKnowledgeEvent,
|
|
60144
60314
|
readKnowledgeEvents,
|
|
60315
|
+
readCounterBaseline,
|
|
60145
60316
|
readLegacyApplicationRecords,
|
|
60146
60317
|
readKnowledgeCounterRollups,
|
|
60147
60318
|
effectiveRetrievalOutcomes,
|
|
@@ -60779,7 +60950,7 @@ function validateLesson(candidate, existingLessons, meta3) {
|
|
|
60779
60950
|
};
|
|
60780
60951
|
}
|
|
60781
60952
|
const normalizedCandidate = candidate.normalize("NFKC").replace(INVISIBLE_FORMAT_CHARS, " ").replace(/\s+/g, " ").toLowerCase();
|
|
60782
|
-
for (const pattern of
|
|
60953
|
+
for (const pattern of DANGEROUS_COMMAND_ERROR_PATTERNS) {
|
|
60783
60954
|
if (pattern.test(normalizedCandidate)) {
|
|
60784
60955
|
return {
|
|
60785
60956
|
valid: false,
|
|
@@ -60789,6 +60960,16 @@ function validateLesson(candidate, existingLessons, meta3) {
|
|
|
60789
60960
|
};
|
|
60790
60961
|
}
|
|
60791
60962
|
}
|
|
60963
|
+
for (const pattern of DANGEROUS_COMMAND_WARNING_PATTERNS) {
|
|
60964
|
+
if (pattern.test(normalizedCandidate)) {
|
|
60965
|
+
return {
|
|
60966
|
+
valid: true,
|
|
60967
|
+
layer: 2,
|
|
60968
|
+
reason: "potentially dangerous command pattern queued for review",
|
|
60969
|
+
severity: "warning"
|
|
60970
|
+
};
|
|
60971
|
+
}
|
|
60972
|
+
}
|
|
60792
60973
|
for (const pattern of SECURITY_DEGRADING_PATTERNS) {
|
|
60793
60974
|
if (pattern.test(normalizedCandidate)) {
|
|
60794
60975
|
return {
|
|
@@ -60811,10 +60992,10 @@ function validateLesson(candidate, existingLessons, meta3) {
|
|
|
60811
60992
|
}
|
|
60812
60993
|
if (detectContradiction(candidate, existingLessons)) {
|
|
60813
60994
|
return {
|
|
60814
|
-
valid:
|
|
60995
|
+
valid: true,
|
|
60815
60996
|
layer: 3,
|
|
60816
|
-
reason: "
|
|
60817
|
-
severity: "
|
|
60997
|
+
reason: "possible contradiction with an existing lesson with shared tags",
|
|
60998
|
+
severity: "warning"
|
|
60818
60999
|
};
|
|
60819
61000
|
}
|
|
60820
61001
|
if (isVagueLesson(candidate)) {
|
|
@@ -60954,31 +61135,22 @@ async function appendUnactionable(directory, entry, reason) {
|
|
|
60954
61135
|
const filePath = resolveUnactionablePath(directory);
|
|
60955
61136
|
const dirPath = path33.dirname(filePath);
|
|
60956
61137
|
await mkdir5(dirPath, { recursive: true });
|
|
60957
|
-
|
|
60958
|
-
try {
|
|
60959
|
-
release = await import_proper_lockfile5.default.lock(dirPath, {
|
|
60960
|
-
retries: { retries: 50, minTimeout: 10, maxTimeout: 100 },
|
|
60961
|
-
stale: 5000
|
|
60962
|
-
});
|
|
61138
|
+
await transactKnowledge(filePath, (existing) => {
|
|
60963
61139
|
const record3 = {
|
|
60964
61140
|
...entry,
|
|
60965
61141
|
status: "quarantined_unactionable",
|
|
60966
61142
|
unactionable_reason: reason,
|
|
60967
61143
|
quarantined_at: new Date().toISOString()
|
|
60968
61144
|
};
|
|
60969
|
-
|
|
60970
|
-
|
|
60971
|
-
|
|
60972
|
-
|
|
60973
|
-
|
|
60974
|
-
await atomicWriteFile(filePath, `${trimmed.map((e) => JSON.stringify(e)).join(`
|
|
60975
|
-
`)}
|
|
60976
|
-
`);
|
|
61145
|
+
const duplicate = findNearDuplicate(record3.lesson, existing, 0.6);
|
|
61146
|
+
if (duplicate?.unactionable_reason === reason) {
|
|
61147
|
+
duplicate.quarantined_at = record3.quarantined_at;
|
|
61148
|
+
duplicate.updated_at = record3.updated_at;
|
|
61149
|
+
return existing;
|
|
60977
61150
|
}
|
|
60978
|
-
|
|
60979
|
-
|
|
60980
|
-
|
|
60981
|
-
}
|
|
61151
|
+
const next = [...existing, record3];
|
|
61152
|
+
return next.length > 200 ? next.slice(-200) : next;
|
|
61153
|
+
});
|
|
60982
61154
|
}
|
|
60983
61155
|
async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
60984
61156
|
if (!directory || directory.includes("..")) {
|
|
@@ -61112,28 +61284,34 @@ async function restoreEntry(directory, entryId) {
|
|
|
61112
61284
|
}
|
|
61113
61285
|
}
|
|
61114
61286
|
}
|
|
61115
|
-
var import_proper_lockfile5, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS, ACTIONABLE_STRING_MAX = 200, ACTIONABLE_LIST_MAX = 20, NAME_PATTERN, SOURCE_REF_FORBIDDEN, ALLOWED_SKILL_PATH_PREFIXES, VALID_DIRECTIVE_PRIORITIES;
|
|
61287
|
+
var import_proper_lockfile5, DANGEROUS_COMMAND_ERROR_PATTERNS, DANGEROUS_COMMAND_WARNING_PATTERNS, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS, ACTIONABLE_STRING_MAX = 200, ACTIONABLE_LIST_MAX = 20, NAME_PATTERN, SOURCE_REF_FORBIDDEN, ALLOWED_SKILL_PATH_PREFIXES, VALID_DIRECTIVE_PRIORITIES;
|
|
61116
61288
|
var init_knowledge_validator = __esm(() => {
|
|
61117
61289
|
init_task_file();
|
|
61118
61290
|
init_logger();
|
|
61119
61291
|
init_knowledge_store();
|
|
61120
61292
|
import_proper_lockfile5 = __toESM(require_proper_lockfile(), 1);
|
|
61121
|
-
|
|
61293
|
+
DANGEROUS_COMMAND_ERROR_PATTERNS = [
|
|
61122
61294
|
/\brm\s+-rf\b/,
|
|
61123
61295
|
/\bsudo\s+rm\b/,
|
|
61124
|
-
/\bformat\b/,
|
|
61125
61296
|
/\bmkfs\b/,
|
|
61126
61297
|
/\bdd\s+if=/,
|
|
61127
61298
|
/:\(\)\s*\{/,
|
|
61128
61299
|
/\bchmod\s+-R\s+777\b/i,
|
|
61129
61300
|
/\bdeltree\b/,
|
|
61130
|
-
/\brmdir\s+\/s\b
|
|
61301
|
+
/\brmdir\s+\/s\b/
|
|
61302
|
+
];
|
|
61303
|
+
DANGEROUS_COMMAND_WARNING_PATTERNS = [
|
|
61304
|
+
/\bformat\b/,
|
|
61131
61305
|
/\bkill\s+-9\b/,
|
|
61132
61306
|
/\bpkill\b/,
|
|
61133
61307
|
/\bkillall\b/,
|
|
61134
61308
|
/`[^`]*`/,
|
|
61135
61309
|
/\$\([^)]*\)/
|
|
61136
61310
|
];
|
|
61311
|
+
DANGEROUS_COMMAND_PATTERNS = [
|
|
61312
|
+
...DANGEROUS_COMMAND_ERROR_PATTERNS,
|
|
61313
|
+
...DANGEROUS_COMMAND_WARNING_PATTERNS
|
|
61314
|
+
];
|
|
61137
61315
|
SECURITY_DEGRADING_PATTERNS = [
|
|
61138
61316
|
/disable\s+.{0,50}firewall/i,
|
|
61139
61317
|
/turn\s+off\s+.{0,50}security/i,
|
|
@@ -61235,7 +61413,7 @@ var init_knowledge_validator = __esm(() => {
|
|
|
61235
61413
|
});
|
|
61236
61414
|
|
|
61237
61415
|
// src/services/skill-changelog.ts
|
|
61238
|
-
import { appendFile as appendFile6, mkdir as mkdir6, readFile as readFile6, writeFile as
|
|
61416
|
+
import { appendFile as appendFile6, mkdir as mkdir6, readFile as readFile6, writeFile as writeFile3 } from "node:fs/promises";
|
|
61239
61417
|
import * as path34 from "node:path";
|
|
61240
61418
|
function resolveSkillChangelogPath(directory, slug) {
|
|
61241
61419
|
if (slug.includes("..") || slug.includes("/") || slug.includes("\\")) {
|
|
@@ -61255,7 +61433,7 @@ async function appendSkillChangelog(directory, slug, entry) {
|
|
|
61255
61433
|
`).filter((line) => line.trim().length > 0);
|
|
61256
61434
|
if (lines.length > MAX_CHANGELOG_ENTRIES_PER_SKILL) {
|
|
61257
61435
|
const trimmed = lines.slice(lines.length - MAX_CHANGELOG_ENTRIES_PER_SKILL);
|
|
61258
|
-
await
|
|
61436
|
+
await writeFile3(filePath, `${trimmed.join(`
|
|
61259
61437
|
`)}
|
|
61260
61438
|
`, "utf-8");
|
|
61261
61439
|
}
|
|
@@ -61280,6 +61458,7 @@ __export(exports_skill_generator, {
|
|
|
61280
61458
|
parseDraftFrontmatter: () => parseDraftFrontmatter,
|
|
61281
61459
|
listSkills: () => listSkills,
|
|
61282
61460
|
isValidSlug: () => isValidSlug,
|
|
61461
|
+
isSkillMaturityEligible: () => isSkillMaturityEligible,
|
|
61283
61462
|
inspectSkill: () => inspectSkill,
|
|
61284
61463
|
generateSkills: () => generateSkills,
|
|
61285
61464
|
clusterEntries: () => clusterEntries,
|
|
@@ -61287,10 +61466,13 @@ __export(exports_skill_generator, {
|
|
|
61287
61466
|
activeRepoRelativePath: () => activeRepoRelativePath,
|
|
61288
61467
|
activePath: () => activePath,
|
|
61289
61468
|
activateProposal: () => activateProposal,
|
|
61290
|
-
_internals: () => _internals24
|
|
61469
|
+
_internals: () => _internals24,
|
|
61470
|
+
STRONG_SKILL_OUTCOME_COUNT: () => STRONG_SKILL_OUTCOME_COUNT,
|
|
61471
|
+
DEFAULT_SKILL_MIN_CONFIRMATIONS: () => DEFAULT_SKILL_MIN_CONFIRMATIONS,
|
|
61472
|
+
DEFAULT_SKILL_MIN_CONFIDENCE: () => DEFAULT_SKILL_MIN_CONFIDENCE
|
|
61291
61473
|
});
|
|
61292
61474
|
import { existsSync as existsSync17, unlinkSync as unlinkSync5 } from "node:fs";
|
|
61293
|
-
import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as
|
|
61475
|
+
import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as writeFile4 } from "node:fs/promises";
|
|
61294
61476
|
import * as path35 from "node:path";
|
|
61295
61477
|
function sanitizeSlug(input) {
|
|
61296
61478
|
const lc = input.toLowerCase().trim();
|
|
@@ -61315,18 +61497,35 @@ async function selectCandidateEntries(directory, opts) {
|
|
|
61315
61497
|
const hivePath = resolveHiveKnowledgePath();
|
|
61316
61498
|
const hive = existsSync17(hivePath) ? await readKnowledge(hivePath) : [];
|
|
61317
61499
|
const all = [...swarm, ...hive];
|
|
61318
|
-
|
|
61500
|
+
const counterRollups = await readKnowledgeCounterRollups(directory);
|
|
61501
|
+
const selected = [];
|
|
61502
|
+
for (const e of all) {
|
|
61319
61503
|
if (e.status === "archived")
|
|
61320
|
-
|
|
61321
|
-
if (e.confidence < opts.minConfidence)
|
|
61322
|
-
return false;
|
|
61323
|
-
const confirmations = (e.confirmed_by ?? []).length;
|
|
61324
|
-
if (confirmations < opts.minConfirmations)
|
|
61325
|
-
return false;
|
|
61504
|
+
continue;
|
|
61326
61505
|
if (e.generated_skill_slug)
|
|
61327
|
-
|
|
61328
|
-
|
|
61329
|
-
|
|
61506
|
+
continue;
|
|
61507
|
+
const outcomes = effectiveRetrievalOutcomes(e.retrieval_outcomes, counterRollups.get(e.id));
|
|
61508
|
+
if (!isSkillMaturityEligible(e, opts, outcomes))
|
|
61509
|
+
continue;
|
|
61510
|
+
selected.push({ ...e, retrieval_outcomes: outcomes });
|
|
61511
|
+
}
|
|
61512
|
+
return selected;
|
|
61513
|
+
}
|
|
61514
|
+
function hasStrongSkillOutcomeRecord(outcomes) {
|
|
61515
|
+
return (outcomes?.applied_explicit_count ?? 0) >= STRONG_SKILL_OUTCOME_COUNT || (outcomes?.succeeded_after_shown_count ?? 0) >= STRONG_SKILL_OUTCOME_COUNT;
|
|
61516
|
+
}
|
|
61517
|
+
function isHighPriorityDirective(entry) {
|
|
61518
|
+
return entry.directive_priority === "critical" || entry.directive_priority === "high";
|
|
61519
|
+
}
|
|
61520
|
+
function isSkillMaturityEligible(entry, opts, outcomes = entry.retrieval_outcomes) {
|
|
61521
|
+
const outcomeSignal = computeOutcomeSignal(outcomes);
|
|
61522
|
+
if (outcomeSignal < 0)
|
|
61523
|
+
return false;
|
|
61524
|
+
const strongOutcomes = hasStrongSkillOutcomeRecord(outcomes);
|
|
61525
|
+
if (entry.confidence < opts.minConfidence && !strongOutcomes)
|
|
61526
|
+
return false;
|
|
61527
|
+
const confirmations = (entry.confirmed_by ?? []).length;
|
|
61528
|
+
return confirmations >= opts.minConfirmations || strongOutcomes;
|
|
61330
61529
|
}
|
|
61331
61530
|
function jaccardSimilarity(setA, setB) {
|
|
61332
61531
|
const normA = setA.map((s) => s.toLowerCase());
|
|
@@ -61366,8 +61565,9 @@ function clusterEntries(entries) {
|
|
|
61366
61565
|
}
|
|
61367
61566
|
const result = [];
|
|
61368
61567
|
for (const c of clusters) {
|
|
61369
|
-
if (c.members.length < MIN_CLUSTER_SIZE)
|
|
61568
|
+
if (c.members.length < MIN_CLUSTER_SIZE && !isSkillSingletonEligible(c.members[0])) {
|
|
61370
61569
|
continue;
|
|
61570
|
+
}
|
|
61371
61571
|
const arr = c.members;
|
|
61372
61572
|
const triggers = uniqueStrings(arr.flatMap((e) => e.triggers ?? []));
|
|
61373
61573
|
const required3 = uniqueStrings(arr.flatMap((e) => e.required_actions ?? []));
|
|
@@ -61393,6 +61593,11 @@ function clusterEntries(entries) {
|
|
|
61393
61593
|
result.sort((a, b) => b.entries.length - a.entries.length || b.avgConfidence - a.avgConfidence || a.slug.localeCompare(b.slug));
|
|
61394
61594
|
return result;
|
|
61395
61595
|
}
|
|
61596
|
+
function isSkillSingletonEligible(entry) {
|
|
61597
|
+
if (!entry)
|
|
61598
|
+
return false;
|
|
61599
|
+
return isHighPriorityDirective(entry) || hasStrongSkillOutcomeRecord(entry.retrieval_outcomes);
|
|
61600
|
+
}
|
|
61396
61601
|
function uniqueStrings(arr) {
|
|
61397
61602
|
return [...new Set(arr.filter((s) => typeof s === "string" && s.length > 0))];
|
|
61398
61603
|
}
|
|
@@ -61493,12 +61698,12 @@ function escapeMarkdown(s) {
|
|
|
61493
61698
|
async function atomicWrite2(p, content) {
|
|
61494
61699
|
await mkdir7(path35.dirname(p), { recursive: true });
|
|
61495
61700
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
61496
|
-
await
|
|
61701
|
+
await writeFile4(tmp, content, "utf-8");
|
|
61497
61702
|
await rename3(tmp, p);
|
|
61498
61703
|
}
|
|
61499
61704
|
async function generateSkills(req) {
|
|
61500
|
-
const minConfidence = req.minConfidence ??
|
|
61501
|
-
const minConfirmations = req.minConfirmations ??
|
|
61705
|
+
const minConfidence = req.minConfidence ?? DEFAULT_SKILL_MIN_CONFIDENCE;
|
|
61706
|
+
const minConfirmations = req.minConfirmations ?? DEFAULT_SKILL_MIN_CONFIRMATIONS;
|
|
61502
61707
|
const candidates = await selectCandidateEntries(req.directory, {
|
|
61503
61708
|
minConfidence,
|
|
61504
61709
|
minConfirmations
|
|
@@ -61893,7 +62098,7 @@ async function retireSkill(directory, slug, reason) {
|
|
|
61893
62098
|
reason: reason ?? "manual_retire"
|
|
61894
62099
|
});
|
|
61895
62100
|
await mkdir7(markerDir, { recursive: true });
|
|
61896
|
-
await
|
|
62101
|
+
await writeFile4(markerPath, markerContent, "utf-8");
|
|
61897
62102
|
return {
|
|
61898
62103
|
retired: true,
|
|
61899
62104
|
path: skillPath,
|
|
@@ -62056,8 +62261,9 @@ async function regenerateSkill(directory, slug) {
|
|
|
62056
62261
|
entryCount: matchedEntries.length
|
|
62057
62262
|
};
|
|
62058
62263
|
}
|
|
62059
|
-
var SLUG_PATTERN, MIN_CLUSTER_SIZE = 2, JACCARD_THRESHOLD = 0.5, AUTO_APPLY_BATCH_LIMIT = 5, _internals24;
|
|
62264
|
+
var SLUG_PATTERN, DEFAULT_SKILL_MIN_CONFIDENCE = 0.7, DEFAULT_SKILL_MIN_CONFIRMATIONS = 2, STRONG_SKILL_OUTCOME_COUNT = 3, MIN_CLUSTER_SIZE = 2, JACCARD_THRESHOLD = 0.5, AUTO_APPLY_BATCH_LIMIT = 5, _internals24;
|
|
62060
62265
|
var init_skill_generator = __esm(() => {
|
|
62266
|
+
init_knowledge_events();
|
|
62061
62267
|
init_knowledge_store();
|
|
62062
62268
|
init_knowledge_validator();
|
|
62063
62269
|
init_logger();
|
|
@@ -62067,6 +62273,7 @@ var init_skill_generator = __esm(() => {
|
|
|
62067
62273
|
sanitizeSlug,
|
|
62068
62274
|
isValidSlug,
|
|
62069
62275
|
selectCandidateEntries,
|
|
62276
|
+
isSkillMaturityEligible,
|
|
62070
62277
|
clusterEntries,
|
|
62071
62278
|
jaccardSimilarity,
|
|
62072
62279
|
renderSkillMarkdown,
|
|
@@ -62085,7 +62292,7 @@ var init_skill_generator = __esm(() => {
|
|
|
62085
62292
|
|
|
62086
62293
|
// src/services/skill-improver-quota.ts
|
|
62087
62294
|
import { existsSync as existsSync18 } from "node:fs";
|
|
62088
|
-
import { mkdir as mkdir8, readFile as readFile8, rename as rename4, writeFile as
|
|
62295
|
+
import { mkdir as mkdir8, readFile as readFile8, rename as rename4, writeFile as writeFile5 } from "node:fs/promises";
|
|
62089
62296
|
import * as path36 from "node:path";
|
|
62090
62297
|
async function acquireLock(dir) {
|
|
62091
62298
|
const acquire = import_proper_lockfile6.default.lock(dir, LOCK_RETRY_OPTS);
|
|
@@ -62103,8 +62310,9 @@ async function acquireLock(dir) {
|
|
|
62103
62310
|
clearTimeout(timer);
|
|
62104
62311
|
}
|
|
62105
62312
|
}
|
|
62106
|
-
function resolveQuotaPath(directory) {
|
|
62107
|
-
|
|
62313
|
+
function resolveQuotaPath(directory, scope = "skill-improver") {
|
|
62314
|
+
const fileName = scope === "knowledge-enrichment" ? "knowledge-enrichment-quota.json" : "skill-improver-quota.json";
|
|
62315
|
+
return path36.join(directory, ".swarm", fileName);
|
|
62108
62316
|
}
|
|
62109
62317
|
function todayKey(window2, now = new Date) {
|
|
62110
62318
|
if (window2 === "utc") {
|
|
@@ -62132,11 +62340,11 @@ async function readState(filePath) {
|
|
|
62132
62340
|
async function writeState(filePath, state) {
|
|
62133
62341
|
await mkdir8(path36.dirname(filePath), { recursive: true });
|
|
62134
62342
|
const tmp = `${filePath}.tmp-${process.pid}`;
|
|
62135
|
-
await
|
|
62343
|
+
await writeFile5(tmp, JSON.stringify(state, null, 2), "utf-8");
|
|
62136
62344
|
await rename4(tmp, filePath);
|
|
62137
62345
|
}
|
|
62138
62346
|
async function getQuotaState(directory, opts) {
|
|
62139
|
-
const filePath = resolveQuotaPath(directory);
|
|
62347
|
+
const filePath = resolveQuotaPath(directory, opts.scope);
|
|
62140
62348
|
const today = todayKey(opts.window, opts.now);
|
|
62141
62349
|
const existing = await readState(filePath);
|
|
62142
62350
|
if (!existing || existing.date !== today || existing.window !== opts.window) {
|
|
@@ -62152,7 +62360,7 @@ async function getQuotaState(directory, opts) {
|
|
|
62152
62360
|
return { ...existing, max_calls: opts.maxCalls };
|
|
62153
62361
|
}
|
|
62154
62362
|
async function reserveQuota(directory, opts) {
|
|
62155
|
-
const filePath = resolveQuotaPath(directory);
|
|
62363
|
+
const filePath = resolveQuotaPath(directory, opts.scope);
|
|
62156
62364
|
await mkdir8(path36.dirname(filePath), { recursive: true });
|
|
62157
62365
|
let release = null;
|
|
62158
62366
|
try {
|
|
@@ -62182,7 +62390,7 @@ async function reserveQuota(directory, opts) {
|
|
|
62182
62390
|
}
|
|
62183
62391
|
}
|
|
62184
62392
|
async function releaseQuota(directory, opts) {
|
|
62185
|
-
const filePath = resolveQuotaPath(directory);
|
|
62393
|
+
const filePath = resolveQuotaPath(directory, opts.scope);
|
|
62186
62394
|
await mkdir8(path36.dirname(filePath), { recursive: true });
|
|
62187
62395
|
let release = null;
|
|
62188
62396
|
try {
|
|
@@ -62218,7 +62426,7 @@ var init_skill_improver_quota = __esm(() => {
|
|
|
62218
62426
|
});
|
|
62219
62427
|
|
|
62220
62428
|
// src/services/skill-reviser.ts
|
|
62221
|
-
import { readFile as readFile9, rename as rename5, writeFile as
|
|
62429
|
+
import { readFile as readFile9, rename as rename5, writeFile as writeFile6 } from "node:fs/promises";
|
|
62222
62430
|
async function getSkillVersion(skillPath) {
|
|
62223
62431
|
try {
|
|
62224
62432
|
const content = await readFile9(skillPath, "utf-8");
|
|
@@ -62324,7 +62532,7 @@ async function reviseSkill(params) {
|
|
|
62324
62532
|
try {
|
|
62325
62533
|
const revised = _internals25.buildDeterministicRevision(params.currentContent, params.currentVersion, params.violationContexts);
|
|
62326
62534
|
const tmpPath = `${params.skillPath}.tmp-${process.pid}-${Date.now()}`;
|
|
62327
|
-
await
|
|
62535
|
+
await writeFile6(tmpPath, revised, "utf-8");
|
|
62328
62536
|
await rename5(tmpPath, params.skillPath);
|
|
62329
62537
|
const newVersion = params.currentVersion + 1;
|
|
62330
62538
|
const entry = {
|
|
@@ -62392,7 +62600,7 @@ async function reviseSkill(params) {
|
|
|
62392
62600
|
finalOutput = finalOutput.replace(/^version:\s*\d+\s*$/m, `version: ${expectedVersion}`);
|
|
62393
62601
|
}
|
|
62394
62602
|
const tmpPath = `${params.skillPath}.tmp-${process.pid}-${Date.now()}`;
|
|
62395
|
-
await
|
|
62603
|
+
await writeFile6(tmpPath, `${finalOutput}
|
|
62396
62604
|
`, "utf-8");
|
|
62397
62605
|
await rename5(tmpPath, params.skillPath);
|
|
62398
62606
|
const newVersion = expectedVersion;
|
|
@@ -62458,6 +62666,89 @@ function resolveLogPath(directory) {
|
|
|
62458
62666
|
function normalizeComplianceVerdict(verdict) {
|
|
62459
62667
|
return verdict === "violation" ? "violated" : verdict;
|
|
62460
62668
|
}
|
|
62669
|
+
function normalizeSkillUsageEntry(raw) {
|
|
62670
|
+
const entry = raw;
|
|
62671
|
+
return {
|
|
62672
|
+
...entry,
|
|
62673
|
+
complianceVerdict: normalizeComplianceVerdict(entry.complianceVerdict)
|
|
62674
|
+
};
|
|
62675
|
+
}
|
|
62676
|
+
function legacySkillUsageId(entry) {
|
|
62677
|
+
const stable = JSON.stringify({
|
|
62678
|
+
skillPath: entry.skillPath,
|
|
62679
|
+
agentName: entry.agentName,
|
|
62680
|
+
taskID: entry.taskID,
|
|
62681
|
+
timestamp: entry.timestamp,
|
|
62682
|
+
complianceVerdict: entry.complianceVerdict,
|
|
62683
|
+
sessionID: entry.sessionID,
|
|
62684
|
+
skillVersion: entry.skillVersion
|
|
62685
|
+
});
|
|
62686
|
+
return `legacy:${crypto4.createHash("sha256").update(stable).digest("hex")}`;
|
|
62687
|
+
}
|
|
62688
|
+
function parseSkillUsageEntry(raw) {
|
|
62689
|
+
const entry = raw;
|
|
62690
|
+
if (entry.type === "feedback_applied")
|
|
62691
|
+
return null;
|
|
62692
|
+
if (typeof entry.skillPath !== "string" || typeof entry.agentName !== "string" || typeof entry.taskID !== "string" || typeof entry.timestamp !== "string" || typeof entry.complianceVerdict !== "string" || typeof entry.sessionID !== "string") {
|
|
62693
|
+
return null;
|
|
62694
|
+
}
|
|
62695
|
+
return normalizeSkillUsageEntry({
|
|
62696
|
+
...entry,
|
|
62697
|
+
id: typeof entry.id === "string" ? entry.id : legacySkillUsageId(entry)
|
|
62698
|
+
});
|
|
62699
|
+
}
|
|
62700
|
+
function parseFeedbackMarker(raw) {
|
|
62701
|
+
const marker = raw;
|
|
62702
|
+
if (marker.type !== "feedback_applied")
|
|
62703
|
+
return null;
|
|
62704
|
+
if (typeof marker.timestamp !== "string")
|
|
62705
|
+
return null;
|
|
62706
|
+
if (!Array.isArray(marker.processedEntryIds))
|
|
62707
|
+
return null;
|
|
62708
|
+
const processedEntryIds = marker.processedEntryIds.filter((id) => typeof id === "string" && id.length > 0);
|
|
62709
|
+
return {
|
|
62710
|
+
type: "feedback_applied",
|
|
62711
|
+
timestamp: marker.timestamp,
|
|
62712
|
+
processedEntryIds
|
|
62713
|
+
};
|
|
62714
|
+
}
|
|
62715
|
+
function readFeedbackAppliedEntryIds(directory) {
|
|
62716
|
+
const resolved = resolveLogPath(directory);
|
|
62717
|
+
const processed = new Set;
|
|
62718
|
+
if (!_internals26.existsSync(resolved))
|
|
62719
|
+
return processed;
|
|
62720
|
+
const raw = _internals26.readFileSync(resolved, "utf-8");
|
|
62721
|
+
for (const line of raw.split(`
|
|
62722
|
+
`)) {
|
|
62723
|
+
const trimmed = line.trim();
|
|
62724
|
+
if (!trimmed)
|
|
62725
|
+
continue;
|
|
62726
|
+
try {
|
|
62727
|
+
const marker = parseFeedbackMarker(JSON.parse(trimmed));
|
|
62728
|
+
if (!marker)
|
|
62729
|
+
continue;
|
|
62730
|
+
for (const id of marker.processedEntryIds)
|
|
62731
|
+
processed.add(id);
|
|
62732
|
+
} catch {}
|
|
62733
|
+
}
|
|
62734
|
+
return processed;
|
|
62735
|
+
}
|
|
62736
|
+
function appendFeedbackAppliedMarker(directory, processedEntryIds) {
|
|
62737
|
+
if (processedEntryIds.length === 0)
|
|
62738
|
+
return;
|
|
62739
|
+
const resolved = resolveLogPath(directory);
|
|
62740
|
+
const dir = path37.dirname(resolved);
|
|
62741
|
+
if (!_internals26.existsSync(dir)) {
|
|
62742
|
+
_internals26.mkdirSync(dir, { recursive: true });
|
|
62743
|
+
}
|
|
62744
|
+
const marker = {
|
|
62745
|
+
type: "feedback_applied",
|
|
62746
|
+
timestamp: new Date().toISOString(),
|
|
62747
|
+
processedEntryIds: [...new Set(processedEntryIds)]
|
|
62748
|
+
};
|
|
62749
|
+
_internals26.appendFileSync(resolved, `${JSON.stringify(marker)}
|
|
62750
|
+
`, "utf-8");
|
|
62751
|
+
}
|
|
62461
62752
|
function appendSkillUsageEntry(directory, entry) {
|
|
62462
62753
|
const {
|
|
62463
62754
|
skillPath,
|
|
@@ -62501,7 +62792,7 @@ function appendSkillUsageEntry(directory, entry) {
|
|
|
62501
62792
|
agentName,
|
|
62502
62793
|
taskID,
|
|
62503
62794
|
timestamp,
|
|
62504
|
-
complianceVerdict,
|
|
62795
|
+
complianceVerdict: normalizeComplianceVerdict(complianceVerdict),
|
|
62505
62796
|
sessionID,
|
|
62506
62797
|
...reviewerNotes !== undefined && { reviewerNotes },
|
|
62507
62798
|
...skillVersion !== undefined && { skillVersion }
|
|
@@ -62509,8 +62800,8 @@ function appendSkillUsageEntry(directory, entry) {
|
|
|
62509
62800
|
_internals26.appendFileSync(resolved, `${JSON.stringify(fullEntry)}
|
|
62510
62801
|
`, "utf-8");
|
|
62511
62802
|
try {
|
|
62512
|
-
const
|
|
62513
|
-
if (
|
|
62803
|
+
const stat4 = _internals26.statSync(resolved);
|
|
62804
|
+
if (stat4.size > SKILL_USAGE_LOG_ROTATE_BYTES) {
|
|
62514
62805
|
_internals26.pruneSkillUsageLog(directory, SKILL_USAGE_LOG_MAX_ENTRIES_PER_SKILL);
|
|
62515
62806
|
}
|
|
62516
62807
|
} catch {}
|
|
@@ -62528,9 +62819,9 @@ function readSkillUsageEntries(directory, options) {
|
|
|
62528
62819
|
if (!trimmed)
|
|
62529
62820
|
continue;
|
|
62530
62821
|
try {
|
|
62531
|
-
const entry = JSON.parse(trimmed);
|
|
62532
|
-
|
|
62533
|
-
|
|
62822
|
+
const entry = parseSkillUsageEntry(JSON.parse(trimmed));
|
|
62823
|
+
if (entry)
|
|
62824
|
+
entries.push(entry);
|
|
62534
62825
|
} catch {}
|
|
62535
62826
|
}
|
|
62536
62827
|
if (!options)
|
|
@@ -62564,11 +62855,11 @@ function readSkillUsageEntriesTail(directory, filters, maxBytes = TAIL_BYTES_DEF
|
|
|
62564
62855
|
try {
|
|
62565
62856
|
const normalizedMaxBytes = Number.isFinite(maxBytes) ? maxBytes : TAIL_BYTES_DEFAULT;
|
|
62566
62857
|
const boundedMaxBytes = Math.min(Math.max(1, normalizedMaxBytes), MAX_TAIL_BYTES);
|
|
62567
|
-
const
|
|
62568
|
-
const start2 = Math.max(0,
|
|
62858
|
+
const stat4 = _internals26.statSync(logPath);
|
|
62859
|
+
const start2 = Math.max(0, stat4.size - boundedMaxBytes);
|
|
62569
62860
|
const fd = _internals26.openSync(logPath, "r");
|
|
62570
62861
|
try {
|
|
62571
|
-
const readLen =
|
|
62862
|
+
const readLen = stat4.size - start2;
|
|
62572
62863
|
if (readLen === 0)
|
|
62573
62864
|
return [];
|
|
62574
62865
|
const buf = Buffer.alloc(readLen);
|
|
@@ -62588,8 +62879,9 @@ function readSkillUsageEntriesTail(directory, filters, maxBytes = TAIL_BYTES_DEF
|
|
|
62588
62879
|
if (!line.trim())
|
|
62589
62880
|
continue;
|
|
62590
62881
|
try {
|
|
62591
|
-
const entry = JSON.parse(line);
|
|
62592
|
-
|
|
62882
|
+
const entry = parseSkillUsageEntry(JSON.parse(line));
|
|
62883
|
+
if (!entry)
|
|
62884
|
+
continue;
|
|
62593
62885
|
if (filters.sessionID !== undefined && entry.sessionID !== filters.sessionID) {
|
|
62594
62886
|
continue;
|
|
62595
62887
|
}
|
|
@@ -62624,8 +62916,9 @@ function computeComplianceByVersion(entries, skillPath) {
|
|
|
62624
62916
|
stats.total += 1;
|
|
62625
62917
|
if (e.complianceVerdict === "compliant")
|
|
62626
62918
|
stats.compliant += 1;
|
|
62627
|
-
if (e.complianceVerdict === "violated")
|
|
62919
|
+
if (normalizeComplianceVerdict(e.complianceVerdict) === "violated") {
|
|
62628
62920
|
stats.violation += 1;
|
|
62921
|
+
}
|
|
62629
62922
|
}
|
|
62630
62923
|
for (const stats of map3.values()) {
|
|
62631
62924
|
stats.rate = stats.total === 0 ? 0 : stats.compliant / stats.total;
|
|
@@ -62736,6 +63029,7 @@ async function applySkillUsageFeedback(directory, options) {
|
|
|
62736
63029
|
let bumps = 0;
|
|
62737
63030
|
try {
|
|
62738
63031
|
const allEntries = readSkillUsageEntries(directory);
|
|
63032
|
+
const alreadyProcessed = readFeedbackAppliedEntryIds(directory);
|
|
62739
63033
|
const actionable = allEntries.filter((e) => {
|
|
62740
63034
|
if (e.complianceVerdict !== "compliant" && e.complianceVerdict !== "violated") {
|
|
62741
63035
|
return false;
|
|
@@ -62743,6 +63037,9 @@ async function applySkillUsageFeedback(directory, options) {
|
|
|
62743
63037
|
if (options?.sinceTimestamp && e.timestamp <= options.sinceTimestamp) {
|
|
62744
63038
|
return false;
|
|
62745
63039
|
}
|
|
63040
|
+
if (alreadyProcessed.has(e.id)) {
|
|
63041
|
+
return false;
|
|
63042
|
+
}
|
|
62746
63043
|
return true;
|
|
62747
63044
|
});
|
|
62748
63045
|
if (actionable.length === 0) {
|
|
@@ -62757,6 +63054,7 @@ async function applySkillUsageFeedback(directory, options) {
|
|
|
62757
63054
|
groups.set(entry.skillPath, [entry]);
|
|
62758
63055
|
}
|
|
62759
63056
|
const allDeltas = [];
|
|
63057
|
+
const processedEntryIds = [];
|
|
62760
63058
|
for (const [skillPath, entries] of Array.from(groups)) {
|
|
62761
63059
|
let compliantCount = 0;
|
|
62762
63060
|
let violationCount = 0;
|
|
@@ -62775,6 +63073,7 @@ async function applySkillUsageFeedback(directory, options) {
|
|
|
62775
63073
|
for (const id of sourceIds) {
|
|
62776
63074
|
allDeltas.push({ id, delta });
|
|
62777
63075
|
}
|
|
63076
|
+
processedEntryIds.push(...entries.map((entry) => entry.id));
|
|
62778
63077
|
processed++;
|
|
62779
63078
|
bumps += sourceIds.length;
|
|
62780
63079
|
}
|
|
@@ -62788,6 +63087,7 @@ async function applySkillUsageFeedback(directory, options) {
|
|
|
62788
63087
|
}));
|
|
62789
63088
|
if (clampedDeltas.length > 0) {
|
|
62790
63089
|
await bumpKnowledgeConfidenceBatch(directory, clampedDeltas);
|
|
63090
|
+
appendFeedbackAppliedMarker(directory, processedEntryIds);
|
|
62791
63091
|
}
|
|
62792
63092
|
} catch (err2) {
|
|
62793
63093
|
console.warn("[skill-usage-log] applySkillUsageFeedback failed (fail-open):", err2 instanceof Error ? err2.message : String(err2));
|
|
@@ -62814,7 +63114,10 @@ var init_skill_usage_log = __esm(() => {
|
|
|
62814
63114
|
resolveSourceKnowledgeIds,
|
|
62815
63115
|
applySkillUsageFeedback,
|
|
62816
63116
|
parseGeneratedFromKnowledge,
|
|
62817
|
-
computeComplianceByVersion
|
|
63117
|
+
computeComplianceByVersion,
|
|
63118
|
+
normalizeComplianceVerdict,
|
|
63119
|
+
readFeedbackAppliedEntryIds,
|
|
63120
|
+
appendFeedbackAppliedMarker
|
|
62818
63121
|
};
|
|
62819
63122
|
TAIL_BYTES_DEFAULT = 64 * 1024;
|
|
62820
63123
|
MAX_TAIL_BYTES = TAIL_BYTES_DEFAULT;
|
|
@@ -62847,7 +63150,7 @@ async function autoRetireSkills(directory, curatorKnowledgePath, excludeSlugs) {
|
|
|
62847
63150
|
return true;
|
|
62848
63151
|
return false;
|
|
62849
63152
|
});
|
|
62850
|
-
const violations = skillUsage.filter((e) => e.complianceVerdict === "violated").length;
|
|
63153
|
+
const violations = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").length;
|
|
62851
63154
|
const violationRate = skillUsage.length > 0 ? violations / skillUsage.length : 0;
|
|
62852
63155
|
let allArchived = false;
|
|
62853
63156
|
try {
|
|
@@ -63512,7 +63815,7 @@ ${phaseDigest.summary}`,
|
|
|
63512
63815
|
});
|
|
63513
63816
|
if (skillUsage.length === 0)
|
|
63514
63817
|
continue;
|
|
63515
|
-
const violations = skillUsage.filter((e) => e.complianceVerdict === "violated").length;
|
|
63818
|
+
const violations = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").length;
|
|
63516
63819
|
const violationRate = violations / skillUsage.length;
|
|
63517
63820
|
if (violationRate > REVISION_VIOLATION_THRESHOLD && violationRate <= 0.3) {
|
|
63518
63821
|
const content = await _internals27.readFileAsync(active.path, "utf-8");
|
|
@@ -63520,7 +63823,7 @@ ${phaseDigest.summary}`,
|
|
|
63520
63823
|
if (fm && fm.skillOrigin === "promoted_external")
|
|
63521
63824
|
continue;
|
|
63522
63825
|
const currentVersion = fm?.version ?? 1;
|
|
63523
|
-
const violationContexts = skillUsage.filter((e) => e.complianceVerdict === "violated").slice(-10).map((e) => ({
|
|
63826
|
+
const violationContexts = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").slice(-10).map((e) => ({
|
|
63524
63827
|
taskId: e.taskID,
|
|
63525
63828
|
agent: e.agentName,
|
|
63526
63829
|
verdict: e.complianceVerdict,
|
|
@@ -63814,6 +64117,9 @@ function isAlreadyInHive(entry, hiveEntries, threshold) {
|
|
|
63814
64117
|
return findNearDuplicate(entry.lesson, hiveEntries, threshold) !== undefined;
|
|
63815
64118
|
}
|
|
63816
64119
|
function isHiveEligible(entry, autoPromoteDays) {
|
|
64120
|
+
if (!isActiveForHivePromotion(entry)) {
|
|
64121
|
+
return false;
|
|
64122
|
+
}
|
|
63817
64123
|
const phaseNumbers = new Set;
|
|
63818
64124
|
for (const record3 of entry.confirmed_by ?? []) {
|
|
63819
64125
|
if (record3 && typeof record3.phase_number === "number") {
|
|
@@ -63834,6 +64140,9 @@ function isHiveEligible(entry, autoPromoteDays) {
|
|
|
63834
64140
|
}
|
|
63835
64141
|
return false;
|
|
63836
64142
|
}
|
|
64143
|
+
function isActiveForHivePromotion(entry) {
|
|
64144
|
+
return !["archived", "quarantined", "quarantined_unactionable"].includes(entry.status);
|
|
64145
|
+
}
|
|
63837
64146
|
function countDistinctProjects(confirmedBy) {
|
|
63838
64147
|
const projectNames = new Set;
|
|
63839
64148
|
for (const record3 of confirmedBy) {
|
|
@@ -63916,7 +64225,7 @@ async function checkHivePromotions(swarmEntries, config3) {
|
|
|
63916
64225
|
}
|
|
63917
64226
|
let hiveModified = false;
|
|
63918
64227
|
for (const hiveEntry of hiveEntries) {
|
|
63919
|
-
const nearDuplicate = findNearDuplicate(hiveEntry.lesson, swarmEntries, config3.dedup_threshold);
|
|
64228
|
+
const nearDuplicate = findNearDuplicate(hiveEntry.lesson, swarmEntries.filter(isActiveForHivePromotion), config3.dedup_threshold);
|
|
63920
64229
|
if (!nearDuplicate) {
|
|
63921
64230
|
continue;
|
|
63922
64231
|
}
|
|
@@ -64074,9 +64383,9 @@ import {
|
|
|
64074
64383
|
mkdir as mkdir9,
|
|
64075
64384
|
readFile as readFile10,
|
|
64076
64385
|
rename as rename6,
|
|
64077
|
-
stat as
|
|
64386
|
+
stat as stat4,
|
|
64078
64387
|
unlink as unlink2,
|
|
64079
|
-
writeFile as
|
|
64388
|
+
writeFile as writeFile7
|
|
64080
64389
|
} from "node:fs/promises";
|
|
64081
64390
|
import * as path40 from "node:path";
|
|
64082
64391
|
function emptySynonymMap() {
|
|
@@ -64263,7 +64572,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
|
|
|
64263
64572
|
}
|
|
64264
64573
|
try {
|
|
64265
64574
|
const ceiling = Math.max(MIN_READ_CEILING_BYTES, Math.floor(maxPairs) * APPROX_BYTES_PER_PAIR);
|
|
64266
|
-
const st = await
|
|
64575
|
+
const st = await stat4(filePath);
|
|
64267
64576
|
if (st.size > ceiling)
|
|
64268
64577
|
return emptySynonymMap();
|
|
64269
64578
|
const raw = await readFile10(filePath, "utf-8");
|
|
@@ -64276,7 +64585,7 @@ async function writeSynonymMapAtomic(filePath, map3) {
|
|
|
64276
64585
|
await mkdir9(path40.dirname(filePath), { recursive: true });
|
|
64277
64586
|
const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
64278
64587
|
try {
|
|
64279
|
-
await
|
|
64588
|
+
await writeFile7(tmp, JSON.stringify(map3, null, 2), "utf-8");
|
|
64280
64589
|
await rename6(tmp, filePath);
|
|
64281
64590
|
} finally {
|
|
64282
64591
|
try {
|
|
@@ -64485,12 +64794,12 @@ function extractKeywords(text) {
|
|
|
64485
64794
|
const words = text.toLowerCase().split(/[^a-z0-9]+/).filter((w) => w.length >= MIN_KEYWORD_LENGTH);
|
|
64486
64795
|
return new Set(words);
|
|
64487
64796
|
}
|
|
64488
|
-
function computeContextMatchScore(taskDescription, skillPath) {
|
|
64797
|
+
function computeContextMatchScore(taskDescription, skillPath, metadata2) {
|
|
64489
64798
|
const taskKeywords = extractKeywords(taskDescription);
|
|
64490
64799
|
if (taskKeywords.size === 0)
|
|
64491
64800
|
return 0;
|
|
64492
64801
|
const skillName = extractSkillName(skillPath);
|
|
64493
|
-
const skillText = `${skillPath} ${skillName}`;
|
|
64802
|
+
const skillText = `${skillPath} ${skillName} ${metadata2?.name ?? ""} ${metadata2?.description ?? ""}`;
|
|
64494
64803
|
const skillKeywords = extractKeywords(skillText);
|
|
64495
64804
|
let matchCount = 0;
|
|
64496
64805
|
for (const kw of taskKeywords) {
|
|
@@ -64501,7 +64810,7 @@ function computeContextMatchScore(taskDescription, skillPath) {
|
|
|
64501
64810
|
return matchCount / taskKeywords.size;
|
|
64502
64811
|
}
|
|
64503
64812
|
function computeSkillRelevanceScore(skillPath, taskDescription, usageHistory, metadata2) {
|
|
64504
|
-
const contextScore = computeContextMatchScore(taskDescription, skillPath) * CONTEXT_WEIGHT;
|
|
64813
|
+
const contextScore = computeContextMatchScore(taskDescription, skillPath, metadata2) * CONTEXT_WEIGHT;
|
|
64505
64814
|
if (usageHistory.length === 0)
|
|
64506
64815
|
return Math.min(1, contextScore);
|
|
64507
64816
|
const usageCount = usageHistory.length;
|
|
@@ -64576,8 +64885,8 @@ function formatSkillIndexWithContext(skills, directory) {
|
|
|
64576
64885
|
const usageLogPath = path41.join(directory, ".swarm", "skill-usage.jsonl");
|
|
64577
64886
|
let hasHistory = false;
|
|
64578
64887
|
try {
|
|
64579
|
-
const
|
|
64580
|
-
hasHistory =
|
|
64888
|
+
const stat5 = fs21.statSync(usageLogPath);
|
|
64889
|
+
hasHistory = stat5.size > 0;
|
|
64581
64890
|
} catch {}
|
|
64582
64891
|
if (!hasHistory) {
|
|
64583
64892
|
return skills.map((sp) => {
|
|
@@ -65098,24 +65407,32 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
|
|
|
65098
65407
|
if (!text)
|
|
65099
65408
|
continue;
|
|
65100
65409
|
const skillPaths = [];
|
|
65410
|
+
let explicitReviewerTaskID;
|
|
65101
65411
|
for (const line of text.split(`
|
|
65102
65412
|
`)) {
|
|
65103
|
-
const
|
|
65413
|
+
const trimmed = line.trim();
|
|
65414
|
+
const taskMatch = trimmed.match(REVIEWER_TASK_PATTERN);
|
|
65415
|
+
if (taskMatch) {
|
|
65416
|
+
explicitReviewerTaskID = taskMatch[1];
|
|
65417
|
+
}
|
|
65418
|
+
const coderMatch = trimmed.match(CODER_SKILLS_PATTERN);
|
|
65104
65419
|
if (coderMatch) {
|
|
65105
65420
|
const parsed = _internals29.parseSkillPaths(coderMatch[1]);
|
|
65106
65421
|
skillPaths.push(...parsed);
|
|
65107
65422
|
}
|
|
65108
65423
|
}
|
|
65109
|
-
let resolvedTaskID = "unknown";
|
|
65424
|
+
let resolvedTaskID = explicitReviewerTaskID ?? "unknown";
|
|
65110
65425
|
if (existingEntries.length > 0) {
|
|
65111
|
-
|
|
65112
|
-
|
|
65113
|
-
|
|
65114
|
-
|
|
65115
|
-
|
|
65116
|
-
|
|
65117
|
-
|
|
65118
|
-
|
|
65426
|
+
if (!explicitReviewerTaskID) {
|
|
65427
|
+
const latestDelegation = [...existingEntries].reverse().find((e) => e.agentName !== "reviewer" && e.skillPath !== "__overall__");
|
|
65428
|
+
if (latestDelegation) {
|
|
65429
|
+
resolvedTaskID = latestDelegation.taskID;
|
|
65430
|
+
}
|
|
65431
|
+
}
|
|
65432
|
+
if (skillPaths.length === 0 && resolvedTaskID !== "unknown") {
|
|
65433
|
+
const delegatedPaths = existingEntries.filter((e) => e.agentName !== "reviewer" && e.skillPath !== "__overall__" && e.taskID === resolvedTaskID).map((e) => e.skillPath);
|
|
65434
|
+
if (delegatedPaths.length > 0) {
|
|
65435
|
+
skillPaths.push(...new Set(delegatedPaths));
|
|
65119
65436
|
}
|
|
65120
65437
|
}
|
|
65121
65438
|
}
|
|
@@ -65205,7 +65522,7 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
|
|
|
65205
65522
|
break;
|
|
65206
65523
|
}
|
|
65207
65524
|
}
|
|
65208
|
-
var SKILL_CAPABLE_AGENTS, SKILL_SEARCH_ROOTS, MAX_SCORING_SESSION_ENTRIES = 500, _internals29, COMPLIANCE_PATTERN, CODER_SKILLS_PATTERN;
|
|
65525
|
+
var SKILL_CAPABLE_AGENTS, SKILL_SEARCH_ROOTS, MAX_SCORING_SESSION_ENTRIES = 500, _internals29, COMPLIANCE_PATTERN, CODER_SKILLS_PATTERN, REVIEWER_TASK_PATTERN;
|
|
65209
65526
|
var init_skill_propagation_gate = __esm(() => {
|
|
65210
65527
|
init_schema();
|
|
65211
65528
|
init_logger();
|
|
@@ -65251,6 +65568,7 @@ var init_skill_propagation_gate = __esm(() => {
|
|
|
65251
65568
|
};
|
|
65252
65569
|
COMPLIANCE_PATTERN = /SKILL_COMPLIANCE\s*:\s*(COMPLIANT|PARTIAL|VIOLATED)(?:\s*(?:—|-)\s*(.*))?\s*$/i;
|
|
65253
65570
|
CODER_SKILLS_PATTERN = /SKILLS_USED_BY_CODER\s*:\s*(.+)/i;
|
|
65571
|
+
REVIEWER_TASK_PATTERN = /TASK\s*:\s*(\S+)/i;
|
|
65254
65572
|
_internals29.skillPropagationGateBefore = skillPropagationGateBefore;
|
|
65255
65573
|
_internals29.skillPropagationTransformScan = skillPropagationTransformScan;
|
|
65256
65574
|
_internals29.writeWarnEvent = writeWarnEvent;
|
|
@@ -65265,7 +65583,7 @@ var init_skill_propagation_gate = __esm(() => {
|
|
|
65265
65583
|
|
|
65266
65584
|
// src/hooks/micro-reflector.ts
|
|
65267
65585
|
import { existsSync as existsSync22 } from "node:fs";
|
|
65268
|
-
import { readFile as readFile11, writeFile as
|
|
65586
|
+
import { readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
|
|
65269
65587
|
import * as path43 from "node:path";
|
|
65270
65588
|
function resolveInsightCandidatesPath(directory) {
|
|
65271
65589
|
return validateSwarmPath(directory, "insight-candidates.jsonl");
|
|
@@ -65334,7 +65652,7 @@ async function appendInsightCandidates(directory, candidates) {
|
|
|
65334
65652
|
const body2 = data.length === 0 ? "" : `${data.map((c) => JSON.stringify(c)).join(`
|
|
65335
65653
|
`)}
|
|
65336
65654
|
`;
|
|
65337
|
-
await
|
|
65655
|
+
await writeFile8(p, body2, "utf-8");
|
|
65338
65656
|
}, (all) => {
|
|
65339
65657
|
const merged = [...all, ...candidates];
|
|
65340
65658
|
const capped = merged.length > INSIGHT_CANDIDATES_MAX_ENTRIES ? merged.slice(-INSIGHT_CANDIDATES_MAX_ENTRIES) : merged;
|
|
@@ -65455,7 +65773,8 @@ async function runMicroReflection(params) {
|
|
|
65455
65773
|
const reservation = await reserveQuota(params.directory, {
|
|
65456
65774
|
nCalls: 1,
|
|
65457
65775
|
maxCalls: quota.maxCalls,
|
|
65458
|
-
window: quota.window
|
|
65776
|
+
window: quota.window,
|
|
65777
|
+
scope: "knowledge-enrichment"
|
|
65459
65778
|
});
|
|
65460
65779
|
if (!reservation.allowed)
|
|
65461
65780
|
return result;
|
|
@@ -65542,7 +65861,7 @@ var init_micro_reflector = __esm(() => {
|
|
|
65542
65861
|
|
|
65543
65862
|
// src/hooks/knowledge-curator.ts
|
|
65544
65863
|
import { existsSync as existsSync23 } from "node:fs";
|
|
65545
|
-
import { appendFile as appendFile7, mkdir as mkdir10, readFile as readFile12, writeFile as
|
|
65864
|
+
import { appendFile as appendFile7, mkdir as mkdir10, readFile as readFile12, writeFile as writeFile9 } from "node:fs/promises";
|
|
65546
65865
|
import * as path44 from "node:path";
|
|
65547
65866
|
function pruneSeenRetroSections() {
|
|
65548
65867
|
const cutoff = Date.now() - 86400000;
|
|
@@ -65783,7 +66102,8 @@ async function enrichLessonToV3(params) {
|
|
|
65783
66102
|
const reservation = await reserveQuota(params.directory, {
|
|
65784
66103
|
nCalls: 1,
|
|
65785
66104
|
maxCalls: quota.maxCalls,
|
|
65786
|
-
window: quota.window
|
|
66105
|
+
window: quota.window,
|
|
66106
|
+
scope: "knowledge-enrichment"
|
|
65787
66107
|
});
|
|
65788
66108
|
if (!reservation.allowed)
|
|
65789
66109
|
return null;
|
|
@@ -65837,7 +66157,7 @@ async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BAT
|
|
|
65837
66157
|
const body2 = data.length === 0 ? "" : `${data.map((c) => JSON.stringify(c)).join(`
|
|
65838
66158
|
`)}
|
|
65839
66159
|
`;
|
|
65840
|
-
await
|
|
66160
|
+
await writeFile9(p, body2, "utf-8");
|
|
65841
66161
|
}, (all) => {
|
|
65842
66162
|
if (all.length === 0)
|
|
65843
66163
|
return null;
|
|
@@ -66128,7 +66448,7 @@ async function runAutoPromotion(directory, config3) {
|
|
|
66128
66448
|
await rewriteKnowledge(knowledgePath, entries);
|
|
66129
66449
|
}
|
|
66130
66450
|
}
|
|
66131
|
-
function createKnowledgeCuratorHook(directory, config3) {
|
|
66451
|
+
function createKnowledgeCuratorHook(directory, config3, options = {}) {
|
|
66132
66452
|
const handler = async (input, _output) => {
|
|
66133
66453
|
pruneSeenRetroSections();
|
|
66134
66454
|
if (!config3.enabled)
|
|
@@ -66173,7 +66493,10 @@ function createKnowledgeCuratorHook(directory, config3) {
|
|
|
66173
66493
|
recordSeenRetroSection(evidenceKey, evidenceHash, Date.now());
|
|
66174
66494
|
const projectName2 = evidenceData.project_name ?? "unknown";
|
|
66175
66495
|
const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
|
|
66176
|
-
await _internals30.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3
|
|
66496
|
+
await _internals30.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3, {
|
|
66497
|
+
llmDelegate: options.llmDelegateFactory?.(sessionID),
|
|
66498
|
+
enrichmentQuota: options.enrichmentQuota
|
|
66499
|
+
});
|
|
66177
66500
|
return;
|
|
66178
66501
|
}
|
|
66179
66502
|
const planContent = await readSwarmFileAsync(directory, "plan.md");
|
|
@@ -66195,7 +66518,10 @@ function createKnowledgeCuratorHook(directory, config3) {
|
|
|
66195
66518
|
const projectName = projectNameMatch ? projectNameMatch[1].trim() : "unknown";
|
|
66196
66519
|
const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
|
|
66197
66520
|
const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
|
|
66198
|
-
await _internals30.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3
|
|
66521
|
+
await _internals30.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3, {
|
|
66522
|
+
llmDelegate: options.llmDelegateFactory?.(sessionID),
|
|
66523
|
+
enrichmentQuota: options.enrichmentQuota
|
|
66524
|
+
});
|
|
66199
66525
|
};
|
|
66200
66526
|
return safeHook(handler);
|
|
66201
66527
|
}
|
|
@@ -66354,7 +66680,7 @@ var init_skill_improver_llm_factory = __esm(() => {
|
|
|
66354
66680
|
});
|
|
66355
66681
|
|
|
66356
66682
|
// src/services/trajectory-cluster.ts
|
|
66357
|
-
import { mkdir as mkdir11, writeFile as
|
|
66683
|
+
import { mkdir as mkdir11, writeFile as writeFile10 } from "node:fs/promises";
|
|
66358
66684
|
import * as path45 from "node:path";
|
|
66359
66685
|
function failureKind(e) {
|
|
66360
66686
|
const tool3 = (e.tool ?? "").toLowerCase();
|
|
@@ -66489,7 +66815,7 @@ async function writeMotifProposals(directory, opts = {}) {
|
|
|
66489
66815
|
for (const motif of motifs.slice(0, max)) {
|
|
66490
66816
|
const slug = `motif-${slugify2(motif.signature)}`;
|
|
66491
66817
|
const filePath = path45.join(proposalsDir, `${slug}.md`);
|
|
66492
|
-
await
|
|
66818
|
+
await writeFile10(filePath, buildMotifProposal(motif), "utf-8");
|
|
66493
66819
|
result.proposalsWritten.push(filePath);
|
|
66494
66820
|
}
|
|
66495
66821
|
return result;
|
|
@@ -66633,7 +66959,7 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
|
|
|
66633
66959
|
for (const motif of motifs.slice(0, max)) {
|
|
66634
66960
|
const slug = workflowSlug(motif.signature);
|
|
66635
66961
|
const filePath = path45.join(proposalsDir, `${slug}.md`);
|
|
66636
|
-
await
|
|
66962
|
+
await writeFile10(filePath, buildWorkflowProposal(motif), "utf-8");
|
|
66637
66963
|
result.proposalsWritten.push(filePath);
|
|
66638
66964
|
}
|
|
66639
66965
|
return result;
|
|
@@ -66764,7 +67090,7 @@ var init_unactionable_hardening = __esm(() => {
|
|
|
66764
67090
|
|
|
66765
67091
|
// src/services/skill-improver.ts
|
|
66766
67092
|
import { existsSync as existsSync25 } from "node:fs";
|
|
66767
|
-
import { mkdir as mkdir12, readFile as readFile13, rename as rename7, writeFile as
|
|
67093
|
+
import { mkdir as mkdir12, readFile as readFile13, rename as rename7, writeFile as writeFile11 } from "node:fs/promises";
|
|
66768
67094
|
import * as path46 from "node:path";
|
|
66769
67095
|
function timestampSlug(d) {
|
|
66770
67096
|
return d.toISOString().replace(/[:.]/g, "-");
|
|
@@ -66772,7 +67098,7 @@ function timestampSlug(d) {
|
|
|
66772
67098
|
async function atomicWrite3(p, content) {
|
|
66773
67099
|
await mkdir12(path46.dirname(p), { recursive: true });
|
|
66774
67100
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
66775
|
-
await
|
|
67101
|
+
await writeFile11(tmp, content, "utf-8");
|
|
66776
67102
|
await rename7(tmp, p);
|
|
66777
67103
|
}
|
|
66778
67104
|
async function gatherInventory(directory) {
|
|
@@ -66826,7 +67152,10 @@ async function gatherInventory(directory) {
|
|
|
66826
67152
|
});
|
|
66827
67153
|
}
|
|
66828
67154
|
}
|
|
66829
|
-
const matureCandidates =
|
|
67155
|
+
const matureCandidates = await selectCandidateEntries(directory, {
|
|
67156
|
+
minConfidence: DEFAULT_SKILL_MIN_CONFIDENCE,
|
|
67157
|
+
minConfirmations: DEFAULT_SKILL_MIN_CONFIRMATIONS
|
|
67158
|
+
});
|
|
66830
67159
|
return {
|
|
66831
67160
|
knowledge: { swarm: swarm.length, hive: hive.length, archived },
|
|
66832
67161
|
skills: {
|
|
@@ -67092,8 +67421,8 @@ async function runSkillImprover(req) {
|
|
|
67092
67421
|
const gen = await generateSkills({
|
|
67093
67422
|
directory: req.directory,
|
|
67094
67423
|
mode: "draft",
|
|
67095
|
-
minConfidence:
|
|
67096
|
-
minConfirmations:
|
|
67424
|
+
minConfidence: DEFAULT_SKILL_MIN_CONFIDENCE,
|
|
67425
|
+
minConfirmations: DEFAULT_SKILL_MIN_CONFIRMATIONS
|
|
67097
67426
|
});
|
|
67098
67427
|
draftSkillsWritten = gen.written.map((w) => ({
|
|
67099
67428
|
slug: w.slug,
|
|
@@ -67129,7 +67458,7 @@ async function runSkillImprover(req) {
|
|
|
67129
67458
|
unactionableHardening = await hardenUnactionableEntries({
|
|
67130
67459
|
directory: req.directory,
|
|
67131
67460
|
llmDelegate: delegate,
|
|
67132
|
-
quota:
|
|
67461
|
+
quota: req.enrichmentQuota
|
|
67133
67462
|
});
|
|
67134
67463
|
}
|
|
67135
67464
|
const motifResult = await writeMotifProposals(req.directory);
|
|
@@ -67955,8 +68284,8 @@ async function copyDirRecursive(src, dest) {
|
|
|
67955
68284
|
const srcEntry = path48.join(src, entry);
|
|
67956
68285
|
const destEntry = path48.join(dest, entry);
|
|
67957
68286
|
try {
|
|
67958
|
-
const
|
|
67959
|
-
if (
|
|
68287
|
+
const stat5 = await fs23.stat(srcEntry);
|
|
68288
|
+
if (stat5.isDirectory()) {
|
|
67960
68289
|
const subCount = await copyDirRecursive(srcEntry, destEntry).catch(() => 0);
|
|
67961
68290
|
count += subCount;
|
|
67962
68291
|
} else {
|
|
@@ -67992,8 +68321,8 @@ function guaranteeAllPlansComplete(planData) {
|
|
|
67992
68321
|
async function handleCloseCommand(directory, args2, options = {}) {
|
|
67993
68322
|
const swarmDir = path48.join(directory, ".swarm");
|
|
67994
68323
|
try {
|
|
67995
|
-
const
|
|
67996
|
-
if (
|
|
68324
|
+
const stat5 = fsSync5.lstatSync(swarmDir);
|
|
68325
|
+
if (stat5.isSymbolicLink()) {
|
|
67997
68326
|
return `❌ Refused: .swarm/ is a symlink or junction. Refusing to operate on a redirected directory for safety.`;
|
|
67998
68327
|
}
|
|
67999
68328
|
} catch (err2) {
|
|
@@ -68147,12 +68476,11 @@ async function handleCloseCommand(directory, args2, options = {}) {
|
|
|
68147
68476
|
let curationSucceeded = false;
|
|
68148
68477
|
let curationResult;
|
|
68149
68478
|
try {
|
|
68150
|
-
const skillImproverCfg = SkillImproverConfigSchema.parse(loadedConfig.skill_improver ?? {});
|
|
68151
68479
|
curationResult = await curateAndStoreSwarm(allLessons, projectName, { phase_number: 0 }, directory, config3, {
|
|
68152
68480
|
llmDelegate: createCuratorLLMDelegate(directory, "phase", options.sessionID),
|
|
68153
68481
|
enrichmentQuota: {
|
|
68154
|
-
maxCalls:
|
|
68155
|
-
window:
|
|
68482
|
+
maxCalls: config3.enrichment.max_calls_per_day,
|
|
68483
|
+
window: config3.enrichment.quota_window
|
|
68156
68484
|
}
|
|
68157
68485
|
});
|
|
68158
68486
|
curationSucceeded = true;
|
|
@@ -68217,7 +68545,11 @@ async function handleCloseCommand(directory, args2, options = {}) {
|
|
|
68217
68545
|
config: skillImproverConfig,
|
|
68218
68546
|
targets: ["skills", "knowledge"],
|
|
68219
68547
|
mode: "proposal",
|
|
68220
|
-
sessionId: options.sessionID
|
|
68548
|
+
sessionId: options.sessionID,
|
|
68549
|
+
enrichmentQuota: {
|
|
68550
|
+
maxCalls: config3.enrichment.max_calls_per_day,
|
|
68551
|
+
window: config3.enrichment.quota_window
|
|
68552
|
+
}
|
|
68221
68553
|
}, options.skillReviewTimeoutMs ?? CLOSE_SKILL_REVIEW_TIMEOUT_MS);
|
|
68222
68554
|
if (skillReviewResult.ran) {
|
|
68223
68555
|
const proposal = skillReviewResult.proposalPath ? ` Proposal: ${skillReviewResult.proposalPath}.` : "";
|
|
@@ -68986,7 +69318,7 @@ __export(exports_co_change_analyzer, {
|
|
|
68986
69318
|
});
|
|
68987
69319
|
import * as child_process3 from "node:child_process";
|
|
68988
69320
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
68989
|
-
import { readdir as readdir2, readFile as readFile14, stat as
|
|
69321
|
+
import { readdir as readdir2, readFile as readFile14, stat as stat5 } from "node:fs/promises";
|
|
68990
69322
|
import * as path50 from "node:path";
|
|
68991
69323
|
import { promisify } from "node:util";
|
|
68992
69324
|
function getExecFileAsync() {
|
|
@@ -69137,7 +69469,7 @@ async function getStaticEdges(directory) {
|
|
|
69137
69469
|
for (const ext of extensions) {
|
|
69138
69470
|
const testPath = resolvedPath + ext;
|
|
69139
69471
|
try {
|
|
69140
|
-
const testStat = await
|
|
69472
|
+
const testStat = await stat5(testPath);
|
|
69141
69473
|
if (testStat.isFile()) {
|
|
69142
69474
|
targetFile = testPath;
|
|
69143
69475
|
break;
|
|
@@ -75517,7 +75849,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
75517
75849
|
// src/hooks/knowledge-migrator.ts
|
|
75518
75850
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
75519
75851
|
import { existsSync as existsSync33, readFileSync as readFileSync18 } from "node:fs";
|
|
75520
|
-
import { mkdir as mkdir13, readFile as readFile16, writeFile as
|
|
75852
|
+
import { mkdir as mkdir13, readFile as readFile16, writeFile as writeFile12 } from "node:fs/promises";
|
|
75521
75853
|
import * as os13 from "node:os";
|
|
75522
75854
|
import * as path58 from "node:path";
|
|
75523
75855
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
@@ -75866,7 +76198,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
75866
76198
|
migration_tool: "knowledge-migrator.ts"
|
|
75867
76199
|
};
|
|
75868
76200
|
await mkdir13(path58.dirname(sentinelPath), { recursive: true });
|
|
75869
|
-
await
|
|
76201
|
+
await writeFile12(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
75870
76202
|
}
|
|
75871
76203
|
function resolveLegacyHiveKnowledgePath() {
|
|
75872
76204
|
const platform = process.platform;
|
|
@@ -76297,7 +76629,7 @@ var init_redaction = __esm(() => {
|
|
|
76297
76629
|
});
|
|
76298
76630
|
|
|
76299
76631
|
// src/memory/schema.ts
|
|
76300
|
-
import { createHash as
|
|
76632
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
76301
76633
|
function normalizeMemoryText(text) {
|
|
76302
76634
|
return text.replace(/\s+/g, " ").trim();
|
|
76303
76635
|
}
|
|
@@ -76321,7 +76653,7 @@ function stableScopeKey(scope) {
|
|
|
76321
76653
|
}
|
|
76322
76654
|
function computeMemoryContentHash(recordLike) {
|
|
76323
76655
|
const normalized = normalizeMemoryText(recordLike.text).toLowerCase();
|
|
76324
|
-
return
|
|
76656
|
+
return createHash7("sha256").update(`${stableScopeKey(recordLike.scope)}
|
|
76325
76657
|
${recordLike.kind}
|
|
76326
76658
|
${normalized}`).digest("hex");
|
|
76327
76659
|
}
|
|
@@ -76329,14 +76661,14 @@ function createMemoryId(recordLike) {
|
|
|
76329
76661
|
return `mem_${computeMemoryContentHash(recordLike).slice(0, 16)}`;
|
|
76330
76662
|
}
|
|
76331
76663
|
function createProposalId(input) {
|
|
76332
|
-
const hash4 =
|
|
76664
|
+
const hash4 = createHash7("sha256").update(`${input.createdAt}
|
|
76333
76665
|
${input.proposer}
|
|
76334
76666
|
${normalizeMemoryText(input.text)}`).digest("hex");
|
|
76335
76667
|
return `prop_${hash4.slice(0, 16)}`;
|
|
76336
76668
|
}
|
|
76337
76669
|
function createBundleId(query, generatedAt) {
|
|
76338
76670
|
const compactTimestamp = generatedAt.replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
76339
|
-
const hash4 =
|
|
76671
|
+
const hash4 = createHash7("sha256").update(`${generatedAt}
|
|
76340
76672
|
${query}`).digest("hex").slice(0, 8);
|
|
76341
76673
|
return `bundle_${compactTimestamp}_${hash4}`;
|
|
76342
76674
|
}
|
|
@@ -77088,7 +77420,7 @@ import {
|
|
|
77088
77420
|
mkdir as mkdir14,
|
|
77089
77421
|
readFile as readFile17,
|
|
77090
77422
|
rename as rename8,
|
|
77091
|
-
writeFile as
|
|
77423
|
+
writeFile as writeFile13
|
|
77092
77424
|
} from "node:fs/promises";
|
|
77093
77425
|
import * as path59 from "node:path";
|
|
77094
77426
|
|
|
@@ -77499,7 +77831,7 @@ async function writeJsonlAtomic(filePath, values) {
|
|
|
77499
77831
|
const content = values.map((value) => JSON.stringify(value)).join(`
|
|
77500
77832
|
`) + (values.length > 0 ? `
|
|
77501
77833
|
` : "");
|
|
77502
|
-
await
|
|
77834
|
+
await writeFile13(tmp, content, "utf-8");
|
|
77503
77835
|
await rename8(tmp, filePath);
|
|
77504
77836
|
}
|
|
77505
77837
|
var init_local_jsonl_provider = __esm(() => {
|
|
@@ -77594,7 +77926,7 @@ var init_prompt_block = __esm(() => {
|
|
|
77594
77926
|
|
|
77595
77927
|
// src/memory/jsonl-migration.ts
|
|
77596
77928
|
import { existsSync as existsSync35 } from "node:fs";
|
|
77597
|
-
import { copyFile, mkdir as mkdir15, readFile as readFile18, stat as
|
|
77929
|
+
import { copyFile, mkdir as mkdir15, readFile as readFile18, stat as stat6, writeFile as writeFile14 } from "node:fs/promises";
|
|
77598
77930
|
import * as path60 from "node:path";
|
|
77599
77931
|
function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
|
|
77600
77932
|
const resolved = resolveConfig(config3);
|
|
@@ -77642,14 +77974,14 @@ async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
|
|
|
77642
77974
|
await mkdir15(exportDir, { recursive: true });
|
|
77643
77975
|
const memoriesPath = path60.join(exportDir, "memories.jsonl");
|
|
77644
77976
|
const proposalsPath = path60.join(exportDir, "proposals.jsonl");
|
|
77645
|
-
await
|
|
77646
|
-
await
|
|
77977
|
+
await writeFile14(memoriesPath, toJsonl(memories), "utf-8");
|
|
77978
|
+
await writeFile14(proposalsPath, toJsonl(proposals), "utf-8");
|
|
77647
77979
|
return { directory: exportDir, memoriesPath, proposalsPath };
|
|
77648
77980
|
}
|
|
77649
77981
|
async function writeMigrationReport(rootDirectory, report, config3 = {}) {
|
|
77650
77982
|
const reportPath = path60.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
77651
77983
|
await mkdir15(path60.dirname(reportPath), { recursive: true });
|
|
77652
|
-
await
|
|
77984
|
+
await writeFile14(reportPath, `${JSON.stringify(report, null, 2)}
|
|
77653
77985
|
`, "utf-8");
|
|
77654
77986
|
return reportPath;
|
|
77655
77987
|
}
|
|
@@ -77670,7 +78002,7 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
|
|
|
77670
78002
|
const filePath = path60.join(storageDir, file3);
|
|
77671
78003
|
let sizeBytes = 0;
|
|
77672
78004
|
if (existsSync35(filePath)) {
|
|
77673
|
-
sizeBytes = (await
|
|
78005
|
+
sizeBytes = (await stat6(filePath)).size;
|
|
77674
78006
|
}
|
|
77675
78007
|
statuses.push({
|
|
77676
78008
|
file: file3,
|
|
@@ -78719,7 +79051,7 @@ var init_sqlite_provider = __esm(() => {
|
|
|
78719
79051
|
});
|
|
78720
79052
|
|
|
78721
79053
|
// src/memory/gateway.ts
|
|
78722
|
-
import { createHash as
|
|
79054
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
78723
79055
|
import { existsSync as existsSync36, readFileSync as readFileSync19 } from "node:fs";
|
|
78724
79056
|
import * as path62 from "node:path";
|
|
78725
79057
|
|
|
@@ -79039,7 +79371,7 @@ function sourceFromEvidence(evidenceRefs, context) {
|
|
|
79039
79371
|
return { type: "manual", ref: first };
|
|
79040
79372
|
}
|
|
79041
79373
|
function createStableId(value) {
|
|
79042
|
-
return
|
|
79374
|
+
return createHash8("sha256").update(value.toLowerCase()).digest("hex").slice(0, 16);
|
|
79043
79375
|
}
|
|
79044
79376
|
function readGitRemoteUrl(directory) {
|
|
79045
79377
|
if (gitRemoteUrlCache.has(directory))
|
|
@@ -82192,8 +82524,8 @@ var init_secretscan = __esm(() => {
|
|
|
82192
82524
|
break;
|
|
82193
82525
|
const fileFindings = scanFileForSecrets(filePath);
|
|
82194
82526
|
try {
|
|
82195
|
-
const
|
|
82196
|
-
if (
|
|
82527
|
+
const stat7 = fs30.statSync(filePath);
|
|
82528
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES) {
|
|
82197
82529
|
skippedFiles++;
|
|
82198
82530
|
continue;
|
|
82199
82531
|
}
|
|
@@ -83003,8 +83335,8 @@ function sharedTrailingSegments(a, b) {
|
|
|
83003
83335
|
function isCacheStale(impactMap, generatedAtMs) {
|
|
83004
83336
|
for (const sourcePath of Object.keys(impactMap)) {
|
|
83005
83337
|
try {
|
|
83006
|
-
const
|
|
83007
|
-
if (
|
|
83338
|
+
const stat7 = fs34.statSync(sourcePath);
|
|
83339
|
+
if (stat7.mtimeMs > generatedAtMs) {
|
|
83008
83340
|
return true;
|
|
83009
83341
|
}
|
|
83010
83342
|
} catch {
|
|
@@ -84350,8 +84682,8 @@ function manifestHash(dir) {
|
|
|
84350
84682
|
if (!entries.has(name2))
|
|
84351
84683
|
continue;
|
|
84352
84684
|
try {
|
|
84353
|
-
const
|
|
84354
|
-
parts2.push(`${name2}:${
|
|
84685
|
+
const stat7 = fs39.statSync(path77.join(dir, name2));
|
|
84686
|
+
parts2.push(`${name2}:${stat7.size}:${stat7.mtimeMs}:${stat7.ino}`);
|
|
84355
84687
|
} catch {}
|
|
84356
84688
|
}
|
|
84357
84689
|
return parts2.join("|");
|
|
@@ -94335,6 +94667,7 @@ SKILL COMPLIANCE REVIEW: When SKILLS_USED_BY_CODER is provided and not "none":
|
|
|
94335
94667
|
- For each skill rule, verify the coder's changes comply
|
|
94336
94668
|
- Flag violations at the same severity as logic errors
|
|
94337
94669
|
- Report the overall compliance verdict in SKILL_COMPLIANCE field of your output
|
|
94670
|
+
- Report TASK: <task id> immediately before SKILL_COMPLIANCE when a task id is available
|
|
94338
94671
|
- If you cannot load a skill (SKILL_LOAD_FAILED), report SKILL_COMPLIANCE: PARTIAL — [skill path] could not be loaded
|
|
94339
94672
|
|
|
94340
94673
|
PROCESSING: If GATES is provided and includes passing results for lint, SAST, placeholder-scan, or secret-scan: skip the corresponding Tier 2 checks that those gates already cover. Focus Tier 2 time on checks NOT covered by automated gates.
|
|
@@ -94346,6 +94679,7 @@ VERDICT: APPROVED | REJECTED
|
|
|
94346
94679
|
REUSE_RE_VERIFICATION: [VERIFIED | DUPLICATION_DETECTED | SKIPPED] — DUPLICATION_DETECTED is only valid when VERDICT is REJECTED
|
|
94347
94680
|
RISK: LOW | MEDIUM | HIGH | CRITICAL
|
|
94348
94681
|
ISSUES: list with line numbers, grouped by CHECK dimension
|
|
94682
|
+
TASK: [task id being reviewed, or "unknown"]
|
|
94349
94683
|
SKILL_COMPLIANCE: COMPLIANT | PARTIAL | VIOLATED — [list of violations or "all rules followed"]
|
|
94350
94684
|
DIRECTIVE_COMPLIANCE: one line per knowledge directive shown during this phase (IDs listed in the DIRECTIVES TO VERIFY block of your prompt, when present). Use exactly one of:
|
|
94351
94685
|
VERIFIED:<id> evidence=<file:line | predicate_passed>
|
|
@@ -94926,7 +95260,7 @@ COVERAGE REPORTING:
|
|
|
94926
95260
|
`;
|
|
94927
95261
|
|
|
94928
95262
|
// src/agents/index.ts
|
|
94929
|
-
import { mkdir as mkdir17, writeFile as
|
|
95263
|
+
import { mkdir as mkdir17, writeFile as writeFile15 } from "node:fs/promises";
|
|
94930
95264
|
import * as path88 from "node:path";
|
|
94931
95265
|
function stripSwarmPrefix(agentName, swarmPrefix) {
|
|
94932
95266
|
if (!swarmPrefix || !agentName)
|
|
@@ -95406,7 +95740,7 @@ function getAgentConfigs(config3, directory, sessionId, projectContext) {
|
|
|
95406
95740
|
generatedAt: new Date().toISOString(),
|
|
95407
95741
|
agents: agentToolSnapshot
|
|
95408
95742
|
}, null, 2);
|
|
95409
|
-
mkdir17(evidenceDir, { recursive: true }).then(() =>
|
|
95743
|
+
mkdir17(evidenceDir, { recursive: true }).then(() => writeFile15(path88.join(evidenceDir, filename), snapshotData)).catch(() => {});
|
|
95410
95744
|
}
|
|
95411
95745
|
return result;
|
|
95412
95746
|
}
|
|
@@ -100118,8 +100452,8 @@ import {
|
|
|
100118
100452
|
readdir as readdir6,
|
|
100119
100453
|
readFile as readFile22,
|
|
100120
100454
|
realpath as realpath3,
|
|
100121
|
-
stat as
|
|
100122
|
-
writeFile as
|
|
100455
|
+
stat as stat9,
|
|
100456
|
+
writeFile as writeFile17
|
|
100123
100457
|
} from "node:fs/promises";
|
|
100124
100458
|
import * as path119 from "node:path";
|
|
100125
100459
|
function normalizeSeparators(filePath) {
|
|
@@ -100201,8 +100535,8 @@ async function scanDocIndex(directory) {
|
|
|
100201
100535
|
for (const file3 of existingManifest.files) {
|
|
100202
100536
|
try {
|
|
100203
100537
|
const fullPath = path119.join(directory, file3.path);
|
|
100204
|
-
const
|
|
100205
|
-
if (
|
|
100538
|
+
const stat10 = fs71.statSync(fullPath);
|
|
100539
|
+
if (stat10.mtimeMs > file3.mtime) {
|
|
100206
100540
|
cacheValid = false;
|
|
100207
100541
|
break;
|
|
100208
100542
|
}
|
|
@@ -100240,7 +100574,7 @@ async function scanDocIndex(directory) {
|
|
|
100240
100574
|
const rel = path119.relative(resolvedDirectory, resolved);
|
|
100241
100575
|
if (rel.startsWith("..") || path119.isAbsolute(rel))
|
|
100242
100576
|
continue;
|
|
100243
|
-
const targetStat = await
|
|
100577
|
+
const targetStat = await stat9(symlinkPath);
|
|
100244
100578
|
isFile = targetStat.isFile();
|
|
100245
100579
|
} catch {
|
|
100246
100580
|
continue;
|
|
@@ -100269,7 +100603,7 @@ async function scanDocIndex(directory) {
|
|
|
100269
100603
|
continue;
|
|
100270
100604
|
let fileStat;
|
|
100271
100605
|
try {
|
|
100272
|
-
fileStat = await
|
|
100606
|
+
fileStat = await stat9(fullPath);
|
|
100273
100607
|
} catch {
|
|
100274
100608
|
continue;
|
|
100275
100609
|
}
|
|
@@ -100317,7 +100651,7 @@ async function scanDocIndex(directory) {
|
|
|
100317
100651
|
};
|
|
100318
100652
|
try {
|
|
100319
100653
|
await mkdir20(path119.dirname(manifestPath), { recursive: true });
|
|
100320
|
-
await
|
|
100654
|
+
await writeFile17(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
100321
100655
|
} catch {}
|
|
100322
100656
|
return { manifest, cached: false };
|
|
100323
100657
|
}
|
|
@@ -101004,7 +101338,7 @@ async function searchKnowledge(params) {
|
|
|
101004
101338
|
const confBoost = context && entry.confidence >= minConf && (ds.actionHit || ds.agentHit) ? 0.25 : 0;
|
|
101005
101339
|
const generatedSkillBoost = entry.generated_skill_path && entry.status !== "archived" ? 0.05 : 0;
|
|
101006
101340
|
const outcomeBoost = computeOutcomeSignal(retrievalOutcomes) * OUTCOME_RANK_WEIGHT;
|
|
101007
|
-
const coldStartBonus = retrievalOutcomes.
|
|
101341
|
+
const coldStartBonus = (retrievalOutcomes.applied_explicit_count ?? 0) === 0 && entryAgePhases(entry) < (config3.retrieval?.cold_start_max_age_phases ?? DEFAULT_COLD_START_MAX_AGE_PHASES) ? config3.retrieval?.cold_start_bonus ?? DEFAULT_COLD_START_BONUS : 0;
|
|
101008
101342
|
let synonymBoost = 0;
|
|
101009
101343
|
if (synonymTokens.length > 0) {
|
|
101010
101344
|
const entryHay = normalize4(entryText(entry));
|
|
@@ -101029,6 +101363,7 @@ async function searchKnowledge(params) {
|
|
|
101029
101363
|
...entry,
|
|
101030
101364
|
retrieval_outcomes: retrievalOutcomes,
|
|
101031
101365
|
finalScore,
|
|
101366
|
+
coldStartBoost: coldStartBonus,
|
|
101032
101367
|
__critical: isCritical
|
|
101033
101368
|
};
|
|
101034
101369
|
});
|
|
@@ -101060,7 +101395,8 @@ async function searchKnowledge(params) {
|
|
|
101060
101395
|
}
|
|
101061
101396
|
}
|
|
101062
101397
|
results = top.map(({ __critical: _c, ...rest }) => rest);
|
|
101063
|
-
} catch {
|
|
101398
|
+
} catch (err2) {
|
|
101399
|
+
warn(`[search-knowledge] retrieval failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
101064
101400
|
results = [];
|
|
101065
101401
|
}
|
|
101066
101402
|
if (emitEvent) {
|
|
@@ -101100,6 +101436,7 @@ var TEXT_WEIGHT = 0.6, META_WEIGHT = 0.4, DIRECTIVE_BOOST_MIN_CONFIDENCE = 0.75,
|
|
|
101100
101436
|
var init_search_knowledge = __esm(() => {
|
|
101101
101437
|
init_schema();
|
|
101102
101438
|
init_synonym_map();
|
|
101439
|
+
init_logger();
|
|
101103
101440
|
init_knowledge_events();
|
|
101104
101441
|
init_knowledge_reader();
|
|
101105
101442
|
init_knowledge_store();
|
|
@@ -101485,8 +101822,8 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
101485
101822
|
const traceabilityAbs = path165.join(outAbs, TRACEABILITY_REL);
|
|
101486
101823
|
let registry3 = null;
|
|
101487
101824
|
try {
|
|
101488
|
-
const
|
|
101489
|
-
if (
|
|
101825
|
+
const stat11 = await fs112.promises.stat(traceabilityAbs);
|
|
101826
|
+
if (stat11.size <= MAX_TRACEABILITY_BYTES) {
|
|
101490
101827
|
const raw = await fs112.promises.readFile(traceabilityAbs, "utf-8");
|
|
101491
101828
|
const parsed = JSON.parse(raw);
|
|
101492
101829
|
registry3 = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
@@ -102799,8 +103136,8 @@ function writeProjectConfigIfNew(directory, quiet = false) {
|
|
|
102799
103136
|
const dest = path92.join(opencodeDir, "opencode-swarm.json");
|
|
102800
103137
|
const normalizePathForCompare = (p) => process.platform === "win32" ? p.toLowerCase() : p;
|
|
102801
103138
|
try {
|
|
102802
|
-
const
|
|
102803
|
-
if (
|
|
103139
|
+
const stat7 = fs50.lstatSync(opencodeDir);
|
|
103140
|
+
if (stat7.isSymbolicLink())
|
|
102804
103141
|
return;
|
|
102805
103142
|
const resolvedDir = fs50.realpathSync(opencodeDir);
|
|
102806
103143
|
const canonicalOpencode = path92.join(fs50.realpathSync(directory), ".opencode");
|
|
@@ -102973,8 +103310,8 @@ function extractFileSummary(filePath, content, absolutePath, existingEntry) {
|
|
|
102973
103310
|
let mtimeMs = 0;
|
|
102974
103311
|
if (absolutePath) {
|
|
102975
103312
|
try {
|
|
102976
|
-
const
|
|
102977
|
-
mtimeMs =
|
|
103313
|
+
const stat7 = fs52.statSync(absolutePath);
|
|
103314
|
+
mtimeMs = stat7.mtimeMs;
|
|
102978
103315
|
} catch {}
|
|
102979
103316
|
}
|
|
102980
103317
|
const base = {
|
|
@@ -105924,9 +106261,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner, dele
|
|
|
105924
106261
|
const initResult = await runner(directory, curatorConfig, llmDelegate);
|
|
105925
106262
|
if (initResult.briefing) {
|
|
105926
106263
|
const briefingPath = path103.join(directory, ".swarm", "curator-briefing.md");
|
|
105927
|
-
const { mkdir: mkdir18, writeFile:
|
|
106264
|
+
const { mkdir: mkdir18, writeFile: writeFile16 } = await import("node:fs/promises");
|
|
105928
106265
|
await mkdir18(path103.dirname(briefingPath), { recursive: true });
|
|
105929
|
-
await
|
|
106266
|
+
await writeFile16(briefingPath, initResult.briefing, "utf-8");
|
|
105930
106267
|
const { buildApprovedReceipt: buildApprovedReceipt2, persistReviewReceipt: persistReviewReceipt2 } = await Promise.resolve().then(() => (init_review_receipt(), exports_review_receipt));
|
|
105931
106268
|
const initReceipt = buildApprovedReceipt2({
|
|
105932
106269
|
agent: "curator",
|
|
@@ -108515,16 +108852,16 @@ function tryResolveTSJS(rawModule, sourceFileAbs) {
|
|
|
108515
108852
|
for (const ext of RESOLVE_EXTENSION_CANDIDATES) {
|
|
108516
108853
|
const test = basePath + ext;
|
|
108517
108854
|
try {
|
|
108518
|
-
const
|
|
108519
|
-
if (
|
|
108855
|
+
const stat9 = fs66.statSync(test);
|
|
108856
|
+
if (stat9.isFile())
|
|
108520
108857
|
return test;
|
|
108521
108858
|
} catch {}
|
|
108522
108859
|
}
|
|
108523
108860
|
for (const indexFile of RESOLVE_INDEX_CANDIDATES) {
|
|
108524
108861
|
const test = path113.join(basePath, indexFile);
|
|
108525
108862
|
try {
|
|
108526
|
-
const
|
|
108527
|
-
if (
|
|
108863
|
+
const stat9 = fs66.statSync(test);
|
|
108864
|
+
if (stat9.isFile())
|
|
108528
108865
|
return test;
|
|
108529
108866
|
} catch {}
|
|
108530
108867
|
}
|
|
@@ -108555,8 +108892,8 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
108555
108892
|
const baseAbs = path113.resolve(sourceDir, upDirs + remainder);
|
|
108556
108893
|
const accept = (test) => {
|
|
108557
108894
|
try {
|
|
108558
|
-
const
|
|
108559
|
-
if (
|
|
108895
|
+
const stat9 = fs66.statSync(test);
|
|
108896
|
+
if (stat9.isFile()) {
|
|
108560
108897
|
const rel = path113.relative(workspaceRoot, test).replace(/\\/g, "/");
|
|
108561
108898
|
if (rel.startsWith(".."))
|
|
108562
108899
|
return null;
|
|
@@ -109409,8 +109746,8 @@ function saveGraph2(workspaceRoot, graph) {
|
|
|
109409
109746
|
const file3 = getGraphPath2(workspaceRoot);
|
|
109410
109747
|
const dir = path116.dirname(file3);
|
|
109411
109748
|
try {
|
|
109412
|
-
const
|
|
109413
|
-
if (
|
|
109749
|
+
const stat9 = fs68.lstatSync(dir);
|
|
109750
|
+
if (stat9.isSymbolicLink()) {
|
|
109414
109751
|
throw new Error(`refusing to write graph: ${SWARM_DIR}/ is a symbolic link`);
|
|
109415
109752
|
}
|
|
109416
109753
|
} catch (err2) {
|
|
@@ -109446,15 +109783,15 @@ function isGraphFresh(graph, maxAgeMs = 5 * 60 * 1000) {
|
|
|
109446
109783
|
var cache2 = new Map;
|
|
109447
109784
|
function getCachedGraph2(directory) {
|
|
109448
109785
|
const file3 = getGraphPath2(directory);
|
|
109449
|
-
let
|
|
109786
|
+
let stat9;
|
|
109450
109787
|
try {
|
|
109451
|
-
|
|
109788
|
+
stat9 = fs69.statSync(file3);
|
|
109452
109789
|
} catch {
|
|
109453
109790
|
cache2.delete(directory);
|
|
109454
109791
|
return null;
|
|
109455
109792
|
}
|
|
109456
109793
|
const cached3 = cache2.get(directory);
|
|
109457
|
-
if (cached3 && cached3.mtimeMs ===
|
|
109794
|
+
if (cached3 && cached3.mtimeMs === stat9.mtimeMs && cached3.size === stat9.size) {
|
|
109458
109795
|
return cached3.graph;
|
|
109459
109796
|
}
|
|
109460
109797
|
const graph = loadGraph2(directory);
|
|
@@ -109462,7 +109799,7 @@ function getCachedGraph2(directory) {
|
|
|
109462
109799
|
cache2.delete(directory);
|
|
109463
109800
|
return null;
|
|
109464
109801
|
}
|
|
109465
|
-
cache2.set(directory, { graph, mtimeMs:
|
|
109802
|
+
cache2.set(directory, { graph, mtimeMs: stat9.mtimeMs, size: stat9.size });
|
|
109466
109803
|
return graph;
|
|
109467
109804
|
}
|
|
109468
109805
|
function buildCoderLocalizationBlock(directory, targetFile) {
|
|
@@ -112023,6 +112360,7 @@ import { appendFile as appendFile13, mkdir as mkdir22 } from "node:fs/promises";
|
|
|
112023
112360
|
import * as path124 from "node:path";
|
|
112024
112361
|
|
|
112025
112362
|
// src/hooks/knowledge-application.ts
|
|
112363
|
+
init_task_file();
|
|
112026
112364
|
init_logger();
|
|
112027
112365
|
init_knowledge_store();
|
|
112028
112366
|
var import_proper_lockfile9 = __toESM(require_proper_lockfile(), 1);
|
|
@@ -112032,6 +112370,7 @@ import * as path122 from "node:path";
|
|
|
112032
112370
|
function resolveApplicationLogPath(directory) {
|
|
112033
112371
|
return path122.join(directory, ".swarm", "knowledge-application.jsonl");
|
|
112034
112372
|
}
|
|
112373
|
+
var MAX_LEGACY_APPLICATION_LOG_ENTRIES = 5000;
|
|
112035
112374
|
var ACK_PATTERN = /KNOWLEDGE_(APPLIED|IGNORED|VIOLATED|N_A)\s*:\s*([0-9a-fA-F-]{8,64})(?:\s+reason\s*=\s*([^\n\r]+?))?(?=$|[\n\r]|\s+KNOWLEDGE_)/g;
|
|
112036
112375
|
function parseAcknowledgments(text) {
|
|
112037
112376
|
if (!text || typeof text !== "string")
|
|
@@ -112048,9 +112387,29 @@ function parseAcknowledgments(text) {
|
|
|
112048
112387
|
}
|
|
112049
112388
|
async function appendAudit(directory, record3) {
|
|
112050
112389
|
const filePath = resolveApplicationLogPath(directory);
|
|
112051
|
-
|
|
112052
|
-
await
|
|
112390
|
+
const dirPath = path122.dirname(filePath);
|
|
112391
|
+
await mkdir21(dirPath, { recursive: true });
|
|
112392
|
+
let release;
|
|
112393
|
+
try {
|
|
112394
|
+
release = await import_proper_lockfile9.default.lock(dirPath, {
|
|
112395
|
+
retries: { retries: 50, minTimeout: 10, maxTimeout: 100 },
|
|
112396
|
+
stale: 5000
|
|
112397
|
+
});
|
|
112398
|
+
await appendFile11(filePath, `${JSON.stringify(record3)}
|
|
112053
112399
|
`, "utf-8");
|
|
112400
|
+
const content = await readFile24(filePath, "utf-8");
|
|
112401
|
+
const lines = content.split(`
|
|
112402
|
+
`).filter((line) => line.trim().length > 0);
|
|
112403
|
+
if (lines.length > MAX_LEGACY_APPLICATION_LOG_ENTRIES) {
|
|
112404
|
+
const trimmed = lines.slice(-MAX_LEGACY_APPLICATION_LOG_ENTRIES);
|
|
112405
|
+
await atomicWriteFile(filePath, `${trimmed.join(`
|
|
112406
|
+
`)}
|
|
112407
|
+
`);
|
|
112408
|
+
}
|
|
112409
|
+
} finally {
|
|
112410
|
+
if (release)
|
|
112411
|
+
await release().catch(() => {});
|
|
112412
|
+
}
|
|
112054
112413
|
}
|
|
112055
112414
|
async function bumpCountersBatch(directory, bumps) {
|
|
112056
112415
|
const filteredBumps = bumps.filter((b) => b.ids.length > 0);
|
|
@@ -112088,14 +112447,10 @@ async function bumpCountersBatch(directory, bumps) {
|
|
|
112088
112447
|
return updated;
|
|
112089
112448
|
};
|
|
112090
112449
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
112091
|
-
|
|
112092
|
-
if (applyOne(swarm))
|
|
112093
|
-
await rewriteKnowledge(swarmPath, swarm);
|
|
112450
|
+
await transactKnowledge(swarmPath, (swarm) => applyOne(swarm) ? swarm : null);
|
|
112094
112451
|
const hivePath = resolveHiveKnowledgePath();
|
|
112095
112452
|
if (existsSync69(hivePath)) {
|
|
112096
|
-
|
|
112097
|
-
if (applyOne(hive))
|
|
112098
|
-
await rewriteKnowledge(hivePath, hive);
|
|
112453
|
+
await transactKnowledge(hivePath, (hive) => applyOne(hive) ? hive : null);
|
|
112099
112454
|
}
|
|
112100
112455
|
}
|
|
112101
112456
|
async function bumpCounters(directory, ids, field) {
|
|
@@ -112165,7 +112520,7 @@ init_knowledge_events();
|
|
|
112165
112520
|
// src/hooks/knowledge-injector.ts
|
|
112166
112521
|
init_schema();
|
|
112167
112522
|
init_manager();
|
|
112168
|
-
import { createHash as
|
|
112523
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
112169
112524
|
|
|
112170
112525
|
// src/services/run-memory.ts
|
|
112171
112526
|
import * as crypto11 from "node:crypto";
|
|
@@ -112342,6 +112697,7 @@ init_extractors();
|
|
|
112342
112697
|
init_knowledge_escalator();
|
|
112343
112698
|
init_knowledge_events();
|
|
112344
112699
|
init_knowledge_store();
|
|
112700
|
+
init_model_limits();
|
|
112345
112701
|
init_search_knowledge();
|
|
112346
112702
|
init_utils2();
|
|
112347
112703
|
var INJECTION_SENTINEL = `${String.fromCharCode(8204)}[[KNOWLEDGE-INJECTED]]`;
|
|
@@ -112658,7 +113014,7 @@ function injectKnowledgeMessage(output, text) {
|
|
|
112658
113014
|
};
|
|
112659
113015
|
output.messages.splice(insertIdx, 0, knowledgeMessage);
|
|
112660
113016
|
}
|
|
112661
|
-
function createKnowledgeInjectorHook(directory, config3) {
|
|
113017
|
+
function createKnowledgeInjectorHook(directory, config3, modelLimitOverrides = {}) {
|
|
112662
113018
|
function buildContextCacheKey(phase, ctx) {
|
|
112663
113019
|
const parts2 = [
|
|
112664
113020
|
String(phase),
|
|
@@ -112668,7 +113024,7 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
112668
113024
|
ctx.taskId ?? "",
|
|
112669
113025
|
(ctx.filePaths ?? []).slice(0, 8).join(",")
|
|
112670
113026
|
].join("|");
|
|
112671
|
-
return
|
|
113027
|
+
return createHash12("sha1").update(parts2).digest("hex").slice(0, 16);
|
|
112672
113028
|
}
|
|
112673
113029
|
let lastSeenCacheKey = null;
|
|
112674
113030
|
let cachedInjectionText = null;
|
|
@@ -112679,7 +113035,9 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
112679
113035
|
const plan = await loadPlan(directory);
|
|
112680
113036
|
const currentPhase = plan?.current_phase ?? 1;
|
|
112681
113037
|
const CHARS_PER_TOKEN = 1 / 0.33;
|
|
112682
|
-
const
|
|
113038
|
+
const { modelID, providerID } = extractModelInfo(output.messages);
|
|
113039
|
+
const modelLimitTokens = resolveModelLimit(modelID, providerID, modelLimitOverrides);
|
|
113040
|
+
const MODEL_LIMIT_CHARS = Math.floor(modelLimitTokens * CHARS_PER_TOKEN);
|
|
112683
113041
|
const existingChars = output.messages.reduce((sum, msg) => {
|
|
112684
113042
|
return sum + (msg.parts?.reduce((s, p) => s + (p.text?.length ?? 0), 0) ?? 0);
|
|
112685
113043
|
}, 0);
|
|
@@ -115919,8 +116277,8 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
|
|
|
115919
116277
|
continue;
|
|
115920
116278
|
const filePath = path131.join(dirPath, entry.name);
|
|
115921
116279
|
try {
|
|
115922
|
-
const
|
|
115923
|
-
if (now -
|
|
116280
|
+
const stat11 = await fs81.stat(filePath);
|
|
116281
|
+
if (now - stat11.mtimeMs > cutoffMs) {
|
|
115924
116282
|
await fs81.unlink(filePath);
|
|
115925
116283
|
}
|
|
115926
116284
|
} catch {}
|
|
@@ -118786,8 +119144,8 @@ function estimateCyclomaticComplexity(content) {
|
|
|
118786
119144
|
}
|
|
118787
119145
|
function getComplexityForFile(filePath) {
|
|
118788
119146
|
try {
|
|
118789
|
-
const
|
|
118790
|
-
if (
|
|
119147
|
+
const stat11 = fs87.statSync(filePath);
|
|
119148
|
+
if (stat11.size > MAX_FILE_SIZE_BYTES4) {
|
|
118791
119149
|
return null;
|
|
118792
119150
|
}
|
|
118793
119151
|
const content = fs87.readFileSync(filePath, "utf-8");
|
|
@@ -118988,8 +119346,8 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
118988
119346
|
continue;
|
|
118989
119347
|
}
|
|
118990
119348
|
try {
|
|
118991
|
-
const
|
|
118992
|
-
if (
|
|
119349
|
+
const stat11 = fs87.statSync(fullPath);
|
|
119350
|
+
if (stat11.size > MAX_FILE_SIZE_BYTES4) {
|
|
118993
119351
|
continue;
|
|
118994
119352
|
}
|
|
118995
119353
|
const content = fs87.readFileSync(fullPath, "utf-8");
|
|
@@ -119449,8 +119807,8 @@ async function getGitChurn(days, directory) {
|
|
|
119449
119807
|
}
|
|
119450
119808
|
function getComplexityForFile2(filePath) {
|
|
119451
119809
|
try {
|
|
119452
|
-
const
|
|
119453
|
-
if (
|
|
119810
|
+
const stat11 = fs88.statSync(filePath);
|
|
119811
|
+
if (stat11.size > MAX_FILE_SIZE_BYTES5) {
|
|
119454
119812
|
return null;
|
|
119455
119813
|
}
|
|
119456
119814
|
const content = fs88.readFileSync(filePath, "utf-8");
|
|
@@ -121919,8 +122277,8 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
121919
122277
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
121920
122278
|
continue;
|
|
121921
122279
|
}
|
|
121922
|
-
const
|
|
121923
|
-
if (!
|
|
122280
|
+
const stat11 = fs93.lstatSync(filePath);
|
|
122281
|
+
if (!stat11.isFile()) {
|
|
121924
122282
|
continue;
|
|
121925
122283
|
}
|
|
121926
122284
|
} catch {
|
|
@@ -122342,11 +122700,11 @@ var external_skill_delete = createSwarmTool({
|
|
|
122342
122700
|
// src/tools/external-skill-discover.ts
|
|
122343
122701
|
init_zod();
|
|
122344
122702
|
init_loader();
|
|
122345
|
-
import { createHash as
|
|
122703
|
+
import { createHash as createHash14, randomUUID as randomUUID13 } from "node:crypto";
|
|
122346
122704
|
|
|
122347
122705
|
// src/services/external-skill-validator.ts
|
|
122348
122706
|
init_knowledge_validator();
|
|
122349
|
-
import { createHash as
|
|
122707
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
122350
122708
|
var PROMPT_INJECTION_PATTERNS = [
|
|
122351
122709
|
{
|
|
122352
122710
|
pattern: /system\s*:/i,
|
|
@@ -122480,31 +122838,31 @@ var UNSAFE_INSTRUCTION_PATTERNS = [
|
|
|
122480
122838
|
pattern: /\bkill\s+-9\b/,
|
|
122481
122839
|
name: "force_kill",
|
|
122482
122840
|
description: "Force process termination",
|
|
122483
|
-
severity: "
|
|
122841
|
+
severity: "warning"
|
|
122484
122842
|
},
|
|
122485
122843
|
{
|
|
122486
122844
|
pattern: /\bpkill\b/,
|
|
122487
122845
|
name: "process_group_kill",
|
|
122488
122846
|
description: "Process group kill",
|
|
122489
|
-
severity: "
|
|
122847
|
+
severity: "warning"
|
|
122490
122848
|
},
|
|
122491
122849
|
{
|
|
122492
122850
|
pattern: /\bkillall\b/,
|
|
122493
122851
|
name: "kill_all_processes",
|
|
122494
122852
|
description: "Kill all processes by name",
|
|
122495
|
-
severity: "
|
|
122853
|
+
severity: "warning"
|
|
122496
122854
|
},
|
|
122497
122855
|
{
|
|
122498
122856
|
pattern: /`[^`]*`/,
|
|
122499
122857
|
name: "backtick_execution",
|
|
122500
122858
|
description: "Backtick shell execution",
|
|
122501
|
-
severity: "
|
|
122859
|
+
severity: "warning"
|
|
122502
122860
|
},
|
|
122503
122861
|
{
|
|
122504
122862
|
pattern: /\$\([^)]*\)/,
|
|
122505
122863
|
name: "shell_substitution",
|
|
122506
122864
|
description: "Shell command substitution",
|
|
122507
|
-
severity: "
|
|
122865
|
+
severity: "warning"
|
|
122508
122866
|
},
|
|
122509
122867
|
{
|
|
122510
122868
|
pattern: /disable\s+.{0,50}firewall/i,
|
|
@@ -122639,6 +122997,9 @@ function scanInvisibleFormatChars(text, fieldName) {
|
|
|
122639
122997
|
}
|
|
122640
122998
|
return findings;
|
|
122641
122999
|
}
|
|
123000
|
+
function stripMarkdownCodeForUnsafeScan(text) {
|
|
123001
|
+
return text.replace(/```[\s\S]*?```/g, " ").replace(/~~~[\s\S]*?~~~/g, " ").replace(/`[^`\n]*`/g, " ");
|
|
123002
|
+
}
|
|
122642
123003
|
function scanPromptInjection(candidate, trustLevel = "low") {
|
|
122643
123004
|
const fields = extractCandidateFields(candidate);
|
|
122644
123005
|
const findings = [];
|
|
@@ -122705,8 +123066,9 @@ function scanUnsafeInstructions(candidate, trustLevel = "low") {
|
|
|
122705
123066
|
const fieldsScanned = [];
|
|
122706
123067
|
for (const { field, value } of fields) {
|
|
122707
123068
|
fieldsScanned.push(field);
|
|
123069
|
+
const scanValue = field === "skill_body" ? stripMarkdownCodeForUnsafeScan(value) : value;
|
|
122708
123070
|
for (const entry of UNSAFE_INSTRUCTION_PATTERNS) {
|
|
122709
|
-
const match = entry.pattern.exec(
|
|
123071
|
+
const match = entry.pattern.exec(scanValue);
|
|
122710
123072
|
if (match !== null) {
|
|
122711
123073
|
findings.push({
|
|
122712
123074
|
pattern: entry.name,
|
|
@@ -122877,7 +123239,8 @@ function evaluateCandidate(candidate, options) {
|
|
|
122877
123239
|
}
|
|
122878
123240
|
var _internals78 = {
|
|
122879
123241
|
getTimestamp: () => new Date().toISOString(),
|
|
122880
|
-
computeSha256: (content) =>
|
|
123242
|
+
computeSha256: (content) => createHash13("sha256").update(content).digest("hex"),
|
|
123243
|
+
stripMarkdownCodeForUnsafeScan
|
|
122881
123244
|
};
|
|
122882
123245
|
|
|
122883
123246
|
// src/tools/external-skill-discover.ts
|
|
@@ -122898,7 +123261,7 @@ var _internals79 = {
|
|
|
122898
123261
|
return { content, finalUrl: response.url };
|
|
122899
123262
|
},
|
|
122900
123263
|
getTimestamp: () => new Date().toISOString(),
|
|
122901
|
-
computeSha256: (content) =>
|
|
123264
|
+
computeSha256: (content) => createHash14("sha256").update(content).digest("hex"),
|
|
122902
123265
|
uuid: () => randomUUID13()
|
|
122903
123266
|
};
|
|
122904
123267
|
var SOURCE_TRUST_LEVELS = {
|
|
@@ -123284,7 +123647,7 @@ var external_skill_list = createSwarmTool({
|
|
|
123284
123647
|
// src/tools/external-skill-promote.ts
|
|
123285
123648
|
init_zod();
|
|
123286
123649
|
init_loader();
|
|
123287
|
-
import { createHash as
|
|
123650
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
123288
123651
|
import * as fs95 from "node:fs/promises";
|
|
123289
123652
|
import * as path146 from "node:path";
|
|
123290
123653
|
init_create_tool();
|
|
@@ -123449,7 +123812,7 @@ var external_skill_promote = createSwarmTool({
|
|
|
123449
123812
|
}
|
|
123450
123813
|
throw writeErr;
|
|
123451
123814
|
}
|
|
123452
|
-
const promotedContentHash =
|
|
123815
|
+
const promotedContentHash = createHash15("sha256").update(skillMarkdown).digest("hex");
|
|
123453
123816
|
const prePromotionHistory = candidate.evaluation_history;
|
|
123454
123817
|
const lastPrePromotionEntry = prePromotionHistory.length > 0 ? prePromotionHistory[prePromotionHistory.length - 1] : undefined;
|
|
123455
123818
|
const originalEvaluation = lastPrePromotionEntry ? {
|
|
@@ -124418,8 +124781,8 @@ var git_blame = createSwarmTool({
|
|
|
124418
124781
|
lines: []
|
|
124419
124782
|
});
|
|
124420
124783
|
}
|
|
124421
|
-
const
|
|
124422
|
-
if (
|
|
124784
|
+
const stat11 = fs97.statSync(resolvedPath);
|
|
124785
|
+
if (stat11.isDirectory()) {
|
|
124423
124786
|
return JSON.stringify({
|
|
124424
124787
|
error: "path is a directory, not a file",
|
|
124425
124788
|
file: file3,
|
|
@@ -124806,9 +125169,9 @@ function findSourceFiles3(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
124806
125169
|
continue;
|
|
124807
125170
|
}
|
|
124808
125171
|
const fullPath = path150.join(dir, entry);
|
|
124809
|
-
let
|
|
125172
|
+
let stat11;
|
|
124810
125173
|
try {
|
|
124811
|
-
|
|
125174
|
+
stat11 = fs98.statSync(fullPath);
|
|
124812
125175
|
} catch (e) {
|
|
124813
125176
|
stats.fileErrors.push({
|
|
124814
125177
|
path: fullPath,
|
|
@@ -124816,9 +125179,9 @@ function findSourceFiles3(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
124816
125179
|
});
|
|
124817
125180
|
continue;
|
|
124818
125181
|
}
|
|
124819
|
-
if (
|
|
125182
|
+
if (stat11.isDirectory()) {
|
|
124820
125183
|
findSourceFiles3(fullPath, files, stats);
|
|
124821
|
-
} else if (
|
|
125184
|
+
} else if (stat11.isFile()) {
|
|
124822
125185
|
const ext = path150.extname(fullPath).toLowerCase();
|
|
124823
125186
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
124824
125187
|
files.push(fullPath);
|
|
@@ -124913,8 +125276,8 @@ var imports = createSwarmTool({
|
|
|
124913
125276
|
if (consumers.length >= MAX_CONSUMERS)
|
|
124914
125277
|
break;
|
|
124915
125278
|
try {
|
|
124916
|
-
const
|
|
124917
|
-
if (
|
|
125279
|
+
const stat11 = fs98.statSync(filePath);
|
|
125280
|
+
if (stat11.size > MAX_FILE_SIZE_BYTES7) {
|
|
124918
125281
|
skippedFileCount++;
|
|
124919
125282
|
continue;
|
|
124920
125283
|
}
|
|
@@ -125276,10 +125639,12 @@ init_knowledge_store();
|
|
|
125276
125639
|
init_logger();
|
|
125277
125640
|
init_create_tool();
|
|
125278
125641
|
var MODES2 = ["archive", "quarantine", "purge"];
|
|
125642
|
+
var TIERS = ["swarm", "hive"];
|
|
125279
125643
|
var knowledge_archive = createSwarmTool({
|
|
125280
|
-
description: "Archive (default), quarantine, or purge a swarm knowledge entry by ID, appending an immutable audit tombstone. 'archive'/'quarantine' set the entry status reversibly and hide it from recall; 'purge' hard-deletes and requires allow_purge:true.",
|
|
125644
|
+
description: "Archive (default), quarantine, or purge a swarm or hive knowledge entry by ID, appending an immutable audit tombstone. 'archive'/'quarantine' set the entry status reversibly and hide it from recall; 'purge' hard-deletes and requires allow_purge:true.",
|
|
125281
125645
|
args: {
|
|
125282
125646
|
id: exports_external.string().min(1).describe("UUID of the knowledge entry"),
|
|
125647
|
+
tier: exports_external.enum(TIERS).optional().describe("Knowledge tier to modify; default 'swarm'"),
|
|
125283
125648
|
reason: exports_external.string().min(1).max(500).describe("Why the entry is being archived/quarantined/purged"),
|
|
125284
125649
|
evidence: exports_external.string().max(1000).optional().describe('Supporting evidence (e.g. "ignored 8 times, contradicted by tests")'),
|
|
125285
125650
|
mode: exports_external.enum(MODES2).optional().describe("Default 'archive'"),
|
|
@@ -125302,6 +125667,7 @@ var knowledge_archive = createSwarmTool({
|
|
|
125302
125667
|
});
|
|
125303
125668
|
}
|
|
125304
125669
|
const evidence = typeof a.evidence === "string" ? a.evidence : undefined;
|
|
125670
|
+
const tier = a.tier === "hive" ? "hive" : "swarm";
|
|
125305
125671
|
const mode = a.mode === "quarantine" || a.mode === "purge" ? a.mode : "archive";
|
|
125306
125672
|
if (mode === "purge" && a.allow_purge !== true) {
|
|
125307
125673
|
return JSON.stringify({
|
|
@@ -125309,44 +125675,40 @@ var knowledge_archive = createSwarmTool({
|
|
|
125309
125675
|
error: "purge requires allow_purge:true (admin flag)"
|
|
125310
125676
|
});
|
|
125311
125677
|
}
|
|
125312
|
-
const
|
|
125313
|
-
let
|
|
125314
|
-
|
|
125315
|
-
entries = await readKnowledge(swarmPath);
|
|
125316
|
-
} catch (err2) {
|
|
125317
|
-
return JSON.stringify({
|
|
125318
|
-
success: false,
|
|
125319
|
-
error: err2 instanceof Error ? err2.message : "Unknown error"
|
|
125320
|
-
});
|
|
125321
|
-
}
|
|
125322
|
-
const target = entries.find((e) => e.id === id);
|
|
125323
|
-
if (!target) {
|
|
125324
|
-
return JSON.stringify({ success: false, message: "entry not found" });
|
|
125325
|
-
}
|
|
125326
|
-
const previousStatus = target.status;
|
|
125678
|
+
const knowledgePath = tier === "hive" ? resolveHiveKnowledgePath() : resolveSwarmKnowledgePath(directory);
|
|
125679
|
+
let found = false;
|
|
125680
|
+
let previousStatus;
|
|
125327
125681
|
const now = new Date().toISOString();
|
|
125328
|
-
let nextEntries;
|
|
125329
125682
|
let resultStatus;
|
|
125330
|
-
if (mode === "purge") {
|
|
125331
|
-
warn(`[knowledge_archive] PURGE: hard-deleting entry id=${id} actor=${ctx?.agent ?? "unknown"} reason=${reason}`);
|
|
125332
|
-
nextEntries = entries.filter((e) => e.id !== id);
|
|
125333
|
-
resultStatus = "purged";
|
|
125334
|
-
} else {
|
|
125335
|
-
const newStatus = mode === "quarantine" ? "quarantined" : "archived";
|
|
125336
|
-
nextEntries = entries.map((e) => e.id === id ? { ...e, status: newStatus, updated_at: now } : e);
|
|
125337
|
-
resultStatus = newStatus;
|
|
125338
|
-
}
|
|
125339
125683
|
try {
|
|
125340
|
-
await
|
|
125684
|
+
await transactKnowledge(knowledgePath, (entries) => {
|
|
125685
|
+
const target = entries.find((e) => e.id === id);
|
|
125686
|
+
if (!target)
|
|
125687
|
+
return null;
|
|
125688
|
+
found = true;
|
|
125689
|
+
previousStatus = target.status;
|
|
125690
|
+
if (mode === "purge") {
|
|
125691
|
+
warn(`[knowledge_archive] PURGE: hard-deleting ${tier} entry id=${id} actor=${ctx?.agent ?? "unknown"} reason=${reason}`);
|
|
125692
|
+
resultStatus = "purged";
|
|
125693
|
+
return entries.filter((e) => e.id !== id);
|
|
125694
|
+
}
|
|
125695
|
+
const newStatus = mode === "quarantine" ? "quarantined" : "archived";
|
|
125696
|
+
resultStatus = newStatus;
|
|
125697
|
+
return entries.map((e) => e.id === id ? { ...e, status: newStatus, updated_at: now } : e);
|
|
125698
|
+
});
|
|
125341
125699
|
} catch (err2) {
|
|
125342
125700
|
return JSON.stringify({
|
|
125343
125701
|
success: false,
|
|
125344
125702
|
error: err2 instanceof Error ? err2.message : "Unknown error"
|
|
125345
125703
|
});
|
|
125346
125704
|
}
|
|
125705
|
+
if (!found) {
|
|
125706
|
+
return JSON.stringify({ success: false, message: "entry not found" });
|
|
125707
|
+
}
|
|
125347
125708
|
await recordKnowledgeEvent(directory, {
|
|
125348
125709
|
type: "archived",
|
|
125349
125710
|
entry_id: id,
|
|
125711
|
+
tier,
|
|
125350
125712
|
actor: ctx?.agent ?? "unknown",
|
|
125351
125713
|
reason,
|
|
125352
125714
|
mode,
|
|
@@ -125356,6 +125718,7 @@ var knowledge_archive = createSwarmTool({
|
|
|
125356
125718
|
return JSON.stringify({
|
|
125357
125719
|
success: true,
|
|
125358
125720
|
id,
|
|
125721
|
+
tier,
|
|
125359
125722
|
mode,
|
|
125360
125723
|
previous_status: previousStatus,
|
|
125361
125724
|
status: resultStatus
|
|
@@ -130326,12 +130689,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
130326
130689
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
130327
130690
|
try {
|
|
130328
130691
|
const projectName = path166.basename(dir);
|
|
130329
|
-
const skillImproverCfg = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
|
|
130330
130692
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig, {
|
|
130331
130693
|
llmDelegate: createCuratorLLMDelegate(dir, "phase", sessionID),
|
|
130332
130694
|
enrichmentQuota: {
|
|
130333
|
-
maxCalls:
|
|
130334
|
-
window:
|
|
130695
|
+
maxCalls: knowledgeConfig.enrichment.max_calls_per_day,
|
|
130696
|
+
window: knowledgeConfig.enrichment.quota_window
|
|
130335
130697
|
}
|
|
130336
130698
|
});
|
|
130337
130699
|
if (curationResult) {
|
|
@@ -132432,8 +132794,8 @@ async function placeholderScan(input, directory) {
|
|
|
132432
132794
|
}
|
|
132433
132795
|
let content;
|
|
132434
132796
|
try {
|
|
132435
|
-
const
|
|
132436
|
-
if (
|
|
132797
|
+
const stat11 = fs115.statSync(fullPath);
|
|
132798
|
+
if (stat11.size > MAX_FILE_SIZE) {
|
|
132437
132799
|
continue;
|
|
132438
132800
|
}
|
|
132439
132801
|
content = fs115.readFileSync(fullPath, "utf-8");
|
|
@@ -134614,14 +134976,14 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
134614
134976
|
skippedFiles++;
|
|
134615
134977
|
continue;
|
|
134616
134978
|
}
|
|
134617
|
-
let
|
|
134979
|
+
let stat11;
|
|
134618
134980
|
try {
|
|
134619
|
-
|
|
134981
|
+
stat11 = fs119.statSync(file3);
|
|
134620
134982
|
} catch {
|
|
134621
134983
|
skippedFiles++;
|
|
134622
134984
|
continue;
|
|
134623
134985
|
}
|
|
134624
|
-
if (
|
|
134986
|
+
if (stat11.size > MAX_FILE_SIZE_BYTES9) {
|
|
134625
134987
|
skippedFiles++;
|
|
134626
134988
|
continue;
|
|
134627
134989
|
}
|
|
@@ -135400,8 +135762,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
135400
135762
|
for (const entry of entries) {
|
|
135401
135763
|
const entryPath = path174.join(evidenceDir, entry);
|
|
135402
135764
|
try {
|
|
135403
|
-
const
|
|
135404
|
-
if (!
|
|
135765
|
+
const stat11 = fs120.statSync(entryPath);
|
|
135766
|
+
if (!stat11.isDirectory()) {
|
|
135405
135767
|
continue;
|
|
135406
135768
|
}
|
|
135407
135769
|
} catch {
|
|
@@ -135421,11 +135783,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
135421
135783
|
if (!resolvedPath.startsWith(evidenceDirResolved + path174.sep)) {
|
|
135422
135784
|
continue;
|
|
135423
135785
|
}
|
|
135424
|
-
const
|
|
135425
|
-
if (!
|
|
135786
|
+
const stat11 = fs120.lstatSync(evidenceFilePath);
|
|
135787
|
+
if (!stat11.isFile()) {
|
|
135426
135788
|
continue;
|
|
135427
135789
|
}
|
|
135428
|
-
if (
|
|
135790
|
+
if (stat11.size > MAX_FILE_SIZE_BYTES9) {
|
|
135429
135791
|
continue;
|
|
135430
135792
|
}
|
|
135431
135793
|
} catch {
|
|
@@ -138176,6 +138538,11 @@ var skill_improve = createSwarmTool({
|
|
|
138176
138538
|
const a = args2 ?? {};
|
|
138177
138539
|
const { config: config3 } = loadPluginConfigWithMeta(directory);
|
|
138178
138540
|
const parsed = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
|
|
138541
|
+
const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
|
|
138542
|
+
const enrichmentConfig = knowledgeConfig.enrichment ?? {
|
|
138543
|
+
max_calls_per_day: 30,
|
|
138544
|
+
quota_window: "utc"
|
|
138545
|
+
};
|
|
138179
138546
|
if (!parsed.enabled) {
|
|
138180
138547
|
return JSON.stringify({
|
|
138181
138548
|
ran: false,
|
|
@@ -138188,7 +138555,11 @@ var skill_improve = createSwarmTool({
|
|
|
138188
138555
|
targets: a.targets,
|
|
138189
138556
|
mode: a.mode,
|
|
138190
138557
|
maxCalls: a.max_calls,
|
|
138191
|
-
sessionId: ctx?.sessionID
|
|
138558
|
+
sessionId: ctx?.sessionID,
|
|
138559
|
+
enrichmentQuota: {
|
|
138560
|
+
maxCalls: enrichmentConfig.max_calls_per_day,
|
|
138561
|
+
window: enrichmentConfig.quota_window
|
|
138562
|
+
}
|
|
138192
138563
|
});
|
|
138193
138564
|
return JSON.stringify(result, null, 2);
|
|
138194
138565
|
}
|
|
@@ -138270,7 +138641,7 @@ init_zod();
|
|
|
138270
138641
|
init_config();
|
|
138271
138642
|
init_schema();
|
|
138272
138643
|
init_create_tool();
|
|
138273
|
-
import { mkdir as mkdir30, rename as rename12, writeFile as
|
|
138644
|
+
import { mkdir as mkdir30, rename as rename12, writeFile as writeFile21 } from "node:fs/promises";
|
|
138274
138645
|
import * as path179 from "node:path";
|
|
138275
138646
|
var MAX_SPEC_BYTES2 = 256 * 1024;
|
|
138276
138647
|
var spec_write = createSwarmTool({
|
|
@@ -138332,7 +138703,7 @@ ${content}
|
|
|
138332
138703
|
}
|
|
138333
138704
|
} catch {}
|
|
138334
138705
|
}
|
|
138335
|
-
await
|
|
138706
|
+
await writeFile21(tmp, finalContent, "utf-8");
|
|
138336
138707
|
await rename12(tmp, target);
|
|
138337
138708
|
return JSON.stringify({ written: true, path: target, bytes: finalContent.length }, null, 2);
|
|
138338
138709
|
}
|
|
@@ -139551,8 +139922,8 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
139551
139922
|
return { result, counted: false, failed: false, skipped: true };
|
|
139552
139923
|
}
|
|
139553
139924
|
try {
|
|
139554
|
-
const
|
|
139555
|
-
if (
|
|
139925
|
+
const stat11 = fs126.statSync(fullPath);
|
|
139926
|
+
if (stat11.size >= MAX_FILE_SIZE2) {
|
|
139556
139927
|
result.skipped_reason = "file_too_large";
|
|
139557
139928
|
return { result, counted: false, failed: false, skipped: true };
|
|
139558
139929
|
}
|
|
@@ -139784,15 +140155,15 @@ function findSourceFiles4(dir, files = []) {
|
|
|
139784
140155
|
continue;
|
|
139785
140156
|
}
|
|
139786
140157
|
const fullPath = path183.join(dir, entry);
|
|
139787
|
-
let
|
|
140158
|
+
let stat11;
|
|
139788
140159
|
try {
|
|
139789
|
-
|
|
140160
|
+
stat11 = fs127.statSync(fullPath);
|
|
139790
140161
|
} catch {
|
|
139791
140162
|
continue;
|
|
139792
140163
|
}
|
|
139793
|
-
if (
|
|
140164
|
+
if (stat11.isDirectory()) {
|
|
139794
140165
|
findSourceFiles4(fullPath, files);
|
|
139795
|
-
} else if (
|
|
140166
|
+
} else if (stat11.isFile()) {
|
|
139796
140167
|
if (isSupportedExtension(fullPath)) {
|
|
139797
140168
|
files.push(fullPath);
|
|
139798
140169
|
}
|
|
@@ -139889,8 +140260,8 @@ var todo_extract = createSwarmTool({
|
|
|
139889
140260
|
return JSON.stringify(errorResult, null, 2);
|
|
139890
140261
|
}
|
|
139891
140262
|
const filesToScan = [];
|
|
139892
|
-
const
|
|
139893
|
-
if (
|
|
140263
|
+
const stat11 = fs127.statSync(scanPath);
|
|
140264
|
+
if (stat11.isFile()) {
|
|
139894
140265
|
if (isSupportedExtension(scanPath)) {
|
|
139895
140266
|
filesToScan.push(scanPath);
|
|
139896
140267
|
} else {
|
|
@@ -141010,7 +141381,7 @@ import * as zlib from "node:zlib";
|
|
|
141010
141381
|
// src/evidence/documents.ts
|
|
141011
141382
|
init_utils2();
|
|
141012
141383
|
init_redaction();
|
|
141013
|
-
import { createHash as
|
|
141384
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
141014
141385
|
import { appendFile as appendFile17, mkdir as mkdir31 } from "node:fs/promises";
|
|
141015
141386
|
import * as path188 from "node:path";
|
|
141016
141387
|
var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
|
|
@@ -141054,7 +141425,7 @@ function createEvidenceDocumentRecord(input, defaultCapturedAt) {
|
|
|
141054
141425
|
};
|
|
141055
141426
|
}
|
|
141056
141427
|
function createEvidenceDocumentId(input) {
|
|
141057
|
-
const hash4 =
|
|
141428
|
+
const hash4 = createHash17("sha256").update([
|
|
141058
141429
|
input.sourceType,
|
|
141059
141430
|
input.query ?? "",
|
|
141060
141431
|
input.title ?? "",
|
|
@@ -142104,13 +142475,12 @@ var write_architecture_supervisor_evidence = createSwarmTool({
|
|
|
142104
142475
|
if (config3.architectural_supervision?.persist_knowledge_recommendations && args2.knowledge_recommendations.length > 0) {
|
|
142105
142476
|
const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
|
|
142106
142477
|
const lessons = args2.knowledge_recommendations.map((r) => r.lesson);
|
|
142107
|
-
const skillImproverCfg = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
|
|
142108
142478
|
const result = await curateAndStoreSwarm(lessons, path189.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, {
|
|
142109
142479
|
skipAutoPromotion: true,
|
|
142110
142480
|
llmDelegate: createCuratorLLMDelegate(dirResult.directory, "phase"),
|
|
142111
142481
|
enrichmentQuota: {
|
|
142112
|
-
maxCalls:
|
|
142113
|
-
window:
|
|
142482
|
+
maxCalls: knowledgeConfig.enrichment.max_calls_per_day,
|
|
142483
|
+
window: knowledgeConfig.enrichment.quota_window
|
|
142114
142484
|
}
|
|
142115
142485
|
});
|
|
142116
142486
|
knowledgeProposed = result.stored;
|
|
@@ -143127,11 +143497,16 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
143127
143497
|
const summaryConfig = SummaryConfigSchema.parse(config3.summaries ?? {});
|
|
143128
143498
|
const toolSummarizerHook = createToolSummarizerHook(summaryConfig, ctx.directory);
|
|
143129
143499
|
const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
|
|
143130
|
-
const skillImproverConfig = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
|
|
143131
143500
|
const skillPropagationConfig = SkillPropagationConfigSchema.parse(config3.skillPropagation ?? {});
|
|
143132
|
-
const knowledgeCuratorHook = knowledgeConfig.enabled ? createKnowledgeCuratorHook(ctx.directory, knowledgeConfig
|
|
143501
|
+
const knowledgeCuratorHook = knowledgeConfig.enabled ? createKnowledgeCuratorHook(ctx.directory, knowledgeConfig, {
|
|
143502
|
+
llmDelegateFactory: (sessionID) => createCuratorLLMDelegate(ctx.directory, "phase", sessionID),
|
|
143503
|
+
enrichmentQuota: {
|
|
143504
|
+
maxCalls: knowledgeConfig.enrichment.max_calls_per_day,
|
|
143505
|
+
window: knowledgeConfig.enrichment.quota_window
|
|
143506
|
+
}
|
|
143507
|
+
}) : undefined;
|
|
143133
143508
|
const hivePromoterHook = knowledgeConfig.enabled && knowledgeConfig.hive_enabled ? createHivePromoterHook(ctx.directory, knowledgeConfig) : undefined;
|
|
143134
|
-
const knowledgeInjectorHook = knowledgeConfig.enabled ? createKnowledgeInjectorHook(ctx.directory, knowledgeConfig) : undefined;
|
|
143509
|
+
const knowledgeInjectorHook = knowledgeConfig.enabled ? createKnowledgeInjectorHook(ctx.directory, knowledgeConfig, config3.context_budget?.model_limits ?? {}) : undefined;
|
|
143135
143510
|
const steeringConsumedHook = createSteeringConsumedHook(ctx.directory);
|
|
143136
143511
|
const coChangeSuggesterHook = createCoChangeSuggesterHook(ctx.directory);
|
|
143137
143512
|
const darkMatterDetectorHook = createDarkMatterDetectorHook(ctx.directory);
|
|
@@ -143858,8 +144233,8 @@ ${usedByCoderLine}`;
|
|
|
143858
144233
|
await safeHook(() => collectDelegateAcksAfter(ctx.directory, input, output))(input, output);
|
|
143859
144234
|
await safeHook(() => collectReviewerVerdictsAfter(ctx.directory, input, output))(input, output);
|
|
143860
144235
|
await safeHook(() => microReflectorAfter(ctx.directory, input, output, createCuratorLLMDelegate(ctx.directory, "phase", input.sessionID), {
|
|
143861
|
-
maxCalls:
|
|
143862
|
-
window:
|
|
144236
|
+
maxCalls: knowledgeConfig.enrichment.max_calls_per_day,
|
|
144237
|
+
window: knowledgeConfig.enrichment.quota_window
|
|
143863
144238
|
}))(input, output);
|
|
143864
144239
|
}
|
|
143865
144240
|
await safeHook(prmHook.toolAfter)(input, output);
|