opencode-swarm 7.39.0 → 7.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/explorer.d.ts +2 -2
- package/dist/cli/index.js +639 -16
- package/dist/commands/memory.d.ts +4 -0
- package/dist/commands/registry.d.ts +28 -0
- package/dist/commands/tool-policy.d.ts +1 -1
- package/dist/config/schema.d.ts +8 -0
- package/dist/evidence/documents.d.ts +31 -0
- package/dist/evidence/index.d.ts +1 -0
- package/dist/index.js +792 -47
- package/dist/memory/config.d.ts +4 -0
- package/dist/memory/curator-decision-helpers.d.ts +2 -0
- package/dist/memory/index.d.ts +2 -1
- package/dist/memory/local-jsonl-provider.d.ts +3 -1
- package/dist/memory/maintenance.d.ts +47 -0
- package/dist/memory/provider.d.ts +16 -0
- package/dist/memory/sqlite-provider.d.ts +3 -1
- package/dist/memory/types.d.ts +1 -0
- package/dist/tools/web-search.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ var package_default;
|
|
|
48
48
|
var init_package = __esm(() => {
|
|
49
49
|
package_default = {
|
|
50
50
|
name: "opencode-swarm",
|
|
51
|
-
version: "7.
|
|
51
|
+
version: "7.41.0",
|
|
52
52
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
53
53
|
main: "dist/index.js",
|
|
54
54
|
types: "dist/index.d.ts",
|
|
@@ -15581,6 +15581,13 @@ var init_schema = __esm(() => {
|
|
|
15581
15581
|
redaction: exports_external.object({
|
|
15582
15582
|
rejectDurableSecrets: exports_external.boolean().default(true)
|
|
15583
15583
|
}).default({ rejectDurableSecrets: true }),
|
|
15584
|
+
maintenance: exports_external.object({
|
|
15585
|
+
lowUtilityMaxConfidence: exports_external.number().min(0).max(1).default(0.45),
|
|
15586
|
+
lowUtilityMinAgeDays: exports_external.number().int().min(1).max(3650).default(30)
|
|
15587
|
+
}).default({
|
|
15588
|
+
lowUtilityMaxConfidence: 0.45,
|
|
15589
|
+
lowUtilityMinAgeDays: 30
|
|
15590
|
+
}),
|
|
15584
15591
|
hardDelete: exports_external.boolean().default(false)
|
|
15585
15592
|
});
|
|
15586
15593
|
CuratorConfigSchema = exports_external.object({
|
|
@@ -55884,6 +55891,7 @@ RULES:
|
|
|
55884
55891
|
- Output under 2000 chars
|
|
55885
55892
|
- No code modifications
|
|
55886
55893
|
- Flag contradictions explicitly with CONTRADICTION: prefix
|
|
55894
|
+
- Memory proposals are for concise durable facts only. Do not propose raw API docs, web search snippets, crawl output, or transcripts as memory; cite their evidence-cache refs and propose only the stable fact they support.
|
|
55887
55895
|
- If no prior summary exists, state "First session — no prior context"
|
|
55888
55896
|
|
|
55889
55897
|
OUTPUT FORMAT:
|
|
@@ -55930,6 +55938,7 @@ RULES:
|
|
|
55930
55938
|
- Compliance observations are READ-ONLY — report, do not enforce
|
|
55931
55939
|
- OBSERVATIONS should not contain directives — report what is observed, do not instruct the architect what to do
|
|
55932
55940
|
- Extend the digest, never replace it
|
|
55941
|
+
- Memory proposals are for concise durable facts only. Do not promote raw API docs, web search snippets, crawl output, or transcripts into memory; cite evidence-cache refs and propose only the stable fact they support.
|
|
55933
55942
|
|
|
55934
55943
|
OUTPUT FORMAT:
|
|
55935
55944
|
PHASE_DIGEST:
|
|
@@ -66897,6 +66906,10 @@ function resolveMemoryConfig(input) {
|
|
|
66897
66906
|
redaction: {
|
|
66898
66907
|
...DEFAULT_MEMORY_CONFIG.redaction,
|
|
66899
66908
|
...input?.redaction ?? {}
|
|
66909
|
+
},
|
|
66910
|
+
maintenance: {
|
|
66911
|
+
...DEFAULT_MEMORY_CONFIG.maintenance,
|
|
66912
|
+
...input?.maintenance ?? {}
|
|
66900
66913
|
}
|
|
66901
66914
|
};
|
|
66902
66915
|
}
|
|
@@ -66928,6 +66941,10 @@ var init_config3 = __esm(() => {
|
|
|
66928
66941
|
redaction: {
|
|
66929
66942
|
rejectDurableSecrets: true
|
|
66930
66943
|
},
|
|
66944
|
+
maintenance: {
|
|
66945
|
+
lowUtilityMaxConfidence: 0.45,
|
|
66946
|
+
lowUtilityMinAgeDays: 30
|
|
66947
|
+
},
|
|
66931
66948
|
hardDelete: false
|
|
66932
66949
|
};
|
|
66933
66950
|
DURABLE_MEMORY_KINDS = new Set([
|
|
@@ -67278,6 +67295,17 @@ function validateDecisionMatchesProposal(decision, proposal) {
|
|
|
67278
67295
|
throw new MemoryValidationError("curator supersede decision target does not match proposal target");
|
|
67279
67296
|
}
|
|
67280
67297
|
}
|
|
67298
|
+
function validateCuratorPromotableMemory(record3) {
|
|
67299
|
+
if (record3.stability !== "durable") {
|
|
67300
|
+
throw new MemoryValidationError("curator memory promotions must be durable facts");
|
|
67301
|
+
}
|
|
67302
|
+
if (!DURABLE_MEMORY_KINDS.has(record3.kind)) {
|
|
67303
|
+
throw new MemoryValidationError("curator memory promotions must use durable fact kinds; store raw docs, search results, and other bulky source material as evidence records instead");
|
|
67304
|
+
}
|
|
67305
|
+
if (normalizeMemoryText(record3.text).length > CURATOR_PROMOTED_MEMORY_MAX_TEXT_LENGTH) {
|
|
67306
|
+
throw new MemoryValidationError(`curator memory promotions must be concise durable facts under ${CURATOR_PROMOTED_MEMORY_MAX_TEXT_LENGTH} characters`);
|
|
67307
|
+
}
|
|
67308
|
+
}
|
|
67281
67309
|
function applyPatchToMemory(existing, patch, updatedAt) {
|
|
67282
67310
|
const base = {
|
|
67283
67311
|
scope: patch.scope ?? existing.scope,
|
|
@@ -67335,11 +67363,174 @@ function buildCuratorDecisionEvent(change, proposal) {
|
|
|
67335
67363
|
function normalizeTags(tags) {
|
|
67336
67364
|
return Array.from(new Set(tags.map((tag) => tag.toLowerCase().replace(/[^\w-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")).filter(Boolean))).slice(0, 32);
|
|
67337
67365
|
}
|
|
67366
|
+
var CURATOR_PROMOTED_MEMORY_MAX_TEXT_LENGTH = 500;
|
|
67338
67367
|
var init_curator_decision_helpers = __esm(() => {
|
|
67368
|
+
init_config3();
|
|
67339
67369
|
init_errors6();
|
|
67340
67370
|
init_schema2();
|
|
67341
67371
|
});
|
|
67342
67372
|
|
|
67373
|
+
// src/memory/maintenance.ts
|
|
67374
|
+
async function buildMemoryMaintenanceReport(provider, options = {}) {
|
|
67375
|
+
const now = options.now ?? new Date;
|
|
67376
|
+
const limit = Math.max(1, Math.trunc(options.limit ?? 20));
|
|
67377
|
+
const memories = await provider.list({
|
|
67378
|
+
includeExpired: true,
|
|
67379
|
+
includeInactive: true
|
|
67380
|
+
});
|
|
67381
|
+
const proposals = await loadMaintenanceProposals(provider, limit);
|
|
67382
|
+
const recallUsage = provider.listRecallUsage ? await provider.listRecallUsage() : [];
|
|
67383
|
+
const usageByMemory = summarizeRecallByMemory(recallUsage);
|
|
67384
|
+
const usageByRole = summarizeRecallByRole(recallUsage);
|
|
67385
|
+
const activeMemories = memories.filter((memory) => isActiveMemory(memory, now));
|
|
67386
|
+
const deletedMemories = memories.filter((memory) => memory.metadata.deleted === true);
|
|
67387
|
+
const expiredScratchMemories = memories.filter((memory) => memory.kind === "scratch" && isExpired(memory, now));
|
|
67388
|
+
const supersededMemories = memories.filter((memory) => Boolean(memory.supersededBy));
|
|
67389
|
+
const lowUtilityMemories = activeMemories.filter((memory) => isLowUtility(memory, usageByMemory, now, {
|
|
67390
|
+
maxConfidence: options.lowUtilityMaxConfidence ?? DEFAULT_LOW_UTILITY_MAX_CONFIDENCE,
|
|
67391
|
+
minAgeDays: options.lowUtilityMinAgeDays ?? DEFAULT_LOW_UTILITY_MIN_AGE_DAYS
|
|
67392
|
+
})).sort(memorySort);
|
|
67393
|
+
const neverRecalledMemories = activeMemories.filter((memory) => !usageByMemory.has(memory.id)).sort(memorySort);
|
|
67394
|
+
const rejectedProposalReasons = proposals.filter((proposal) => proposal.status === "rejected").sort(proposalSort);
|
|
67395
|
+
const pendingProposals = proposals.filter((proposal) => proposal.status === "pending").sort(proposalSort);
|
|
67396
|
+
return {
|
|
67397
|
+
generatedAt: now.toISOString(),
|
|
67398
|
+
totalMemories: memories.length,
|
|
67399
|
+
activeMemories: activeMemories.length,
|
|
67400
|
+
deletedMemories: deletedMemories.slice(0, limit),
|
|
67401
|
+
expiredScratchMemories: expiredScratchMemories.slice(0, limit),
|
|
67402
|
+
supersededMemories: supersededMemories.slice(0, limit),
|
|
67403
|
+
supersededChains: buildSupersededChains(memories).slice(0, limit),
|
|
67404
|
+
lowUtilityMemories: lowUtilityMemories.slice(0, limit),
|
|
67405
|
+
neverRecalledMemories: neverRecalledMemories.slice(0, limit),
|
|
67406
|
+
mostRecalledMemories: Array.from(usageByMemory.values()).sort((a, b) => b.count - a.count || b.lastRecalledAt.localeCompare(a.lastRecalledAt) || a.memoryId.localeCompare(b.memoryId)).slice(0, limit),
|
|
67407
|
+
recallByAgentRole: Array.from(usageByRole.values()).sort((a, b) => b.count - a.count || a.agentRole.localeCompare(b.agentRole)).slice(0, limit),
|
|
67408
|
+
rejectedProposalReasons: rejectedProposalReasons.slice(0, limit),
|
|
67409
|
+
pendingProposals: pendingProposals.slice(0, limit),
|
|
67410
|
+
recallEventCount: recallUsage.length
|
|
67411
|
+
};
|
|
67412
|
+
}
|
|
67413
|
+
function shouldCompactMemory(memory, now = new Date) {
|
|
67414
|
+
if (memory.metadata.deleted === true)
|
|
67415
|
+
return "deleted";
|
|
67416
|
+
if (memory.supersededBy)
|
|
67417
|
+
return "superseded";
|
|
67418
|
+
if (memory.kind === "scratch" && isExpired(memory, now)) {
|
|
67419
|
+
return "expired_scratch";
|
|
67420
|
+
}
|
|
67421
|
+
return null;
|
|
67422
|
+
}
|
|
67423
|
+
function isActiveMemory(memory, now) {
|
|
67424
|
+
return memory.metadata.deleted !== true && !memory.supersededBy && !isExpired(memory, now);
|
|
67425
|
+
}
|
|
67426
|
+
function isLowUtility(memory, usageByMemory, now, options) {
|
|
67427
|
+
if (usageByMemory.has(memory.id))
|
|
67428
|
+
return false;
|
|
67429
|
+
const updated = Date.parse(memory.updatedAt);
|
|
67430
|
+
const ageDays = Number.isFinite(updated) ? (now.getTime() - updated) / (24 * 60 * 60 * 1000) : 0;
|
|
67431
|
+
return memory.confidence <= options.maxConfidence || ageDays >= options.minAgeDays;
|
|
67432
|
+
}
|
|
67433
|
+
function summarizeRecallByMemory(usageEvents) {
|
|
67434
|
+
const byMemory = new Map;
|
|
67435
|
+
for (const event of usageEvents) {
|
|
67436
|
+
event.memoryIds.forEach((memoryId, index) => {
|
|
67437
|
+
const role = event.agentRole ?? "unknown";
|
|
67438
|
+
const existing = byMemory.get(memoryId) ?? {
|
|
67439
|
+
memoryId,
|
|
67440
|
+
count: 0,
|
|
67441
|
+
lastRecalledAt: event.timestamp,
|
|
67442
|
+
agentRoles: {},
|
|
67443
|
+
averageScore: 0,
|
|
67444
|
+
scoreTotal: 0,
|
|
67445
|
+
scoreCount: 0
|
|
67446
|
+
};
|
|
67447
|
+
existing.count++;
|
|
67448
|
+
existing.lastRecalledAt = event.timestamp > existing.lastRecalledAt ? event.timestamp : existing.lastRecalledAt;
|
|
67449
|
+
existing.agentRoles[role] = (existing.agentRoles[role] ?? 0) + 1;
|
|
67450
|
+
const score = event.scores[index];
|
|
67451
|
+
if (typeof score === "number" && Number.isFinite(score)) {
|
|
67452
|
+
existing.scoreTotal += score;
|
|
67453
|
+
existing.scoreCount++;
|
|
67454
|
+
existing.averageScore = existing.scoreTotal / existing.scoreCount;
|
|
67455
|
+
}
|
|
67456
|
+
byMemory.set(memoryId, existing);
|
|
67457
|
+
});
|
|
67458
|
+
}
|
|
67459
|
+
return new Map(Array.from(byMemory, ([memoryId, value]) => [
|
|
67460
|
+
memoryId,
|
|
67461
|
+
{
|
|
67462
|
+
memoryId,
|
|
67463
|
+
count: value.count,
|
|
67464
|
+
lastRecalledAt: value.lastRecalledAt,
|
|
67465
|
+
agentRoles: value.agentRoles,
|
|
67466
|
+
averageScore: value.averageScore
|
|
67467
|
+
}
|
|
67468
|
+
]));
|
|
67469
|
+
}
|
|
67470
|
+
async function loadMaintenanceProposals(provider, limit) {
|
|
67471
|
+
if (!provider.listProposals)
|
|
67472
|
+
return [];
|
|
67473
|
+
const [pending, rejected, recent] = await Promise.all([
|
|
67474
|
+
provider.listProposals({ status: "pending", limit }),
|
|
67475
|
+
provider.listProposals({ status: "rejected", limit }),
|
|
67476
|
+
provider.listProposals({ limit: Math.max(limit * 4, 100) })
|
|
67477
|
+
]);
|
|
67478
|
+
const byId = new Map;
|
|
67479
|
+
for (const proposal of [...pending, ...rejected, ...recent]) {
|
|
67480
|
+
byId.set(proposal.id, proposal);
|
|
67481
|
+
}
|
|
67482
|
+
return Array.from(byId.values());
|
|
67483
|
+
}
|
|
67484
|
+
function summarizeRecallByRole(usageEvents) {
|
|
67485
|
+
const byRole = new Map;
|
|
67486
|
+
for (const event of usageEvents) {
|
|
67487
|
+
const role = event.agentRole ?? "unknown";
|
|
67488
|
+
const existing = byRole.get(role) ?? {
|
|
67489
|
+
agentRole: role,
|
|
67490
|
+
count: 0,
|
|
67491
|
+
memoryIds: {}
|
|
67492
|
+
};
|
|
67493
|
+
existing.count++;
|
|
67494
|
+
for (const memoryId of event.memoryIds) {
|
|
67495
|
+
existing.memoryIds[memoryId] = (existing.memoryIds[memoryId] ?? 0) + 1;
|
|
67496
|
+
}
|
|
67497
|
+
byRole.set(role, existing);
|
|
67498
|
+
}
|
|
67499
|
+
return byRole;
|
|
67500
|
+
}
|
|
67501
|
+
function buildSupersededChains(memories) {
|
|
67502
|
+
const byId = new Map(memories.map((memory) => [memory.id, memory]));
|
|
67503
|
+
const supersededIds = new Set(memories.filter((memory) => memory.supersededBy).map((memory) => memory.id));
|
|
67504
|
+
const roots = memories.filter((memory) => memory.supersededBy && !(memory.supersedes ?? []).some((id) => supersededIds.has(id)));
|
|
67505
|
+
return roots.map((root) => {
|
|
67506
|
+
const chain = [root.id];
|
|
67507
|
+
const seen = new Set(chain);
|
|
67508
|
+
let cursor = root;
|
|
67509
|
+
while (cursor?.supersededBy && !seen.has(cursor.supersededBy)) {
|
|
67510
|
+
chain.push(cursor.supersededBy);
|
|
67511
|
+
seen.add(cursor.supersededBy);
|
|
67512
|
+
cursor = byId.get(cursor.supersededBy);
|
|
67513
|
+
}
|
|
67514
|
+
return {
|
|
67515
|
+
rootId: root.id,
|
|
67516
|
+
chain,
|
|
67517
|
+
reason: typeof root.metadata.supersedeReason === "string" ? root.metadata.supersedeReason : undefined
|
|
67518
|
+
};
|
|
67519
|
+
});
|
|
67520
|
+
}
|
|
67521
|
+
function memorySort(a, b) {
|
|
67522
|
+
return b.updatedAt.localeCompare(a.updatedAt) || a.id.localeCompare(b.id);
|
|
67523
|
+
}
|
|
67524
|
+
function proposalSort(a, b) {
|
|
67525
|
+
const aTime = a.reviewedAt ?? a.createdAt;
|
|
67526
|
+
const bTime = b.reviewedAt ?? b.createdAt;
|
|
67527
|
+
return bTime.localeCompare(aTime) || a.id.localeCompare(b.id);
|
|
67528
|
+
}
|
|
67529
|
+
var DEFAULT_LOW_UTILITY_MAX_CONFIDENCE = 0.45, DEFAULT_LOW_UTILITY_MIN_AGE_DAYS = 30;
|
|
67530
|
+
var init_maintenance = __esm(() => {
|
|
67531
|
+
init_schema2();
|
|
67532
|
+
});
|
|
67533
|
+
|
|
67343
67534
|
// src/memory/role-profiles.ts
|
|
67344
67535
|
function resolveMemoryRecallProfile(agentRole) {
|
|
67345
67536
|
const role = normalizeMemoryAgentRole(agentRole);
|
|
@@ -67727,16 +67918,21 @@ class LocalJsonlMemoryProvider {
|
|
|
67727
67918
|
}
|
|
67728
67919
|
async recordRecallUsage(event) {
|
|
67729
67920
|
await this.initialize();
|
|
67730
|
-
await this.audit("recall", event.bundleId,
|
|
67731
|
-
|
|
67732
|
-
|
|
67733
|
-
|
|
67734
|
-
|
|
67735
|
-
|
|
67736
|
-
|
|
67737
|
-
|
|
67738
|
-
|
|
67739
|
-
|
|
67921
|
+
await this.audit("recall", event.bundleId, undefined, event);
|
|
67922
|
+
}
|
|
67923
|
+
async listRecallUsage(filter = {}) {
|
|
67924
|
+
await this.initialize();
|
|
67925
|
+
const events = await readAuditEvents(this.pathFor("audit"));
|
|
67926
|
+
const usage = [];
|
|
67927
|
+
for (const event of events) {
|
|
67928
|
+
if (event.operation !== "recall")
|
|
67929
|
+
continue;
|
|
67930
|
+
const parsed = parseRecallUsageEvent(event);
|
|
67931
|
+
if (parsed)
|
|
67932
|
+
usage.push(parsed);
|
|
67933
|
+
}
|
|
67934
|
+
usage.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
67935
|
+
return usage.slice(0, filter.limit ?? usage.length);
|
|
67740
67936
|
}
|
|
67741
67937
|
async list(filter = {}) {
|
|
67742
67938
|
await this.initialize();
|
|
@@ -67756,7 +67952,9 @@ class LocalJsonlMemoryProvider {
|
|
|
67756
67952
|
return !Number.isFinite(expires) || expires > now;
|
|
67757
67953
|
});
|
|
67758
67954
|
}
|
|
67759
|
-
|
|
67955
|
+
if (!filter.includeInactive) {
|
|
67956
|
+
records = records.filter((record3) => !record3.supersededBy && record3.metadata.deleted !== true);
|
|
67957
|
+
}
|
|
67760
67958
|
records.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
67761
67959
|
return records.slice(0, filter.limit ?? records.length);
|
|
67762
67960
|
}
|
|
@@ -67797,12 +67995,14 @@ class LocalJsonlMemoryProvider {
|
|
|
67797
67995
|
...decision.memory,
|
|
67798
67996
|
updatedAt: appliedAt
|
|
67799
67997
|
});
|
|
67998
|
+
validateCuratorPromotableMemory(memory);
|
|
67800
67999
|
this.memories.set(memory.id, memory);
|
|
67801
68000
|
await appendJsonl(this.pathFor("memories"), memory);
|
|
67802
68001
|
memoryId = memory.id;
|
|
67803
68002
|
} else if (decision.action === "update") {
|
|
67804
68003
|
const existing = this.activeMemory(decision.targetMemoryId);
|
|
67805
68004
|
const updated = this.validateDecisionMemory(applyPatchToMemory(existing, decision.patch, appliedAt));
|
|
68005
|
+
validateCuratorPromotableMemory(updated);
|
|
67806
68006
|
if (updated.id !== existing.id) {
|
|
67807
68007
|
const tombstone = this.validateDecisionMemory({
|
|
67808
68008
|
...existing,
|
|
@@ -67828,6 +68028,7 @@ class LocalJsonlMemoryProvider {
|
|
|
67828
68028
|
updatedAt: appliedAt,
|
|
67829
68029
|
supersedes: Array.from(new Set([...decision.replacement.supersedes ?? [], oldMemory.id]))
|
|
67830
68030
|
});
|
|
68031
|
+
validateCuratorPromotableMemory(replacement);
|
|
67831
68032
|
const superseded = this.validateDecisionMemory({
|
|
67832
68033
|
...oldMemory,
|
|
67833
68034
|
updatedAt: appliedAt,
|
|
@@ -67868,6 +68069,41 @@ class LocalJsonlMemoryProvider {
|
|
|
67868
68069
|
await writeJsonlAtomic(this.pathFor("memories"), Array.from(this.memories.values()));
|
|
67869
68070
|
await this.audit("compact", "memories");
|
|
67870
68071
|
}
|
|
68072
|
+
async compactMaintenance(options = {}) {
|
|
68073
|
+
await this.initialize();
|
|
68074
|
+
const now = options.now ? new Date(options.now) : new Date;
|
|
68075
|
+
const kept = [];
|
|
68076
|
+
const result = {
|
|
68077
|
+
dryRun: options.dryRun !== false,
|
|
68078
|
+
removedDeleted: 0,
|
|
68079
|
+
removedSuperseded: 0,
|
|
68080
|
+
removedExpiredScratch: 0,
|
|
68081
|
+
remaining: 0
|
|
68082
|
+
};
|
|
68083
|
+
for (const memory of this.memories.values()) {
|
|
68084
|
+
const compactReason = shouldCompactMemory(memory, now);
|
|
68085
|
+
if (compactReason === "deleted") {
|
|
68086
|
+
result.removedDeleted++;
|
|
68087
|
+
continue;
|
|
68088
|
+
}
|
|
68089
|
+
if (compactReason === "superseded") {
|
|
68090
|
+
result.removedSuperseded++;
|
|
68091
|
+
continue;
|
|
68092
|
+
}
|
|
68093
|
+
if (compactReason === "expired_scratch") {
|
|
68094
|
+
result.removedExpiredScratch++;
|
|
68095
|
+
continue;
|
|
68096
|
+
}
|
|
68097
|
+
kept.push(memory);
|
|
68098
|
+
}
|
|
68099
|
+
result.remaining = kept.length;
|
|
68100
|
+
if (result.dryRun)
|
|
68101
|
+
return result;
|
|
68102
|
+
this.memories = new Map(kept.map((memory) => [memory.id, memory]));
|
|
68103
|
+
await writeJsonlAtomic(this.pathFor("memories"), kept);
|
|
68104
|
+
await this.audit("compact", "memories", "removed deleted, superseded, and expired scratch memories", result);
|
|
68105
|
+
return result;
|
|
68106
|
+
}
|
|
67871
68107
|
async audit(operation, targetId, reason, eventJson) {
|
|
67872
68108
|
const event = {
|
|
67873
68109
|
id: randomUUID4(),
|
|
@@ -67946,6 +68182,46 @@ async function readJsonl(filePath) {
|
|
|
67946
68182
|
}
|
|
67947
68183
|
return records;
|
|
67948
68184
|
}
|
|
68185
|
+
async function readAuditEvents(filePath) {
|
|
68186
|
+
const values = await readJsonl(filePath);
|
|
68187
|
+
const events = [];
|
|
68188
|
+
for (const value of values) {
|
|
68189
|
+
if (!value || typeof value !== "object")
|
|
68190
|
+
continue;
|
|
68191
|
+
const candidate = value;
|
|
68192
|
+
if (typeof candidate.id !== "string" || typeof candidate.operation !== "string" || typeof candidate.targetId !== "string" || typeof candidate.timestamp !== "string") {
|
|
68193
|
+
continue;
|
|
68194
|
+
}
|
|
68195
|
+
events.push(candidate);
|
|
68196
|
+
}
|
|
68197
|
+
return events;
|
|
68198
|
+
}
|
|
68199
|
+
function parseRecallUsageEvent(event) {
|
|
68200
|
+
const raw = event.eventJson ?? event.reason;
|
|
68201
|
+
if (typeof raw !== "string" && (!raw || typeof raw !== "object")) {
|
|
68202
|
+
return null;
|
|
68203
|
+
}
|
|
68204
|
+
try {
|
|
68205
|
+
const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
68206
|
+
if (!Array.isArray(parsed.memoryIds) || typeof parsed.query !== "string") {
|
|
68207
|
+
return null;
|
|
68208
|
+
}
|
|
68209
|
+
return {
|
|
68210
|
+
bundleId: typeof parsed.bundleId === "string" ? parsed.bundleId : event.targetId,
|
|
68211
|
+
query: parsed.query,
|
|
68212
|
+
scopes: Array.isArray(parsed.scopes) ? parsed.scopes : [],
|
|
68213
|
+
kinds: Array.isArray(parsed.kinds) ? parsed.kinds : undefined,
|
|
68214
|
+
memoryIds: parsed.memoryIds.filter((memoryId) => typeof memoryId === "string"),
|
|
68215
|
+
scores: Array.isArray(parsed.scores) ? parsed.scores.filter((score) => typeof score === "number" && Number.isFinite(score)) : [],
|
|
68216
|
+
tokenEstimate: typeof parsed.tokenEstimate === "number" ? parsed.tokenEstimate : 0,
|
|
68217
|
+
agentRole: typeof parsed.agentRole === "string" ? parsed.agentRole : undefined,
|
|
68218
|
+
runId: typeof parsed.runId === "string" ? parsed.runId : undefined,
|
|
68219
|
+
timestamp: typeof parsed.timestamp === "string" ? parsed.timestamp : event.timestamp
|
|
68220
|
+
};
|
|
68221
|
+
} catch {
|
|
68222
|
+
return null;
|
|
68223
|
+
}
|
|
68224
|
+
}
|
|
67949
68225
|
async function appendJsonl(filePath, value) {
|
|
67950
68226
|
await mkdir9(path39.dirname(filePath), { recursive: true });
|
|
67951
68227
|
await appendFile5(filePath, `${JSON.stringify(value)}
|
|
@@ -67965,6 +68241,7 @@ var init_local_jsonl_provider = __esm(() => {
|
|
|
67965
68241
|
init_config3();
|
|
67966
68242
|
init_curator_decision_helpers();
|
|
67967
68243
|
init_errors6();
|
|
68244
|
+
init_maintenance();
|
|
67968
68245
|
init_schema2();
|
|
67969
68246
|
init_scoring();
|
|
67970
68247
|
});
|
|
@@ -68296,6 +68573,10 @@ class SQLiteMemoryProvider {
|
|
|
68296
68573
|
redaction: {
|
|
68297
68574
|
...DEFAULT_MEMORY_CONFIG.redaction,
|
|
68298
68575
|
...config3.redaction ?? {}
|
|
68576
|
+
},
|
|
68577
|
+
maintenance: {
|
|
68578
|
+
...DEFAULT_MEMORY_CONFIG.maintenance,
|
|
68579
|
+
...config3.maintenance ?? {}
|
|
68299
68580
|
}
|
|
68300
68581
|
};
|
|
68301
68582
|
}
|
|
@@ -68401,6 +68682,26 @@ class SQLiteMemoryProvider {
|
|
|
68401
68682
|
) VALUES (?, ?, ?, ?)`, [randomUUID5(), event.bundleId, event.timestamp, JSON.stringify(event)]);
|
|
68402
68683
|
await this.event("recall", event.bundleId, JSON.stringify(event));
|
|
68403
68684
|
}
|
|
68685
|
+
async listRecallUsage(filter = {}) {
|
|
68686
|
+
await this.initialize();
|
|
68687
|
+
const rows = typeof filter.limit === "number" ? this.requireDb().query(`SELECT usage_json
|
|
68688
|
+
FROM memory_recall_usage
|
|
68689
|
+
ORDER BY timestamp DESC
|
|
68690
|
+
LIMIT ?`).all(Math.max(1, Math.trunc(filter.limit))) : this.requireDb().query(`SELECT usage_json
|
|
68691
|
+
FROM memory_recall_usage
|
|
68692
|
+
ORDER BY timestamp DESC
|
|
68693
|
+
`).all();
|
|
68694
|
+
const events = [];
|
|
68695
|
+
for (const row of rows) {
|
|
68696
|
+
try {
|
|
68697
|
+
const parsed = JSON.parse(row.usage_json);
|
|
68698
|
+
if (Array.isArray(parsed.memoryIds) && typeof parsed.query === "string") {
|
|
68699
|
+
events.push(parsed);
|
|
68700
|
+
}
|
|
68701
|
+
} catch {}
|
|
68702
|
+
}
|
|
68703
|
+
return events;
|
|
68704
|
+
}
|
|
68404
68705
|
async list(filter = {}) {
|
|
68405
68706
|
await this.initialize();
|
|
68406
68707
|
let records = Array.from(this.memories.values());
|
|
@@ -68419,7 +68720,9 @@ class SQLiteMemoryProvider {
|
|
|
68419
68720
|
return !Number.isFinite(expires) || expires > now;
|
|
68420
68721
|
});
|
|
68421
68722
|
}
|
|
68422
|
-
|
|
68723
|
+
if (!filter.includeInactive) {
|
|
68724
|
+
records = records.filter((record3) => !record3.supersededBy && record3.metadata.deleted !== true);
|
|
68725
|
+
}
|
|
68423
68726
|
records.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
68424
68727
|
return records.slice(0, filter.limit ?? records.length);
|
|
68425
68728
|
}
|
|
@@ -68500,6 +68803,52 @@ class SQLiteMemoryProvider {
|
|
|
68500
68803
|
proposals: proposals.length
|
|
68501
68804
|
};
|
|
68502
68805
|
}
|
|
68806
|
+
async compactMaintenance(options = {}) {
|
|
68807
|
+
await this.initialize();
|
|
68808
|
+
const now = options.now ? new Date(options.now) : new Date;
|
|
68809
|
+
const kept = [];
|
|
68810
|
+
const removeIds = [];
|
|
68811
|
+
const result = {
|
|
68812
|
+
dryRun: options.dryRun !== false,
|
|
68813
|
+
removedDeleted: 0,
|
|
68814
|
+
removedSuperseded: 0,
|
|
68815
|
+
removedExpiredScratch: 0,
|
|
68816
|
+
remaining: 0
|
|
68817
|
+
};
|
|
68818
|
+
for (const memory of this.memories.values()) {
|
|
68819
|
+
const compactReason = shouldCompactMemory(memory, now);
|
|
68820
|
+
if (compactReason === "deleted") {
|
|
68821
|
+
result.removedDeleted++;
|
|
68822
|
+
removeIds.push(memory.id);
|
|
68823
|
+
continue;
|
|
68824
|
+
}
|
|
68825
|
+
if (compactReason === "superseded") {
|
|
68826
|
+
result.removedSuperseded++;
|
|
68827
|
+
removeIds.push(memory.id);
|
|
68828
|
+
continue;
|
|
68829
|
+
}
|
|
68830
|
+
if (compactReason === "expired_scratch") {
|
|
68831
|
+
result.removedExpiredScratch++;
|
|
68832
|
+
removeIds.push(memory.id);
|
|
68833
|
+
continue;
|
|
68834
|
+
}
|
|
68835
|
+
kept.push(memory);
|
|
68836
|
+
}
|
|
68837
|
+
result.remaining = kept.length;
|
|
68838
|
+
if (result.dryRun)
|
|
68839
|
+
return result;
|
|
68840
|
+
const db = this.requireDb();
|
|
68841
|
+
const compact = db.transaction(() => {
|
|
68842
|
+
for (const id of removeIds) {
|
|
68843
|
+
db.run("DELETE FROM memory_items WHERE id = ?", [id]);
|
|
68844
|
+
this.deleteMemoryFts(id);
|
|
68845
|
+
}
|
|
68846
|
+
this.insertEvent("compact", "memory_items", "removed deleted, superseded, and expired scratch memories", JSON.stringify(result));
|
|
68847
|
+
});
|
|
68848
|
+
compact();
|
|
68849
|
+
this.memories = new Map(kept.map((memory) => [memory.id, memory]));
|
|
68850
|
+
return result;
|
|
68851
|
+
}
|
|
68503
68852
|
hasMigration(name2) {
|
|
68504
68853
|
const row = this.requireDb().query("SELECT version, name FROM schema_migrations WHERE name = ? LIMIT 1").get(name2);
|
|
68505
68854
|
return Boolean(row);
|
|
@@ -68733,12 +69082,14 @@ class SQLiteMemoryProvider {
|
|
|
68733
69082
|
...decision.memory,
|
|
68734
69083
|
updatedAt: appliedAt
|
|
68735
69084
|
});
|
|
69085
|
+
validateCuratorPromotableMemory(memory);
|
|
68736
69086
|
this.writeMemory(memory);
|
|
68737
69087
|
memories.push(memory);
|
|
68738
69088
|
memoryId = memory.id;
|
|
68739
69089
|
} else if (decision.action === "update") {
|
|
68740
69090
|
const existing = this.readActiveMemory(decision.targetMemoryId);
|
|
68741
69091
|
const updated = this.validateDecisionMemory(applyPatchToMemory(existing, decision.patch, appliedAt));
|
|
69092
|
+
validateCuratorPromotableMemory(updated);
|
|
68742
69093
|
if (updated.id !== existing.id) {
|
|
68743
69094
|
const tombstone = this.validateDecisionMemory({
|
|
68744
69095
|
...existing,
|
|
@@ -68764,6 +69115,7 @@ class SQLiteMemoryProvider {
|
|
|
68764
69115
|
updatedAt: appliedAt,
|
|
68765
69116
|
supersedes: Array.from(new Set([...decision.replacement.supersedes ?? [], oldMemory.id]))
|
|
68766
69117
|
});
|
|
69118
|
+
validateCuratorPromotableMemory(replacement);
|
|
68767
69119
|
const superseded = this.validateDecisionMemory({
|
|
68768
69120
|
...oldMemory,
|
|
68769
69121
|
updatedAt: appliedAt,
|
|
@@ -68976,6 +69328,7 @@ var init_sqlite_provider = __esm(() => {
|
|
|
68976
69328
|
init_curator_decision_helpers();
|
|
68977
69329
|
init_errors6();
|
|
68978
69330
|
init_jsonl_migration();
|
|
69331
|
+
init_maintenance();
|
|
68979
69332
|
init_schema2();
|
|
68980
69333
|
init_scoring();
|
|
68981
69334
|
FTS_INDEX_COLUMNS = [
|
|
@@ -70391,6 +70744,7 @@ var init_memory = __esm(() => {
|
|
|
70391
70744
|
init_injector();
|
|
70392
70745
|
init_jsonl_migration();
|
|
70393
70746
|
init_local_jsonl_provider();
|
|
70747
|
+
init_maintenance();
|
|
70394
70748
|
init_prompt_block();
|
|
70395
70749
|
init_recall_planner();
|
|
70396
70750
|
init_redaction();
|
|
@@ -70409,6 +70763,10 @@ async function handleMemoryCommand(_directory, _args) {
|
|
|
70409
70763
|
"## Swarm Memory",
|
|
70410
70764
|
"",
|
|
70411
70765
|
"- `/swarm memory status` - show provider, SQLite path, JSONL files, and last migration report",
|
|
70766
|
+
"- `/swarm memory pending` - show pending proposals and recent rejection reasons",
|
|
70767
|
+
"- `/swarm memory recall-log` - summarize recall usage by agent role and memory ID",
|
|
70768
|
+
"- `/swarm memory stale` - list expired scratch, superseded, deleted, and low-utility memories",
|
|
70769
|
+
"- `/swarm memory compact` - dry-run compaction; pass `--confirm` to remove deleted, superseded, and expired scratch records",
|
|
70412
70770
|
"- `/swarm memory export` - export current memory and proposals to `.swarm/memory/export/*.jsonl`",
|
|
70413
70771
|
"- `/swarm memory import` - import `.swarm/memory/{memories,proposals}.jsonl` into SQLite",
|
|
70414
70772
|
"- `/swarm memory migrate` - run the one-time legacy JSONL to SQLite migration",
|
|
@@ -70430,6 +70788,7 @@ async function handleMemoryStatusCommand(directory, _args) {
|
|
|
70430
70788
|
`- Storage: \`${storageDir}\``,
|
|
70431
70789
|
`- SQLite path: \`${sqlitePath}\``,
|
|
70432
70790
|
`- SQLite database exists: \`${existsSync25(sqlitePath)}\``,
|
|
70791
|
+
`- Automatic destructive cleanup: \`disabled\``,
|
|
70433
70792
|
"",
|
|
70434
70793
|
"### Legacy JSONL"
|
|
70435
70794
|
];
|
|
@@ -70454,6 +70813,119 @@ async function handleMemoryStatusCommand(directory, _args) {
|
|
|
70454
70813
|
return lines.join(`
|
|
70455
70814
|
`);
|
|
70456
70815
|
}
|
|
70816
|
+
async function handleMemoryPendingCommand(directory, args2) {
|
|
70817
|
+
const parsed = parseMaintenanceArgs(args2, {
|
|
70818
|
+
usage: "Usage: /swarm memory pending [--limit <n>]",
|
|
70819
|
+
allowConfirm: false
|
|
70820
|
+
});
|
|
70821
|
+
if ("error" in parsed)
|
|
70822
|
+
return parsed.error;
|
|
70823
|
+
const config3 = resolveCommandMemoryConfig(directory);
|
|
70824
|
+
const provider = createMaintenanceProvider(directory, config3);
|
|
70825
|
+
try {
|
|
70826
|
+
await provider.initialize?.();
|
|
70827
|
+
const report = await buildMemoryMaintenanceReport(provider, {
|
|
70828
|
+
...maintenanceReportOptions(config3, parsed.limit)
|
|
70829
|
+
});
|
|
70830
|
+
const lines = [
|
|
70831
|
+
"## Swarm Memory Pending",
|
|
70832
|
+
"",
|
|
70833
|
+
`- Pending proposals shown: \`${report.pendingProposals.length}\``,
|
|
70834
|
+
`- Rejected proposal reasons shown: \`${report.rejectedProposalReasons.length}\``
|
|
70835
|
+
];
|
|
70836
|
+
appendProposalLines(lines, "Pending proposals", report.pendingProposals);
|
|
70837
|
+
appendProposalLines(lines, "Rejected proposal reasons", report.rejectedProposalReasons);
|
|
70838
|
+
return lines.join(`
|
|
70839
|
+
`);
|
|
70840
|
+
} finally {
|
|
70841
|
+
await provider.close?.();
|
|
70842
|
+
}
|
|
70843
|
+
}
|
|
70844
|
+
async function handleMemoryRecallLogCommand(directory, args2) {
|
|
70845
|
+
const parsed = parseMaintenanceArgs(args2, {
|
|
70846
|
+
usage: "Usage: /swarm memory recall-log [--limit <n>]",
|
|
70847
|
+
allowConfirm: false
|
|
70848
|
+
});
|
|
70849
|
+
if ("error" in parsed)
|
|
70850
|
+
return parsed.error;
|
|
70851
|
+
const config3 = resolveCommandMemoryConfig(directory);
|
|
70852
|
+
const provider = createMaintenanceProvider(directory, config3);
|
|
70853
|
+
try {
|
|
70854
|
+
await provider.initialize?.();
|
|
70855
|
+
const report = await buildMemoryMaintenanceReport(provider, {
|
|
70856
|
+
...maintenanceReportOptions(config3, parsed.limit)
|
|
70857
|
+
});
|
|
70858
|
+
const lines = [
|
|
70859
|
+
"## Swarm Memory Recall Log",
|
|
70860
|
+
"",
|
|
70861
|
+
`- Recall events scanned: \`${report.recallEventCount}\``,
|
|
70862
|
+
`- Most-recalled memories shown: \`${report.mostRecalledMemories.length}\``,
|
|
70863
|
+
`- Never-recalled memories shown: \`${report.neverRecalledMemories.length}\``
|
|
70864
|
+
];
|
|
70865
|
+
appendRecallRoleLines(lines, report.recallByAgentRole);
|
|
70866
|
+
appendRecallMemoryLines(lines, report.mostRecalledMemories);
|
|
70867
|
+
appendMemoryLines(lines, "Never-recalled memories", report.neverRecalledMemories);
|
|
70868
|
+
return lines.join(`
|
|
70869
|
+
`);
|
|
70870
|
+
} finally {
|
|
70871
|
+
await provider.close?.();
|
|
70872
|
+
}
|
|
70873
|
+
}
|
|
70874
|
+
async function handleMemoryStaleCommand(directory, args2) {
|
|
70875
|
+
const parsed = parseMaintenanceArgs(args2, {
|
|
70876
|
+
usage: "Usage: /swarm memory stale [--limit <n>]",
|
|
70877
|
+
allowConfirm: false
|
|
70878
|
+
});
|
|
70879
|
+
if ("error" in parsed)
|
|
70880
|
+
return parsed.error;
|
|
70881
|
+
const config3 = resolveCommandMemoryConfig(directory);
|
|
70882
|
+
const provider = createMaintenanceProvider(directory, config3);
|
|
70883
|
+
try {
|
|
70884
|
+
await provider.initialize?.();
|
|
70885
|
+
const report = await buildMemoryMaintenanceReport(provider, {
|
|
70886
|
+
...maintenanceReportOptions(config3, parsed.limit)
|
|
70887
|
+
});
|
|
70888
|
+
const lines = [
|
|
70889
|
+
"## Swarm Memory Stale",
|
|
70890
|
+
"",
|
|
70891
|
+
`- Active memories: \`${report.activeMemories}\``,
|
|
70892
|
+
`- Expired scratch memories shown: \`${report.expiredScratchMemories.length}\``,
|
|
70893
|
+
`- Deleted tombstones shown: \`${report.deletedMemories.length}\``,
|
|
70894
|
+
`- Superseded memories shown: \`${report.supersededMemories.length}\``,
|
|
70895
|
+
`- Low-utility memories shown: \`${report.lowUtilityMemories.length}\``
|
|
70896
|
+
];
|
|
70897
|
+
appendMemoryLines(lines, "Expired scratch memories", report.expiredScratchMemories);
|
|
70898
|
+
appendMemoryLines(lines, "Deleted tombstones", report.deletedMemories);
|
|
70899
|
+
appendSupersededChains(lines, report);
|
|
70900
|
+
appendMemoryLines(lines, "Low-utility memories", report.lowUtilityMemories);
|
|
70901
|
+
return lines.join(`
|
|
70902
|
+
`);
|
|
70903
|
+
} finally {
|
|
70904
|
+
await provider.close?.();
|
|
70905
|
+
}
|
|
70906
|
+
}
|
|
70907
|
+
async function handleMemoryCompactCommand(directory, args2) {
|
|
70908
|
+
const parsed = parseMaintenanceArgs(args2, {
|
|
70909
|
+
usage: "Usage: /swarm memory compact [--confirm]",
|
|
70910
|
+
allowConfirm: true,
|
|
70911
|
+
allowLimit: false
|
|
70912
|
+
});
|
|
70913
|
+
if ("error" in parsed)
|
|
70914
|
+
return parsed.error;
|
|
70915
|
+
const provider = createMaintenanceProvider(directory, resolveCommandMemoryConfig(directory));
|
|
70916
|
+
try {
|
|
70917
|
+
await provider.initialize?.();
|
|
70918
|
+
if (!provider.compactMaintenance) {
|
|
70919
|
+
return "Memory provider does not support compaction.";
|
|
70920
|
+
}
|
|
70921
|
+
const result = await provider.compactMaintenance({
|
|
70922
|
+
dryRun: !parsed.confirm
|
|
70923
|
+
});
|
|
70924
|
+
return formatCompactResult(result, parsed.confirm);
|
|
70925
|
+
} finally {
|
|
70926
|
+
await provider.close?.();
|
|
70927
|
+
}
|
|
70928
|
+
}
|
|
70457
70929
|
async function handleMemoryMigrateCommand(directory, _args) {
|
|
70458
70930
|
const config3 = {
|
|
70459
70931
|
...resolveCommandMemoryConfig(directory),
|
|
@@ -70510,6 +70982,16 @@ async function handleMemoryExportCommand(directory, _args) {
|
|
|
70510
70982
|
await provider.close?.();
|
|
70511
70983
|
}
|
|
70512
70984
|
}
|
|
70985
|
+
function createMaintenanceProvider(directory, config3) {
|
|
70986
|
+
return createConfiguredMemoryProvider(directory, config3);
|
|
70987
|
+
}
|
|
70988
|
+
function maintenanceReportOptions(config3, limit) {
|
|
70989
|
+
return {
|
|
70990
|
+
limit,
|
|
70991
|
+
lowUtilityMaxConfidence: config3.maintenance.lowUtilityMaxConfidence,
|
|
70992
|
+
lowUtilityMinAgeDays: config3.maintenance.lowUtilityMinAgeDays
|
|
70993
|
+
};
|
|
70994
|
+
}
|
|
70513
70995
|
async function handleMemoryEvaluateCommand(directory, args2) {
|
|
70514
70996
|
const parsed = parseEvaluateArgs(directory, args2);
|
|
70515
70997
|
if ("error" in parsed)
|
|
@@ -70568,6 +71050,28 @@ function parseEvaluateArgs(directory, args2) {
|
|
|
70568
71050
|
}
|
|
70569
71051
|
return { json: json3, fixtureDirectory };
|
|
70570
71052
|
}
|
|
71053
|
+
function parseMaintenanceArgs(args2, options) {
|
|
71054
|
+
let limit = 20;
|
|
71055
|
+
let confirm = false;
|
|
71056
|
+
const allowLimit = options.allowLimit ?? true;
|
|
71057
|
+
for (let i2 = 0;i2 < args2.length; i2++) {
|
|
71058
|
+
const arg = args2[i2];
|
|
71059
|
+
if (arg === "--confirm" && options.allowConfirm) {
|
|
71060
|
+
confirm = true;
|
|
71061
|
+
continue;
|
|
71062
|
+
}
|
|
71063
|
+
if (arg === "--limit" && allowLimit) {
|
|
71064
|
+
const next = args2[i2 + 1];
|
|
71065
|
+
if (!next || !/^\d+$/.test(next))
|
|
71066
|
+
return { error: options.usage };
|
|
71067
|
+
limit = Math.min(100, Math.max(1, Number(next)));
|
|
71068
|
+
i2++;
|
|
71069
|
+
continue;
|
|
71070
|
+
}
|
|
71071
|
+
return { error: options.usage };
|
|
71072
|
+
}
|
|
71073
|
+
return { limit, confirm };
|
|
71074
|
+
}
|
|
70571
71075
|
function resolvePackageRootFromModule(modulePath) {
|
|
70572
71076
|
const moduleDir = path45.dirname(modulePath);
|
|
70573
71077
|
const leaf = path45.basename(moduleDir);
|
|
@@ -70618,6 +71122,80 @@ function appendInvalidRows(lines, invalidRows) {
|
|
|
70618
71122
|
lines.push(`- ... ${invalidRows.length - 20} more`);
|
|
70619
71123
|
}
|
|
70620
71124
|
}
|
|
71125
|
+
function appendProposalLines(lines, title, proposals) {
|
|
71126
|
+
lines.push("", `### ${title}`);
|
|
71127
|
+
if (proposals.length === 0) {
|
|
71128
|
+
lines.push("- none");
|
|
71129
|
+
return;
|
|
71130
|
+
}
|
|
71131
|
+
for (const proposal of proposals) {
|
|
71132
|
+
const reason = proposal.status === "rejected" ? ` - ${proposal.rejectionReason ?? "no reason recorded"}` : "";
|
|
71133
|
+
lines.push(`- \`${proposal.id}\` ${proposal.operation} ${proposal.targetMemoryId ?? proposal.proposedRecord?.id ?? "new"} (${proposal.status})${reason}`);
|
|
71134
|
+
}
|
|
71135
|
+
}
|
|
71136
|
+
function appendMemoryLines(lines, title, memories) {
|
|
71137
|
+
lines.push("", `### ${title}`);
|
|
71138
|
+
if (memories.length === 0) {
|
|
71139
|
+
lines.push("- none");
|
|
71140
|
+
return;
|
|
71141
|
+
}
|
|
71142
|
+
for (const memory of memories) {
|
|
71143
|
+
lines.push(`- \`${memory.id}\` ${memory.kind} confidence=${memory.confidence.toFixed(2)} updated=${memory.updatedAt} - ${truncate(memory.text, 100)}`);
|
|
71144
|
+
}
|
|
71145
|
+
}
|
|
71146
|
+
function appendRecallRoleLines(lines, roles) {
|
|
71147
|
+
lines.push("", "### Recall by agent role");
|
|
71148
|
+
if (roles.length === 0) {
|
|
71149
|
+
lines.push("- none");
|
|
71150
|
+
return;
|
|
71151
|
+
}
|
|
71152
|
+
for (const role of roles) {
|
|
71153
|
+
const memoryCount = Object.keys(role.memoryIds).length;
|
|
71154
|
+
lines.push(`- \`${role.agentRole}\`: ${role.count} recall event(s), ${memoryCount} memory ID(s)`);
|
|
71155
|
+
}
|
|
71156
|
+
}
|
|
71157
|
+
function appendRecallMemoryLines(lines, memories) {
|
|
71158
|
+
lines.push("", "### Most-recalled memories");
|
|
71159
|
+
if (memories.length === 0) {
|
|
71160
|
+
lines.push("- none");
|
|
71161
|
+
return;
|
|
71162
|
+
}
|
|
71163
|
+
for (const memory of memories) {
|
|
71164
|
+
lines.push(`- \`${memory.memoryId}\`: ${memory.count} hit(s), last=${memory.lastRecalledAt}, avgScore=${memory.averageScore.toFixed(3)}`);
|
|
71165
|
+
}
|
|
71166
|
+
}
|
|
71167
|
+
function appendSupersededChains(lines, report) {
|
|
71168
|
+
lines.push("", "### Superseded chains");
|
|
71169
|
+
if (report.supersededChains.length === 0) {
|
|
71170
|
+
lines.push("- none");
|
|
71171
|
+
return;
|
|
71172
|
+
}
|
|
71173
|
+
for (const chain of report.supersededChains) {
|
|
71174
|
+
const reason = chain.reason ? ` - ${chain.reason}` : "";
|
|
71175
|
+
lines.push(`- ${chain.chain.map((id) => `\`${id}\``).join(" -> ")}${reason}`);
|
|
71176
|
+
}
|
|
71177
|
+
}
|
|
71178
|
+
function formatCompactResult(result, confirmed) {
|
|
71179
|
+
const lines = [
|
|
71180
|
+
"## Swarm Memory Compact",
|
|
71181
|
+
"",
|
|
71182
|
+
`- Mode: \`${confirmed ? "confirmed" : "dry-run"}\``,
|
|
71183
|
+
`- Deleted tombstones: \`${result.removedDeleted}\``,
|
|
71184
|
+
`- Superseded records: \`${result.removedSuperseded}\``,
|
|
71185
|
+
`- Expired scratch records: \`${result.removedExpiredScratch}\``,
|
|
71186
|
+
`- Remaining memories: \`${result.remaining}\``
|
|
71187
|
+
];
|
|
71188
|
+
if (!confirmed) {
|
|
71189
|
+
lines.push("", "No records were removed. Re-run `/swarm memory compact --confirm` to apply this compaction.");
|
|
71190
|
+
}
|
|
71191
|
+
return lines.join(`
|
|
71192
|
+
`);
|
|
71193
|
+
}
|
|
71194
|
+
function truncate(value, maxLength) {
|
|
71195
|
+
if (value.length <= maxLength)
|
|
71196
|
+
return value;
|
|
71197
|
+
return `${value.slice(0, maxLength - 3)}...`;
|
|
71198
|
+
}
|
|
70621
71199
|
var PACKAGE_ROOT;
|
|
70622
71200
|
var init_memory2 = __esm(() => {
|
|
70623
71201
|
init_loader();
|
|
@@ -79002,7 +79580,7 @@ function classifySwarmCommandToolUse(resolved) {
|
|
|
79002
79580
|
return { allowed: true };
|
|
79003
79581
|
return {
|
|
79004
79582
|
allowed: false,
|
|
79005
|
-
message: "Use `/swarm memory status`, `/swarm memory export`, or `/swarm memory evaluate --json` through swarm_command. Memory import and
|
|
79583
|
+
message: "Use `/swarm memory status`, `/swarm memory pending`, `/swarm memory recall-log`, `/swarm memory stale`, `/swarm memory export`, or `/swarm memory evaluate --json` through swarm_command. Memory import, migrate, and compact are intentionally excluded from chat-tool execution."
|
|
79006
79584
|
};
|
|
79007
79585
|
}
|
|
79008
79586
|
if (canonicalKey === "memory evaluate") {
|
|
@@ -79015,6 +79593,17 @@ function classifySwarmCommandToolUse(resolved) {
|
|
|
79015
79593
|
message: "Usage through swarm_command: `/swarm memory evaluate --json`. Custom fixture directories are only available through direct user command execution."
|
|
79016
79594
|
};
|
|
79017
79595
|
}
|
|
79596
|
+
if (canonicalKey === "memory pending" || canonicalKey === "memory recall-log" || canonicalKey === "memory stale") {
|
|
79597
|
+
if (args2.length === 0)
|
|
79598
|
+
return { allowed: true };
|
|
79599
|
+
if (args2.length === 2 && args2[0] === "--limit" && /^\d+$/.test(args2[1])) {
|
|
79600
|
+
return { allowed: true };
|
|
79601
|
+
}
|
|
79602
|
+
return {
|
|
79603
|
+
allowed: false,
|
|
79604
|
+
message: `Usage through swarm_command: \`/swarm ${canonicalKey}\` or ` + `\`/swarm ${canonicalKey} --limit <n>\`.`
|
|
79605
|
+
};
|
|
79606
|
+
}
|
|
79018
79607
|
if (canonicalKey === "retrieve") {
|
|
79019
79608
|
if (args2.length !== 1 || !SUMMARY_ID_PATTERN.test(args2[0])) {
|
|
79020
79609
|
return {
|
|
@@ -79066,7 +79655,7 @@ function classifySwarmCommandChatFallbackUse(resolved) {
|
|
|
79066
79655
|
message: "/swarm config doctor --fix is not available through chat fallback because it can modify configuration files. Run the CLI command directly when you intend to apply fixes."
|
|
79067
79656
|
};
|
|
79068
79657
|
}
|
|
79069
|
-
if (canonicalKey === "knowledge migrate" || canonicalKey === "knowledge quarantine" || canonicalKey === "knowledge restore" || canonicalKey === "memory import" || canonicalKey === "memory migrate") {
|
|
79658
|
+
if (canonicalKey === "knowledge migrate" || canonicalKey === "knowledge quarantine" || canonicalKey === "knowledge restore" || canonicalKey === "memory import" || canonicalKey === "memory migrate" || canonicalKey === "memory compact") {
|
|
79070
79659
|
return {
|
|
79071
79660
|
allowed: false,
|
|
79072
79661
|
message: `/swarm ${canonicalKey} is not available through chat fallback because it mutates .swarm state. ` + "Run the CLI command directly after confirming the intended state change."
|
|
@@ -79099,6 +79688,10 @@ var init_tool_policy = __esm(() => {
|
|
|
79099
79688
|
"knowledge",
|
|
79100
79689
|
"memory",
|
|
79101
79690
|
"memory status",
|
|
79691
|
+
"memory pending",
|
|
79692
|
+
"memory recall-log",
|
|
79693
|
+
"memory compact",
|
|
79694
|
+
"memory stale",
|
|
79102
79695
|
"memory export",
|
|
79103
79696
|
"memory evaluate",
|
|
79104
79697
|
"memory import",
|
|
@@ -79125,6 +79718,9 @@ var init_tool_policy = __esm(() => {
|
|
|
79125
79718
|
"knowledge",
|
|
79126
79719
|
"memory",
|
|
79127
79720
|
"memory status",
|
|
79721
|
+
"memory pending",
|
|
79722
|
+
"memory recall-log",
|
|
79723
|
+
"memory stale",
|
|
79128
79724
|
"memory export",
|
|
79129
79725
|
"memory evaluate",
|
|
79130
79726
|
"sync-plan",
|
|
@@ -79137,7 +79733,8 @@ var init_tool_policy = __esm(() => {
|
|
|
79137
79733
|
"rollback",
|
|
79138
79734
|
"checkpoint",
|
|
79139
79735
|
"memory import",
|
|
79140
|
-
"memory migrate"
|
|
79736
|
+
"memory migrate",
|
|
79737
|
+
"memory compact"
|
|
79141
79738
|
]);
|
|
79142
79739
|
NO_ARGS = new Set([
|
|
79143
79740
|
"agents",
|
|
@@ -80132,6 +80729,34 @@ Subcommands:
|
|
|
80132
80729
|
args: "",
|
|
80133
80730
|
category: "diagnostics"
|
|
80134
80731
|
},
|
|
80732
|
+
"memory pending": {
|
|
80733
|
+
handler: (ctx) => handleMemoryPendingCommand(ctx.directory, ctx.args),
|
|
80734
|
+
description: "Show pending Swarm memory proposals and rejection reasons",
|
|
80735
|
+
subcommandOf: "memory",
|
|
80736
|
+
args: "--limit <n>",
|
|
80737
|
+
category: "diagnostics"
|
|
80738
|
+
},
|
|
80739
|
+
"memory recall-log": {
|
|
80740
|
+
handler: (ctx) => handleMemoryRecallLogCommand(ctx.directory, ctx.args),
|
|
80741
|
+
description: "Summarize Swarm memory recall usage",
|
|
80742
|
+
subcommandOf: "memory",
|
|
80743
|
+
args: "--limit <n>",
|
|
80744
|
+
category: "diagnostics"
|
|
80745
|
+
},
|
|
80746
|
+
"memory compact": {
|
|
80747
|
+
handler: (ctx) => handleMemoryCompactCommand(ctx.directory, ctx.args),
|
|
80748
|
+
description: "Compact deleted, superseded, and expired scratch memories",
|
|
80749
|
+
subcommandOf: "memory",
|
|
80750
|
+
args: "--confirm",
|
|
80751
|
+
category: "utility"
|
|
80752
|
+
},
|
|
80753
|
+
"memory stale": {
|
|
80754
|
+
handler: (ctx) => handleMemoryStaleCommand(ctx.directory, ctx.args),
|
|
80755
|
+
description: "List stale and low-utility Swarm memories",
|
|
80756
|
+
subcommandOf: "memory",
|
|
80757
|
+
args: "--limit <n>",
|
|
80758
|
+
category: "diagnostics"
|
|
80759
|
+
},
|
|
80135
80760
|
"memory export": {
|
|
80136
80761
|
handler: (ctx) => handleMemoryExportCommand(ctx.directory, ctx.args),
|
|
80137
80762
|
description: "Export current Swarm memory to JSONL files",
|
|
@@ -83887,6 +84512,7 @@ API: [exact names/signatures/versions to use]
|
|
|
83887
84512
|
PLATFORM: [cross-platform notes if OS-interaction APIs]
|
|
83888
84513
|
GOTCHAS: [common pitfalls or edge cases]
|
|
83889
84514
|
DEPS: [required dependencies/tools]
|
|
84515
|
+
EVIDENCE_REFS: [cite evidence-cache:<id>, URL, file, or doc refs used; use "none" if no external evidence was available]
|
|
83890
84516
|
|
|
83891
84517
|
## DOMAIN CHECKLISTS
|
|
83892
84518
|
Apply the relevant checklist when the DOMAIN matches:
|
|
@@ -83925,7 +84551,8 @@ Cache lookup steps:
|
|
|
83925
84551
|
1. If \`.swarm/context.md\` does not exist: proceed with fresh research.
|
|
83926
84552
|
2. If the \`## Research Sources\` section is absent: proceed with fresh research.
|
|
83927
84553
|
3. If URL/topic IS listed in ## Research Sources: reuse cached summary — no re-fetch needed.
|
|
83928
|
-
4. If
|
|
84554
|
+
4. If fresh search/API-doc/crawl evidence is provided, cite its \`evidence-cache:<id>\` refs in EVIDENCE_REFS. Raw docs/search snippets are evidence, not memory.
|
|
84555
|
+
5. If cache miss (URL/topic not listed): fetch URL, then append this line at the end of your response:
|
|
83929
84556
|
CACHE-UPDATE: [YYYY-MM-DD] | [URL or topic] | [one-line summary of finding]
|
|
83930
84557
|
The Architect will save this line to .swarm/context.md ## Research Sources. Do NOT write to any file yourself.
|
|
83931
84558
|
|
|
@@ -89644,11 +90271,11 @@ var init_curator_drift = __esm(() => {
|
|
|
89644
90271
|
var exports_project_context = {};
|
|
89645
90272
|
__export(exports_project_context, {
|
|
89646
90273
|
buildProjectContext: () => buildProjectContext,
|
|
89647
|
-
_internals: () =>
|
|
90274
|
+
_internals: () => _internals65,
|
|
89648
90275
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
89649
90276
|
});
|
|
89650
90277
|
import * as fs115 from "node:fs";
|
|
89651
|
-
import * as
|
|
90278
|
+
import * as path155 from "node:path";
|
|
89652
90279
|
function detectFileExists2(directory, pattern) {
|
|
89653
90280
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
89654
90281
|
try {
|
|
@@ -89660,7 +90287,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
89660
90287
|
}
|
|
89661
90288
|
}
|
|
89662
90289
|
try {
|
|
89663
|
-
fs115.accessSync(
|
|
90290
|
+
fs115.accessSync(path155.join(directory, pattern));
|
|
89664
90291
|
return true;
|
|
89665
90292
|
} catch {
|
|
89666
90293
|
return false;
|
|
@@ -89669,7 +90296,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
89669
90296
|
function selectTestCommandFromScriptsTest(backend, directory) {
|
|
89670
90297
|
let pkgRaw;
|
|
89671
90298
|
try {
|
|
89672
|
-
pkgRaw = fs115.readFileSync(
|
|
90299
|
+
pkgRaw = fs115.readFileSync(path155.join(directory, "package.json"), "utf-8");
|
|
89673
90300
|
} catch {
|
|
89674
90301
|
return null;
|
|
89675
90302
|
}
|
|
@@ -89728,7 +90355,7 @@ function selectLintCommand(backend, directory) {
|
|
|
89728
90355
|
return null;
|
|
89729
90356
|
}
|
|
89730
90357
|
async function buildProjectContext(directory) {
|
|
89731
|
-
const backend = await
|
|
90358
|
+
const backend = await _internals65.pickBackend(directory);
|
|
89732
90359
|
if (!backend)
|
|
89733
90360
|
return null;
|
|
89734
90361
|
const ctx = emptyProjectContext();
|
|
@@ -89759,16 +90386,16 @@ async function buildProjectContext(directory) {
|
|
|
89759
90386
|
if (backend.prompts.reviewerChecklist.length > 0) {
|
|
89760
90387
|
ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
|
|
89761
90388
|
}
|
|
89762
|
-
const profiles =
|
|
90389
|
+
const profiles = _internals65.pickedProfiles(directory);
|
|
89763
90390
|
if (profiles.length > 1) {
|
|
89764
90391
|
ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
|
|
89765
90392
|
}
|
|
89766
90393
|
return ctx;
|
|
89767
90394
|
}
|
|
89768
|
-
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300,
|
|
90395
|
+
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals65;
|
|
89769
90396
|
var init_project_context = __esm(() => {
|
|
89770
90397
|
init_dispatch();
|
|
89771
|
-
|
|
90398
|
+
_internals65 = {
|
|
89772
90399
|
pickBackend,
|
|
89773
90400
|
pickedProfiles
|
|
89774
90401
|
};
|
|
@@ -89778,7 +90405,7 @@ var init_project_context = __esm(() => {
|
|
|
89778
90405
|
init_package();
|
|
89779
90406
|
init_agents2();
|
|
89780
90407
|
init_critic();
|
|
89781
|
-
import * as
|
|
90408
|
+
import * as path156 from "node:path";
|
|
89782
90409
|
|
|
89783
90410
|
// src/background/index.ts
|
|
89784
90411
|
init_event_bus();
|
|
@@ -122958,6 +123585,83 @@ function createWebSearchProvider(config3) {
|
|
|
122958
123585
|
}
|
|
122959
123586
|
}
|
|
122960
123587
|
|
|
123588
|
+
// src/evidence/documents.ts
|
|
123589
|
+
init_utils2();
|
|
123590
|
+
init_redaction();
|
|
123591
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
123592
|
+
import { appendFile as appendFile13, mkdir as mkdir24 } from "node:fs/promises";
|
|
123593
|
+
import * as path150 from "node:path";
|
|
123594
|
+
var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
|
|
123595
|
+
var MAX_EVIDENCE_TEXT_LENGTH = 4000;
|
|
123596
|
+
async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
123597
|
+
const filePath = validateSwarmPath(directory, EVIDENCE_CACHE_FILE);
|
|
123598
|
+
const capturedAt = now().toISOString();
|
|
123599
|
+
const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
|
|
123600
|
+
if (records.length > 0) {
|
|
123601
|
+
await mkdir24(path150.dirname(filePath), { recursive: true });
|
|
123602
|
+
await appendFile13(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
|
|
123603
|
+
`)}
|
|
123604
|
+
`, "utf-8");
|
|
123605
|
+
}
|
|
123606
|
+
return {
|
|
123607
|
+
path: ".swarm/evidence-cache/documents.jsonl",
|
|
123608
|
+
records,
|
|
123609
|
+
refs: records.map((record3) => record3.ref)
|
|
123610
|
+
};
|
|
123611
|
+
}
|
|
123612
|
+
function createEvidenceDocumentRecord(input, defaultCapturedAt) {
|
|
123613
|
+
const text = normalizeEvidenceText(input.text ?? input.snippet ?? "");
|
|
123614
|
+
if (!text)
|
|
123615
|
+
return null;
|
|
123616
|
+
const capturedAt = input.capturedAt ?? defaultCapturedAt;
|
|
123617
|
+
const base = {
|
|
123618
|
+
sourceType: input.sourceType,
|
|
123619
|
+
query: normalizeOptional(input.query),
|
|
123620
|
+
title: normalizeOptional(input.title),
|
|
123621
|
+
url: normalizeOptional(input.url),
|
|
123622
|
+
text
|
|
123623
|
+
};
|
|
123624
|
+
const id = createEvidenceDocumentId(base);
|
|
123625
|
+
return {
|
|
123626
|
+
id,
|
|
123627
|
+
ref: `evidence-cache:${id}`,
|
|
123628
|
+
...base,
|
|
123629
|
+
capturedAt,
|
|
123630
|
+
createdBy: normalizeOptional(input.createdBy),
|
|
123631
|
+
metadata: input.metadata ?? {}
|
|
123632
|
+
};
|
|
123633
|
+
}
|
|
123634
|
+
function createEvidenceDocumentId(input) {
|
|
123635
|
+
const hash3 = createHash12("sha256").update([
|
|
123636
|
+
input.sourceType,
|
|
123637
|
+
input.query ?? "",
|
|
123638
|
+
input.title ?? "",
|
|
123639
|
+
input.url ?? "",
|
|
123640
|
+
input.text
|
|
123641
|
+
].join(`
|
|
123642
|
+
`)).digest("hex");
|
|
123643
|
+
return `evd_${hash3.slice(0, 16)}`;
|
|
123644
|
+
}
|
|
123645
|
+
function normalizeEvidenceText(text) {
|
|
123646
|
+
const normalized = redactSecrets(text.replace(/\s+/g, " ").trim());
|
|
123647
|
+
return truncateEvidenceText(normalized, MAX_EVIDENCE_TEXT_LENGTH);
|
|
123648
|
+
}
|
|
123649
|
+
function truncateEvidenceText(text, maxLength) {
|
|
123650
|
+
if (text.length <= maxLength)
|
|
123651
|
+
return text;
|
|
123652
|
+
const truncated = text.slice(0, maxLength);
|
|
123653
|
+
const lastPlaceholderStart = truncated.lastIndexOf("[REDACTED:");
|
|
123654
|
+
const lastPlaceholderEnd = truncated.lastIndexOf("]");
|
|
123655
|
+
if (lastPlaceholderStart > lastPlaceholderEnd) {
|
|
123656
|
+
return truncated.slice(0, lastPlaceholderStart).trimEnd();
|
|
123657
|
+
}
|
|
123658
|
+
return truncated;
|
|
123659
|
+
}
|
|
123660
|
+
function normalizeOptional(value) {
|
|
123661
|
+
const normalized = value?.replace(/\s+/g, " ").trim();
|
|
123662
|
+
return normalized ? redactSecrets(normalized) : undefined;
|
|
123663
|
+
}
|
|
123664
|
+
|
|
122961
123665
|
// src/tools/web-search.ts
|
|
122962
123666
|
init_create_tool();
|
|
122963
123667
|
init_resolve_working_directory();
|
|
@@ -123018,6 +123722,7 @@ var web_search = createSwarmTool({
|
|
|
123018
123722
|
}
|
|
123019
123723
|
try {
|
|
123020
123724
|
const results = await provider.search(parsed.data.query, maxResults);
|
|
123725
|
+
const evidence = await captureSearchEvidence(dirResult.directory, parsed.data.query, results);
|
|
123021
123726
|
const ok2 = {
|
|
123022
123727
|
success: true,
|
|
123023
123728
|
query: parsed.data.query,
|
|
@@ -123025,8 +123730,15 @@ var web_search = createSwarmTool({
|
|
|
123025
123730
|
results: results.map(({ title, url: url3, snippet }) => ({
|
|
123026
123731
|
title,
|
|
123027
123732
|
url: url3,
|
|
123028
|
-
snippet
|
|
123029
|
-
|
|
123733
|
+
snippet,
|
|
123734
|
+
evidenceRef: evidence.refByUrl.get(url3)
|
|
123735
|
+
})),
|
|
123736
|
+
evidence: {
|
|
123737
|
+
stored: evidence.stored,
|
|
123738
|
+
path: evidence.path,
|
|
123739
|
+
refs: evidence.refs,
|
|
123740
|
+
error: evidence.error
|
|
123741
|
+
}
|
|
123030
123742
|
};
|
|
123031
123743
|
return JSON.stringify(ok2, null, 2);
|
|
123032
123744
|
} catch (err3) {
|
|
@@ -123039,6 +123751,39 @@ var web_search = createSwarmTool({
|
|
|
123039
123751
|
}
|
|
123040
123752
|
}
|
|
123041
123753
|
});
|
|
123754
|
+
async function captureSearchEvidence(directory, query, results) {
|
|
123755
|
+
try {
|
|
123756
|
+
const written = await _internals64.writeEvidenceDocuments(directory, results.map((result) => ({
|
|
123757
|
+
sourceType: "web_search",
|
|
123758
|
+
query,
|
|
123759
|
+
title: result.title,
|
|
123760
|
+
url: result.url,
|
|
123761
|
+
snippet: result.snippet,
|
|
123762
|
+
createdBy: "web_search"
|
|
123763
|
+
})));
|
|
123764
|
+
const refByUrl = new Map;
|
|
123765
|
+
for (const record3 of written.records) {
|
|
123766
|
+
if (record3.url)
|
|
123767
|
+
refByUrl.set(record3.url, record3.ref);
|
|
123768
|
+
}
|
|
123769
|
+
return {
|
|
123770
|
+
stored: written.records.length > 0,
|
|
123771
|
+
path: written.path,
|
|
123772
|
+
refs: written.refs,
|
|
123773
|
+
refByUrl
|
|
123774
|
+
};
|
|
123775
|
+
} catch (err3) {
|
|
123776
|
+
return {
|
|
123777
|
+
stored: false,
|
|
123778
|
+
refs: [],
|
|
123779
|
+
refByUrl: new Map,
|
|
123780
|
+
error: err3 instanceof Error ? err3.message : String(err3)
|
|
123781
|
+
};
|
|
123782
|
+
}
|
|
123783
|
+
}
|
|
123784
|
+
var _internals64 = {
|
|
123785
|
+
writeEvidenceDocuments
|
|
123786
|
+
};
|
|
123042
123787
|
// src/tools/write-drift-evidence.ts
|
|
123043
123788
|
init_zod();
|
|
123044
123789
|
init_qa_gate_profile();
|
|
@@ -123047,7 +123792,7 @@ init_ledger();
|
|
|
123047
123792
|
init_manager();
|
|
123048
123793
|
init_create_tool();
|
|
123049
123794
|
import fs111 from "node:fs";
|
|
123050
|
-
import
|
|
123795
|
+
import path151 from "node:path";
|
|
123051
123796
|
function normalizeVerdict(verdict) {
|
|
123052
123797
|
switch (verdict) {
|
|
123053
123798
|
case "APPROVED":
|
|
@@ -123095,7 +123840,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
123095
123840
|
entries: [evidenceEntry]
|
|
123096
123841
|
};
|
|
123097
123842
|
const filename = "drift-verifier.json";
|
|
123098
|
-
const relativePath =
|
|
123843
|
+
const relativePath = path151.join("evidence", String(phase), filename);
|
|
123099
123844
|
let validatedPath;
|
|
123100
123845
|
try {
|
|
123101
123846
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -123106,10 +123851,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
123106
123851
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
123107
123852
|
}, null, 2);
|
|
123108
123853
|
}
|
|
123109
|
-
const evidenceDir =
|
|
123854
|
+
const evidenceDir = path151.dirname(validatedPath);
|
|
123110
123855
|
try {
|
|
123111
123856
|
await fs111.promises.mkdir(evidenceDir, { recursive: true });
|
|
123112
|
-
const tempPath =
|
|
123857
|
+
const tempPath = path151.join(evidenceDir, `.${filename}.tmp`);
|
|
123113
123858
|
await fs111.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
123114
123859
|
await fs111.promises.rename(tempPath, validatedPath);
|
|
123115
123860
|
let snapshotInfo;
|
|
@@ -123205,7 +123950,7 @@ var write_drift_evidence = createSwarmTool({
|
|
|
123205
123950
|
init_zod();
|
|
123206
123951
|
init_loader();
|
|
123207
123952
|
import fs112 from "node:fs";
|
|
123208
|
-
import
|
|
123953
|
+
import path152 from "node:path";
|
|
123209
123954
|
init_utils2();
|
|
123210
123955
|
init_manager();
|
|
123211
123956
|
init_create_tool();
|
|
@@ -123293,7 +124038,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
123293
124038
|
timestamp: synthesis.timestamp
|
|
123294
124039
|
};
|
|
123295
124040
|
const filename = "final-council.json";
|
|
123296
|
-
const relativePath =
|
|
124041
|
+
const relativePath = path152.join("evidence", filename);
|
|
123297
124042
|
let validatedPath;
|
|
123298
124043
|
try {
|
|
123299
124044
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -123307,10 +124052,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
123307
124052
|
const evidenceContent = {
|
|
123308
124053
|
entries: [evidenceEntry]
|
|
123309
124054
|
};
|
|
123310
|
-
const evidenceDir =
|
|
124055
|
+
const evidenceDir = path152.dirname(validatedPath);
|
|
123311
124056
|
try {
|
|
123312
124057
|
await fs112.promises.mkdir(evidenceDir, { recursive: true });
|
|
123313
|
-
const tempPath =
|
|
124058
|
+
const tempPath = path152.join(evidenceDir, `.${filename}.tmp`);
|
|
123314
124059
|
await fs112.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
123315
124060
|
await fs112.promises.rename(tempPath, validatedPath);
|
|
123316
124061
|
return JSON.stringify({
|
|
@@ -123369,7 +124114,7 @@ init_zod();
|
|
|
123369
124114
|
init_utils2();
|
|
123370
124115
|
init_create_tool();
|
|
123371
124116
|
import fs113 from "node:fs";
|
|
123372
|
-
import
|
|
124117
|
+
import path153 from "node:path";
|
|
123373
124118
|
function normalizeVerdict2(verdict) {
|
|
123374
124119
|
switch (verdict) {
|
|
123375
124120
|
case "APPROVED":
|
|
@@ -123417,7 +124162,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
123417
124162
|
entries: [evidenceEntry]
|
|
123418
124163
|
};
|
|
123419
124164
|
const filename = "hallucination-guard.json";
|
|
123420
|
-
const relativePath =
|
|
124165
|
+
const relativePath = path153.join("evidence", String(phase), filename);
|
|
123421
124166
|
let validatedPath;
|
|
123422
124167
|
try {
|
|
123423
124168
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -123428,10 +124173,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
123428
124173
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
123429
124174
|
}, null, 2);
|
|
123430
124175
|
}
|
|
123431
|
-
const evidenceDir =
|
|
124176
|
+
const evidenceDir = path153.dirname(validatedPath);
|
|
123432
124177
|
try {
|
|
123433
124178
|
await fs113.promises.mkdir(evidenceDir, { recursive: true });
|
|
123434
|
-
const tempPath =
|
|
124179
|
+
const tempPath = path153.join(evidenceDir, `.${filename}.tmp`);
|
|
123435
124180
|
await fs113.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
123436
124181
|
await fs113.promises.rename(tempPath, validatedPath);
|
|
123437
124182
|
return JSON.stringify({
|
|
@@ -123480,7 +124225,7 @@ init_zod();
|
|
|
123480
124225
|
init_utils2();
|
|
123481
124226
|
init_create_tool();
|
|
123482
124227
|
import fs114 from "node:fs";
|
|
123483
|
-
import
|
|
124228
|
+
import path154 from "node:path";
|
|
123484
124229
|
function normalizeVerdict3(verdict) {
|
|
123485
124230
|
switch (verdict) {
|
|
123486
124231
|
case "PASS":
|
|
@@ -123554,7 +124299,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
123554
124299
|
entries: [evidenceEntry]
|
|
123555
124300
|
};
|
|
123556
124301
|
const filename = "mutation-gate.json";
|
|
123557
|
-
const relativePath =
|
|
124302
|
+
const relativePath = path154.join("evidence", String(phase), filename);
|
|
123558
124303
|
let validatedPath;
|
|
123559
124304
|
try {
|
|
123560
124305
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -123565,10 +124310,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
123565
124310
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
123566
124311
|
}, null, 2);
|
|
123567
124312
|
}
|
|
123568
|
-
const evidenceDir =
|
|
124313
|
+
const evidenceDir = path154.dirname(validatedPath);
|
|
123569
124314
|
try {
|
|
123570
124315
|
await fs114.promises.mkdir(evidenceDir, { recursive: true });
|
|
123571
|
-
const tempPath =
|
|
124316
|
+
const tempPath = path154.join(evidenceDir, `.${filename}.tmp`);
|
|
123572
124317
|
await fs114.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
123573
124318
|
await fs114.promises.rename(tempPath, validatedPath);
|
|
123574
124319
|
return JSON.stringify({
|
|
@@ -123918,7 +124663,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
123918
124663
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
123919
124664
|
preflightTriggerManager = new PTM(automationConfig);
|
|
123920
124665
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
123921
|
-
const swarmDir =
|
|
124666
|
+
const swarmDir = path156.resolve(ctx.directory, ".swarm");
|
|
123922
124667
|
statusArtifact = new ASA(swarmDir);
|
|
123923
124668
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
123924
124669
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|
|
@@ -124522,7 +125267,7 @@ ${promptRaw}`;
|
|
|
124522
125267
|
"ci-failure-resolver": "CI/CD failure resolution"
|
|
124523
125268
|
};
|
|
124524
125269
|
const skillPaths = topSkills.map((s) => {
|
|
124525
|
-
const dirName =
|
|
125270
|
+
const dirName = path156.basename(path156.dirname(s.skillPath));
|
|
124526
125271
|
const desc = SKILL_DESCRIPTIONS[dirName] ?? dirName;
|
|
124527
125272
|
return `file:${s.skillPath} (-- ${desc})`;
|
|
124528
125273
|
}).join(", ");
|
|
@@ -124531,7 +125276,7 @@ ${promptRaw}`;
|
|
|
124531
125276
|
|
|
124532
125277
|
${promptRaw}`;
|
|
124533
125278
|
argsRecord.prompt = newPrompt;
|
|
124534
|
-
const skillNames = topSkills.map((s) => `${
|
|
125279
|
+
const skillNames = topSkills.map((s) => `${path156.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
|
|
124535
125280
|
console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
|
|
124536
125281
|
for (const skill of topSkills) {
|
|
124537
125282
|
try {
|