opencode-swarm 7.32.2 → 7.33.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/cli/index.js +32 -4
- package/dist/config/schema.d.ts +30 -2
- package/dist/index.js +990 -415
- package/dist/memory/config.d.ts +12 -1
- package/dist/memory/gateway.d.ts +5 -1
- package/dist/memory/index.d.ts +3 -2
- package/dist/memory/injector.d.ts +1 -1
- package/dist/memory/local-jsonl-provider.d.ts +5 -0
- package/dist/memory/prompt-block.d.ts +1 -0
- package/dist/memory/provider.d.ts +7 -0
- package/dist/memory/run-log.d.ts +1 -1
- package/dist/memory/scoring.d.ts +12 -0
- package/dist/memory/sqlite-provider.d.ts +39 -0
- package/dist/memory/types.d.ts +19 -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.33.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",
|
|
@@ -15539,13 +15539,41 @@ var init_schema = __esm(() => {
|
|
|
15539
15539
|
});
|
|
15540
15540
|
MemoryConfigSchema = exports_external.object({
|
|
15541
15541
|
enabled: exports_external.boolean().default(false),
|
|
15542
|
-
provider: exports_external.
|
|
15542
|
+
provider: exports_external.enum(["local-jsonl", "sqlite"]).default("local-jsonl"),
|
|
15543
15543
|
storageDir: exports_external.string().default(".swarm/memory"),
|
|
15544
|
+
sqlite: exports_external.object({
|
|
15545
|
+
path: exports_external.string().default(".swarm/memory/memory.db"),
|
|
15546
|
+
busyTimeoutMs: exports_external.number().int().min(0).max(60000).default(5000)
|
|
15547
|
+
}).default({ path: ".swarm/memory/memory.db", busyTimeoutMs: 5000 }),
|
|
15544
15548
|
recall: exports_external.object({
|
|
15545
15549
|
defaultMaxItems: exports_external.number().int().min(1).max(20).default(8),
|
|
15546
15550
|
defaultTokenBudget: exports_external.number().int().min(100).max(5000).default(1200),
|
|
15547
|
-
minScore: exports_external.number().min(0).max(1).default(0.05)
|
|
15548
|
-
|
|
15551
|
+
minScore: exports_external.number().min(0).max(1).default(0.05),
|
|
15552
|
+
injection: exports_external.object({
|
|
15553
|
+
enabled: exports_external.boolean().default(true),
|
|
15554
|
+
minScore: exports_external.number().min(0).max(1).default(0.25),
|
|
15555
|
+
requireQuerySignal: exports_external.boolean().default(true),
|
|
15556
|
+
maxItems: exports_external.number().int().min(1).max(20).default(6),
|
|
15557
|
+
tokenBudget: exports_external.number().int().min(100).max(5000).default(1000)
|
|
15558
|
+
}).default({
|
|
15559
|
+
enabled: true,
|
|
15560
|
+
minScore: 0.25,
|
|
15561
|
+
requireQuerySignal: true,
|
|
15562
|
+
maxItems: 6,
|
|
15563
|
+
tokenBudget: 1000
|
|
15564
|
+
})
|
|
15565
|
+
}).default({
|
|
15566
|
+
defaultMaxItems: 8,
|
|
15567
|
+
defaultTokenBudget: 1200,
|
|
15568
|
+
minScore: 0.05,
|
|
15569
|
+
injection: {
|
|
15570
|
+
enabled: true,
|
|
15571
|
+
minScore: 0.25,
|
|
15572
|
+
requireQuerySignal: true,
|
|
15573
|
+
maxItems: 6,
|
|
15574
|
+
tokenBudget: 1000
|
|
15575
|
+
}
|
|
15576
|
+
}),
|
|
15549
15577
|
writes: exports_external.object({
|
|
15550
15578
|
mode: exports_external.literal("propose").default("propose")
|
|
15551
15579
|
}).default({ mode: "propose" }),
|
|
@@ -84575,7 +84603,7 @@ __export(exports_project_context, {
|
|
|
84575
84603
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
84576
84604
|
});
|
|
84577
84605
|
import * as fs113 from "node:fs";
|
|
84578
|
-
import * as
|
|
84606
|
+
import * as path148 from "node:path";
|
|
84579
84607
|
function detectFileExists2(directory, pattern) {
|
|
84580
84608
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
84581
84609
|
try {
|
|
@@ -84587,7 +84615,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
84587
84615
|
}
|
|
84588
84616
|
}
|
|
84589
84617
|
try {
|
|
84590
|
-
fs113.accessSync(
|
|
84618
|
+
fs113.accessSync(path148.join(directory, pattern));
|
|
84591
84619
|
return true;
|
|
84592
84620
|
} catch {
|
|
84593
84621
|
return false;
|
|
@@ -84596,7 +84624,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
84596
84624
|
function selectTestCommandFromScriptsTest(backend, directory) {
|
|
84597
84625
|
let pkgRaw;
|
|
84598
84626
|
try {
|
|
84599
|
-
pkgRaw = fs113.readFileSync(
|
|
84627
|
+
pkgRaw = fs113.readFileSync(path148.join(directory, "package.json"), "utf-8");
|
|
84600
84628
|
} catch {
|
|
84601
84629
|
return null;
|
|
84602
84630
|
}
|
|
@@ -84705,7 +84733,7 @@ var init_project_context = __esm(() => {
|
|
|
84705
84733
|
init_package();
|
|
84706
84734
|
init_agents2();
|
|
84707
84735
|
init_critic();
|
|
84708
|
-
import * as
|
|
84736
|
+
import * as path149 from "node:path";
|
|
84709
84737
|
|
|
84710
84738
|
// src/background/index.ts
|
|
84711
84739
|
init_event_bus();
|
|
@@ -97571,10 +97599,21 @@ var DEFAULT_MEMORY_CONFIG = {
|
|
|
97571
97599
|
enabled: false,
|
|
97572
97600
|
provider: "local-jsonl",
|
|
97573
97601
|
storageDir: ".swarm/memory",
|
|
97602
|
+
sqlite: {
|
|
97603
|
+
path: ".swarm/memory/memory.db",
|
|
97604
|
+
busyTimeoutMs: 5000
|
|
97605
|
+
},
|
|
97574
97606
|
recall: {
|
|
97575
97607
|
defaultMaxItems: 8,
|
|
97576
97608
|
defaultTokenBudget: 1200,
|
|
97577
|
-
minScore: 0.05
|
|
97609
|
+
minScore: 0.05,
|
|
97610
|
+
injection: {
|
|
97611
|
+
enabled: true,
|
|
97612
|
+
minScore: 0.25,
|
|
97613
|
+
requireQuerySignal: true,
|
|
97614
|
+
maxItems: 6,
|
|
97615
|
+
tokenBudget: 1000
|
|
97616
|
+
}
|
|
97578
97617
|
},
|
|
97579
97618
|
writes: {
|
|
97580
97619
|
mode: "propose"
|
|
@@ -97603,9 +97642,17 @@ function resolveMemoryConfig(input) {
|
|
|
97603
97642
|
return {
|
|
97604
97643
|
...DEFAULT_MEMORY_CONFIG,
|
|
97605
97644
|
...input ?? {},
|
|
97645
|
+
sqlite: {
|
|
97646
|
+
...DEFAULT_MEMORY_CONFIG.sqlite,
|
|
97647
|
+
...input?.sqlite ?? {}
|
|
97648
|
+
},
|
|
97606
97649
|
recall: {
|
|
97607
97650
|
...DEFAULT_MEMORY_CONFIG.recall,
|
|
97608
|
-
...input?.recall ?? {}
|
|
97651
|
+
...input?.recall ?? {},
|
|
97652
|
+
injection: {
|
|
97653
|
+
...DEFAULT_MEMORY_CONFIG.recall.injection,
|
|
97654
|
+
...input?.recall?.injection ?? {}
|
|
97655
|
+
}
|
|
97609
97656
|
},
|
|
97610
97657
|
writes: {
|
|
97611
97658
|
...DEFAULT_MEMORY_CONFIG.writes,
|
|
@@ -97636,7 +97683,7 @@ class MemoryDisabledError extends Error {
|
|
|
97636
97683
|
// src/memory/gateway.ts
|
|
97637
97684
|
import { createHash as createHash9 } from "node:crypto";
|
|
97638
97685
|
import { existsSync as existsSync50, readFileSync as readFileSync39 } from "node:fs";
|
|
97639
|
-
import * as
|
|
97686
|
+
import * as path97 from "node:path";
|
|
97640
97687
|
|
|
97641
97688
|
// src/memory/local-jsonl-provider.ts
|
|
97642
97689
|
init_utils2();
|
|
@@ -97887,6 +97934,24 @@ function validateMemoryProposal(proposal) {
|
|
|
97887
97934
|
function tokenize(text) {
|
|
97888
97935
|
return new Set(text.toLowerCase().replace(/[^\w\s-]/g, " ").split(/\s+/).map((token) => token.trim()).filter(Boolean));
|
|
97889
97936
|
}
|
|
97937
|
+
function normalizeKindText(kind) {
|
|
97938
|
+
return kind.replace(/_/g, " ");
|
|
97939
|
+
}
|
|
97940
|
+
function collectMetadataStrings(metadata2, keys) {
|
|
97941
|
+
const values = [];
|
|
97942
|
+
for (const key of keys) {
|
|
97943
|
+
const value = metadata2[key];
|
|
97944
|
+
if (typeof value === "string")
|
|
97945
|
+
values.push(value);
|
|
97946
|
+
if (Array.isArray(value)) {
|
|
97947
|
+
for (const item of value) {
|
|
97948
|
+
if (typeof item === "string")
|
|
97949
|
+
values.push(item);
|
|
97950
|
+
}
|
|
97951
|
+
}
|
|
97952
|
+
}
|
|
97953
|
+
return values;
|
|
97954
|
+
}
|
|
97890
97955
|
function overlap(a, b) {
|
|
97891
97956
|
if (a.size === 0 || b.size === 0)
|
|
97892
97957
|
return 0;
|
|
@@ -97924,37 +97989,101 @@ function sameScope(a, b) {
|
|
|
97924
97989
|
function scopeAllowed(recordScope, allowedScopes) {
|
|
97925
97990
|
return allowedScopes.some((scope) => sameScope(recordScope, scope));
|
|
97926
97991
|
}
|
|
97927
|
-
function
|
|
97928
|
-
if (!request.includeExpired && isExpired2(record3))
|
|
97929
|
-
return null;
|
|
97992
|
+
function scoreMemoryRecordDetailed(record3, request) {
|
|
97993
|
+
if (!request.includeExpired && isExpired2(record3)) {
|
|
97994
|
+
return { item: null, skipReason: "filtered" };
|
|
97995
|
+
}
|
|
97930
97996
|
if (record3.supersededBy)
|
|
97931
|
-
return null;
|
|
97932
|
-
if (record3.metadata.deleted === true)
|
|
97933
|
-
return null;
|
|
97934
|
-
|
|
97935
|
-
|
|
97936
|
-
|
|
97937
|
-
|
|
97938
|
-
|
|
97997
|
+
return { item: null, skipReason: "filtered" };
|
|
97998
|
+
if (record3.metadata.deleted === true) {
|
|
97999
|
+
return { item: null, skipReason: "filtered" };
|
|
98000
|
+
}
|
|
98001
|
+
if (!scopeAllowed(record3.scope, request.scopes)) {
|
|
98002
|
+
return { item: null, skipReason: "filtered" };
|
|
98003
|
+
}
|
|
98004
|
+
if (request.kinds && !request.kinds.includes(record3.kind)) {
|
|
98005
|
+
return { item: null, skipReason: "filtered" };
|
|
98006
|
+
}
|
|
98007
|
+
const queryTokens = request.mode === "injection" && request.task ? tokenize(request.task) : tokenize(request.query);
|
|
97939
98008
|
const textTokens = tokenize(record3.text);
|
|
97940
98009
|
const tagTokens = tokenize(record3.tags.join(" "));
|
|
98010
|
+
const fileTokens = tokenize([
|
|
98011
|
+
record3.source.filePath,
|
|
98012
|
+
...collectMetadataStrings(record3.metadata, [
|
|
98013
|
+
"file",
|
|
98014
|
+
"filePath",
|
|
98015
|
+
"files",
|
|
98016
|
+
"touchedFiles"
|
|
98017
|
+
])
|
|
98018
|
+
].filter((value) => typeof value === "string").join(" "));
|
|
98019
|
+
const symbolTokens = tokenize(collectMetadataStrings(record3.metadata, ["symbol", "symbols"]).join(" "));
|
|
98020
|
+
const kindQueryOverlap = overlap(queryTokens, tokenize(normalizeKindText(record3.kind)));
|
|
97941
98021
|
const textOverlap = overlap(queryTokens, textTokens);
|
|
97942
98022
|
const tagOverlap = overlap(queryTokens, tagTokens);
|
|
97943
|
-
const
|
|
98023
|
+
const fileOverlap = overlap(queryTokens, fileTokens);
|
|
98024
|
+
const symbolOverlap = overlap(queryTokens, symbolTokens);
|
|
98025
|
+
const kindMatch = request.kinds?.includes(record3.kind) ?? false;
|
|
98026
|
+
const scopeMatch = scopeAllowed(record3.scope, request.scopes);
|
|
98027
|
+
const hasQuerySignal = textOverlap > 0 || tagOverlap > 0 || fileOverlap > 0 || symbolOverlap > 0 || kindQueryOverlap > 0;
|
|
98028
|
+
if (request.mode === "injection" && request.requireQuerySignal !== false && !hasQuerySignal) {
|
|
98029
|
+
return { item: null, skipReason: "no_signal" };
|
|
98030
|
+
}
|
|
98031
|
+
const score = textOverlap * 0.45 + tagOverlap * 0.2 + fileOverlap * 0.05 + symbolOverlap * 0.05 + scopeSpecificityBoost(record3.scope) * 0.15 + kindProfileBoost(record3.kind, request) * 0.1 + record3.confidence * 0.1;
|
|
97944
98032
|
const reasonParts = [
|
|
97945
98033
|
textOverlap > 0 ? `text_overlap=${textOverlap.toFixed(2)}` : null,
|
|
97946
98034
|
tagOverlap > 0 ? `tag_overlap=${tagOverlap.toFixed(2)}` : null,
|
|
98035
|
+
fileOverlap > 0 ? `file_overlap=${fileOverlap.toFixed(2)}` : null,
|
|
98036
|
+
symbolOverlap > 0 ? `symbol_overlap=${symbolOverlap.toFixed(2)}` : null,
|
|
98037
|
+
kindQueryOverlap > 0 ? `kind_query=${kindQueryOverlap.toFixed(2)}` : null,
|
|
97947
98038
|
`scope=${record3.scope.type}`,
|
|
97948
98039
|
`confidence=${record3.confidence.toFixed(2)}`
|
|
97949
98040
|
].filter(Boolean);
|
|
97950
98041
|
return {
|
|
97951
|
-
|
|
97952
|
-
|
|
97953
|
-
|
|
98042
|
+
item: {
|
|
98043
|
+
record: record3,
|
|
98044
|
+
score,
|
|
98045
|
+
reason: reasonParts.join(", "),
|
|
98046
|
+
signals: {
|
|
98047
|
+
textOverlap,
|
|
98048
|
+
tagOverlap,
|
|
98049
|
+
fileOverlap,
|
|
98050
|
+
symbolOverlap,
|
|
98051
|
+
kindMatch,
|
|
98052
|
+
scopeMatch
|
|
98053
|
+
}
|
|
98054
|
+
}
|
|
97954
98055
|
};
|
|
97955
98056
|
}
|
|
97956
|
-
function
|
|
97957
|
-
|
|
98057
|
+
function scoreMemoryRecordsWithDiagnostics(records, request) {
|
|
98058
|
+
const minScore = request.minScore ?? 0;
|
|
98059
|
+
const diagnostics = {
|
|
98060
|
+
candidateCount: records.length,
|
|
98061
|
+
preScoredFilteredCount: 0,
|
|
98062
|
+
scoredCount: 0,
|
|
98063
|
+
returnedCount: 0,
|
|
98064
|
+
noSignalCount: 0,
|
|
98065
|
+
belowThresholdCount: 0
|
|
98066
|
+
};
|
|
98067
|
+
const items = [];
|
|
98068
|
+
for (const record3 of records) {
|
|
98069
|
+
const result = scoreMemoryRecordDetailed(record3, request);
|
|
98070
|
+
if (!result.item) {
|
|
98071
|
+
if (result.skipReason === "filtered")
|
|
98072
|
+
diagnostics.preScoredFilteredCount++;
|
|
98073
|
+
if (result.skipReason === "no_signal")
|
|
98074
|
+
diagnostics.noSignalCount++;
|
|
98075
|
+
continue;
|
|
98076
|
+
}
|
|
98077
|
+
diagnostics.scoredCount++;
|
|
98078
|
+
if (result.item.score < minScore) {
|
|
98079
|
+
diagnostics.belowThresholdCount++;
|
|
98080
|
+
continue;
|
|
98081
|
+
}
|
|
98082
|
+
items.push(result.item);
|
|
98083
|
+
}
|
|
98084
|
+
items.sort((a, b) => b.score - a.score || a.record.id.localeCompare(b.record.id));
|
|
98085
|
+
diagnostics.returnedCount = items.length;
|
|
98086
|
+
return { items, diagnostics };
|
|
97958
98087
|
}
|
|
97959
98088
|
|
|
97960
98089
|
// src/memory/local-jsonl-provider.ts
|
|
@@ -98030,13 +98159,23 @@ class LocalJsonlMemoryProvider {
|
|
|
98030
98159
|
await this.audit("delete", id, reason);
|
|
98031
98160
|
}
|
|
98032
98161
|
async recall(request) {
|
|
98162
|
+
return (await this.recallWithDiagnostics(request)).items;
|
|
98163
|
+
}
|
|
98164
|
+
async recallWithDiagnostics(request) {
|
|
98033
98165
|
await this.initialize();
|
|
98034
98166
|
const records = await this.list({
|
|
98035
98167
|
scopes: request.scopes,
|
|
98036
98168
|
kinds: request.kinds,
|
|
98037
98169
|
includeExpired: request.includeExpired
|
|
98038
98170
|
});
|
|
98039
|
-
|
|
98171
|
+
const result = scoreMemoryRecordsWithDiagnostics(records, request);
|
|
98172
|
+
return {
|
|
98173
|
+
items: result.items.slice(0, request.maxItems),
|
|
98174
|
+
diagnostics: {
|
|
98175
|
+
...result.diagnostics,
|
|
98176
|
+
returnedCount: Math.min(result.diagnostics.returnedCount, request.maxItems)
|
|
98177
|
+
}
|
|
98178
|
+
};
|
|
98040
98179
|
}
|
|
98041
98180
|
async recordRecallUsage(event) {
|
|
98042
98181
|
await this.initialize();
|
|
@@ -98241,10 +98380,372 @@ function toRecallBundle(input) {
|
|
|
98241
98380
|
generatedAt: input.generatedAt,
|
|
98242
98381
|
items: block.items,
|
|
98243
98382
|
tokenEstimate: block.tokenEstimate,
|
|
98244
|
-
promptBlock: block.promptBlock
|
|
98383
|
+
promptBlock: block.promptBlock,
|
|
98384
|
+
diagnostics: input.diagnostics
|
|
98245
98385
|
};
|
|
98246
98386
|
}
|
|
98247
98387
|
|
|
98388
|
+
// src/memory/sqlite-provider.ts
|
|
98389
|
+
init_utils2();
|
|
98390
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
98391
|
+
import { mkdirSync as mkdirSync24 } from "node:fs";
|
|
98392
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
98393
|
+
import * as path96 from "node:path";
|
|
98394
|
+
var _DatabaseCtor2 = null;
|
|
98395
|
+
function loadDatabaseCtor2() {
|
|
98396
|
+
if (_DatabaseCtor2)
|
|
98397
|
+
return _DatabaseCtor2;
|
|
98398
|
+
const req = createRequire3(import.meta.url);
|
|
98399
|
+
_DatabaseCtor2 = req("bun:sqlite").Database;
|
|
98400
|
+
return _DatabaseCtor2;
|
|
98401
|
+
}
|
|
98402
|
+
var MIGRATIONS2 = [
|
|
98403
|
+
{
|
|
98404
|
+
version: 1,
|
|
98405
|
+
name: "create_memory_provider_tables",
|
|
98406
|
+
sql: `
|
|
98407
|
+
CREATE TABLE IF NOT EXISTS memory_items (
|
|
98408
|
+
id TEXT PRIMARY KEY,
|
|
98409
|
+
scope_key TEXT NOT NULL,
|
|
98410
|
+
kind TEXT NOT NULL,
|
|
98411
|
+
updated_at TEXT NOT NULL,
|
|
98412
|
+
expires_at TEXT,
|
|
98413
|
+
superseded_by TEXT,
|
|
98414
|
+
deleted INTEGER NOT NULL DEFAULT 0,
|
|
98415
|
+
record_json TEXT NOT NULL
|
|
98416
|
+
);
|
|
98417
|
+
CREATE INDEX IF NOT EXISTS idx_memory_items_scope_kind
|
|
98418
|
+
ON memory_items(scope_key, kind);
|
|
98419
|
+
CREATE INDEX IF NOT EXISTS idx_memory_items_updated_at
|
|
98420
|
+
ON memory_items(updated_at);
|
|
98421
|
+
|
|
98422
|
+
CREATE TABLE IF NOT EXISTS memory_proposals (
|
|
98423
|
+
id TEXT PRIMARY KEY,
|
|
98424
|
+
status TEXT NOT NULL,
|
|
98425
|
+
created_at TEXT NOT NULL,
|
|
98426
|
+
proposal_json TEXT NOT NULL
|
|
98427
|
+
);
|
|
98428
|
+
CREATE INDEX IF NOT EXISTS idx_memory_proposals_status_created
|
|
98429
|
+
ON memory_proposals(status, created_at);
|
|
98430
|
+
|
|
98431
|
+
CREATE TABLE IF NOT EXISTS memory_events (
|
|
98432
|
+
id TEXT PRIMARY KEY,
|
|
98433
|
+
operation TEXT NOT NULL,
|
|
98434
|
+
target_id TEXT NOT NULL,
|
|
98435
|
+
reason TEXT,
|
|
98436
|
+
timestamp TEXT NOT NULL,
|
|
98437
|
+
event_json TEXT
|
|
98438
|
+
);
|
|
98439
|
+
|
|
98440
|
+
CREATE TABLE IF NOT EXISTS memory_recall_usage (
|
|
98441
|
+
id TEXT PRIMARY KEY,
|
|
98442
|
+
bundle_id TEXT NOT NULL,
|
|
98443
|
+
timestamp TEXT NOT NULL,
|
|
98444
|
+
usage_json TEXT NOT NULL
|
|
98445
|
+
);
|
|
98446
|
+
CREATE INDEX IF NOT EXISTS idx_memory_recall_usage_bundle
|
|
98447
|
+
ON memory_recall_usage(bundle_id);
|
|
98448
|
+
`
|
|
98449
|
+
}
|
|
98450
|
+
];
|
|
98451
|
+
|
|
98452
|
+
class SQLiteMemoryProvider {
|
|
98453
|
+
name = "sqlite";
|
|
98454
|
+
rootDirectory;
|
|
98455
|
+
config;
|
|
98456
|
+
initialized = false;
|
|
98457
|
+
db = null;
|
|
98458
|
+
memories = new Map;
|
|
98459
|
+
proposals = new Map;
|
|
98460
|
+
constructor(rootDirectory, config3 = {}) {
|
|
98461
|
+
this.rootDirectory = rootDirectory;
|
|
98462
|
+
this.config = {
|
|
98463
|
+
...DEFAULT_MEMORY_CONFIG,
|
|
98464
|
+
...config3,
|
|
98465
|
+
sqlite: {
|
|
98466
|
+
...DEFAULT_MEMORY_CONFIG.sqlite,
|
|
98467
|
+
...config3.sqlite ?? {}
|
|
98468
|
+
},
|
|
98469
|
+
recall: {
|
|
98470
|
+
...DEFAULT_MEMORY_CONFIG.recall,
|
|
98471
|
+
...config3.recall ?? {},
|
|
98472
|
+
injection: {
|
|
98473
|
+
...DEFAULT_MEMORY_CONFIG.recall.injection,
|
|
98474
|
+
...config3.recall?.injection ?? {}
|
|
98475
|
+
}
|
|
98476
|
+
},
|
|
98477
|
+
writes: {
|
|
98478
|
+
...DEFAULT_MEMORY_CONFIG.writes,
|
|
98479
|
+
...config3.writes ?? {}
|
|
98480
|
+
},
|
|
98481
|
+
redaction: {
|
|
98482
|
+
...DEFAULT_MEMORY_CONFIG.redaction,
|
|
98483
|
+
...config3.redaction ?? {}
|
|
98484
|
+
}
|
|
98485
|
+
};
|
|
98486
|
+
}
|
|
98487
|
+
databasePath() {
|
|
98488
|
+
const relativePath = this.config.sqlite.path.replace(/^\.swarm[/\\]?/, "");
|
|
98489
|
+
return validateSwarmPath(this.rootDirectory, relativePath);
|
|
98490
|
+
}
|
|
98491
|
+
async initialize() {
|
|
98492
|
+
if (this.initialized)
|
|
98493
|
+
return;
|
|
98494
|
+
const dbPath = this.databasePath();
|
|
98495
|
+
mkdirSync24(path96.dirname(dbPath), { recursive: true });
|
|
98496
|
+
const Db = loadDatabaseCtor2();
|
|
98497
|
+
this.db = new Db(dbPath);
|
|
98498
|
+
this.db.run("PRAGMA journal_mode = WAL;");
|
|
98499
|
+
this.db.run("PRAGMA synchronous = NORMAL;");
|
|
98500
|
+
const busyTimeoutMs = Math.min(60000, Math.max(0, Math.trunc(this.config.sqlite.busyTimeoutMs)));
|
|
98501
|
+
this.db.run(`PRAGMA busy_timeout = ${busyTimeoutMs};`);
|
|
98502
|
+
this.db.run("PRAGMA foreign_keys = ON;");
|
|
98503
|
+
this.runMigrations();
|
|
98504
|
+
const memoryLoad = this.loadMemories();
|
|
98505
|
+
const proposalLoad = this.loadProposals();
|
|
98506
|
+
this.memories = new Map(memoryLoad.records.map((record3) => [record3.id, record3]));
|
|
98507
|
+
this.proposals = new Map(proposalLoad.records.map((proposal) => [proposal.id, proposal]));
|
|
98508
|
+
this.initialized = true;
|
|
98509
|
+
if (memoryLoad.invalidCount > 0) {
|
|
98510
|
+
await this.event("invalid_load", "memory_items", `${memoryLoad.invalidCount} invalid SQLite memory row(s) skipped`);
|
|
98511
|
+
}
|
|
98512
|
+
if (proposalLoad.invalidCount > 0) {
|
|
98513
|
+
await this.event("invalid_load", "memory_proposals", `${proposalLoad.invalidCount} invalid SQLite proposal row(s) skipped`);
|
|
98514
|
+
}
|
|
98515
|
+
}
|
|
98516
|
+
async upsert(record3) {
|
|
98517
|
+
await this.initialize();
|
|
98518
|
+
const existing = this.memories.get(record3.id);
|
|
98519
|
+
if (existing?.metadata.deleted === true) {
|
|
98520
|
+
throw new MemoryValidationError("memory is tombstoned and cannot be upserted");
|
|
98521
|
+
}
|
|
98522
|
+
const next = validateMemoryRecordRules({
|
|
98523
|
+
...record3,
|
|
98524
|
+
createdAt: existing?.createdAt ?? record3.createdAt
|
|
98525
|
+
}, { rejectDurableSecrets: this.config.redaction.rejectDurableSecrets });
|
|
98526
|
+
this.memories.set(next.id, next);
|
|
98527
|
+
this.writeMemory(next);
|
|
98528
|
+
await this.event("upsert", next.id);
|
|
98529
|
+
return next;
|
|
98530
|
+
}
|
|
98531
|
+
async get(id) {
|
|
98532
|
+
await this.initialize();
|
|
98533
|
+
return this.memories.get(id) ?? null;
|
|
98534
|
+
}
|
|
98535
|
+
async delete(id, reason) {
|
|
98536
|
+
await this.initialize();
|
|
98537
|
+
const existing = this.memories.get(id);
|
|
98538
|
+
if (!existing)
|
|
98539
|
+
return;
|
|
98540
|
+
if (this.config.hardDelete) {
|
|
98541
|
+
this.memories.delete(id);
|
|
98542
|
+
this.requireDb().run("DELETE FROM memory_items WHERE id = ?", [id]);
|
|
98543
|
+
} else {
|
|
98544
|
+
const tombstone = {
|
|
98545
|
+
...existing,
|
|
98546
|
+
updatedAt: new Date().toISOString(),
|
|
98547
|
+
metadata: { ...existing.metadata, deleted: true, deleteReason: reason }
|
|
98548
|
+
};
|
|
98549
|
+
this.memories.set(id, tombstone);
|
|
98550
|
+
this.writeMemory(tombstone);
|
|
98551
|
+
}
|
|
98552
|
+
await this.event("delete", id, reason);
|
|
98553
|
+
}
|
|
98554
|
+
async recall(request) {
|
|
98555
|
+
return (await this.recallWithDiagnostics(request)).items;
|
|
98556
|
+
}
|
|
98557
|
+
async recallWithDiagnostics(request) {
|
|
98558
|
+
await this.initialize();
|
|
98559
|
+
const records = await this.list({
|
|
98560
|
+
scopes: request.scopes,
|
|
98561
|
+
kinds: request.kinds,
|
|
98562
|
+
includeExpired: request.includeExpired
|
|
98563
|
+
});
|
|
98564
|
+
const result = scoreMemoryRecordsWithDiagnostics(records, request);
|
|
98565
|
+
return {
|
|
98566
|
+
items: result.items.slice(0, request.maxItems),
|
|
98567
|
+
diagnostics: {
|
|
98568
|
+
...result.diagnostics,
|
|
98569
|
+
returnedCount: Math.min(result.diagnostics.returnedCount, request.maxItems)
|
|
98570
|
+
}
|
|
98571
|
+
};
|
|
98572
|
+
}
|
|
98573
|
+
async recordRecallUsage(event) {
|
|
98574
|
+
await this.initialize();
|
|
98575
|
+
this.requireDb().run(`INSERT INTO memory_recall_usage (
|
|
98576
|
+
id,
|
|
98577
|
+
bundle_id,
|
|
98578
|
+
timestamp,
|
|
98579
|
+
usage_json
|
|
98580
|
+
) VALUES (?, ?, ?, ?)`, [randomUUID9(), event.bundleId, event.timestamp, JSON.stringify(event)]);
|
|
98581
|
+
await this.event("recall", event.bundleId, JSON.stringify(event));
|
|
98582
|
+
}
|
|
98583
|
+
async list(filter = {}) {
|
|
98584
|
+
await this.initialize();
|
|
98585
|
+
let records = Array.from(this.memories.values());
|
|
98586
|
+
if (filter.scopes && filter.scopes.length > 0) {
|
|
98587
|
+
records = records.filter((record3) => scopeAllowed(record3.scope, filter.scopes ?? []));
|
|
98588
|
+
}
|
|
98589
|
+
if (filter.kinds && filter.kinds.length > 0) {
|
|
98590
|
+
records = records.filter((record3) => filter.kinds?.includes(record3.kind));
|
|
98591
|
+
}
|
|
98592
|
+
if (!filter.includeExpired) {
|
|
98593
|
+
const now = Date.now();
|
|
98594
|
+
records = records.filter((record3) => {
|
|
98595
|
+
if (!record3.expiresAt)
|
|
98596
|
+
return true;
|
|
98597
|
+
const expires = Date.parse(record3.expiresAt);
|
|
98598
|
+
return !Number.isFinite(expires) || expires > now;
|
|
98599
|
+
});
|
|
98600
|
+
}
|
|
98601
|
+
records = records.filter((record3) => !record3.supersededBy && record3.metadata.deleted !== true);
|
|
98602
|
+
records.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
98603
|
+
return records.slice(0, filter.limit ?? records.length);
|
|
98604
|
+
}
|
|
98605
|
+
async createProposal(proposal) {
|
|
98606
|
+
await this.initialize();
|
|
98607
|
+
const next = validateMemoryProposal(proposal);
|
|
98608
|
+
if (next.proposedRecord) {
|
|
98609
|
+
validateMemoryRecordRules(next.proposedRecord, {
|
|
98610
|
+
rejectDurableSecrets: this.config.redaction.rejectDurableSecrets
|
|
98611
|
+
});
|
|
98612
|
+
}
|
|
98613
|
+
this.proposals.set(next.id, next);
|
|
98614
|
+
this.requireDb().run(`INSERT OR REPLACE INTO memory_proposals (
|
|
98615
|
+
id,
|
|
98616
|
+
status,
|
|
98617
|
+
created_at,
|
|
98618
|
+
proposal_json
|
|
98619
|
+
) VALUES (?, ?, ?, ?)`, [next.id, next.status, next.createdAt, JSON.stringify(next)]);
|
|
98620
|
+
await this.event("proposal", next.id);
|
|
98621
|
+
return next;
|
|
98622
|
+
}
|
|
98623
|
+
async listProposals(filter = {}) {
|
|
98624
|
+
await this.initialize();
|
|
98625
|
+
let proposals = Array.from(this.proposals.values());
|
|
98626
|
+
if (filter.status) {
|
|
98627
|
+
proposals = proposals.filter((proposal) => proposal.status === filter.status);
|
|
98628
|
+
}
|
|
98629
|
+
proposals.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
98630
|
+
return proposals.slice(0, filter.limit ?? proposals.length);
|
|
98631
|
+
}
|
|
98632
|
+
close() {
|
|
98633
|
+
if (!this.db)
|
|
98634
|
+
return;
|
|
98635
|
+
this.db.close();
|
|
98636
|
+
this.db = null;
|
|
98637
|
+
this.initialized = false;
|
|
98638
|
+
}
|
|
98639
|
+
runMigrations() {
|
|
98640
|
+
const db = this.requireDb();
|
|
98641
|
+
db.run(`CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
98642
|
+
version INTEGER PRIMARY KEY,
|
|
98643
|
+
name TEXT NOT NULL,
|
|
98644
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
98645
|
+
)`);
|
|
98646
|
+
const row = db.query("SELECT MAX(version) as version FROM schema_migrations").get();
|
|
98647
|
+
const currentVersion = row?.version ?? 0;
|
|
98648
|
+
for (const migration of MIGRATIONS2) {
|
|
98649
|
+
if (migration.version <= currentVersion)
|
|
98650
|
+
continue;
|
|
98651
|
+
const apply = db.transaction(() => {
|
|
98652
|
+
for (const statement of splitSql(migration.sql)) {
|
|
98653
|
+
db.run(statement);
|
|
98654
|
+
}
|
|
98655
|
+
db.run("INSERT INTO schema_migrations (version, name) VALUES (?, ?)", [
|
|
98656
|
+
migration.version,
|
|
98657
|
+
migration.name
|
|
98658
|
+
]);
|
|
98659
|
+
this.insertEvent("migration", String(migration.version), migration.name);
|
|
98660
|
+
});
|
|
98661
|
+
apply();
|
|
98662
|
+
}
|
|
98663
|
+
}
|
|
98664
|
+
loadMemories() {
|
|
98665
|
+
const rows = this.requireDb().query("SELECT id, record_json FROM memory_items ORDER BY updated_at ASC").all();
|
|
98666
|
+
const records = [];
|
|
98667
|
+
let invalidCount = 0;
|
|
98668
|
+
for (const row of rows) {
|
|
98669
|
+
try {
|
|
98670
|
+
records.push(validateMemoryRecordRules(JSON.parse(row.record_json), {
|
|
98671
|
+
rejectDurableSecrets: this.config.redaction.rejectDurableSecrets
|
|
98672
|
+
}));
|
|
98673
|
+
} catch {
|
|
98674
|
+
invalidCount++;
|
|
98675
|
+
}
|
|
98676
|
+
}
|
|
98677
|
+
return { records, invalidCount };
|
|
98678
|
+
}
|
|
98679
|
+
loadProposals() {
|
|
98680
|
+
const rows = this.requireDb().query("SELECT id, proposal_json FROM memory_proposals ORDER BY created_at ASC").all();
|
|
98681
|
+
const records = [];
|
|
98682
|
+
let invalidCount = 0;
|
|
98683
|
+
for (const row of rows) {
|
|
98684
|
+
try {
|
|
98685
|
+
const proposal = validateMemoryProposal(JSON.parse(row.proposal_json));
|
|
98686
|
+
if (proposal.proposedRecord) {
|
|
98687
|
+
validateMemoryRecordRules(proposal.proposedRecord, {
|
|
98688
|
+
rejectDurableSecrets: this.config.redaction.rejectDurableSecrets
|
|
98689
|
+
});
|
|
98690
|
+
}
|
|
98691
|
+
records.push(proposal);
|
|
98692
|
+
} catch {
|
|
98693
|
+
invalidCount++;
|
|
98694
|
+
}
|
|
98695
|
+
}
|
|
98696
|
+
return { records, invalidCount };
|
|
98697
|
+
}
|
|
98698
|
+
writeMemory(record3) {
|
|
98699
|
+
this.requireDb().run(`INSERT OR REPLACE INTO memory_items (
|
|
98700
|
+
id,
|
|
98701
|
+
scope_key,
|
|
98702
|
+
kind,
|
|
98703
|
+
updated_at,
|
|
98704
|
+
expires_at,
|
|
98705
|
+
superseded_by,
|
|
98706
|
+
deleted,
|
|
98707
|
+
record_json
|
|
98708
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
98709
|
+
record3.id,
|
|
98710
|
+
JSON.stringify(record3.scope),
|
|
98711
|
+
record3.kind,
|
|
98712
|
+
record3.updatedAt,
|
|
98713
|
+
record3.expiresAt ?? null,
|
|
98714
|
+
record3.supersededBy ?? null,
|
|
98715
|
+
record3.metadata.deleted === true ? 1 : 0,
|
|
98716
|
+
JSON.stringify(record3)
|
|
98717
|
+
]);
|
|
98718
|
+
}
|
|
98719
|
+
async event(operation, targetId, reason) {
|
|
98720
|
+
this.insertEvent(operation, targetId, reason);
|
|
98721
|
+
}
|
|
98722
|
+
insertEvent(operation, targetId, reason) {
|
|
98723
|
+
this.requireDb().run(`INSERT INTO memory_events (
|
|
98724
|
+
id,
|
|
98725
|
+
operation,
|
|
98726
|
+
target_id,
|
|
98727
|
+
reason,
|
|
98728
|
+
timestamp,
|
|
98729
|
+
event_json
|
|
98730
|
+
) VALUES (?, ?, ?, ?, ?, ?)`, [
|
|
98731
|
+
randomUUID9(),
|
|
98732
|
+
operation,
|
|
98733
|
+
targetId,
|
|
98734
|
+
reason ?? null,
|
|
98735
|
+
new Date().toISOString(),
|
|
98736
|
+
reason ? JSON.stringify({ reason }) : null
|
|
98737
|
+
]);
|
|
98738
|
+
}
|
|
98739
|
+
requireDb() {
|
|
98740
|
+
if (!this.db)
|
|
98741
|
+
throw new Error("SQLite memory provider is not initialized");
|
|
98742
|
+
return this.db;
|
|
98743
|
+
}
|
|
98744
|
+
}
|
|
98745
|
+
function splitSql(sql) {
|
|
98746
|
+
return sql.split(";").map((statement) => statement.trim()).filter(Boolean);
|
|
98747
|
+
}
|
|
98748
|
+
|
|
98248
98749
|
// src/memory/gateway.ts
|
|
98249
98750
|
class MemoryGateway {
|
|
98250
98751
|
context;
|
|
@@ -98254,16 +98755,19 @@ class MemoryGateway {
|
|
|
98254
98755
|
constructor(context, options = {}) {
|
|
98255
98756
|
this.context = context;
|
|
98256
98757
|
this.config = resolveMemoryConfig(options.config ?? DEFAULT_MEMORY_CONFIG);
|
|
98257
|
-
this.provider = options.provider ??
|
|
98758
|
+
this.provider = options.provider ?? createConfiguredMemoryProvider(context.directory, this.config);
|
|
98258
98759
|
this.now = options.now ?? (() => new Date);
|
|
98259
98760
|
}
|
|
98260
98761
|
isEnabled() {
|
|
98261
98762
|
return this.config.enabled;
|
|
98262
98763
|
}
|
|
98764
|
+
async dispose() {
|
|
98765
|
+
await this.provider.close?.();
|
|
98766
|
+
}
|
|
98263
98767
|
deriveAllowedScopes() {
|
|
98264
|
-
const resolvedRoot =
|
|
98265
|
-
const repoId = createStableId(readGitRemoteUrl(resolvedRoot) ??
|
|
98266
|
-
const workspaceId = createStableId(
|
|
98768
|
+
const resolvedRoot = path97.resolve(this.context.directory);
|
|
98769
|
+
const repoId = createStableId(readGitRemoteUrl(resolvedRoot) ?? path97.basename(resolvedRoot));
|
|
98770
|
+
const workspaceId = createStableId(path97.dirname(resolvedRoot));
|
|
98267
98771
|
const scopes = [
|
|
98268
98772
|
{ type: "workspace", workspaceId },
|
|
98269
98773
|
{
|
|
@@ -98302,20 +98806,29 @@ class MemoryGateway {
|
|
|
98302
98806
|
query,
|
|
98303
98807
|
task: input.task,
|
|
98304
98808
|
agentRole: this.context.agentRole,
|
|
98809
|
+
mode: input.mode ?? "manual",
|
|
98305
98810
|
scopes,
|
|
98306
98811
|
kinds: input.kinds,
|
|
98307
98812
|
maxItems,
|
|
98308
98813
|
tokenBudget,
|
|
98309
98814
|
minScore: input.minScore ?? this.config.recall.minScore,
|
|
98815
|
+
requireQuerySignal: input.requireQuerySignal,
|
|
98310
98816
|
includeExpired: input.includeExpired
|
|
98311
98817
|
};
|
|
98312
|
-
const
|
|
98818
|
+
const recallResult = this.provider.recallWithDiagnostics ? await this.provider.recallWithDiagnostics(request) : { items: await this.provider.recall(request) };
|
|
98313
98819
|
const bundle = toRecallBundle({
|
|
98314
98820
|
id: createBundleId(query, generatedAt),
|
|
98315
98821
|
query,
|
|
98316
98822
|
generatedAt,
|
|
98317
|
-
items:
|
|
98318
|
-
tokenBudget
|
|
98823
|
+
items: recallResult.items,
|
|
98824
|
+
tokenBudget,
|
|
98825
|
+
diagnostics: recallResult.diagnostics ? {
|
|
98826
|
+
injectionSkipReason: input.mode === "injection" ? resolveInjectionSkipReason(recallResult.diagnostics) : undefined,
|
|
98827
|
+
candidateCount: recallResult.diagnostics.candidateCount,
|
|
98828
|
+
preScoredFilteredCount: recallResult.diagnostics.preScoredFilteredCount,
|
|
98829
|
+
noSignalCount: recallResult.diagnostics.noSignalCount,
|
|
98830
|
+
belowThresholdCount: recallResult.diagnostics.belowThresholdCount
|
|
98831
|
+
} : undefined
|
|
98319
98832
|
});
|
|
98320
98833
|
await this.provider.recordRecallUsage?.({
|
|
98321
98834
|
bundleId: bundle.id,
|
|
@@ -98454,6 +98967,12 @@ class MemoryGateway {
|
|
|
98454
98967
|
function createMemoryGateway(context, options = {}) {
|
|
98455
98968
|
return new MemoryGateway(context, options);
|
|
98456
98969
|
}
|
|
98970
|
+
function createConfiguredMemoryProvider(directory, config3) {
|
|
98971
|
+
if (config3.provider === "sqlite") {
|
|
98972
|
+
return new SQLiteMemoryProvider(directory, config3);
|
|
98973
|
+
}
|
|
98974
|
+
return new LocalJsonlMemoryProvider(directory, config3);
|
|
98975
|
+
}
|
|
98457
98976
|
function sourceFromEvidence(evidenceRefs, context) {
|
|
98458
98977
|
const first = evidenceRefs[0];
|
|
98459
98978
|
if (!first) {
|
|
@@ -98475,7 +98994,7 @@ var gitRemoteUrlCache = new Map;
|
|
|
98475
98994
|
function readGitRemoteUrl(directory) {
|
|
98476
98995
|
if (gitRemoteUrlCache.has(directory))
|
|
98477
98996
|
return gitRemoteUrlCache.get(directory);
|
|
98478
|
-
const gitConfigPath =
|
|
98997
|
+
const gitConfigPath = path97.join(directory, ".git", "config");
|
|
98479
98998
|
if (!existsSync50(gitConfigPath)) {
|
|
98480
98999
|
gitRemoteUrlCache.set(directory, undefined);
|
|
98481
99000
|
return;
|
|
@@ -98503,6 +99022,19 @@ function validateRequestedScopes(requested, allowed) {
|
|
|
98503
99022
|
}
|
|
98504
99023
|
return requested;
|
|
98505
99024
|
}
|
|
99025
|
+
function resolveInjectionSkipReason(diagnostics) {
|
|
99026
|
+
if (diagnostics.returnedCount > 0)
|
|
99027
|
+
return;
|
|
99028
|
+
if (diagnostics.candidateCount === 0)
|
|
99029
|
+
return "no_results";
|
|
99030
|
+
const signalEligibleCount = diagnostics.candidateCount - diagnostics.preScoredFilteredCount;
|
|
99031
|
+
if (signalEligibleCount > 0 && diagnostics.noSignalCount > 0 && diagnostics.noSignalCount >= signalEligibleCount) {
|
|
99032
|
+
return "no_signal";
|
|
99033
|
+
}
|
|
99034
|
+
if (diagnostics.belowThresholdCount > 0)
|
|
99035
|
+
return "below_threshold";
|
|
99036
|
+
return "no_results";
|
|
99037
|
+
}
|
|
98506
99038
|
function scopeKey(scope) {
|
|
98507
99039
|
return JSON.stringify({
|
|
98508
99040
|
type: scope.type,
|
|
@@ -98510,7 +99042,7 @@ function scopeKey(scope) {
|
|
|
98510
99042
|
workspaceId: scope.workspaceId,
|
|
98511
99043
|
projectId: scope.projectId,
|
|
98512
99044
|
repoId: scope.repoId,
|
|
98513
|
-
repoRoot: scope.repoRoot ?
|
|
99045
|
+
repoRoot: scope.repoRoot ? path97.resolve(scope.repoRoot) : undefined,
|
|
98514
99046
|
runId: scope.runId,
|
|
98515
99047
|
agentId: scope.agentId
|
|
98516
99048
|
});
|
|
@@ -98757,12 +99289,12 @@ function buildScopesFromInput(input) {
|
|
|
98757
99289
|
// src/memory/run-log.ts
|
|
98758
99290
|
init_utils2();
|
|
98759
99291
|
import { appendFile as appendFile12, mkdir as mkdir19 } from "node:fs/promises";
|
|
98760
|
-
import * as
|
|
99292
|
+
import * as path98 from "node:path";
|
|
98761
99293
|
async function appendMemoryRunLog(directory, runId, event) {
|
|
98762
99294
|
const safeRunId = sanitizeRunId(runId);
|
|
98763
|
-
const relativePath =
|
|
99295
|
+
const relativePath = path98.join("runs", safeRunId, "memory.jsonl");
|
|
98764
99296
|
const filePath = validateSwarmPath(directory, relativePath);
|
|
98765
|
-
await mkdir19(
|
|
99297
|
+
await mkdir19(path98.dirname(filePath), { recursive: true });
|
|
98766
99298
|
await appendFile12(filePath, `${JSON.stringify({
|
|
98767
99299
|
...event,
|
|
98768
99300
|
runId: safeRunId,
|
|
@@ -98897,8 +99429,15 @@ async function recallForAgent(input) {
|
|
|
98897
99429
|
agentId: input.agentId,
|
|
98898
99430
|
runId: input.sessionID
|
|
98899
99431
|
}, { config: input.config });
|
|
98900
|
-
|
|
99432
|
+
const resolvedConfig = resolveMemoryConfig(input.config);
|
|
99433
|
+
if (!gateway.isEnabled()) {
|
|
99434
|
+
await logInjectionSkipped(input, "disabled");
|
|
99435
|
+
return null;
|
|
99436
|
+
}
|
|
99437
|
+
if (!resolvedConfig.recall.injection.enabled) {
|
|
99438
|
+
await logInjectionSkipped(input, "disabled");
|
|
98901
99439
|
return null;
|
|
99440
|
+
}
|
|
98902
99441
|
const scopes = gateway.deriveAllowedScopes();
|
|
98903
99442
|
const planInput = {
|
|
98904
99443
|
userGoal: compactText(input.userGoal),
|
|
@@ -98909,6 +99448,8 @@ async function recallForAgent(input) {
|
|
|
98909
99448
|
touchedFiles: extractTouchedFiles(input.agentTask)
|
|
98910
99449
|
};
|
|
98911
99450
|
const plan = buildMemoryRecallPlan(planInput, { scopes });
|
|
99451
|
+
plan.maxItems = resolvedConfig.recall.injection.maxItems;
|
|
99452
|
+
plan.tokenBudget = resolvedConfig.recall.injection.tokenBudget;
|
|
98912
99453
|
await input.appendRunLog(input.directory, input.sessionID, {
|
|
98913
99454
|
event: "recall_requested",
|
|
98914
99455
|
runId: input.sessionID ?? "unknown",
|
|
@@ -98924,10 +99465,13 @@ async function recallForAgent(input) {
|
|
|
98924
99465
|
const recallInput = {
|
|
98925
99466
|
query: plan.query,
|
|
98926
99467
|
task: planInput.agentTask,
|
|
99468
|
+
mode: "injection",
|
|
98927
99469
|
scopes: plan.scopes,
|
|
98928
99470
|
kinds: plan.kinds,
|
|
98929
99471
|
maxItems: plan.maxItems,
|
|
98930
|
-
tokenBudget: plan.tokenBudget
|
|
99472
|
+
tokenBudget: plan.tokenBudget,
|
|
99473
|
+
minScore: resolvedConfig.recall.injection.minScore,
|
|
99474
|
+
requireQuerySignal: resolvedConfig.recall.injection.requireQuerySignal
|
|
98931
99475
|
};
|
|
98932
99476
|
const bundle = await gateway.recall(recallInput);
|
|
98933
99477
|
await input.appendRunLog(input.directory, input.sessionID, {
|
|
@@ -98940,8 +99484,31 @@ async function recallForAgent(input) {
|
|
|
98940
99484
|
scores: bundle.items.map((item) => item.score),
|
|
98941
99485
|
tokenEstimate: bundle.tokenEstimate
|
|
98942
99486
|
});
|
|
99487
|
+
if (bundle.items.length === 0) {
|
|
99488
|
+
await logInjectionSkipped(input, bundle.diagnostics?.injectionSkipReason ?? "no_results", bundle);
|
|
99489
|
+
}
|
|
98943
99490
|
return { bundle, scopes };
|
|
98944
99491
|
}
|
|
99492
|
+
async function logInjectionSkipped(input, reason, bundle) {
|
|
99493
|
+
await input.appendRunLog(input.directory, input.sessionID, {
|
|
99494
|
+
event: "prompt_injection_skipped",
|
|
99495
|
+
runId: input.sessionID ?? "unknown",
|
|
99496
|
+
agentRole: input.agentRole,
|
|
99497
|
+
agentId: input.agentId,
|
|
99498
|
+
bundleId: bundle?.id,
|
|
99499
|
+
memoryIds: bundle?.items.map((item) => item.record.id),
|
|
99500
|
+
scores: bundle?.items.map((item) => item.score),
|
|
99501
|
+
tokenEstimate: bundle?.tokenEstimate,
|
|
99502
|
+
rejectionReason: reason,
|
|
99503
|
+
metadata: {
|
|
99504
|
+
reason,
|
|
99505
|
+
candidateCount: bundle?.diagnostics?.candidateCount,
|
|
99506
|
+
preScoredFilteredCount: bundle?.diagnostics?.preScoredFilteredCount,
|
|
99507
|
+
noSignalCount: bundle?.diagnostics?.noSignalCount,
|
|
99508
|
+
belowThresholdCount: bundle?.diagnostics?.belowThresholdCount
|
|
99509
|
+
}
|
|
99510
|
+
});
|
|
99511
|
+
}
|
|
98945
99512
|
function parseTaskToolInput(input) {
|
|
98946
99513
|
const record3 = input;
|
|
98947
99514
|
const rawTool = typeof record3.tool === "string" ? record3.tool : undefined;
|
|
@@ -99505,16 +100072,16 @@ init_telemetry();
|
|
|
99505
100072
|
|
|
99506
100073
|
// src/prm/replay.ts
|
|
99507
100074
|
import { promises as fs68 } from "node:fs";
|
|
99508
|
-
import
|
|
100075
|
+
import path99 from "node:path";
|
|
99509
100076
|
function isPathSafe2(targetPath, basePath) {
|
|
99510
|
-
const resolvedTarget =
|
|
99511
|
-
const resolvedBase =
|
|
99512
|
-
const rel =
|
|
99513
|
-
return !rel.startsWith("..") && !
|
|
100077
|
+
const resolvedTarget = path99.resolve(targetPath);
|
|
100078
|
+
const resolvedBase = path99.resolve(basePath);
|
|
100079
|
+
const rel = path99.relative(resolvedBase, resolvedTarget);
|
|
100080
|
+
return !rel.startsWith("..") && !path99.isAbsolute(rel);
|
|
99514
100081
|
}
|
|
99515
100082
|
function isWithinReplaysDir(targetPath) {
|
|
99516
|
-
const resolved =
|
|
99517
|
-
const parts2 = resolved.split(
|
|
100083
|
+
const resolved = path99.resolve(targetPath);
|
|
100084
|
+
const parts2 = resolved.split(path99.sep);
|
|
99518
100085
|
for (let i2 = 0;i2 < parts2.length - 1; i2++) {
|
|
99519
100086
|
if (parts2[i2] === ".swarm" && parts2[i2 + 1] === "replays") {
|
|
99520
100087
|
return true;
|
|
@@ -99527,10 +100094,10 @@ function sanitizeFilename(input) {
|
|
|
99527
100094
|
}
|
|
99528
100095
|
async function startReplayRecording(sessionID, directory) {
|
|
99529
100096
|
try {
|
|
99530
|
-
const replayDir =
|
|
100097
|
+
const replayDir = path99.join(directory, ".swarm", "replays");
|
|
99531
100098
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
99532
100099
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
99533
|
-
const filepath =
|
|
100100
|
+
const filepath = path99.join(replayDir, filename);
|
|
99534
100101
|
if (!isPathSafe2(filepath, replayDir)) {
|
|
99535
100102
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
99536
100103
|
return null;
|
|
@@ -99911,7 +100478,7 @@ init_telemetry();
|
|
|
99911
100478
|
init_dist();
|
|
99912
100479
|
init_create_tool();
|
|
99913
100480
|
import * as fs69 from "node:fs";
|
|
99914
|
-
import * as
|
|
100481
|
+
import * as path100 from "node:path";
|
|
99915
100482
|
init_path_security();
|
|
99916
100483
|
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
99917
100484
|
function containsWindowsAttacks2(str) {
|
|
@@ -99928,14 +100495,14 @@ function containsWindowsAttacks2(str) {
|
|
|
99928
100495
|
}
|
|
99929
100496
|
function isPathInWorkspace2(filePath, workspace) {
|
|
99930
100497
|
try {
|
|
99931
|
-
const resolvedPath =
|
|
100498
|
+
const resolvedPath = path100.resolve(workspace, filePath);
|
|
99932
100499
|
if (!fs69.existsSync(resolvedPath)) {
|
|
99933
100500
|
return true;
|
|
99934
100501
|
}
|
|
99935
100502
|
const realWorkspace = fs69.realpathSync(workspace);
|
|
99936
100503
|
const realResolvedPath = fs69.realpathSync(resolvedPath);
|
|
99937
|
-
const relativePath =
|
|
99938
|
-
if (relativePath.startsWith("..") ||
|
|
100504
|
+
const relativePath = path100.relative(realWorkspace, realResolvedPath);
|
|
100505
|
+
if (relativePath.startsWith("..") || path100.isAbsolute(relativePath)) {
|
|
99939
100506
|
return false;
|
|
99940
100507
|
}
|
|
99941
100508
|
return true;
|
|
@@ -99944,7 +100511,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
99944
100511
|
}
|
|
99945
100512
|
}
|
|
99946
100513
|
function processFile2(file3, cwd, exportedOnly) {
|
|
99947
|
-
const ext =
|
|
100514
|
+
const ext = path100.extname(file3);
|
|
99948
100515
|
if (containsControlChars(file3)) {
|
|
99949
100516
|
return {
|
|
99950
100517
|
file: file3,
|
|
@@ -99977,7 +100544,7 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
99977
100544
|
errorType: "path-outside-workspace"
|
|
99978
100545
|
};
|
|
99979
100546
|
}
|
|
99980
|
-
const fullPath =
|
|
100547
|
+
const fullPath = path100.join(cwd, file3);
|
|
99981
100548
|
if (!fs69.existsSync(fullPath)) {
|
|
99982
100549
|
return {
|
|
99983
100550
|
file: file3,
|
|
@@ -100269,15 +100836,15 @@ init_task_id();
|
|
|
100269
100836
|
init_create_tool();
|
|
100270
100837
|
init_resolve_working_directory();
|
|
100271
100838
|
import * as fs70 from "node:fs";
|
|
100272
|
-
import * as
|
|
100839
|
+
import * as path101 from "node:path";
|
|
100273
100840
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
100274
100841
|
function isValidTaskId3(taskId) {
|
|
100275
100842
|
return isStrictTaskId(taskId);
|
|
100276
100843
|
}
|
|
100277
100844
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
100278
|
-
const normalizedWorkspace =
|
|
100279
|
-
const swarmPath =
|
|
100280
|
-
const normalizedPath =
|
|
100845
|
+
const normalizedWorkspace = path101.resolve(workspaceRoot);
|
|
100846
|
+
const swarmPath = path101.join(normalizedWorkspace, ".swarm", "evidence");
|
|
100847
|
+
const normalizedPath = path101.resolve(filePath);
|
|
100281
100848
|
return normalizedPath.startsWith(swarmPath);
|
|
100282
100849
|
}
|
|
100283
100850
|
function readEvidenceFile(evidencePath) {
|
|
@@ -100358,7 +100925,7 @@ var check_gate_status = createSwarmTool({
|
|
|
100358
100925
|
};
|
|
100359
100926
|
return JSON.stringify(errorResult, null, 2);
|
|
100360
100927
|
}
|
|
100361
|
-
const evidencePath =
|
|
100928
|
+
const evidencePath = path101.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
100362
100929
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
100363
100930
|
const errorResult = {
|
|
100364
100931
|
taskId: taskIdInput,
|
|
@@ -100455,7 +101022,7 @@ init_state();
|
|
|
100455
101022
|
init_create_tool();
|
|
100456
101023
|
init_resolve_working_directory();
|
|
100457
101024
|
import * as fs71 from "node:fs";
|
|
100458
|
-
import * as
|
|
101025
|
+
import * as path102 from "node:path";
|
|
100459
101026
|
function extractMatches(regex, text) {
|
|
100460
101027
|
return Array.from(text.matchAll(regex));
|
|
100461
101028
|
}
|
|
@@ -100607,10 +101174,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
100607
101174
|
let hasFileReadFailure = false;
|
|
100608
101175
|
for (const filePath of fileTargets) {
|
|
100609
101176
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
100610
|
-
const resolvedPath =
|
|
100611
|
-
const projectRoot =
|
|
100612
|
-
const relative21 =
|
|
100613
|
-
const withinProject = relative21 === "" || !relative21.startsWith("..") && !
|
|
101177
|
+
const resolvedPath = path102.resolve(directory, normalizedPath);
|
|
101178
|
+
const projectRoot = path102.resolve(directory);
|
|
101179
|
+
const relative21 = path102.relative(projectRoot, resolvedPath);
|
|
101180
|
+
const withinProject = relative21 === "" || !relative21.startsWith("..") && !path102.isAbsolute(relative21);
|
|
100614
101181
|
if (!withinProject) {
|
|
100615
101182
|
blockedTasks.push({
|
|
100616
101183
|
task_id: task.id,
|
|
@@ -100665,8 +101232,8 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
100665
101232
|
blockedTasks
|
|
100666
101233
|
};
|
|
100667
101234
|
try {
|
|
100668
|
-
const evidenceDir =
|
|
100669
|
-
const evidencePath =
|
|
101235
|
+
const evidenceDir = path102.join(directory, ".swarm", "evidence", `${phase}`);
|
|
101236
|
+
const evidencePath = path102.join(evidenceDir, "completion-verify.json");
|
|
100670
101237
|
fs71.mkdirSync(evidenceDir, { recursive: true });
|
|
100671
101238
|
const evidenceBundle = {
|
|
100672
101239
|
schema_version: "1.0.0",
|
|
@@ -100743,11 +101310,11 @@ var completion_verify = createSwarmTool({
|
|
|
100743
101310
|
// src/tools/complexity-hotspots.ts
|
|
100744
101311
|
init_zod();
|
|
100745
101312
|
import * as fs73 from "node:fs";
|
|
100746
|
-
import * as
|
|
101313
|
+
import * as path104 from "node:path";
|
|
100747
101314
|
|
|
100748
101315
|
// src/quality/metrics.ts
|
|
100749
101316
|
import * as fs72 from "node:fs";
|
|
100750
|
-
import * as
|
|
101317
|
+
import * as path103 from "node:path";
|
|
100751
101318
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
100752
101319
|
var MIN_DUPLICATION_LINES = 10;
|
|
100753
101320
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -100799,7 +101366,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
100799
101366
|
let totalComplexity = 0;
|
|
100800
101367
|
const analyzedFiles = [];
|
|
100801
101368
|
for (const file3 of files) {
|
|
100802
|
-
const fullPath =
|
|
101369
|
+
const fullPath = path103.isAbsolute(file3) ? file3 : path103.join(workingDir, file3);
|
|
100803
101370
|
if (!fs72.existsSync(fullPath)) {
|
|
100804
101371
|
continue;
|
|
100805
101372
|
}
|
|
@@ -100922,7 +101489,7 @@ function countGoExports(content) {
|
|
|
100922
101489
|
function getExportCountForFile(filePath) {
|
|
100923
101490
|
try {
|
|
100924
101491
|
const content = fs72.readFileSync(filePath, "utf-8");
|
|
100925
|
-
const ext =
|
|
101492
|
+
const ext = path103.extname(filePath).toLowerCase();
|
|
100926
101493
|
switch (ext) {
|
|
100927
101494
|
case ".ts":
|
|
100928
101495
|
case ".tsx":
|
|
@@ -100948,7 +101515,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
100948
101515
|
let totalExports = 0;
|
|
100949
101516
|
const analyzedFiles = [];
|
|
100950
101517
|
for (const file3 of files) {
|
|
100951
|
-
const fullPath =
|
|
101518
|
+
const fullPath = path103.isAbsolute(file3) ? file3 : path103.join(workingDir, file3);
|
|
100952
101519
|
if (!fs72.existsSync(fullPath)) {
|
|
100953
101520
|
continue;
|
|
100954
101521
|
}
|
|
@@ -100982,7 +101549,7 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
100982
101549
|
let duplicateLines = 0;
|
|
100983
101550
|
const analyzedFiles = [];
|
|
100984
101551
|
for (const file3 of files) {
|
|
100985
|
-
const fullPath =
|
|
101552
|
+
const fullPath = path103.isAbsolute(file3) ? file3 : path103.join(workingDir, file3);
|
|
100986
101553
|
if (!fs72.existsSync(fullPath)) {
|
|
100987
101554
|
continue;
|
|
100988
101555
|
}
|
|
@@ -101015,8 +101582,8 @@ function countCodeLines(content) {
|
|
|
101015
101582
|
return lines.length;
|
|
101016
101583
|
}
|
|
101017
101584
|
function isTestFile(filePath) {
|
|
101018
|
-
const basename15 =
|
|
101019
|
-
const _ext =
|
|
101585
|
+
const basename15 = path103.basename(filePath);
|
|
101586
|
+
const _ext = path103.extname(filePath).toLowerCase();
|
|
101020
101587
|
const testPatterns = [
|
|
101021
101588
|
".test.",
|
|
101022
101589
|
".spec.",
|
|
@@ -101097,8 +101664,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
101097
101664
|
}
|
|
101098
101665
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
101099
101666
|
}
|
|
101100
|
-
function matchesGlobSegment(
|
|
101101
|
-
const normalizedPath =
|
|
101667
|
+
function matchesGlobSegment(path104, glob) {
|
|
101668
|
+
const normalizedPath = path104.replace(/\\/g, "/");
|
|
101102
101669
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
101103
101670
|
if (normalizedPath.includes("//")) {
|
|
101104
101671
|
return false;
|
|
@@ -101129,8 +101696,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
101129
101696
|
function hasGlobstar(glob) {
|
|
101130
101697
|
return glob.includes("**");
|
|
101131
101698
|
}
|
|
101132
|
-
function globMatches(
|
|
101133
|
-
const normalizedPath =
|
|
101699
|
+
function globMatches(path104, glob) {
|
|
101700
|
+
const normalizedPath = path104.replace(/\\/g, "/");
|
|
101134
101701
|
if (!glob || glob === "") {
|
|
101135
101702
|
if (normalizedPath.includes("//")) {
|
|
101136
101703
|
return false;
|
|
@@ -101166,7 +101733,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
101166
101733
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
101167
101734
|
let testLines = 0;
|
|
101168
101735
|
let codeLines = 0;
|
|
101169
|
-
const srcDir =
|
|
101736
|
+
const srcDir = path103.join(workingDir, "src");
|
|
101170
101737
|
if (fs72.existsSync(srcDir)) {
|
|
101171
101738
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
101172
101739
|
codeLines += lines;
|
|
@@ -101174,14 +101741,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
101174
101741
|
}
|
|
101175
101742
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
101176
101743
|
for (const dir of possibleSrcDirs) {
|
|
101177
|
-
const dirPath =
|
|
101744
|
+
const dirPath = path103.join(workingDir, dir);
|
|
101178
101745
|
if (fs72.existsSync(dirPath)) {
|
|
101179
101746
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
101180
101747
|
codeLines += lines;
|
|
101181
101748
|
});
|
|
101182
101749
|
}
|
|
101183
101750
|
}
|
|
101184
|
-
const testsDir =
|
|
101751
|
+
const testsDir = path103.join(workingDir, "tests");
|
|
101185
101752
|
if (fs72.existsSync(testsDir)) {
|
|
101186
101753
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
101187
101754
|
testLines += lines;
|
|
@@ -101189,7 +101756,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
101189
101756
|
}
|
|
101190
101757
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
101191
101758
|
for (const dir of possibleTestDirs) {
|
|
101192
|
-
const dirPath =
|
|
101759
|
+
const dirPath = path103.join(workingDir, dir);
|
|
101193
101760
|
if (fs72.existsSync(dirPath) && dirPath !== testsDir) {
|
|
101194
101761
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
101195
101762
|
testLines += lines;
|
|
@@ -101204,7 +101771,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
101204
101771
|
try {
|
|
101205
101772
|
const entries = fs72.readdirSync(dirPath, { withFileTypes: true });
|
|
101206
101773
|
for (const entry of entries) {
|
|
101207
|
-
const fullPath =
|
|
101774
|
+
const fullPath = path103.join(dirPath, entry.name);
|
|
101208
101775
|
if (entry.isDirectory()) {
|
|
101209
101776
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
101210
101777
|
continue;
|
|
@@ -101212,7 +101779,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
101212
101779
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
101213
101780
|
} else if (entry.isFile()) {
|
|
101214
101781
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
101215
|
-
const ext =
|
|
101782
|
+
const ext = path103.extname(entry.name).toLowerCase();
|
|
101216
101783
|
const validExts = [
|
|
101217
101784
|
".ts",
|
|
101218
101785
|
".tsx",
|
|
@@ -101463,7 +102030,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
101463
102030
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
101464
102031
|
const filteredChurn = new Map;
|
|
101465
102032
|
for (const [file3, count] of churnMap) {
|
|
101466
|
-
const ext =
|
|
102033
|
+
const ext = path104.extname(file3).toLowerCase();
|
|
101467
102034
|
if (extSet.has(ext)) {
|
|
101468
102035
|
filteredChurn.set(file3, count);
|
|
101469
102036
|
}
|
|
@@ -101474,7 +102041,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
101474
102041
|
for (const [file3, churnCount] of filteredChurn) {
|
|
101475
102042
|
let fullPath = file3;
|
|
101476
102043
|
if (!fs73.existsSync(fullPath)) {
|
|
101477
|
-
fullPath =
|
|
102044
|
+
fullPath = path104.join(cwd, file3);
|
|
101478
102045
|
}
|
|
101479
102046
|
const complexity = getComplexityForFile2(fullPath);
|
|
101480
102047
|
if (complexity !== null) {
|
|
@@ -101642,7 +102209,7 @@ ${body2}`);
|
|
|
101642
102209
|
|
|
101643
102210
|
// src/council/council-evidence-writer.ts
|
|
101644
102211
|
init_task_file();
|
|
101645
|
-
import { appendFileSync as appendFileSync12, existsSync as existsSync55, mkdirSync as
|
|
102212
|
+
import { appendFileSync as appendFileSync12, existsSync as existsSync55, mkdirSync as mkdirSync26, readFileSync as readFileSync45 } from "node:fs";
|
|
101646
102213
|
import { join as join88 } from "node:path";
|
|
101647
102214
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
101648
102215
|
var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -101681,7 +102248,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
101681
102248
|
throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
|
|
101682
102249
|
}
|
|
101683
102250
|
const dir = join88(workingDir, EVIDENCE_DIR2);
|
|
101684
|
-
|
|
102251
|
+
mkdirSync26(dir, { recursive: true });
|
|
101685
102252
|
const filePath = taskEvidencePath(workingDir, synthesis.taskId);
|
|
101686
102253
|
await _internals45.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
|
|
101687
102254
|
const existingRoot = Object.create(null);
|
|
@@ -101719,7 +102286,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
101719
102286
|
});
|
|
101720
102287
|
try {
|
|
101721
102288
|
const councilDir = join88(workingDir, ".swarm", "council");
|
|
101722
|
-
|
|
102289
|
+
mkdirSync26(councilDir, { recursive: true });
|
|
101723
102290
|
const auditLine = JSON.stringify({
|
|
101724
102291
|
round: synthesis.roundNumber,
|
|
101725
102292
|
verdict: synthesis.overallVerdict,
|
|
@@ -102048,12 +102615,12 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
|
|
|
102048
102615
|
}
|
|
102049
102616
|
|
|
102050
102617
|
// src/council/criteria-store.ts
|
|
102051
|
-
import { existsSync as existsSync56, mkdirSync as
|
|
102618
|
+
import { existsSync as existsSync56, mkdirSync as mkdirSync27, readFileSync as readFileSync46, writeFileSync as writeFileSync17 } from "node:fs";
|
|
102052
102619
|
import { join as join89 } from "node:path";
|
|
102053
102620
|
var COUNCIL_DIR = ".swarm/council";
|
|
102054
102621
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
102055
102622
|
const dir = join89(workingDir, COUNCIL_DIR);
|
|
102056
|
-
|
|
102623
|
+
mkdirSync27(dir, { recursive: true });
|
|
102057
102624
|
const payload = {
|
|
102058
102625
|
taskId,
|
|
102059
102626
|
criteria,
|
|
@@ -102215,7 +102782,7 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
102215
102782
|
init_zod();
|
|
102216
102783
|
init_loader();
|
|
102217
102784
|
import * as fs74 from "node:fs";
|
|
102218
|
-
import * as
|
|
102785
|
+
import * as path105 from "node:path";
|
|
102219
102786
|
|
|
102220
102787
|
// src/council/general-council-advisory.ts
|
|
102221
102788
|
var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
|
|
@@ -102643,10 +103210,10 @@ var convene_general_council = createSwarmTool({
|
|
|
102643
103210
|
const round1 = input.round1Responses;
|
|
102644
103211
|
const round2 = input.round2Responses ?? [];
|
|
102645
103212
|
const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
|
|
102646
|
-
const evidenceDir =
|
|
103213
|
+
const evidenceDir = path105.join(workingDir, ".swarm", "council", "general");
|
|
102647
103214
|
const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
|
|
102648
103215
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
102649
|
-
const evidencePath =
|
|
103216
|
+
const evidencePath = path105.join(evidenceDir, evidenceFile);
|
|
102650
103217
|
try {
|
|
102651
103218
|
await fs74.promises.mkdir(evidenceDir, { recursive: true });
|
|
102652
103219
|
await fs74.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
@@ -102891,7 +103458,7 @@ init_state();
|
|
|
102891
103458
|
init_task_id();
|
|
102892
103459
|
init_create_tool();
|
|
102893
103460
|
import * as fs75 from "node:fs";
|
|
102894
|
-
import * as
|
|
103461
|
+
import * as path106 from "node:path";
|
|
102895
103462
|
function validateTaskIdFormat2(taskId) {
|
|
102896
103463
|
return validateTaskIdFormat(taskId);
|
|
102897
103464
|
}
|
|
@@ -102965,8 +103532,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
102965
103532
|
};
|
|
102966
103533
|
}
|
|
102967
103534
|
}
|
|
102968
|
-
normalizedDir =
|
|
102969
|
-
const pathParts = normalizedDir.split(
|
|
103535
|
+
normalizedDir = path106.normalize(args2.working_directory);
|
|
103536
|
+
const pathParts = normalizedDir.split(path106.sep);
|
|
102970
103537
|
if (pathParts.includes("..")) {
|
|
102971
103538
|
return {
|
|
102972
103539
|
success: false,
|
|
@@ -102976,10 +103543,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
102976
103543
|
]
|
|
102977
103544
|
};
|
|
102978
103545
|
}
|
|
102979
|
-
const resolvedDir =
|
|
103546
|
+
const resolvedDir = path106.resolve(normalizedDir);
|
|
102980
103547
|
try {
|
|
102981
103548
|
const realPath = fs75.realpathSync(resolvedDir);
|
|
102982
|
-
const planPath2 =
|
|
103549
|
+
const planPath2 = path106.join(realPath, ".swarm", "plan.json");
|
|
102983
103550
|
if (!fs75.existsSync(planPath2)) {
|
|
102984
103551
|
return {
|
|
102985
103552
|
success: false,
|
|
@@ -103000,9 +103567,9 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
103000
103567
|
}
|
|
103001
103568
|
if (normalizedDir && fallbackDir) {
|
|
103002
103569
|
try {
|
|
103003
|
-
const canonicalWorkingDir = fs75.realpathSync(
|
|
103004
|
-
const canonicalProjectRoot = fs75.realpathSync(
|
|
103005
|
-
if (canonicalWorkingDir.startsWith(canonicalProjectRoot +
|
|
103570
|
+
const canonicalWorkingDir = fs75.realpathSync(path106.resolve(normalizedDir));
|
|
103571
|
+
const canonicalProjectRoot = fs75.realpathSync(path106.resolve(fallbackDir));
|
|
103572
|
+
if (canonicalWorkingDir.startsWith(canonicalProjectRoot + path106.sep)) {
|
|
103006
103573
|
return {
|
|
103007
103574
|
success: false,
|
|
103008
103575
|
message: `working_directory "${normalizedDir}" is a subdirectory of the project root. Use the project root "${fallbackDir}" instead.`,
|
|
@@ -103024,7 +103591,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
103024
103591
|
};
|
|
103025
103592
|
}
|
|
103026
103593
|
const directory = normalizedDir || fallbackDir;
|
|
103027
|
-
const planPath =
|
|
103594
|
+
const planPath = path106.resolve(directory, ".swarm", "plan.json");
|
|
103028
103595
|
if (!fs75.existsSync(planPath)) {
|
|
103029
103596
|
return {
|
|
103030
103597
|
success: false,
|
|
@@ -103064,8 +103631,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
103064
103631
|
const normalizeErrors = [];
|
|
103065
103632
|
const dir = directory;
|
|
103066
103633
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
103067
|
-
if (
|
|
103068
|
-
const relativePath =
|
|
103634
|
+
if (path106.isAbsolute(file3)) {
|
|
103635
|
+
const relativePath = path106.relative(dir, file3).replace(/\\/g, "/");
|
|
103069
103636
|
if (relativePath.startsWith("..")) {
|
|
103070
103637
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
103071
103638
|
return file3;
|
|
@@ -103126,7 +103693,7 @@ var declare_scope = createSwarmTool({
|
|
|
103126
103693
|
init_zod();
|
|
103127
103694
|
import * as child_process7 from "node:child_process";
|
|
103128
103695
|
import * as fs76 from "node:fs";
|
|
103129
|
-
import * as
|
|
103696
|
+
import * as path107 from "node:path";
|
|
103130
103697
|
init_create_tool();
|
|
103131
103698
|
var MAX_DIFF_LINES = 500;
|
|
103132
103699
|
var DIFF_TIMEOUT_MS = 30000;
|
|
@@ -103155,20 +103722,20 @@ function validateBase(base) {
|
|
|
103155
103722
|
function validatePaths(paths) {
|
|
103156
103723
|
if (!paths)
|
|
103157
103724
|
return null;
|
|
103158
|
-
for (const
|
|
103159
|
-
if (!
|
|
103725
|
+
for (const path108 of paths) {
|
|
103726
|
+
if (!path108 || path108.length === 0) {
|
|
103160
103727
|
return "empty path not allowed";
|
|
103161
103728
|
}
|
|
103162
|
-
if (
|
|
103729
|
+
if (path108.length > MAX_PATH_LENGTH) {
|
|
103163
103730
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
103164
103731
|
}
|
|
103165
|
-
if (SHELL_METACHARACTERS2.test(
|
|
103732
|
+
if (SHELL_METACHARACTERS2.test(path108)) {
|
|
103166
103733
|
return "path contains shell metacharacters";
|
|
103167
103734
|
}
|
|
103168
|
-
if (
|
|
103735
|
+
if (path108.startsWith("-")) {
|
|
103169
103736
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
103170
103737
|
}
|
|
103171
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
103738
|
+
if (CONTROL_CHAR_PATTERN2.test(path108)) {
|
|
103172
103739
|
return "path contains control characters";
|
|
103173
103740
|
}
|
|
103174
103741
|
}
|
|
@@ -103276,8 +103843,8 @@ var diff = createSwarmTool({
|
|
|
103276
103843
|
if (parts2.length >= 3) {
|
|
103277
103844
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
103278
103845
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
103279
|
-
const
|
|
103280
|
-
files.push({ path:
|
|
103846
|
+
const path108 = parts2[2];
|
|
103847
|
+
files.push({ path: path108, additions, deletions });
|
|
103281
103848
|
}
|
|
103282
103849
|
}
|
|
103283
103850
|
const contractChanges = [];
|
|
@@ -103317,7 +103884,7 @@ var diff = createSwarmTool({
|
|
|
103317
103884
|
} else if (base === "unstaged") {
|
|
103318
103885
|
const oldRef = `:${file3.path}`;
|
|
103319
103886
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
103320
|
-
newContent = fs76.readFileSync(
|
|
103887
|
+
newContent = fs76.readFileSync(path107.join(directory, file3.path), "utf-8");
|
|
103321
103888
|
} else {
|
|
103322
103889
|
const oldRef = `${base}:${file3.path}`;
|
|
103323
103890
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -103392,7 +103959,7 @@ var diff = createSwarmTool({
|
|
|
103392
103959
|
init_zod();
|
|
103393
103960
|
import * as child_process8 from "node:child_process";
|
|
103394
103961
|
import * as fs77 from "node:fs";
|
|
103395
|
-
import * as
|
|
103962
|
+
import * as path108 from "node:path";
|
|
103396
103963
|
init_create_tool();
|
|
103397
103964
|
init_resolve_working_directory();
|
|
103398
103965
|
var diff_summary = createSwarmTool({
|
|
@@ -103445,7 +104012,7 @@ var diff_summary = createSwarmTool({
|
|
|
103445
104012
|
}
|
|
103446
104013
|
try {
|
|
103447
104014
|
let oldContent;
|
|
103448
|
-
const newContent = fs77.readFileSync(
|
|
104015
|
+
const newContent = fs77.readFileSync(path108.join(workingDir, filePath), "utf-8");
|
|
103449
104016
|
if (fileExistsInHead) {
|
|
103450
104017
|
oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
|
|
103451
104018
|
encoding: "utf-8",
|
|
@@ -103674,7 +104241,7 @@ init_zod();
|
|
|
103674
104241
|
init_create_tool();
|
|
103675
104242
|
init_path_security();
|
|
103676
104243
|
import * as fs78 from "node:fs";
|
|
103677
|
-
import * as
|
|
104244
|
+
import * as path109 from "node:path";
|
|
103678
104245
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
103679
104246
|
var MAX_EVIDENCE_FILES = 1000;
|
|
103680
104247
|
var EVIDENCE_DIR3 = ".swarm/evidence";
|
|
@@ -103701,9 +104268,9 @@ function validateRequiredTypes(input) {
|
|
|
103701
104268
|
return null;
|
|
103702
104269
|
}
|
|
103703
104270
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
103704
|
-
const normalizedCwd =
|
|
103705
|
-
const swarmPath =
|
|
103706
|
-
const normalizedPath =
|
|
104271
|
+
const normalizedCwd = path109.resolve(cwd);
|
|
104272
|
+
const swarmPath = path109.join(normalizedCwd, ".swarm");
|
|
104273
|
+
const normalizedPath = path109.resolve(filePath);
|
|
103707
104274
|
return normalizedPath.startsWith(swarmPath);
|
|
103708
104275
|
}
|
|
103709
104276
|
function parseCompletedTasks(planContent) {
|
|
@@ -103733,10 +104300,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
103733
104300
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
103734
104301
|
continue;
|
|
103735
104302
|
}
|
|
103736
|
-
const filePath =
|
|
104303
|
+
const filePath = path109.join(evidenceDir, filename);
|
|
103737
104304
|
try {
|
|
103738
|
-
const resolvedPath =
|
|
103739
|
-
const evidenceDirResolved =
|
|
104305
|
+
const resolvedPath = path109.resolve(filePath);
|
|
104306
|
+
const evidenceDirResolved = path109.resolve(evidenceDir);
|
|
103740
104307
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
103741
104308
|
continue;
|
|
103742
104309
|
}
|
|
@@ -103854,7 +104421,7 @@ var evidence_check = createSwarmTool({
|
|
|
103854
104421
|
return JSON.stringify(errorResult, null, 2);
|
|
103855
104422
|
}
|
|
103856
104423
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
103857
|
-
const planPath =
|
|
104424
|
+
const planPath = path109.join(cwd, PLAN_FILE);
|
|
103858
104425
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
103859
104426
|
const errorResult = {
|
|
103860
104427
|
error: "plan file path validation failed",
|
|
@@ -103886,7 +104453,7 @@ var evidence_check = createSwarmTool({
|
|
|
103886
104453
|
};
|
|
103887
104454
|
return JSON.stringify(result2, null, 2);
|
|
103888
104455
|
}
|
|
103889
|
-
const evidenceDir =
|
|
104456
|
+
const evidenceDir = path109.join(cwd, EVIDENCE_DIR3);
|
|
103890
104457
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
103891
104458
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
103892
104459
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -103904,7 +104471,7 @@ var evidence_check = createSwarmTool({
|
|
|
103904
104471
|
init_zod();
|
|
103905
104472
|
init_create_tool();
|
|
103906
104473
|
import * as fs79 from "node:fs";
|
|
103907
|
-
import * as
|
|
104474
|
+
import * as path110 from "node:path";
|
|
103908
104475
|
var EXT_MAP = {
|
|
103909
104476
|
python: ".py",
|
|
103910
104477
|
py: ".py",
|
|
@@ -103985,12 +104552,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
103985
104552
|
if (prefix) {
|
|
103986
104553
|
filename = `${prefix}_${filename}`;
|
|
103987
104554
|
}
|
|
103988
|
-
let filepath =
|
|
103989
|
-
const base =
|
|
103990
|
-
const ext =
|
|
104555
|
+
let filepath = path110.join(targetDir, filename);
|
|
104556
|
+
const base = path110.basename(filepath, path110.extname(filepath));
|
|
104557
|
+
const ext = path110.extname(filepath);
|
|
103991
104558
|
let counter = 1;
|
|
103992
104559
|
while (fs79.existsSync(filepath)) {
|
|
103993
|
-
filepath =
|
|
104560
|
+
filepath = path110.join(targetDir, `${base}_${counter}${ext}`);
|
|
103994
104561
|
counter++;
|
|
103995
104562
|
}
|
|
103996
104563
|
try {
|
|
@@ -104248,7 +104815,7 @@ init_zod();
|
|
|
104248
104815
|
init_create_tool();
|
|
104249
104816
|
init_path_security();
|
|
104250
104817
|
import * as fs80 from "node:fs";
|
|
104251
|
-
import * as
|
|
104818
|
+
import * as path111 from "node:path";
|
|
104252
104819
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
104253
104820
|
var MAX_SYMBOL_LENGTH = 256;
|
|
104254
104821
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -104296,7 +104863,7 @@ function validateSymbolInput(symbol3) {
|
|
|
104296
104863
|
return null;
|
|
104297
104864
|
}
|
|
104298
104865
|
function isBinaryFile2(filePath, buffer) {
|
|
104299
|
-
const ext =
|
|
104866
|
+
const ext = path111.extname(filePath).toLowerCase();
|
|
104300
104867
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
104301
104868
|
return false;
|
|
104302
104869
|
}
|
|
@@ -104320,15 +104887,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
104320
104887
|
const imports = [];
|
|
104321
104888
|
let _resolvedTarget;
|
|
104322
104889
|
try {
|
|
104323
|
-
_resolvedTarget =
|
|
104890
|
+
_resolvedTarget = path111.resolve(targetFile);
|
|
104324
104891
|
} catch {
|
|
104325
104892
|
_resolvedTarget = targetFile;
|
|
104326
104893
|
}
|
|
104327
|
-
const targetBasename =
|
|
104894
|
+
const targetBasename = path111.basename(targetFile, path111.extname(targetFile));
|
|
104328
104895
|
const targetWithExt = targetFile;
|
|
104329
104896
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
104330
|
-
const normalizedTargetWithExt =
|
|
104331
|
-
const normalizedTargetWithoutExt =
|
|
104897
|
+
const normalizedTargetWithExt = path111.normalize(targetWithExt).replace(/\\/g, "/");
|
|
104898
|
+
const normalizedTargetWithoutExt = path111.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
104332
104899
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
104333
104900
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
104334
104901
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -104351,9 +104918,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
104351
104918
|
}
|
|
104352
104919
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
104353
104920
|
let isMatch = false;
|
|
104354
|
-
const _targetDir =
|
|
104355
|
-
const targetExt =
|
|
104356
|
-
const targetBasenameNoExt =
|
|
104921
|
+
const _targetDir = path111.dirname(targetFile);
|
|
104922
|
+
const targetExt = path111.extname(targetFile);
|
|
104923
|
+
const targetBasenameNoExt = path111.basename(targetFile, targetExt);
|
|
104357
104924
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
104358
104925
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
104359
104926
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -104421,10 +104988,10 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
104421
104988
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
104422
104989
|
for (const entry of entries) {
|
|
104423
104990
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
104424
|
-
stats.skippedDirs.push(
|
|
104991
|
+
stats.skippedDirs.push(path111.join(dir, entry));
|
|
104425
104992
|
continue;
|
|
104426
104993
|
}
|
|
104427
|
-
const fullPath =
|
|
104994
|
+
const fullPath = path111.join(dir, entry);
|
|
104428
104995
|
let stat8;
|
|
104429
104996
|
try {
|
|
104430
104997
|
stat8 = fs80.statSync(fullPath);
|
|
@@ -104438,7 +105005,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
104438
105005
|
if (stat8.isDirectory()) {
|
|
104439
105006
|
findSourceFiles2(fullPath, files, stats);
|
|
104440
105007
|
} else if (stat8.isFile()) {
|
|
104441
|
-
const ext =
|
|
105008
|
+
const ext = path111.extname(fullPath).toLowerCase();
|
|
104442
105009
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
104443
105010
|
files.push(fullPath);
|
|
104444
105011
|
}
|
|
@@ -104495,7 +105062,7 @@ var imports = createSwarmTool({
|
|
|
104495
105062
|
return JSON.stringify(errorResult, null, 2);
|
|
104496
105063
|
}
|
|
104497
105064
|
try {
|
|
104498
|
-
const targetFile =
|
|
105065
|
+
const targetFile = path111.resolve(file3);
|
|
104499
105066
|
if (!fs80.existsSync(targetFile)) {
|
|
104500
105067
|
const errorResult = {
|
|
104501
105068
|
error: `target file not found: ${file3}`,
|
|
@@ -104517,7 +105084,7 @@ var imports = createSwarmTool({
|
|
|
104517
105084
|
};
|
|
104518
105085
|
return JSON.stringify(errorResult, null, 2);
|
|
104519
105086
|
}
|
|
104520
|
-
const baseDir =
|
|
105087
|
+
const baseDir = path111.dirname(targetFile);
|
|
104521
105088
|
const scanStats = {
|
|
104522
105089
|
skippedDirs: [],
|
|
104523
105090
|
skippedFiles: 0,
|
|
@@ -104602,7 +105169,7 @@ var imports = createSwarmTool({
|
|
|
104602
105169
|
});
|
|
104603
105170
|
// src/tools/knowledge-ack.ts
|
|
104604
105171
|
init_zod();
|
|
104605
|
-
import { randomUUID as
|
|
105172
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
104606
105173
|
init_state();
|
|
104607
105174
|
init_logger();
|
|
104608
105175
|
init_create_tool();
|
|
@@ -104635,7 +105202,7 @@ var knowledge_ack = createSwarmTool({
|
|
|
104635
105202
|
let sessionId = ctx?.sessionID;
|
|
104636
105203
|
if (!sessionId) {
|
|
104637
105204
|
warn("[knowledge-ack] No sessionID in tool context — dedup disabled for this acknowledgment");
|
|
104638
|
-
sessionId =
|
|
105205
|
+
sessionId = randomUUID10();
|
|
104639
105206
|
}
|
|
104640
105207
|
const dedupKey = buildAckDedupKey(sessionId, a.id, a.result);
|
|
104641
105208
|
if (swarmState.knowledgeAckDedup.has(dedupKey)) {
|
|
@@ -104665,7 +105232,7 @@ init_knowledge_store();
|
|
|
104665
105232
|
init_knowledge_validator();
|
|
104666
105233
|
init_manager();
|
|
104667
105234
|
init_create_tool();
|
|
104668
|
-
import { randomUUID as
|
|
105235
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
104669
105236
|
var VALID_CATEGORIES2 = [
|
|
104670
105237
|
"process",
|
|
104671
105238
|
"architecture",
|
|
@@ -104739,7 +105306,7 @@ var knowledge_add = createSwarmTool({
|
|
|
104739
105306
|
project_name = plan?.title ?? "";
|
|
104740
105307
|
} catch {}
|
|
104741
105308
|
const entry = {
|
|
104742
|
-
id:
|
|
105309
|
+
id: randomUUID11(),
|
|
104743
105310
|
tier: "swarm",
|
|
104744
105311
|
lesson,
|
|
104745
105312
|
category,
|
|
@@ -105142,22 +105709,22 @@ init_schema();
|
|
|
105142
105709
|
init_qa_gate_profile();
|
|
105143
105710
|
init_manager2();
|
|
105144
105711
|
import * as fs85 from "node:fs";
|
|
105145
|
-
import * as
|
|
105712
|
+
import * as path116 from "node:path";
|
|
105146
105713
|
|
|
105147
105714
|
// src/full-auto/phase-approval.ts
|
|
105148
105715
|
init_utils2();
|
|
105149
105716
|
init_logger();
|
|
105150
105717
|
init_state2();
|
|
105151
105718
|
import * as fs81 from "node:fs";
|
|
105152
|
-
import * as
|
|
105719
|
+
import * as path112 from "node:path";
|
|
105153
105720
|
var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
|
|
105154
105721
|
function readEvidenceDir(directory, phase) {
|
|
105155
105722
|
try {
|
|
105156
|
-
const dirPath = validateSwarmPath(directory,
|
|
105723
|
+
const dirPath = validateSwarmPath(directory, path112.posix.join("evidence", String(phase)));
|
|
105157
105724
|
if (!fs81.existsSync(dirPath))
|
|
105158
105725
|
return [];
|
|
105159
105726
|
const entries = fs81.readdirSync(dirPath);
|
|
105160
|
-
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) =>
|
|
105727
|
+
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path112.join(dirPath, e));
|
|
105161
105728
|
} catch {
|
|
105162
105729
|
return [];
|
|
105163
105730
|
}
|
|
@@ -105296,16 +105863,16 @@ init_plan_schema();
|
|
|
105296
105863
|
init_ledger();
|
|
105297
105864
|
init_manager();
|
|
105298
105865
|
import * as fs82 from "node:fs";
|
|
105299
|
-
import * as
|
|
105866
|
+
import * as path113 from "node:path";
|
|
105300
105867
|
async function writeCheckpoint(directory) {
|
|
105301
105868
|
try {
|
|
105302
105869
|
const plan = await loadPlan(directory);
|
|
105303
105870
|
if (!plan)
|
|
105304
105871
|
return;
|
|
105305
|
-
const swarmDir =
|
|
105872
|
+
const swarmDir = path113.join(directory, ".swarm");
|
|
105306
105873
|
fs82.mkdirSync(swarmDir, { recursive: true });
|
|
105307
|
-
const jsonPath =
|
|
105308
|
-
const mdPath =
|
|
105874
|
+
const jsonPath = path113.join(swarmDir, "SWARM_PLAN.json");
|
|
105875
|
+
const mdPath = path113.join(swarmDir, "SWARM_PLAN.md");
|
|
105309
105876
|
fs82.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
105310
105877
|
const md = derivePlanMarkdown(plan);
|
|
105311
105878
|
fs82.writeFileSync(mdPath, md, "utf8");
|
|
@@ -105324,15 +105891,15 @@ init_telemetry();
|
|
|
105324
105891
|
// src/turbo/lean/phase-ready.ts
|
|
105325
105892
|
init_file_locks();
|
|
105326
105893
|
import * as fs84 from "node:fs";
|
|
105327
|
-
import * as
|
|
105894
|
+
import * as path115 from "node:path";
|
|
105328
105895
|
|
|
105329
105896
|
// src/turbo/lean/evidence.ts
|
|
105330
105897
|
init_bun_compat();
|
|
105331
105898
|
import { rmSync as rmSync6 } from "node:fs";
|
|
105332
105899
|
import * as fs83 from "node:fs/promises";
|
|
105333
|
-
import * as
|
|
105900
|
+
import * as path114 from "node:path";
|
|
105334
105901
|
function leanTurboEvidenceDir(directory, phase) {
|
|
105335
|
-
return
|
|
105902
|
+
return path114.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
105336
105903
|
}
|
|
105337
105904
|
function validateLaneId(laneId) {
|
|
105338
105905
|
if (laneId.length === 0) {
|
|
@@ -105354,16 +105921,16 @@ function validateLaneId(laneId) {
|
|
|
105354
105921
|
function laneEvidencePath(directory, phase, laneId) {
|
|
105355
105922
|
validateLaneId(laneId);
|
|
105356
105923
|
const expectedDir = leanTurboEvidenceDir(directory, phase);
|
|
105357
|
-
const resolvedPath =
|
|
105358
|
-
const resolvedDir =
|
|
105359
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
105924
|
+
const resolvedPath = path114.resolve(path114.join(expectedDir, `${laneId}.json`));
|
|
105925
|
+
const resolvedDir = path114.resolve(expectedDir);
|
|
105926
|
+
if (!resolvedPath.startsWith(resolvedDir + path114.sep) && resolvedPath !== resolvedDir) {
|
|
105360
105927
|
throw new Error(`Invalid laneId: path traversal detected (got "${laneId}")`);
|
|
105361
105928
|
}
|
|
105362
105929
|
return resolvedPath;
|
|
105363
105930
|
}
|
|
105364
105931
|
async function atomicWriteJson(filePath, data) {
|
|
105365
105932
|
const content = JSON.stringify(data, null, 2);
|
|
105366
|
-
const dir =
|
|
105933
|
+
const dir = path114.dirname(filePath);
|
|
105367
105934
|
await fs83.mkdir(dir, { recursive: true });
|
|
105368
105935
|
const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
105369
105936
|
try {
|
|
@@ -105377,7 +105944,7 @@ async function atomicWriteJson(filePath, data) {
|
|
|
105377
105944
|
}
|
|
105378
105945
|
}
|
|
105379
105946
|
function phaseEvidencePath(directory, phase) {
|
|
105380
|
-
return
|
|
105947
|
+
return path114.join(leanTurboEvidenceDir(directory, phase), "lean-turbo-phase.json");
|
|
105381
105948
|
}
|
|
105382
105949
|
async function writeLaneEvidence(directory, phase, evidence) {
|
|
105383
105950
|
const targetPath = laneEvidencePath(directory, phase, evidence.laneId);
|
|
@@ -105421,7 +105988,7 @@ async function listLaneEvidence(directory, phase) {
|
|
|
105421
105988
|
if (entry === "lean-turbo-phase.json") {
|
|
105422
105989
|
continue;
|
|
105423
105990
|
}
|
|
105424
|
-
const filePath =
|
|
105991
|
+
const filePath = path114.join(evidenceDir, entry);
|
|
105425
105992
|
let content;
|
|
105426
105993
|
try {
|
|
105427
105994
|
content = await fs83.readFile(filePath, "utf-8");
|
|
@@ -105445,7 +106012,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
105445
106012
|
};
|
|
105446
106013
|
function defaultReadPlanJson(dir) {
|
|
105447
106014
|
try {
|
|
105448
|
-
const planPath =
|
|
106015
|
+
const planPath = path115.join(dir, ".swarm", "plan.json");
|
|
105449
106016
|
if (!fs84.existsSync(planPath))
|
|
105450
106017
|
return null;
|
|
105451
106018
|
const raw = fs84.readFileSync(planPath, "utf-8");
|
|
@@ -105460,7 +106027,7 @@ function defaultReadPlanJson(dir) {
|
|
|
105460
106027
|
}
|
|
105461
106028
|
function readReviewerEvidenceFromFile(directory, phase) {
|
|
105462
106029
|
try {
|
|
105463
|
-
const evidencePath =
|
|
106030
|
+
const evidencePath = path115.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
|
|
105464
106031
|
if (!fs84.existsSync(evidencePath)) {
|
|
105465
106032
|
return null;
|
|
105466
106033
|
}
|
|
@@ -105480,7 +106047,7 @@ function readReviewerEvidenceFromFile(directory, phase) {
|
|
|
105480
106047
|
}
|
|
105481
106048
|
function readCriticEvidenceFromFile(directory, phase) {
|
|
105482
106049
|
try {
|
|
105483
|
-
const evidencePath =
|
|
106050
|
+
const evidencePath = path115.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
|
|
105484
106051
|
if (!fs84.existsSync(evidencePath)) {
|
|
105485
106052
|
return null;
|
|
105486
106053
|
}
|
|
@@ -105499,7 +106066,7 @@ function readCriticEvidenceFromFile(directory, phase) {
|
|
|
105499
106066
|
}
|
|
105500
106067
|
}
|
|
105501
106068
|
function listLaneEvidenceSync(directory, phase) {
|
|
105502
|
-
const evidenceDir =
|
|
106069
|
+
const evidenceDir = path115.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
105503
106070
|
let entries;
|
|
105504
106071
|
try {
|
|
105505
106072
|
entries = fs84.readdirSync(evidenceDir);
|
|
@@ -105569,7 +106136,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
105569
106136
|
...DEFAULT_CONFIG2,
|
|
105570
106137
|
...actualConfig
|
|
105571
106138
|
};
|
|
105572
|
-
const statePath =
|
|
106139
|
+
const statePath = path115.join(directory, ".swarm", "turbo-state.json");
|
|
105573
106140
|
if (!fs84.existsSync(statePath)) {
|
|
105574
106141
|
return {
|
|
105575
106142
|
ok: false,
|
|
@@ -105757,7 +106324,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
105757
106324
|
}
|
|
105758
106325
|
}
|
|
105759
106326
|
if (mergedConfig.integrated_diff_required) {
|
|
105760
|
-
const evidencePath =
|
|
106327
|
+
const evidencePath = path115.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
|
|
105761
106328
|
let hasDiff = false;
|
|
105762
106329
|
try {
|
|
105763
106330
|
const content = fs84.readFileSync(evidencePath, "utf-8");
|
|
@@ -106052,7 +106619,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106052
106619
|
let driftCheckEnabled = true;
|
|
106053
106620
|
let driftHasSpecMd = false;
|
|
106054
106621
|
try {
|
|
106055
|
-
const specMdPath =
|
|
106622
|
+
const specMdPath = path116.join(dir, ".swarm", "spec.md");
|
|
106056
106623
|
driftHasSpecMd = fs85.existsSync(specMdPath);
|
|
106057
106624
|
const gatePlan = await loadPlan(dir);
|
|
106058
106625
|
if (gatePlan) {
|
|
@@ -106073,7 +106640,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106073
106640
|
} else {
|
|
106074
106641
|
let phaseType;
|
|
106075
106642
|
try {
|
|
106076
|
-
const planPath =
|
|
106643
|
+
const planPath = path116.join(dir, ".swarm", "plan.json");
|
|
106077
106644
|
if (fs85.existsSync(planPath)) {
|
|
106078
106645
|
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
106079
106646
|
const plan = JSON.parse(planRaw);
|
|
@@ -106085,7 +106652,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106085
106652
|
warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
|
|
106086
106653
|
} else {
|
|
106087
106654
|
try {
|
|
106088
|
-
const driftEvidencePath =
|
|
106655
|
+
const driftEvidencePath = path116.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
106089
106656
|
let driftVerdictFound = false;
|
|
106090
106657
|
let driftVerdictApproved = false;
|
|
106091
106658
|
try {
|
|
@@ -106123,7 +106690,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106123
106690
|
let incompleteTaskCount = 0;
|
|
106124
106691
|
let planParseable = false;
|
|
106125
106692
|
try {
|
|
106126
|
-
const planPath =
|
|
106693
|
+
const planPath = path116.join(dir, ".swarm", "plan.json");
|
|
106127
106694
|
if (fs85.existsSync(planPath)) {
|
|
106128
106695
|
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
106129
106696
|
const plan = JSON.parse(planRaw);
|
|
@@ -106190,7 +106757,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106190
106757
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
106191
106758
|
const effective = getEffectiveGates(profile, overrides);
|
|
106192
106759
|
if (effective.hallucination_guard === true) {
|
|
106193
|
-
const hgPath =
|
|
106760
|
+
const hgPath = path116.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
106194
106761
|
let hgVerdictFound = false;
|
|
106195
106762
|
let hgVerdictApproved = false;
|
|
106196
106763
|
try {
|
|
@@ -106262,7 +106829,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106262
106829
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
106263
106830
|
const effective = getEffectiveGates(profile, overrides);
|
|
106264
106831
|
if (effective.mutation_test === true) {
|
|
106265
|
-
const mgPath =
|
|
106832
|
+
const mgPath = path116.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
106266
106833
|
let mgVerdictFound = false;
|
|
106267
106834
|
let mgVerdict;
|
|
106268
106835
|
try {
|
|
@@ -106336,7 +106903,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106336
106903
|
const effective = getEffectiveGates(profile, overrides);
|
|
106337
106904
|
if (effective.council_mode === true) {
|
|
106338
106905
|
councilModeEnabled = true;
|
|
106339
|
-
const pcPath =
|
|
106906
|
+
const pcPath = path116.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
106340
106907
|
let pcVerdictFound = false;
|
|
106341
106908
|
let _pcVerdict;
|
|
106342
106909
|
let pcQuorumSize;
|
|
@@ -106544,7 +107111,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
106544
107111
|
const effective = getEffectiveGates(profile, overrides);
|
|
106545
107112
|
if (effective.final_council === true) {
|
|
106546
107113
|
finalCouncilEnabled = true;
|
|
106547
|
-
const fcPath =
|
|
107114
|
+
const fcPath = path116.join(dir, ".swarm", "evidence", "final-council.json");
|
|
106548
107115
|
let fcVerdictFound = false;
|
|
106549
107116
|
let _fcVerdict;
|
|
106550
107117
|
try {
|
|
@@ -106732,7 +107299,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
106732
107299
|
}
|
|
106733
107300
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
106734
107301
|
try {
|
|
106735
|
-
const projectName =
|
|
107302
|
+
const projectName = path116.basename(dir);
|
|
106736
107303
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
106737
107304
|
if (curationResult) {
|
|
106738
107305
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -107102,7 +107669,7 @@ init_utils();
|
|
|
107102
107669
|
init_bun_compat();
|
|
107103
107670
|
init_create_tool();
|
|
107104
107671
|
import * as fs86 from "node:fs";
|
|
107105
|
-
import * as
|
|
107672
|
+
import * as path117 from "node:path";
|
|
107106
107673
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
107107
107674
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
107108
107675
|
function isValidEcosystem(value) {
|
|
@@ -107130,16 +107697,16 @@ function validateArgs3(args2) {
|
|
|
107130
107697
|
function detectEcosystems(directory) {
|
|
107131
107698
|
const ecosystems = [];
|
|
107132
107699
|
const cwd = directory;
|
|
107133
|
-
if (fs86.existsSync(
|
|
107700
|
+
if (fs86.existsSync(path117.join(cwd, "package.json"))) {
|
|
107134
107701
|
ecosystems.push("npm");
|
|
107135
107702
|
}
|
|
107136
|
-
if (fs86.existsSync(
|
|
107703
|
+
if (fs86.existsSync(path117.join(cwd, "pyproject.toml")) || fs86.existsSync(path117.join(cwd, "requirements.txt"))) {
|
|
107137
107704
|
ecosystems.push("pip");
|
|
107138
107705
|
}
|
|
107139
|
-
if (fs86.existsSync(
|
|
107706
|
+
if (fs86.existsSync(path117.join(cwd, "Cargo.toml"))) {
|
|
107140
107707
|
ecosystems.push("cargo");
|
|
107141
107708
|
}
|
|
107142
|
-
if (fs86.existsSync(
|
|
107709
|
+
if (fs86.existsSync(path117.join(cwd, "go.mod"))) {
|
|
107143
107710
|
ecosystems.push("go");
|
|
107144
107711
|
}
|
|
107145
107712
|
try {
|
|
@@ -107148,13 +107715,13 @@ function detectEcosystems(directory) {
|
|
|
107148
107715
|
ecosystems.push("dotnet");
|
|
107149
107716
|
}
|
|
107150
107717
|
} catch {}
|
|
107151
|
-
if (fs86.existsSync(
|
|
107718
|
+
if (fs86.existsSync(path117.join(cwd, "Gemfile")) || fs86.existsSync(path117.join(cwd, "Gemfile.lock"))) {
|
|
107152
107719
|
ecosystems.push("ruby");
|
|
107153
107720
|
}
|
|
107154
|
-
if (fs86.existsSync(
|
|
107721
|
+
if (fs86.existsSync(path117.join(cwd, "pubspec.yaml"))) {
|
|
107155
107722
|
ecosystems.push("dart");
|
|
107156
107723
|
}
|
|
107157
|
-
if (fs86.existsSync(
|
|
107724
|
+
if (fs86.existsSync(path117.join(cwd, "composer.lock"))) {
|
|
107158
107725
|
ecosystems.push("composer");
|
|
107159
107726
|
}
|
|
107160
107727
|
return ecosystems;
|
|
@@ -108290,7 +108857,7 @@ var pkg_audit = createSwarmTool({
|
|
|
108290
108857
|
init_zod();
|
|
108291
108858
|
init_manager2();
|
|
108292
108859
|
import * as fs87 from "node:fs";
|
|
108293
|
-
import * as
|
|
108860
|
+
import * as path118 from "node:path";
|
|
108294
108861
|
init_utils();
|
|
108295
108862
|
init_create_tool();
|
|
108296
108863
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -108413,7 +108980,7 @@ function isScaffoldFile(filePath) {
|
|
|
108413
108980
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
108414
108981
|
return true;
|
|
108415
108982
|
}
|
|
108416
|
-
const filename =
|
|
108983
|
+
const filename = path118.basename(filePath);
|
|
108417
108984
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
108418
108985
|
return true;
|
|
108419
108986
|
}
|
|
@@ -108430,7 +108997,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
108430
108997
|
if (regex.test(normalizedPath)) {
|
|
108431
108998
|
return true;
|
|
108432
108999
|
}
|
|
108433
|
-
const filename =
|
|
109000
|
+
const filename = path118.basename(filePath);
|
|
108434
109001
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
108435
109002
|
if (filenameRegex.test(filename)) {
|
|
108436
109003
|
return true;
|
|
@@ -108439,7 +109006,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
108439
109006
|
return false;
|
|
108440
109007
|
}
|
|
108441
109008
|
function isParserSupported(filePath) {
|
|
108442
|
-
const ext =
|
|
109009
|
+
const ext = path118.extname(filePath).toLowerCase();
|
|
108443
109010
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
108444
109011
|
}
|
|
108445
109012
|
function isPlanFile(filePath) {
|
|
@@ -108686,9 +109253,9 @@ async function placeholderScan(input, directory) {
|
|
|
108686
109253
|
let filesScanned = 0;
|
|
108687
109254
|
const filesWithFindings = new Set;
|
|
108688
109255
|
for (const filePath of changed_files) {
|
|
108689
|
-
const fullPath =
|
|
108690
|
-
const resolvedDirectory =
|
|
108691
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
109256
|
+
const fullPath = path118.isAbsolute(filePath) ? filePath : path118.resolve(directory, filePath);
|
|
109257
|
+
const resolvedDirectory = path118.resolve(directory);
|
|
109258
|
+
if (!fullPath.startsWith(resolvedDirectory + path118.sep) && fullPath !== resolvedDirectory) {
|
|
108692
109259
|
continue;
|
|
108693
109260
|
}
|
|
108694
109261
|
if (!fs87.existsSync(fullPath)) {
|
|
@@ -108697,7 +109264,7 @@ async function placeholderScan(input, directory) {
|
|
|
108697
109264
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
108698
109265
|
continue;
|
|
108699
109266
|
}
|
|
108700
|
-
const relativeFilePath =
|
|
109267
|
+
const relativeFilePath = path118.relative(directory, fullPath).replace(/\\/g, "/");
|
|
108701
109268
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
108702
109269
|
continue;
|
|
108703
109270
|
}
|
|
@@ -108769,7 +109336,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
108769
109336
|
});
|
|
108770
109337
|
// src/tools/pre-check-batch.ts
|
|
108771
109338
|
import * as fs91 from "node:fs";
|
|
108772
|
-
import * as
|
|
109339
|
+
import * as path122 from "node:path";
|
|
108773
109340
|
init_zod();
|
|
108774
109341
|
init_manager2();
|
|
108775
109342
|
init_utils();
|
|
@@ -108910,7 +109477,7 @@ init_zod();
|
|
|
108910
109477
|
init_manager2();
|
|
108911
109478
|
init_detector();
|
|
108912
109479
|
import * as fs90 from "node:fs";
|
|
108913
|
-
import * as
|
|
109480
|
+
import * as path121 from "node:path";
|
|
108914
109481
|
import { extname as extname20 } from "node:path";
|
|
108915
109482
|
|
|
108916
109483
|
// src/sast/rules/c.ts
|
|
@@ -109626,7 +110193,7 @@ function executeRulesSync(filePath, content, language) {
|
|
|
109626
110193
|
// src/sast/semgrep.ts
|
|
109627
110194
|
import * as child_process9 from "node:child_process";
|
|
109628
110195
|
import * as fs88 from "node:fs";
|
|
109629
|
-
import * as
|
|
110196
|
+
import * as path119 from "node:path";
|
|
109630
110197
|
var semgrepAvailableCache = null;
|
|
109631
110198
|
var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
|
|
109632
110199
|
var DEFAULT_TIMEOUT_MS3 = 30000;
|
|
@@ -109813,7 +110380,7 @@ async function runSemgrep(options) {
|
|
|
109813
110380
|
}
|
|
109814
110381
|
function getRulesDirectory(projectRoot) {
|
|
109815
110382
|
if (projectRoot) {
|
|
109816
|
-
return
|
|
110383
|
+
return path119.resolve(projectRoot, DEFAULT_RULES_DIR);
|
|
109817
110384
|
}
|
|
109818
110385
|
return DEFAULT_RULES_DIR;
|
|
109819
110386
|
}
|
|
@@ -109834,24 +110401,24 @@ init_create_tool();
|
|
|
109834
110401
|
init_utils2();
|
|
109835
110402
|
import * as crypto10 from "node:crypto";
|
|
109836
110403
|
import * as fs89 from "node:fs";
|
|
109837
|
-
import * as
|
|
110404
|
+
import * as path120 from "node:path";
|
|
109838
110405
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
109839
110406
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
109840
110407
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
109841
110408
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
109842
110409
|
function normalizeFindingPath(directory, file3) {
|
|
109843
|
-
const resolved =
|
|
109844
|
-
const rel =
|
|
110410
|
+
const resolved = path120.isAbsolute(file3) ? file3 : path120.resolve(directory, file3);
|
|
110411
|
+
const rel = path120.relative(path120.resolve(directory), resolved);
|
|
109845
110412
|
return rel.replace(/\\/g, "/");
|
|
109846
110413
|
}
|
|
109847
110414
|
function baselineRelPath(phase) {
|
|
109848
|
-
return
|
|
110415
|
+
return path120.join("evidence", String(phase), "sast-baseline.json");
|
|
109849
110416
|
}
|
|
109850
110417
|
function tempRelPath(phase) {
|
|
109851
|
-
return
|
|
110418
|
+
return path120.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
109852
110419
|
}
|
|
109853
110420
|
function lockRelPath(phase) {
|
|
109854
|
-
return
|
|
110421
|
+
return path120.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
109855
110422
|
}
|
|
109856
110423
|
function getLine(lines, idx) {
|
|
109857
110424
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -109972,8 +110539,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
109972
110539
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
109973
110540
|
};
|
|
109974
110541
|
}
|
|
109975
|
-
fs89.mkdirSync(
|
|
109976
|
-
fs89.mkdirSync(
|
|
110542
|
+
fs89.mkdirSync(path120.dirname(baselinePath), { recursive: true });
|
|
110543
|
+
fs89.mkdirSync(path120.dirname(tempPath), { recursive: true });
|
|
109977
110544
|
const releaseLock = await acquireLock2(lockPath);
|
|
109978
110545
|
try {
|
|
109979
110546
|
let existing = null;
|
|
@@ -110246,9 +110813,9 @@ async function sastScan(input, directory, config3) {
|
|
|
110246
110813
|
_filesSkipped++;
|
|
110247
110814
|
continue;
|
|
110248
110815
|
}
|
|
110249
|
-
const resolvedPath =
|
|
110250
|
-
const resolvedDirectory =
|
|
110251
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
110816
|
+
const resolvedPath = path121.isAbsolute(filePath) ? filePath : path121.resolve(directory, filePath);
|
|
110817
|
+
const resolvedDirectory = path121.resolve(directory);
|
|
110818
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path121.sep) && resolvedPath !== resolvedDirectory) {
|
|
110252
110819
|
_filesSkipped++;
|
|
110253
110820
|
continue;
|
|
110254
110821
|
}
|
|
@@ -110563,18 +111130,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
110563
111130
|
let resolved;
|
|
110564
111131
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
110565
111132
|
if (isWinAbs) {
|
|
110566
|
-
resolved =
|
|
110567
|
-
} else if (
|
|
110568
|
-
resolved =
|
|
111133
|
+
resolved = path122.win32.resolve(inputPath);
|
|
111134
|
+
} else if (path122.isAbsolute(inputPath)) {
|
|
111135
|
+
resolved = path122.resolve(inputPath);
|
|
110569
111136
|
} else {
|
|
110570
|
-
resolved =
|
|
111137
|
+
resolved = path122.resolve(baseDir, inputPath);
|
|
110571
111138
|
}
|
|
110572
|
-
const workspaceResolved =
|
|
111139
|
+
const workspaceResolved = path122.resolve(workspaceDir);
|
|
110573
111140
|
let relative25;
|
|
110574
111141
|
if (isWinAbs) {
|
|
110575
|
-
relative25 =
|
|
111142
|
+
relative25 = path122.win32.relative(workspaceResolved, resolved);
|
|
110576
111143
|
} else {
|
|
110577
|
-
relative25 =
|
|
111144
|
+
relative25 = path122.relative(workspaceResolved, resolved);
|
|
110578
111145
|
}
|
|
110579
111146
|
if (relative25.startsWith("..")) {
|
|
110580
111147
|
return "path traversal detected";
|
|
@@ -110639,7 +111206,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
110639
111206
|
if (typeof file3 !== "string") {
|
|
110640
111207
|
continue;
|
|
110641
111208
|
}
|
|
110642
|
-
const resolvedPath =
|
|
111209
|
+
const resolvedPath = path122.resolve(file3);
|
|
110643
111210
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
110644
111211
|
if (validationError) {
|
|
110645
111212
|
continue;
|
|
@@ -110796,7 +111363,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
110796
111363
|
skippedFiles++;
|
|
110797
111364
|
continue;
|
|
110798
111365
|
}
|
|
110799
|
-
const resolvedPath =
|
|
111366
|
+
const resolvedPath = path122.resolve(file3);
|
|
110800
111367
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
110801
111368
|
if (validationError) {
|
|
110802
111369
|
skippedFiles++;
|
|
@@ -110814,7 +111381,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
110814
111381
|
};
|
|
110815
111382
|
}
|
|
110816
111383
|
for (const file3 of validatedFiles) {
|
|
110817
|
-
const ext =
|
|
111384
|
+
const ext = path122.extname(file3).toLowerCase();
|
|
110818
111385
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
110819
111386
|
skippedFiles++;
|
|
110820
111387
|
continue;
|
|
@@ -111033,7 +111600,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
111033
111600
|
const preexistingFindings = [];
|
|
111034
111601
|
for (const finding of findings) {
|
|
111035
111602
|
const filePath = finding.location.file;
|
|
111036
|
-
const normalised =
|
|
111603
|
+
const normalised = path122.relative(directory, filePath).replace(/\\/g, "/");
|
|
111037
111604
|
const changedLines = changedLineRanges.get(normalised);
|
|
111038
111605
|
if (changedLines?.has(finding.location.line)) {
|
|
111039
111606
|
newFindings.push(finding);
|
|
@@ -111084,7 +111651,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
111084
111651
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
111085
111652
|
continue;
|
|
111086
111653
|
}
|
|
111087
|
-
changedFiles.push(
|
|
111654
|
+
changedFiles.push(path122.resolve(directory, file3));
|
|
111088
111655
|
}
|
|
111089
111656
|
if (changedFiles.length === 0) {
|
|
111090
111657
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -111285,9 +111852,9 @@ var pre_check_batch = createSwarmTool({
|
|
|
111285
111852
|
};
|
|
111286
111853
|
return JSON.stringify(errorResult, null, 2);
|
|
111287
111854
|
}
|
|
111288
|
-
const resolvedDirectory =
|
|
111289
|
-
const workspaceAnchor =
|
|
111290
|
-
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor +
|
|
111855
|
+
const resolvedDirectory = path122.resolve(typedArgs.directory);
|
|
111856
|
+
const workspaceAnchor = path122.resolve(directory);
|
|
111857
|
+
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path122.sep)) {
|
|
111291
111858
|
const subDirError = `directory "${typedArgs.directory}" is a subdirectory of the project root — pre_check_batch requires the project root directory "${workspaceAnchor}"`;
|
|
111292
111859
|
const subDirResult = {
|
|
111293
111860
|
gates_passed: false,
|
|
@@ -111338,7 +111905,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
111338
111905
|
});
|
|
111339
111906
|
// src/tools/repo-map.ts
|
|
111340
111907
|
init_zod();
|
|
111341
|
-
import * as
|
|
111908
|
+
import * as path123 from "node:path";
|
|
111342
111909
|
init_path_security();
|
|
111343
111910
|
init_create_tool();
|
|
111344
111911
|
var VALID_ACTIONS = [
|
|
@@ -111363,7 +111930,7 @@ function validateFile(p) {
|
|
|
111363
111930
|
return "file contains control characters";
|
|
111364
111931
|
if (containsPathTraversal(p))
|
|
111365
111932
|
return "file contains path traversal";
|
|
111366
|
-
if (
|
|
111933
|
+
if (path123.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
111367
111934
|
return "file must be a workspace-relative path, not absolute";
|
|
111368
111935
|
}
|
|
111369
111936
|
return null;
|
|
@@ -111386,8 +111953,8 @@ function ok(action, payload) {
|
|
|
111386
111953
|
}
|
|
111387
111954
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
111388
111955
|
const normalized = input.replace(/\\/g, "/");
|
|
111389
|
-
if (
|
|
111390
|
-
const rel =
|
|
111956
|
+
if (path123.isAbsolute(normalized)) {
|
|
111957
|
+
const rel = path123.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
111391
111958
|
return normalizeGraphPath2(rel);
|
|
111392
111959
|
}
|
|
111393
111960
|
return normalizeGraphPath2(normalized);
|
|
@@ -111532,7 +112099,7 @@ var repo_map = createSwarmTool({
|
|
|
111532
112099
|
init_zod();
|
|
111533
112100
|
init_create_tool();
|
|
111534
112101
|
import * as fs92 from "node:fs";
|
|
111535
|
-
import * as
|
|
112102
|
+
import * as path124 from "node:path";
|
|
111536
112103
|
var SPEC_FILE = ".swarm/spec.md";
|
|
111537
112104
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
111538
112105
|
var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -111601,7 +112168,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
111601
112168
|
return [];
|
|
111602
112169
|
}
|
|
111603
112170
|
for (const entry of entries) {
|
|
111604
|
-
const entryPath =
|
|
112171
|
+
const entryPath = path124.join(evidenceDir, entry);
|
|
111605
112172
|
try {
|
|
111606
112173
|
const stat8 = fs92.statSync(entryPath);
|
|
111607
112174
|
if (!stat8.isDirectory()) {
|
|
@@ -111617,11 +112184,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
111617
112184
|
if (entryPhase !== String(phase)) {
|
|
111618
112185
|
continue;
|
|
111619
112186
|
}
|
|
111620
|
-
const evidenceFilePath =
|
|
112187
|
+
const evidenceFilePath = path124.join(entryPath, "evidence.json");
|
|
111621
112188
|
try {
|
|
111622
|
-
const resolvedPath =
|
|
111623
|
-
const evidenceDirResolved =
|
|
111624
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
112189
|
+
const resolvedPath = path124.resolve(evidenceFilePath);
|
|
112190
|
+
const evidenceDirResolved = path124.resolve(evidenceDir);
|
|
112191
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path124.sep)) {
|
|
111625
112192
|
continue;
|
|
111626
112193
|
}
|
|
111627
112194
|
const stat8 = fs92.lstatSync(evidenceFilePath);
|
|
@@ -111655,7 +112222,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
111655
112222
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
111656
112223
|
for (const file3 of diffEntry.files_changed) {
|
|
111657
112224
|
if (typeof file3 === "string") {
|
|
111658
|
-
touchedFiles.add(
|
|
112225
|
+
touchedFiles.add(path124.resolve(cwd, file3));
|
|
111659
112226
|
}
|
|
111660
112227
|
}
|
|
111661
112228
|
}
|
|
@@ -111668,8 +112235,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
111668
112235
|
}
|
|
111669
112236
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
111670
112237
|
try {
|
|
111671
|
-
const resolvedPath =
|
|
111672
|
-
const cwdResolved =
|
|
112238
|
+
const resolvedPath = path124.resolve(filePath);
|
|
112239
|
+
const cwdResolved = path124.resolve(cwd);
|
|
111673
112240
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
111674
112241
|
return false;
|
|
111675
112242
|
}
|
|
@@ -111803,7 +112370,7 @@ var req_coverage = createSwarmTool({
|
|
|
111803
112370
|
}, null, 2);
|
|
111804
112371
|
}
|
|
111805
112372
|
const cwd = inputDirectory || directory;
|
|
111806
|
-
const specPath =
|
|
112373
|
+
const specPath = path124.join(cwd, SPEC_FILE);
|
|
111807
112374
|
let specContent;
|
|
111808
112375
|
try {
|
|
111809
112376
|
specContent = fs92.readFileSync(specPath, "utf-8");
|
|
@@ -111830,7 +112397,7 @@ var req_coverage = createSwarmTool({
|
|
|
111830
112397
|
message: "No FR requirements found in spec.md"
|
|
111831
112398
|
}, null, 2);
|
|
111832
112399
|
}
|
|
111833
|
-
const evidenceDir =
|
|
112400
|
+
const evidenceDir = path124.join(cwd, EVIDENCE_DIR4);
|
|
111834
112401
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
111835
112402
|
const analyzedRequirements = [];
|
|
111836
112403
|
let coveredCount = 0;
|
|
@@ -111856,7 +112423,7 @@ var req_coverage = createSwarmTool({
|
|
|
111856
112423
|
requirements: analyzedRequirements
|
|
111857
112424
|
};
|
|
111858
112425
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
111859
|
-
const reportPath =
|
|
112426
|
+
const reportPath = path124.join(evidenceDir, reportFilename);
|
|
111860
112427
|
try {
|
|
111861
112428
|
if (!fs92.existsSync(evidenceDir)) {
|
|
111862
112429
|
fs92.mkdirSync(evidenceDir, { recursive: true });
|
|
@@ -111944,7 +112511,7 @@ init_qa_gate_profile();
|
|
|
111944
112511
|
init_file_locks();
|
|
111945
112512
|
import * as crypto11 from "node:crypto";
|
|
111946
112513
|
import * as fs93 from "node:fs";
|
|
111947
|
-
import * as
|
|
112514
|
+
import * as path125 from "node:path";
|
|
111948
112515
|
init_ledger();
|
|
111949
112516
|
init_manager();
|
|
111950
112517
|
init_state();
|
|
@@ -112022,8 +112589,8 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112022
112589
|
};
|
|
112023
112590
|
}
|
|
112024
112591
|
if (args2.working_directory && fallbackDir) {
|
|
112025
|
-
const resolvedTarget =
|
|
112026
|
-
const resolvedRoot =
|
|
112592
|
+
const resolvedTarget = path125.resolve(args2.working_directory);
|
|
112593
|
+
const resolvedRoot = path125.resolve(fallbackDir);
|
|
112027
112594
|
let fallbackExists = false;
|
|
112028
112595
|
try {
|
|
112029
112596
|
fs93.accessSync(resolvedRoot, fs93.constants.F_OK);
|
|
@@ -112032,7 +112599,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112032
112599
|
fallbackExists = false;
|
|
112033
112600
|
}
|
|
112034
112601
|
if (fallbackExists) {
|
|
112035
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
112602
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path125.sep);
|
|
112036
112603
|
if (isSubdirectory) {
|
|
112037
112604
|
return {
|
|
112038
112605
|
success: false,
|
|
@@ -112048,7 +112615,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112048
112615
|
let specMtime;
|
|
112049
112616
|
let specHash;
|
|
112050
112617
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
112051
|
-
const specPath =
|
|
112618
|
+
const specPath = path125.join(targetWorkspace, ".swarm", "spec.md");
|
|
112052
112619
|
try {
|
|
112053
112620
|
const stat8 = await fs93.promises.stat(specPath);
|
|
112054
112621
|
specMtime = stat8.mtime.toISOString();
|
|
@@ -112064,7 +112631,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112064
112631
|
}
|
|
112065
112632
|
}
|
|
112066
112633
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
112067
|
-
const contextPath =
|
|
112634
|
+
const contextPath = path125.join(targetWorkspace, ".swarm", "context.md");
|
|
112068
112635
|
let contextContent = "";
|
|
112069
112636
|
try {
|
|
112070
112637
|
contextContent = await fs93.promises.readFile(contextPath, "utf8");
|
|
@@ -112321,7 +112888,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112321
112888
|
}
|
|
112322
112889
|
await writeCheckpoint(dir).catch(() => {});
|
|
112323
112890
|
try {
|
|
112324
|
-
const markerPath =
|
|
112891
|
+
const markerPath = path125.join(dir, ".swarm", ".plan-write-marker");
|
|
112325
112892
|
const marker = JSON.stringify({
|
|
112326
112893
|
source: "save_plan",
|
|
112327
112894
|
timestamp: new Date().toISOString(),
|
|
@@ -112344,7 +112911,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112344
112911
|
return {
|
|
112345
112912
|
success: true,
|
|
112346
112913
|
message: "Plan saved successfully",
|
|
112347
|
-
plan_path:
|
|
112914
|
+
plan_path: path125.join(dir, ".swarm", "plan.json"),
|
|
112348
112915
|
phases_count: plan.phases.length,
|
|
112349
112916
|
tasks_count: tasksCount,
|
|
112350
112917
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -112409,7 +112976,7 @@ var save_plan = createSwarmTool({
|
|
|
112409
112976
|
init_zod();
|
|
112410
112977
|
init_manager2();
|
|
112411
112978
|
import * as fs94 from "node:fs";
|
|
112412
|
-
import * as
|
|
112979
|
+
import * as path126 from "node:path";
|
|
112413
112980
|
|
|
112414
112981
|
// src/sbom/detectors/index.ts
|
|
112415
112982
|
init_utils();
|
|
@@ -113259,7 +113826,7 @@ function findManifestFiles(rootDir) {
|
|
|
113259
113826
|
try {
|
|
113260
113827
|
const entries = fs94.readdirSync(dir, { withFileTypes: true });
|
|
113261
113828
|
for (const entry of entries) {
|
|
113262
|
-
const fullPath =
|
|
113829
|
+
const fullPath = path126.join(dir, entry.name);
|
|
113263
113830
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
113264
113831
|
continue;
|
|
113265
113832
|
}
|
|
@@ -113268,7 +113835,7 @@ function findManifestFiles(rootDir) {
|
|
|
113268
113835
|
} else if (entry.isFile()) {
|
|
113269
113836
|
for (const pattern of patterns) {
|
|
113270
113837
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
113271
|
-
manifestFiles.push(
|
|
113838
|
+
manifestFiles.push(path126.relative(rootDir, fullPath));
|
|
113272
113839
|
break;
|
|
113273
113840
|
}
|
|
113274
113841
|
}
|
|
@@ -113286,11 +113853,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
113286
113853
|
try {
|
|
113287
113854
|
const entries = fs94.readdirSync(dir, { withFileTypes: true });
|
|
113288
113855
|
for (const entry of entries) {
|
|
113289
|
-
const fullPath =
|
|
113856
|
+
const fullPath = path126.join(dir, entry.name);
|
|
113290
113857
|
if (entry.isFile()) {
|
|
113291
113858
|
for (const pattern of patterns) {
|
|
113292
113859
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
113293
|
-
found.push(
|
|
113860
|
+
found.push(path126.relative(workingDir, fullPath));
|
|
113294
113861
|
break;
|
|
113295
113862
|
}
|
|
113296
113863
|
}
|
|
@@ -113303,11 +113870,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
113303
113870
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
113304
113871
|
const dirs = new Set;
|
|
113305
113872
|
for (const file3 of changedFiles) {
|
|
113306
|
-
let currentDir =
|
|
113873
|
+
let currentDir = path126.dirname(file3);
|
|
113307
113874
|
while (true) {
|
|
113308
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
113309
|
-
dirs.add(
|
|
113310
|
-
const parent =
|
|
113875
|
+
if (currentDir && currentDir !== "." && currentDir !== path126.sep) {
|
|
113876
|
+
dirs.add(path126.join(workingDir, currentDir));
|
|
113877
|
+
const parent = path126.dirname(currentDir);
|
|
113311
113878
|
if (parent === currentDir)
|
|
113312
113879
|
break;
|
|
113313
113880
|
currentDir = parent;
|
|
@@ -113391,7 +113958,7 @@ var sbom_generate = createSwarmTool({
|
|
|
113391
113958
|
const changedFiles = obj.changed_files;
|
|
113392
113959
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
113393
113960
|
const workingDir = directory;
|
|
113394
|
-
const outputDir =
|
|
113961
|
+
const outputDir = path126.isAbsolute(relativeOutputDir) ? relativeOutputDir : path126.join(workingDir, relativeOutputDir);
|
|
113395
113962
|
let manifestFiles = [];
|
|
113396
113963
|
if (scope === "all") {
|
|
113397
113964
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -113414,7 +113981,7 @@ var sbom_generate = createSwarmTool({
|
|
|
113414
113981
|
const processedFiles = [];
|
|
113415
113982
|
for (const manifestFile of manifestFiles) {
|
|
113416
113983
|
try {
|
|
113417
|
-
const fullPath =
|
|
113984
|
+
const fullPath = path126.isAbsolute(manifestFile) ? manifestFile : path126.join(workingDir, manifestFile);
|
|
113418
113985
|
if (!fs94.existsSync(fullPath)) {
|
|
113419
113986
|
continue;
|
|
113420
113987
|
}
|
|
@@ -113431,7 +113998,7 @@ var sbom_generate = createSwarmTool({
|
|
|
113431
113998
|
const bom = generateCycloneDX(allComponents);
|
|
113432
113999
|
const bomJson = serializeCycloneDX(bom);
|
|
113433
114000
|
const filename = generateSbomFilename();
|
|
113434
|
-
const outputPath =
|
|
114001
|
+
const outputPath = path126.join(outputDir, filename);
|
|
113435
114002
|
fs94.writeFileSync(outputPath, bomJson, "utf-8");
|
|
113436
114003
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
113437
114004
|
try {
|
|
@@ -113475,7 +114042,7 @@ var sbom_generate = createSwarmTool({
|
|
|
113475
114042
|
init_zod();
|
|
113476
114043
|
init_create_tool();
|
|
113477
114044
|
import * as fs95 from "node:fs";
|
|
113478
|
-
import * as
|
|
114045
|
+
import * as path127 from "node:path";
|
|
113479
114046
|
var SPEC_CANDIDATES = [
|
|
113480
114047
|
"openapi.json",
|
|
113481
114048
|
"openapi.yaml",
|
|
@@ -113507,12 +114074,12 @@ function normalizePath4(p) {
|
|
|
113507
114074
|
}
|
|
113508
114075
|
function discoverSpecFile(cwd, specFileArg) {
|
|
113509
114076
|
if (specFileArg) {
|
|
113510
|
-
const resolvedPath =
|
|
113511
|
-
const normalizedCwd = cwd.endsWith(
|
|
114077
|
+
const resolvedPath = path127.resolve(cwd, specFileArg);
|
|
114078
|
+
const normalizedCwd = cwd.endsWith(path127.sep) ? cwd : cwd + path127.sep;
|
|
113512
114079
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
113513
114080
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
113514
114081
|
}
|
|
113515
|
-
const ext =
|
|
114082
|
+
const ext = path127.extname(resolvedPath).toLowerCase();
|
|
113516
114083
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
113517
114084
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
113518
114085
|
}
|
|
@@ -113526,7 +114093,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
113526
114093
|
return resolvedPath;
|
|
113527
114094
|
}
|
|
113528
114095
|
for (const candidate of SPEC_CANDIDATES) {
|
|
113529
|
-
const candidatePath =
|
|
114096
|
+
const candidatePath = path127.resolve(cwd, candidate);
|
|
113530
114097
|
if (fs95.existsSync(candidatePath)) {
|
|
113531
114098
|
const stats = fs95.statSync(candidatePath);
|
|
113532
114099
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -113538,7 +114105,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
113538
114105
|
}
|
|
113539
114106
|
function parseSpec(specFile) {
|
|
113540
114107
|
const content = fs95.readFileSync(specFile, "utf-8");
|
|
113541
|
-
const ext =
|
|
114108
|
+
const ext = path127.extname(specFile).toLowerCase();
|
|
113542
114109
|
if (ext === ".json") {
|
|
113543
114110
|
return parseJsonSpec(content);
|
|
113544
114111
|
}
|
|
@@ -113614,7 +114181,7 @@ function extractRoutes(cwd) {
|
|
|
113614
114181
|
return;
|
|
113615
114182
|
}
|
|
113616
114183
|
for (const entry of entries) {
|
|
113617
|
-
const fullPath =
|
|
114184
|
+
const fullPath = path127.join(dir, entry.name);
|
|
113618
114185
|
if (entry.isSymbolicLink()) {
|
|
113619
114186
|
continue;
|
|
113620
114187
|
}
|
|
@@ -113624,7 +114191,7 @@ function extractRoutes(cwd) {
|
|
|
113624
114191
|
}
|
|
113625
114192
|
walkDir(fullPath);
|
|
113626
114193
|
} else if (entry.isFile()) {
|
|
113627
|
-
const ext =
|
|
114194
|
+
const ext = path127.extname(entry.name).toLowerCase();
|
|
113628
114195
|
const baseName = entry.name.toLowerCase();
|
|
113629
114196
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
113630
114197
|
continue;
|
|
@@ -113792,7 +114359,7 @@ init_bun_compat();
|
|
|
113792
114359
|
init_path_security();
|
|
113793
114360
|
init_create_tool();
|
|
113794
114361
|
import * as fs96 from "node:fs";
|
|
113795
|
-
import * as
|
|
114362
|
+
import * as path128 from "node:path";
|
|
113796
114363
|
var DEFAULT_MAX_RESULTS = 100;
|
|
113797
114364
|
var DEFAULT_MAX_LINES = 200;
|
|
113798
114365
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -113828,11 +114395,11 @@ function containsWindowsAttacks3(str) {
|
|
|
113828
114395
|
}
|
|
113829
114396
|
function isPathInWorkspace3(filePath, workspace) {
|
|
113830
114397
|
try {
|
|
113831
|
-
const resolvedPath =
|
|
114398
|
+
const resolvedPath = path128.resolve(workspace, filePath);
|
|
113832
114399
|
const realWorkspace = fs96.realpathSync(workspace);
|
|
113833
114400
|
const realResolvedPath = fs96.realpathSync(resolvedPath);
|
|
113834
|
-
const relativePath =
|
|
113835
|
-
if (relativePath.startsWith("..") ||
|
|
114401
|
+
const relativePath = path128.relative(realWorkspace, realResolvedPath);
|
|
114402
|
+
if (relativePath.startsWith("..") || path128.isAbsolute(relativePath)) {
|
|
113836
114403
|
return false;
|
|
113837
114404
|
}
|
|
113838
114405
|
return true;
|
|
@@ -113845,11 +114412,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
113845
114412
|
}
|
|
113846
114413
|
function findRgInEnvPath() {
|
|
113847
114414
|
const searchPath = process.env.PATH ?? "";
|
|
113848
|
-
for (const dir of searchPath.split(
|
|
114415
|
+
for (const dir of searchPath.split(path128.delimiter)) {
|
|
113849
114416
|
if (!dir)
|
|
113850
114417
|
continue;
|
|
113851
114418
|
const isWindows = process.platform === "win32";
|
|
113852
|
-
const candidate =
|
|
114419
|
+
const candidate = path128.join(dir, isWindows ? "rg.exe" : "rg");
|
|
113853
114420
|
if (fs96.existsSync(candidate))
|
|
113854
114421
|
return candidate;
|
|
113855
114422
|
}
|
|
@@ -113979,8 +114546,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
113979
114546
|
try {
|
|
113980
114547
|
const entries = fs96.readdirSync(dir, { withFileTypes: true });
|
|
113981
114548
|
for (const entry of entries) {
|
|
113982
|
-
const fullPath =
|
|
113983
|
-
const relativePath =
|
|
114549
|
+
const fullPath = path128.join(dir, entry.name);
|
|
114550
|
+
const relativePath = path128.relative(workspace, fullPath);
|
|
113984
114551
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
113985
114552
|
continue;
|
|
113986
114553
|
}
|
|
@@ -114021,7 +114588,7 @@ async function fallbackSearch(opts) {
|
|
|
114021
114588
|
const matches = [];
|
|
114022
114589
|
let total = 0;
|
|
114023
114590
|
for (const file3 of files) {
|
|
114024
|
-
const fullPath =
|
|
114591
|
+
const fullPath = path128.join(opts.workspace, file3);
|
|
114025
114592
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
114026
114593
|
continue;
|
|
114027
114594
|
}
|
|
@@ -114389,7 +114956,7 @@ init_config();
|
|
|
114389
114956
|
init_schema();
|
|
114390
114957
|
init_create_tool();
|
|
114391
114958
|
import { mkdir as mkdir21, rename as rename9, writeFile as writeFile16 } from "node:fs/promises";
|
|
114392
|
-
import * as
|
|
114959
|
+
import * as path129 from "node:path";
|
|
114393
114960
|
var MAX_SPEC_BYTES = 256 * 1024;
|
|
114394
114961
|
var spec_write = createSwarmTool({
|
|
114395
114962
|
description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
|
|
@@ -114430,8 +114997,8 @@ var spec_write = createSwarmTool({
|
|
|
114430
114997
|
reason: 'spec must contain at least one top-level "# Heading"'
|
|
114431
114998
|
}, null, 2);
|
|
114432
114999
|
}
|
|
114433
|
-
const target =
|
|
114434
|
-
await mkdir21(
|
|
115000
|
+
const target = path129.join(directory, ".swarm", "spec.md");
|
|
115001
|
+
await mkdir21(path129.dirname(target), { recursive: true });
|
|
114435
115002
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
114436
115003
|
let finalContent = content;
|
|
114437
115004
|
if (mode === "append") {
|
|
@@ -114460,13 +115027,13 @@ init_zod();
|
|
|
114460
115027
|
init_loader();
|
|
114461
115028
|
import {
|
|
114462
115029
|
existsSync as existsSync74,
|
|
114463
|
-
mkdirSync as
|
|
115030
|
+
mkdirSync as mkdirSync33,
|
|
114464
115031
|
readFileSync as readFileSync64,
|
|
114465
115032
|
renameSync as renameSync20,
|
|
114466
115033
|
unlinkSync as unlinkSync16,
|
|
114467
115034
|
writeFileSync as writeFileSync24
|
|
114468
115035
|
} from "node:fs";
|
|
114469
|
-
import
|
|
115036
|
+
import path130 from "node:path";
|
|
114470
115037
|
init_create_tool();
|
|
114471
115038
|
init_resolve_working_directory();
|
|
114472
115039
|
var VerdictSchema2 = exports_external.object({
|
|
@@ -114596,7 +115163,7 @@ var submit_phase_council_verdicts = createSwarmTool({
|
|
|
114596
115163
|
}
|
|
114597
115164
|
});
|
|
114598
115165
|
function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
114599
|
-
const mutationGatePath =
|
|
115166
|
+
const mutationGatePath = path130.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
|
|
114600
115167
|
try {
|
|
114601
115168
|
const raw = readFileSync64(mutationGatePath, "utf-8");
|
|
114602
115169
|
const parsed = JSON.parse(raw);
|
|
@@ -114658,9 +115225,9 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
|
114658
115225
|
}
|
|
114659
115226
|
}
|
|
114660
115227
|
function writePhaseCouncilEvidence(workingDir, synthesis) {
|
|
114661
|
-
const evidenceDir =
|
|
114662
|
-
|
|
114663
|
-
const evidenceFile =
|
|
115228
|
+
const evidenceDir = path130.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
|
|
115229
|
+
mkdirSync33(evidenceDir, { recursive: true });
|
|
115230
|
+
const evidenceFile = path130.join(evidenceDir, "phase-council.json");
|
|
114664
115231
|
const evidenceBundle = {
|
|
114665
115232
|
entries: [
|
|
114666
115233
|
{
|
|
@@ -114813,16 +115380,20 @@ var swarm_memory_propose = createSwarmTool({
|
|
|
114813
115380
|
}, {
|
|
114814
115381
|
config: config3.memory
|
|
114815
115382
|
});
|
|
114816
|
-
|
|
114817
|
-
|
|
114818
|
-
|
|
114819
|
-
|
|
114820
|
-
|
|
114821
|
-
|
|
114822
|
-
|
|
114823
|
-
|
|
114824
|
-
|
|
114825
|
-
|
|
115383
|
+
try {
|
|
115384
|
+
const proposal = await gateway.propose(parsed.data);
|
|
115385
|
+
return JSON.stringify({
|
|
115386
|
+
success: proposal.status !== "rejected",
|
|
115387
|
+
proposal_id: proposal.id,
|
|
115388
|
+
status: proposal.status,
|
|
115389
|
+
operation: proposal.operation,
|
|
115390
|
+
memory_id: proposal.proposedRecord?.id,
|
|
115391
|
+
rejection_reason: proposal.rejectionReason,
|
|
115392
|
+
message: proposal.status === "pending" ? "Memory proposal created. Durable memory was not written." : "Memory proposal was captured with policy rejection metadata."
|
|
115393
|
+
}, null, 2);
|
|
115394
|
+
} finally {
|
|
115395
|
+
await gateway.dispose();
|
|
115396
|
+
}
|
|
114826
115397
|
}
|
|
114827
115398
|
});
|
|
114828
115399
|
var _internals51 = {
|
|
@@ -114886,15 +115457,23 @@ var swarm_memory_recall = createSwarmTool({
|
|
|
114886
115457
|
}, {
|
|
114887
115458
|
config: config3.memory
|
|
114888
115459
|
});
|
|
114889
|
-
|
|
114890
|
-
|
|
114891
|
-
|
|
114892
|
-
|
|
114893
|
-
|
|
114894
|
-
|
|
114895
|
-
|
|
114896
|
-
|
|
114897
|
-
|
|
115460
|
+
try {
|
|
115461
|
+
const bundle = await gateway.recall(parsed.data);
|
|
115462
|
+
return JSON.stringify({
|
|
115463
|
+
success: true,
|
|
115464
|
+
bundle_id: bundle.id,
|
|
115465
|
+
memory_ids: bundle.items.map((item) => item.record.id),
|
|
115466
|
+
total: bundle.items.length,
|
|
115467
|
+
token_estimate: bundle.tokenEstimate,
|
|
115468
|
+
signals: bundle.items.map((item) => ({
|
|
115469
|
+
memory_id: item.record.id,
|
|
115470
|
+
...item.signals
|
|
115471
|
+
})),
|
|
115472
|
+
prompt_block: bundle.promptBlock
|
|
115473
|
+
}, null, 2);
|
|
115474
|
+
} finally {
|
|
115475
|
+
await gateway.dispose();
|
|
115476
|
+
}
|
|
114898
115477
|
}
|
|
114899
115478
|
});
|
|
114900
115479
|
var RecallArgsSchema = exports_external.object({
|
|
@@ -114917,7 +115496,7 @@ init_zod();
|
|
|
114917
115496
|
init_path_security();
|
|
114918
115497
|
init_create_tool();
|
|
114919
115498
|
import * as fs97 from "node:fs";
|
|
114920
|
-
import * as
|
|
115499
|
+
import * as path131 from "node:path";
|
|
114921
115500
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
114922
115501
|
function containsWindowsAttacks4(str) {
|
|
114923
115502
|
if (/:[^\\/]/.test(str))
|
|
@@ -114931,14 +115510,14 @@ function containsWindowsAttacks4(str) {
|
|
|
114931
115510
|
}
|
|
114932
115511
|
function isPathInWorkspace4(filePath, workspace) {
|
|
114933
115512
|
try {
|
|
114934
|
-
const resolvedPath =
|
|
115513
|
+
const resolvedPath = path131.resolve(workspace, filePath);
|
|
114935
115514
|
if (!fs97.existsSync(resolvedPath)) {
|
|
114936
115515
|
return true;
|
|
114937
115516
|
}
|
|
114938
115517
|
const realWorkspace = fs97.realpathSync(workspace);
|
|
114939
115518
|
const realResolvedPath = fs97.realpathSync(resolvedPath);
|
|
114940
|
-
const relativePath =
|
|
114941
|
-
if (relativePath.startsWith("..") ||
|
|
115519
|
+
const relativePath = path131.relative(realWorkspace, realResolvedPath);
|
|
115520
|
+
if (relativePath.startsWith("..") || path131.isAbsolute(relativePath)) {
|
|
114942
115521
|
return false;
|
|
114943
115522
|
}
|
|
114944
115523
|
return true;
|
|
@@ -115146,7 +115725,7 @@ var suggestPatch = createSwarmTool({
|
|
|
115146
115725
|
});
|
|
115147
115726
|
continue;
|
|
115148
115727
|
}
|
|
115149
|
-
const fullPath =
|
|
115728
|
+
const fullPath = path131.resolve(directory, change.file);
|
|
115150
115729
|
if (!fs97.existsSync(fullPath)) {
|
|
115151
115730
|
errors5.push({
|
|
115152
115731
|
success: false,
|
|
@@ -115450,11 +116029,11 @@ var lean_turbo_acquire_locks = createSwarmTool({
|
|
|
115450
116029
|
init_zod();
|
|
115451
116030
|
init_constants();
|
|
115452
116031
|
import * as fs99 from "node:fs";
|
|
115453
|
-
import * as
|
|
116032
|
+
import * as path133 from "node:path";
|
|
115454
116033
|
|
|
115455
116034
|
// src/turbo/lean/conflicts.ts
|
|
115456
116035
|
import * as fs98 from "node:fs";
|
|
115457
|
-
import * as
|
|
116036
|
+
import * as path132 from "node:path";
|
|
115458
116037
|
var DEFAULT_GLOBAL_FILES = [
|
|
115459
116038
|
"package.json",
|
|
115460
116039
|
"package-lock.json",
|
|
@@ -115581,7 +116160,7 @@ function isProtectedPath2(normalizedPath) {
|
|
|
115581
116160
|
return false;
|
|
115582
116161
|
}
|
|
115583
116162
|
function readTaskScopes(directory, taskId) {
|
|
115584
|
-
const scopePath =
|
|
116163
|
+
const scopePath = path132.join(directory, ".swarm", "scopes", `scope-${taskId}.json`);
|
|
115585
116164
|
try {
|
|
115586
116165
|
if (!fs98.existsSync(scopePath)) {
|
|
115587
116166
|
return null;
|
|
@@ -115969,7 +116548,7 @@ function createEmptyPlan(phaseNumber, planId) {
|
|
|
115969
116548
|
// src/tools/lean-turbo-plan-lanes.ts
|
|
115970
116549
|
init_create_tool();
|
|
115971
116550
|
function readPlanJson(directory) {
|
|
115972
|
-
const planPath =
|
|
116551
|
+
const planPath = path133.join(directory, ".swarm", "plan.json");
|
|
115973
116552
|
if (!fs99.existsSync(planPath)) {
|
|
115974
116553
|
return null;
|
|
115975
116554
|
}
|
|
@@ -116024,7 +116603,7 @@ init_config();
|
|
|
116024
116603
|
// src/turbo/lean/reviewer.ts
|
|
116025
116604
|
init_state();
|
|
116026
116605
|
import * as fs100 from "node:fs/promises";
|
|
116027
|
-
import * as
|
|
116606
|
+
import * as path134 from "node:path";
|
|
116028
116607
|
init_state3();
|
|
116029
116608
|
var DEFAULT_CONFIG3 = {
|
|
116030
116609
|
reviewerAgent: "",
|
|
@@ -116140,9 +116719,9 @@ function parseReviewerVerdict(responseText) {
|
|
|
116140
116719
|
return { verdict, reason };
|
|
116141
116720
|
}
|
|
116142
116721
|
async function writeReviewerEvidence(directory, phase, verdict, reason) {
|
|
116143
|
-
const evidenceDir =
|
|
116722
|
+
const evidenceDir = path134.join(directory, ".swarm", "evidence", String(phase));
|
|
116144
116723
|
await fs100.mkdir(evidenceDir, { recursive: true });
|
|
116145
|
-
const evidencePath =
|
|
116724
|
+
const evidencePath = path134.join(evidenceDir, "lean-turbo-reviewer.json");
|
|
116146
116725
|
const content = JSON.stringify({
|
|
116147
116726
|
phase,
|
|
116148
116727
|
verdict,
|
|
@@ -116947,7 +117526,7 @@ var lean_turbo_status = createSwarmTool({
|
|
|
116947
117526
|
init_spec_schema();
|
|
116948
117527
|
init_create_tool();
|
|
116949
117528
|
import * as fs101 from "node:fs";
|
|
116950
|
-
import * as
|
|
117529
|
+
import * as path135 from "node:path";
|
|
116951
117530
|
var SPEC_FILE_NAME = "spec.md";
|
|
116952
117531
|
var SWARM_DIR2 = ".swarm";
|
|
116953
117532
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -117000,7 +117579,7 @@ var lint_spec = createSwarmTool({
|
|
|
117000
117579
|
async execute(_args, directory) {
|
|
117001
117580
|
const errors5 = [];
|
|
117002
117581
|
const warnings = [];
|
|
117003
|
-
const specPath =
|
|
117582
|
+
const specPath = path135.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
117004
117583
|
if (!fs101.existsSync(specPath)) {
|
|
117005
117584
|
const result2 = {
|
|
117006
117585
|
valid: false,
|
|
@@ -117071,12 +117650,12 @@ var lint_spec = createSwarmTool({
|
|
|
117071
117650
|
// src/tools/mutation-test.ts
|
|
117072
117651
|
init_zod();
|
|
117073
117652
|
import * as fs102 from "node:fs";
|
|
117074
|
-
import * as
|
|
117653
|
+
import * as path137 from "node:path";
|
|
117075
117654
|
|
|
117076
117655
|
// src/mutation/engine.ts
|
|
117077
117656
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
117078
117657
|
import { unlinkSync as unlinkSync17, writeFileSync as writeFileSync25 } from "node:fs";
|
|
117079
|
-
import * as
|
|
117658
|
+
import * as path136 from "node:path";
|
|
117080
117659
|
|
|
117081
117660
|
// src/mutation/equivalence.ts
|
|
117082
117661
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -117222,7 +117801,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
117222
117801
|
let patchFile;
|
|
117223
117802
|
try {
|
|
117224
117803
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
117225
|
-
patchFile =
|
|
117804
|
+
patchFile = path136.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
117226
117805
|
try {
|
|
117227
117806
|
writeFileSync25(patchFile, patch.patch);
|
|
117228
117807
|
} catch (writeErr) {
|
|
@@ -117626,7 +118205,7 @@ var mutation_test = createSwarmTool({
|
|
|
117626
118205
|
];
|
|
117627
118206
|
for (const filePath of uniquePaths) {
|
|
117628
118207
|
try {
|
|
117629
|
-
const resolvedPath =
|
|
118208
|
+
const resolvedPath = path137.resolve(cwd, filePath);
|
|
117630
118209
|
sourceFiles.set(filePath, fs102.readFileSync(resolvedPath, "utf-8"));
|
|
117631
118210
|
} catch {}
|
|
117632
118211
|
}
|
|
@@ -117646,7 +118225,7 @@ init_zod();
|
|
|
117646
118225
|
init_manager2();
|
|
117647
118226
|
init_detector();
|
|
117648
118227
|
import * as fs103 from "node:fs";
|
|
117649
|
-
import * as
|
|
118228
|
+
import * as path138 from "node:path";
|
|
117650
118229
|
init_create_tool();
|
|
117651
118230
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
117652
118231
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -117712,7 +118291,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
117712
118291
|
if (languages?.length) {
|
|
117713
118292
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
117714
118293
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
117715
|
-
const ext =
|
|
118294
|
+
const ext = path138.extname(file3.path).toLowerCase();
|
|
117716
118295
|
const langDef = getLanguageForExtension(ext);
|
|
117717
118296
|
const fileProfile = getProfileForFile(file3.path);
|
|
117718
118297
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -117725,7 +118304,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
117725
118304
|
let skippedCount = 0;
|
|
117726
118305
|
for (const fileInfo of filesToCheck) {
|
|
117727
118306
|
const { path: filePath } = fileInfo;
|
|
117728
|
-
const fullPath =
|
|
118307
|
+
const fullPath = path138.isAbsolute(filePath) ? filePath : path138.join(directory, filePath);
|
|
117729
118308
|
const result = {
|
|
117730
118309
|
path: filePath,
|
|
117731
118310
|
language: "",
|
|
@@ -117774,7 +118353,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
117774
118353
|
results.push(result);
|
|
117775
118354
|
continue;
|
|
117776
118355
|
}
|
|
117777
|
-
const ext =
|
|
118356
|
+
const ext = path138.extname(filePath).toLowerCase();
|
|
117778
118357
|
const langDef = getLanguageForExtension(ext);
|
|
117779
118358
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
117780
118359
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -117872,7 +118451,7 @@ init_utils();
|
|
|
117872
118451
|
init_create_tool();
|
|
117873
118452
|
init_path_security();
|
|
117874
118453
|
import * as fs104 from "node:fs";
|
|
117875
|
-
import * as
|
|
118454
|
+
import * as path139 from "node:path";
|
|
117876
118455
|
var MAX_TEXT_LENGTH = 200;
|
|
117877
118456
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
117878
118457
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -117938,9 +118517,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
117938
118517
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
117939
118518
|
}
|
|
117940
118519
|
try {
|
|
117941
|
-
const resolvedPath =
|
|
117942
|
-
const normalizedCwd =
|
|
117943
|
-
const normalizedResolved =
|
|
118520
|
+
const resolvedPath = path139.resolve(paths);
|
|
118521
|
+
const normalizedCwd = path139.resolve(cwd);
|
|
118522
|
+
const normalizedResolved = path139.resolve(resolvedPath);
|
|
117944
118523
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
117945
118524
|
return {
|
|
117946
118525
|
error: "paths must be within the current working directory",
|
|
@@ -117956,7 +118535,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
117956
118535
|
}
|
|
117957
118536
|
}
|
|
117958
118537
|
function isSupportedExtension(filePath) {
|
|
117959
|
-
const ext =
|
|
118538
|
+
const ext = path139.extname(filePath).toLowerCase();
|
|
117960
118539
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
117961
118540
|
}
|
|
117962
118541
|
function findSourceFiles3(dir, files = []) {
|
|
@@ -117971,7 +118550,7 @@ function findSourceFiles3(dir, files = []) {
|
|
|
117971
118550
|
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
117972
118551
|
continue;
|
|
117973
118552
|
}
|
|
117974
|
-
const fullPath =
|
|
118553
|
+
const fullPath = path139.join(dir, entry);
|
|
117975
118554
|
let stat8;
|
|
117976
118555
|
try {
|
|
117977
118556
|
stat8 = fs104.statSync(fullPath);
|
|
@@ -118083,7 +118662,7 @@ var todo_extract = createSwarmTool({
|
|
|
118083
118662
|
filesToScan.push(scanPath);
|
|
118084
118663
|
} else {
|
|
118085
118664
|
const errorResult = {
|
|
118086
|
-
error: `unsupported file extension: ${
|
|
118665
|
+
error: `unsupported file extension: ${path139.extname(scanPath)}`,
|
|
118087
118666
|
total: 0,
|
|
118088
118667
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
118089
118668
|
entries: []
|
|
@@ -118132,17 +118711,17 @@ init_schema();
|
|
|
118132
118711
|
init_qa_gate_profile();
|
|
118133
118712
|
init_gate_evidence();
|
|
118134
118713
|
import * as fs108 from "node:fs";
|
|
118135
|
-
import * as
|
|
118714
|
+
import * as path143 from "node:path";
|
|
118136
118715
|
|
|
118137
118716
|
// src/hooks/diff-scope.ts
|
|
118138
118717
|
init_bun_compat();
|
|
118139
118718
|
import * as fs106 from "node:fs";
|
|
118140
|
-
import * as
|
|
118719
|
+
import * as path141 from "node:path";
|
|
118141
118720
|
|
|
118142
118721
|
// src/utils/gitignore-warning.ts
|
|
118143
118722
|
init_bun_compat();
|
|
118144
118723
|
import * as fs105 from "node:fs";
|
|
118145
|
-
import * as
|
|
118724
|
+
import * as path140 from "node:path";
|
|
118146
118725
|
var _internals58 = { bunSpawn };
|
|
118147
118726
|
var _swarmGitExcludedChecked = false;
|
|
118148
118727
|
function fileCoversSwarm(content) {
|
|
@@ -118216,10 +118795,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
118216
118795
|
const excludeRelPath = excludePathRaw.trim();
|
|
118217
118796
|
if (!excludeRelPath)
|
|
118218
118797
|
return;
|
|
118219
|
-
const excludePath =
|
|
118798
|
+
const excludePath = path140.isAbsolute(excludeRelPath) ? excludeRelPath : path140.join(directory, excludeRelPath);
|
|
118220
118799
|
if (checkIgnoreExitCode !== 0) {
|
|
118221
118800
|
try {
|
|
118222
|
-
fs105.mkdirSync(
|
|
118801
|
+
fs105.mkdirSync(path140.dirname(excludePath), { recursive: true });
|
|
118223
118802
|
let existing = "";
|
|
118224
118803
|
try {
|
|
118225
118804
|
existing = fs105.readFileSync(excludePath, "utf8");
|
|
@@ -118263,7 +118842,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
118263
118842
|
var _internals59 = { bunSpawn };
|
|
118264
118843
|
function getDeclaredScope(taskId, directory) {
|
|
118265
118844
|
try {
|
|
118266
|
-
const planPath =
|
|
118845
|
+
const planPath = path141.join(directory, ".swarm", "plan.json");
|
|
118267
118846
|
if (!fs106.existsSync(planPath))
|
|
118268
118847
|
return null;
|
|
118269
118848
|
const raw = fs106.readFileSync(planPath, "utf-8");
|
|
@@ -118369,7 +118948,7 @@ init_telemetry();
|
|
|
118369
118948
|
// src/turbo/lean/task-completion.ts
|
|
118370
118949
|
init_file_locks();
|
|
118371
118950
|
import * as fs107 from "node:fs";
|
|
118372
|
-
import * as
|
|
118951
|
+
import * as path142 from "node:path";
|
|
118373
118952
|
var _internals60 = {
|
|
118374
118953
|
listActiveLocks,
|
|
118375
118954
|
verifyLeanTurboTaskCompletion
|
|
@@ -118388,7 +118967,7 @@ var TIER_3_PATTERNS = [
|
|
|
118388
118967
|
];
|
|
118389
118968
|
function matchesTier3Pattern(files) {
|
|
118390
118969
|
for (const file3 of files) {
|
|
118391
|
-
const fileName =
|
|
118970
|
+
const fileName = path142.basename(file3);
|
|
118392
118971
|
for (const pattern of TIER_3_PATTERNS) {
|
|
118393
118972
|
if (pattern.test(fileName)) {
|
|
118394
118973
|
return true;
|
|
@@ -118400,7 +118979,7 @@ function matchesTier3Pattern(files) {
|
|
|
118400
118979
|
function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
118401
118980
|
let persisted = null;
|
|
118402
118981
|
try {
|
|
118403
|
-
const statePath =
|
|
118982
|
+
const statePath = path142.join(directory, ".swarm", "turbo-state.json");
|
|
118404
118983
|
if (!fs107.existsSync(statePath)) {
|
|
118405
118984
|
return {
|
|
118406
118985
|
ok: false,
|
|
@@ -118484,11 +119063,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
118484
119063
|
};
|
|
118485
119064
|
}
|
|
118486
119065
|
const phase = runState.phase ?? 0;
|
|
118487
|
-
const evidencePath =
|
|
118488
|
-
const expectedDir =
|
|
118489
|
-
const resolvedPath =
|
|
118490
|
-
const resolvedDir =
|
|
118491
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
119066
|
+
const evidencePath = path142.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
|
|
119067
|
+
const expectedDir = path142.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
119068
|
+
const resolvedPath = path142.resolve(evidencePath);
|
|
119069
|
+
const resolvedDir = path142.resolve(expectedDir);
|
|
119070
|
+
if (!resolvedPath.startsWith(resolvedDir + path142.sep) && resolvedPath !== resolvedDir) {
|
|
118492
119071
|
return {
|
|
118493
119072
|
ok: false,
|
|
118494
119073
|
reason: `Lane ID causes path traversal: ${lane.laneId}`,
|
|
@@ -118528,7 +119107,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
118528
119107
|
}
|
|
118529
119108
|
let filesTouched = [];
|
|
118530
119109
|
try {
|
|
118531
|
-
const planPath =
|
|
119110
|
+
const planPath = path142.join(directory, ".swarm", "plan.json");
|
|
118532
119111
|
const planRaw = fs107.readFileSync(planPath, "utf-8");
|
|
118533
119112
|
const plan = JSON.parse(planRaw);
|
|
118534
119113
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -118612,7 +119191,7 @@ var TIER_3_PATTERNS2 = [
|
|
|
118612
119191
|
];
|
|
118613
119192
|
function matchesTier3Pattern2(files) {
|
|
118614
119193
|
for (const file3 of files) {
|
|
118615
|
-
const fileName =
|
|
119194
|
+
const fileName = path143.basename(file3);
|
|
118616
119195
|
for (const pattern of TIER_3_PATTERNS2) {
|
|
118617
119196
|
if (pattern.test(fileName)) {
|
|
118618
119197
|
return true;
|
|
@@ -118651,7 +119230,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
118651
119230
|
if (!skipStandardTurboBypass && hasActiveTurboMode()) {
|
|
118652
119231
|
const resolvedDir2 = workingDirectory;
|
|
118653
119232
|
try {
|
|
118654
|
-
const planPath =
|
|
119233
|
+
const planPath = path143.join(resolvedDir2, ".swarm", "plan.json");
|
|
118655
119234
|
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
118656
119235
|
const plan = JSON.parse(planRaw);
|
|
118657
119236
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -118729,7 +119308,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
118729
119308
|
}
|
|
118730
119309
|
if (resolvedDir) {
|
|
118731
119310
|
try {
|
|
118732
|
-
const planPath =
|
|
119311
|
+
const planPath = path143.join(resolvedDir, ".swarm", "plan.json");
|
|
118733
119312
|
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
118734
119313
|
const plan = JSON.parse(planRaw);
|
|
118735
119314
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -118966,8 +119545,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
118966
119545
|
};
|
|
118967
119546
|
}
|
|
118968
119547
|
}
|
|
118969
|
-
normalizedDir =
|
|
118970
|
-
const pathParts = normalizedDir.split(
|
|
119548
|
+
normalizedDir = path143.normalize(args2.working_directory);
|
|
119549
|
+
const pathParts = normalizedDir.split(path143.sep);
|
|
118971
119550
|
if (pathParts.includes("..")) {
|
|
118972
119551
|
return {
|
|
118973
119552
|
success: false,
|
|
@@ -118977,10 +119556,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
118977
119556
|
]
|
|
118978
119557
|
};
|
|
118979
119558
|
}
|
|
118980
|
-
const resolvedDir =
|
|
119559
|
+
const resolvedDir = path143.resolve(normalizedDir);
|
|
118981
119560
|
try {
|
|
118982
119561
|
const realPath = fs108.realpathSync(resolvedDir);
|
|
118983
|
-
const planPath =
|
|
119562
|
+
const planPath = path143.join(realPath, ".swarm", "plan.json");
|
|
118984
119563
|
if (!fs108.existsSync(planPath)) {
|
|
118985
119564
|
return {
|
|
118986
119565
|
success: false,
|
|
@@ -119011,9 +119590,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
119011
119590
|
directory = fallbackDir;
|
|
119012
119591
|
}
|
|
119013
119592
|
if (fallbackDir && directory !== fallbackDir) {
|
|
119014
|
-
const canonicalDir = fs108.realpathSync(
|
|
119015
|
-
const canonicalRoot = fs108.realpathSync(
|
|
119016
|
-
if (canonicalDir.startsWith(canonicalRoot +
|
|
119593
|
+
const canonicalDir = fs108.realpathSync(path143.resolve(directory));
|
|
119594
|
+
const canonicalRoot = fs108.realpathSync(path143.resolve(fallbackDir));
|
|
119595
|
+
if (canonicalDir.startsWith(canonicalRoot + path143.sep)) {
|
|
119017
119596
|
return {
|
|
119018
119597
|
success: false,
|
|
119019
119598
|
message: `Invalid working_directory: "${directory}" is a subdirectory of ` + `the project root "${fallbackDir}". Pass the project root path or ` + `omit working_directory entirely.`,
|
|
@@ -119025,8 +119604,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
119025
119604
|
}
|
|
119026
119605
|
if (args2.status === "in_progress") {
|
|
119027
119606
|
try {
|
|
119028
|
-
const evidencePath =
|
|
119029
|
-
fs108.mkdirSync(
|
|
119607
|
+
const evidencePath = path143.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
119608
|
+
fs108.mkdirSync(path143.dirname(evidencePath), { recursive: true });
|
|
119030
119609
|
const fd = fs108.openSync(evidencePath, "wx");
|
|
119031
119610
|
let writeOk = false;
|
|
119032
119611
|
try {
|
|
@@ -119050,7 +119629,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
119050
119629
|
recoverTaskStateFromDelegations(args2.task_id, directory);
|
|
119051
119630
|
let phaseRequiresReviewer = true;
|
|
119052
119631
|
try {
|
|
119053
|
-
const planPath =
|
|
119632
|
+
const planPath = path143.join(directory, ".swarm", "plan.json");
|
|
119054
119633
|
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
119055
119634
|
const plan = JSON.parse(planRaw);
|
|
119056
119635
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -119362,7 +119941,7 @@ init_ledger();
|
|
|
119362
119941
|
init_manager();
|
|
119363
119942
|
init_create_tool();
|
|
119364
119943
|
import fs109 from "node:fs";
|
|
119365
|
-
import
|
|
119944
|
+
import path144 from "node:path";
|
|
119366
119945
|
function normalizeVerdict(verdict) {
|
|
119367
119946
|
switch (verdict) {
|
|
119368
119947
|
case "APPROVED":
|
|
@@ -119410,7 +119989,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
119410
119989
|
entries: [evidenceEntry]
|
|
119411
119990
|
};
|
|
119412
119991
|
const filename = "drift-verifier.json";
|
|
119413
|
-
const relativePath =
|
|
119992
|
+
const relativePath = path144.join("evidence", String(phase), filename);
|
|
119414
119993
|
let validatedPath;
|
|
119415
119994
|
try {
|
|
119416
119995
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -119421,10 +120000,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
119421
120000
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
119422
120001
|
}, null, 2);
|
|
119423
120002
|
}
|
|
119424
|
-
const evidenceDir =
|
|
120003
|
+
const evidenceDir = path144.dirname(validatedPath);
|
|
119425
120004
|
try {
|
|
119426
120005
|
await fs109.promises.mkdir(evidenceDir, { recursive: true });
|
|
119427
|
-
const tempPath =
|
|
120006
|
+
const tempPath = path144.join(evidenceDir, `.${filename}.tmp`);
|
|
119428
120007
|
await fs109.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
119429
120008
|
await fs109.promises.rename(tempPath, validatedPath);
|
|
119430
120009
|
let snapshotInfo;
|
|
@@ -119520,7 +120099,7 @@ var write_drift_evidence = createSwarmTool({
|
|
|
119520
120099
|
init_zod();
|
|
119521
120100
|
init_loader();
|
|
119522
120101
|
import fs110 from "node:fs";
|
|
119523
|
-
import
|
|
120102
|
+
import path145 from "node:path";
|
|
119524
120103
|
init_utils2();
|
|
119525
120104
|
init_manager();
|
|
119526
120105
|
init_create_tool();
|
|
@@ -119608,7 +120187,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
119608
120187
|
timestamp: synthesis.timestamp
|
|
119609
120188
|
};
|
|
119610
120189
|
const filename = "final-council.json";
|
|
119611
|
-
const relativePath =
|
|
120190
|
+
const relativePath = path145.join("evidence", filename);
|
|
119612
120191
|
let validatedPath;
|
|
119613
120192
|
try {
|
|
119614
120193
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -119622,10 +120201,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
119622
120201
|
const evidenceContent = {
|
|
119623
120202
|
entries: [evidenceEntry]
|
|
119624
120203
|
};
|
|
119625
|
-
const evidenceDir =
|
|
120204
|
+
const evidenceDir = path145.dirname(validatedPath);
|
|
119626
120205
|
try {
|
|
119627
120206
|
await fs110.promises.mkdir(evidenceDir, { recursive: true });
|
|
119628
|
-
const tempPath =
|
|
120207
|
+
const tempPath = path145.join(evidenceDir, `.${filename}.tmp`);
|
|
119629
120208
|
await fs110.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
119630
120209
|
await fs110.promises.rename(tempPath, validatedPath);
|
|
119631
120210
|
return JSON.stringify({
|
|
@@ -119684,7 +120263,7 @@ init_zod();
|
|
|
119684
120263
|
init_utils2();
|
|
119685
120264
|
init_create_tool();
|
|
119686
120265
|
import fs111 from "node:fs";
|
|
119687
|
-
import
|
|
120266
|
+
import path146 from "node:path";
|
|
119688
120267
|
function normalizeVerdict2(verdict) {
|
|
119689
120268
|
switch (verdict) {
|
|
119690
120269
|
case "APPROVED":
|
|
@@ -119732,7 +120311,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
119732
120311
|
entries: [evidenceEntry]
|
|
119733
120312
|
};
|
|
119734
120313
|
const filename = "hallucination-guard.json";
|
|
119735
|
-
const relativePath =
|
|
120314
|
+
const relativePath = path146.join("evidence", String(phase), filename);
|
|
119736
120315
|
let validatedPath;
|
|
119737
120316
|
try {
|
|
119738
120317
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -119743,10 +120322,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
119743
120322
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
119744
120323
|
}, null, 2);
|
|
119745
120324
|
}
|
|
119746
|
-
const evidenceDir =
|
|
120325
|
+
const evidenceDir = path146.dirname(validatedPath);
|
|
119747
120326
|
try {
|
|
119748
120327
|
await fs111.promises.mkdir(evidenceDir, { recursive: true });
|
|
119749
|
-
const tempPath =
|
|
120328
|
+
const tempPath = path146.join(evidenceDir, `.${filename}.tmp`);
|
|
119750
120329
|
await fs111.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
119751
120330
|
await fs111.promises.rename(tempPath, validatedPath);
|
|
119752
120331
|
return JSON.stringify({
|
|
@@ -119795,7 +120374,7 @@ init_zod();
|
|
|
119795
120374
|
init_utils2();
|
|
119796
120375
|
init_create_tool();
|
|
119797
120376
|
import fs112 from "node:fs";
|
|
119798
|
-
import
|
|
120377
|
+
import path147 from "node:path";
|
|
119799
120378
|
function normalizeVerdict3(verdict) {
|
|
119800
120379
|
switch (verdict) {
|
|
119801
120380
|
case "PASS":
|
|
@@ -119869,7 +120448,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
119869
120448
|
entries: [evidenceEntry]
|
|
119870
120449
|
};
|
|
119871
120450
|
const filename = "mutation-gate.json";
|
|
119872
|
-
const relativePath =
|
|
120451
|
+
const relativePath = path147.join("evidence", String(phase), filename);
|
|
119873
120452
|
let validatedPath;
|
|
119874
120453
|
try {
|
|
119875
120454
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -119880,10 +120459,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
119880
120459
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
119881
120460
|
}, null, 2);
|
|
119882
120461
|
}
|
|
119883
|
-
const evidenceDir =
|
|
120462
|
+
const evidenceDir = path147.dirname(validatedPath);
|
|
119884
120463
|
try {
|
|
119885
120464
|
await fs112.promises.mkdir(evidenceDir, { recursive: true });
|
|
119886
|
-
const tempPath =
|
|
120465
|
+
const tempPath = path147.join(evidenceDir, `.${filename}.tmp`);
|
|
119887
120466
|
await fs112.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
119888
120467
|
await fs112.promises.rename(tempPath, validatedPath);
|
|
119889
120468
|
return JSON.stringify({
|
|
@@ -120233,7 +120812,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
120233
120812
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
120234
120813
|
preflightTriggerManager = new PTM(automationConfig);
|
|
120235
120814
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
120236
|
-
const swarmDir =
|
|
120815
|
+
const swarmDir = path149.resolve(ctx.directory, ".swarm");
|
|
120237
120816
|
statusArtifact = new ASA(swarmDir);
|
|
120238
120817
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
120239
120818
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|
|
@@ -120412,30 +120991,29 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
120412
120991
|
swarm_command: createSwarmCommandTool(agentDefinitionMap)
|
|
120413
120992
|
},
|
|
120414
120993
|
config: async (opencodeConfig) => {
|
|
120415
|
-
|
|
120416
|
-
|
|
120417
|
-
|
|
120418
|
-
|
|
120419
|
-
opencodeConfig.agent = { ...agents };
|
|
120420
|
-
} else {
|
|
120421
|
-
Object.assign(opencodeConfig.agent, agents);
|
|
120994
|
+
const isObjectRecord = (value) => typeof value === "object" && value !== null;
|
|
120995
|
+
const pluginConfig = opencodeConfig;
|
|
120996
|
+
if (!isObjectRecord(pluginConfig.agent)) {
|
|
120997
|
+
pluginConfig.agent = {};
|
|
120422
120998
|
}
|
|
120999
|
+
const agentConfig = pluginConfig.agent;
|
|
121000
|
+
Object.assign(agentConfig, agents);
|
|
120423
121001
|
const autoSelect = config3?.auto_select_architect;
|
|
120424
121002
|
if (autoSelect) {
|
|
120425
121003
|
const hasArchitect = Object.keys(agents).some((name2) => stripKnownSwarmPrefix(name2) === "architect");
|
|
120426
121004
|
if (hasArchitect) {
|
|
120427
121005
|
for (const builtin of ["build", "plan"]) {
|
|
120428
|
-
const existing =
|
|
120429
|
-
if (existing &&
|
|
121006
|
+
const existing = agentConfig[builtin];
|
|
121007
|
+
if (isObjectRecord(existing) && existing.disable === true) {
|
|
120430
121008
|
continue;
|
|
120431
121009
|
}
|
|
120432
|
-
|
|
120433
|
-
...existing
|
|
121010
|
+
agentConfig[builtin] = {
|
|
121011
|
+
...isObjectRecord(existing) ? existing : {},
|
|
120434
121012
|
disable: true
|
|
120435
121013
|
};
|
|
120436
121014
|
}
|
|
120437
121015
|
if (autoSelect === true) {
|
|
120438
|
-
const primaryArchitects = Object.entries(agents).filter(([name2, cfg]) => stripKnownSwarmPrefix(name2) === "architect" && cfg.mode === "primary");
|
|
121016
|
+
const primaryArchitects = Object.entries(agents).filter(([name2, cfg]) => stripKnownSwarmPrefix(name2) === "architect" && isObjectRecord(cfg) && cfg.mode === "primary");
|
|
120439
121017
|
if (primaryArchitects.length > 1) {
|
|
120440
121018
|
const names = primaryArchitects.map(([n]) => n).join(", ");
|
|
120441
121019
|
addDeferredWarning(`[swarm] auto_select_architect is true but ${primaryArchitects.length} architect agents are primary (${names}). Consider setting auto_select_architect to a specific agent name.`);
|
|
@@ -120447,22 +121025,19 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
120447
121025
|
if (targetIsArchitect) {
|
|
120448
121026
|
for (const [name2, cfg] of Object.entries(agents)) {
|
|
120449
121027
|
if (stripKnownSwarmPrefix(name2) === "architect" && name2 !== targetName) {
|
|
120450
|
-
|
|
120451
|
-
|
|
120452
|
-
|
|
120453
|
-
|
|
120454
|
-
};
|
|
120455
|
-
}
|
|
121028
|
+
agentConfig[name2] = {
|
|
121029
|
+
...isObjectRecord(cfg) ? cfg : {},
|
|
121030
|
+
mode: "subagent"
|
|
121031
|
+
};
|
|
120456
121032
|
}
|
|
120457
121033
|
}
|
|
120458
|
-
|
|
120459
|
-
|
|
120460
|
-
|
|
120461
|
-
|
|
120462
|
-
|
|
120463
|
-
|
|
120464
|
-
|
|
120465
|
-
}
|
|
121034
|
+
const targetExisting = agentConfig[targetName];
|
|
121035
|
+
const targetAgent = agents[targetName];
|
|
121036
|
+
agentConfig[targetName] = {
|
|
121037
|
+
...isObjectRecord(targetExisting) ? targetExisting : {},
|
|
121038
|
+
...isObjectRecord(targetAgent) ? targetAgent : {},
|
|
121039
|
+
mode: "primary"
|
|
121040
|
+
};
|
|
120466
121041
|
} else {
|
|
120467
121042
|
addDeferredWarning(`[swarm] auto_select_architect is set to "${targetName}" but that is not a known architect agent. No architect demotion applied.`);
|
|
120468
121043
|
}
|
|
@@ -120817,7 +121392,7 @@ ${promptRaw}`;
|
|
|
120817
121392
|
"ci-failure-resolver": "CI/CD failure resolution"
|
|
120818
121393
|
};
|
|
120819
121394
|
const skillPaths = topSkills.map((s) => {
|
|
120820
|
-
const dirName =
|
|
121395
|
+
const dirName = path149.basename(path149.dirname(s.skillPath));
|
|
120821
121396
|
const desc = SKILL_DESCRIPTIONS[dirName] ?? dirName;
|
|
120822
121397
|
return `file:${s.skillPath} (-- ${desc})`;
|
|
120823
121398
|
}).join(", ");
|
|
@@ -120826,7 +121401,7 @@ ${promptRaw}`;
|
|
|
120826
121401
|
|
|
120827
121402
|
${promptRaw}`;
|
|
120828
121403
|
argsRecord.prompt = newPrompt;
|
|
120829
|
-
const skillNames = topSkills.map((s) => `${
|
|
121404
|
+
const skillNames = topSkills.map((s) => `${path149.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
|
|
120830
121405
|
console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
|
|
120831
121406
|
for (const skill of topSkills) {
|
|
120832
121407
|
try {
|