opencode-swarm 7.1.1 → 7.2.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 +1 -1
- package/dist/config/project-init.d.ts +15 -0
- package/dist/index.js +800 -762
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var package_default;
|
|
|
33
33
|
var init_package = __esm(() => {
|
|
34
34
|
package_default = {
|
|
35
35
|
name: "opencode-swarm",
|
|
36
|
-
version: "7.
|
|
36
|
+
version: "7.2.0",
|
|
37
37
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
38
38
|
main: "dist/index.js",
|
|
39
39
|
types: "dist/index.d.ts",
|
|
@@ -60207,13 +60207,13 @@ __export(exports_review_receipt, {
|
|
|
60207
60207
|
buildApprovedReceipt: () => buildApprovedReceipt
|
|
60208
60208
|
});
|
|
60209
60209
|
import * as crypto5 from "node:crypto";
|
|
60210
|
-
import * as
|
|
60211
|
-
import * as
|
|
60210
|
+
import * as fs35 from "node:fs";
|
|
60211
|
+
import * as path49 from "node:path";
|
|
60212
60212
|
function resolveReceiptsDir(directory) {
|
|
60213
|
-
return
|
|
60213
|
+
return path49.join(directory, ".swarm", "review-receipts");
|
|
60214
60214
|
}
|
|
60215
60215
|
function resolveReceiptIndexPath(directory) {
|
|
60216
|
-
return
|
|
60216
|
+
return path49.join(resolveReceiptsDir(directory), "index.json");
|
|
60217
60217
|
}
|
|
60218
60218
|
function buildReceiptFilename(id, date9) {
|
|
60219
60219
|
const dateStr = date9.toISOString().slice(0, 10);
|
|
@@ -60236,11 +60236,11 @@ function isScopeStale(receipt, currentContent) {
|
|
|
60236
60236
|
}
|
|
60237
60237
|
async function readReceiptIndex(directory) {
|
|
60238
60238
|
const indexPath = resolveReceiptIndexPath(directory);
|
|
60239
|
-
if (!
|
|
60239
|
+
if (!fs35.existsSync(indexPath)) {
|
|
60240
60240
|
return { schema_version: 1, entries: [] };
|
|
60241
60241
|
}
|
|
60242
60242
|
try {
|
|
60243
|
-
const content = await
|
|
60243
|
+
const content = await fs35.promises.readFile(indexPath, "utf-8");
|
|
60244
60244
|
const parsed = JSON.parse(content);
|
|
60245
60245
|
if (parsed.schema_version !== 1 || !Array.isArray(parsed.entries)) {
|
|
60246
60246
|
return { schema_version: 1, entries: [] };
|
|
@@ -60252,21 +60252,21 @@ async function readReceiptIndex(directory) {
|
|
|
60252
60252
|
}
|
|
60253
60253
|
async function writeReceiptIndex(directory, index) {
|
|
60254
60254
|
const indexPath = resolveReceiptIndexPath(directory);
|
|
60255
|
-
const dir =
|
|
60256
|
-
await
|
|
60255
|
+
const dir = path49.dirname(indexPath);
|
|
60256
|
+
await fs35.promises.mkdir(dir, { recursive: true });
|
|
60257
60257
|
const tmpPath = `${indexPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
60258
|
-
await
|
|
60259
|
-
|
|
60258
|
+
await fs35.promises.writeFile(tmpPath, JSON.stringify(index, null, 2), "utf-8");
|
|
60259
|
+
fs35.renameSync(tmpPath, indexPath);
|
|
60260
60260
|
}
|
|
60261
60261
|
async function persistReviewReceipt(directory, receipt) {
|
|
60262
60262
|
const receiptsDir = resolveReceiptsDir(directory);
|
|
60263
|
-
await
|
|
60263
|
+
await fs35.promises.mkdir(receiptsDir, { recursive: true });
|
|
60264
60264
|
const now = new Date(receipt.reviewed_at);
|
|
60265
60265
|
const filename = buildReceiptFilename(receipt.id, now);
|
|
60266
|
-
const receiptPath =
|
|
60266
|
+
const receiptPath = path49.join(receiptsDir, filename);
|
|
60267
60267
|
const tmpPath = `${receiptPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
60268
|
-
await
|
|
60269
|
-
|
|
60268
|
+
await fs35.promises.writeFile(tmpPath, JSON.stringify(receipt, null, 2), "utf-8");
|
|
60269
|
+
fs35.renameSync(tmpPath, receiptPath);
|
|
60270
60270
|
const index = await readReceiptIndex(directory);
|
|
60271
60271
|
const entry = {
|
|
60272
60272
|
id: receipt.id,
|
|
@@ -60285,9 +60285,9 @@ async function readReceiptById(directory, receiptId) {
|
|
|
60285
60285
|
const entry = index.entries.find((e) => e.id === receiptId);
|
|
60286
60286
|
if (!entry)
|
|
60287
60287
|
return null;
|
|
60288
|
-
const receiptPath =
|
|
60288
|
+
const receiptPath = path49.join(resolveReceiptsDir(directory), entry.filename);
|
|
60289
60289
|
try {
|
|
60290
|
-
const content = await
|
|
60290
|
+
const content = await fs35.promises.readFile(receiptPath, "utf-8");
|
|
60291
60291
|
return JSON.parse(content);
|
|
60292
60292
|
} catch {
|
|
60293
60293
|
return null;
|
|
@@ -60298,9 +60298,9 @@ async function readReceiptsByScopeHash(directory, scopeHash) {
|
|
|
60298
60298
|
const matching = index.entries.filter((e) => e.scope_hash === scopeHash).sort((a, b) => b.reviewed_at.localeCompare(a.reviewed_at));
|
|
60299
60299
|
const receipts = [];
|
|
60300
60300
|
for (const entry of matching) {
|
|
60301
|
-
const receiptPath =
|
|
60301
|
+
const receiptPath = path49.join(resolveReceiptsDir(directory), entry.filename);
|
|
60302
60302
|
try {
|
|
60303
|
-
const content = await
|
|
60303
|
+
const content = await fs35.promises.readFile(receiptPath, "utf-8");
|
|
60304
60304
|
receipts.push(JSON.parse(content));
|
|
60305
60305
|
} catch {}
|
|
60306
60306
|
}
|
|
@@ -60311,9 +60311,9 @@ async function readAllReceipts(directory) {
|
|
|
60311
60311
|
const sorted = [...index.entries].sort((a, b) => b.reviewed_at.localeCompare(a.reviewed_at));
|
|
60312
60312
|
const receipts = [];
|
|
60313
60313
|
for (const entry of sorted) {
|
|
60314
|
-
const receiptPath =
|
|
60314
|
+
const receiptPath = path49.join(resolveReceiptsDir(directory), entry.filename);
|
|
60315
60315
|
try {
|
|
60316
|
-
const content = await
|
|
60316
|
+
const content = await fs35.promises.readFile(receiptPath, "utf-8");
|
|
60317
60317
|
receipts.push(JSON.parse(content));
|
|
60318
60318
|
} catch {}
|
|
60319
60319
|
}
|
|
@@ -61898,11 +61898,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
61898
61898
|
throw toThrow;
|
|
61899
61899
|
}, "quit_");
|
|
61900
61900
|
var scriptDirectory = "";
|
|
61901
|
-
function locateFile(
|
|
61901
|
+
function locateFile(path60) {
|
|
61902
61902
|
if (Module["locateFile"]) {
|
|
61903
|
-
return Module["locateFile"](
|
|
61903
|
+
return Module["locateFile"](path60, scriptDirectory);
|
|
61904
61904
|
}
|
|
61905
|
-
return scriptDirectory +
|
|
61905
|
+
return scriptDirectory + path60;
|
|
61906
61906
|
}
|
|
61907
61907
|
__name(locateFile, "locateFile");
|
|
61908
61908
|
var readAsync, readBinary;
|
|
@@ -63651,13 +63651,13 @@ __export(exports_runtime, {
|
|
|
63651
63651
|
getInitializedLanguages: () => getInitializedLanguages,
|
|
63652
63652
|
clearParserCache: () => clearParserCache
|
|
63653
63653
|
});
|
|
63654
|
-
import * as
|
|
63654
|
+
import * as path60 from "node:path";
|
|
63655
63655
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
63656
63656
|
async function initTreeSitter() {
|
|
63657
63657
|
if (treeSitterInitialized) {
|
|
63658
63658
|
return;
|
|
63659
63659
|
}
|
|
63660
|
-
const thisDir =
|
|
63660
|
+
const thisDir = path60.dirname(fileURLToPath2(import.meta.url));
|
|
63661
63661
|
const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
|
|
63662
63662
|
if (isSource) {
|
|
63663
63663
|
await Parser.init();
|
|
@@ -63665,7 +63665,7 @@ async function initTreeSitter() {
|
|
|
63665
63665
|
const grammarsDir = getGrammarsDirAbsolute();
|
|
63666
63666
|
await Parser.init({
|
|
63667
63667
|
locateFile(scriptName) {
|
|
63668
|
-
return
|
|
63668
|
+
return path60.join(grammarsDir, scriptName);
|
|
63669
63669
|
}
|
|
63670
63670
|
});
|
|
63671
63671
|
}
|
|
@@ -63686,11 +63686,11 @@ function getWasmFileName(languageId) {
|
|
|
63686
63686
|
return `tree-sitter-${sanitized}.wasm`;
|
|
63687
63687
|
}
|
|
63688
63688
|
function getGrammarsDirAbsolute() {
|
|
63689
|
-
const thisDir =
|
|
63689
|
+
const thisDir = path60.dirname(fileURLToPath2(import.meta.url));
|
|
63690
63690
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
63691
63691
|
const isSource = normalized.endsWith("/src/lang");
|
|
63692
63692
|
const isCliBundle = normalized.endsWith("/cli");
|
|
63693
|
-
return isSource ?
|
|
63693
|
+
return isSource ? path60.join(thisDir, "grammars") : isCliBundle ? path60.join(thisDir, "..", "lang", "grammars") : path60.join(thisDir, "lang", "grammars");
|
|
63694
63694
|
}
|
|
63695
63695
|
async function loadGrammar(languageId) {
|
|
63696
63696
|
if (typeof languageId !== "string" || languageId.length > 100) {
|
|
@@ -63706,9 +63706,9 @@ async function loadGrammar(languageId) {
|
|
|
63706
63706
|
await initTreeSitter();
|
|
63707
63707
|
const parser = new Parser;
|
|
63708
63708
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
63709
|
-
const wasmPath =
|
|
63710
|
-
const { existsSync:
|
|
63711
|
-
if (!
|
|
63709
|
+
const wasmPath = path60.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
63710
|
+
const { existsSync: existsSync31 } = await import("node:fs");
|
|
63711
|
+
if (!existsSync31(wasmPath)) {
|
|
63712
63712
|
throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
|
|
63713
63713
|
Make sure to run 'bun run build' to copy grammar files to dist/lang/grammars/`);
|
|
63714
63714
|
}
|
|
@@ -63741,7 +63741,7 @@ async function isGrammarAvailable(languageId) {
|
|
|
63741
63741
|
}
|
|
63742
63742
|
try {
|
|
63743
63743
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
63744
|
-
const wasmPath =
|
|
63744
|
+
const wasmPath = path60.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
63745
63745
|
const { statSync: statSync19 } = await import("node:fs");
|
|
63746
63746
|
statSync19(wasmPath);
|
|
63747
63747
|
return true;
|
|
@@ -63798,15 +63798,15 @@ __export(exports_doc_scan, {
|
|
|
63798
63798
|
doc_extract: () => doc_extract
|
|
63799
63799
|
});
|
|
63800
63800
|
import * as crypto7 from "node:crypto";
|
|
63801
|
-
import * as
|
|
63801
|
+
import * as fs44 from "node:fs";
|
|
63802
63802
|
import { mkdir as mkdir10, readFile as readFile10, writeFile as writeFile9 } from "node:fs/promises";
|
|
63803
|
-
import * as
|
|
63803
|
+
import * as path62 from "node:path";
|
|
63804
63804
|
function normalizeSeparators(filePath) {
|
|
63805
63805
|
return filePath.replace(/\\/g, "/");
|
|
63806
63806
|
}
|
|
63807
63807
|
function matchesDocPattern(filePath, patterns) {
|
|
63808
63808
|
const normalizedPath = normalizeSeparators(filePath);
|
|
63809
|
-
const basename9 =
|
|
63809
|
+
const basename9 = path62.basename(filePath);
|
|
63810
63810
|
for (const pattern of patterns) {
|
|
63811
63811
|
if (!pattern.includes("/") && !pattern.includes("\\")) {
|
|
63812
63812
|
if (basename9 === pattern) {
|
|
@@ -63862,7 +63862,7 @@ function stripMarkdown(text) {
|
|
|
63862
63862
|
return text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s*[-*•]\s+/gm, "").replace(/^\s*\d+\.\s+/gm, "").trim();
|
|
63863
63863
|
}
|
|
63864
63864
|
async function scanDocIndex(directory) {
|
|
63865
|
-
const manifestPath =
|
|
63865
|
+
const manifestPath = path62.join(directory, ".swarm", "doc-manifest.json");
|
|
63866
63866
|
const defaultPatterns = DocsConfigSchema.parse({}).doc_patterns;
|
|
63867
63867
|
const extraPatterns = [
|
|
63868
63868
|
"ARCHITECTURE.md",
|
|
@@ -63879,8 +63879,8 @@ async function scanDocIndex(directory) {
|
|
|
63879
63879
|
let cacheValid = true;
|
|
63880
63880
|
for (const file3 of existingManifest.files) {
|
|
63881
63881
|
try {
|
|
63882
|
-
const fullPath =
|
|
63883
|
-
const stat5 =
|
|
63882
|
+
const fullPath = path62.join(directory, file3.path);
|
|
63883
|
+
const stat5 = fs44.statSync(fullPath);
|
|
63884
63884
|
if (stat5.mtimeMs > file3.mtime) {
|
|
63885
63885
|
cacheValid = false;
|
|
63886
63886
|
break;
|
|
@@ -63898,7 +63898,7 @@ async function scanDocIndex(directory) {
|
|
|
63898
63898
|
const discoveredFiles = [];
|
|
63899
63899
|
let rawEntries;
|
|
63900
63900
|
try {
|
|
63901
|
-
rawEntries =
|
|
63901
|
+
rawEntries = fs44.readdirSync(directory, { recursive: true });
|
|
63902
63902
|
} catch {
|
|
63903
63903
|
const manifest2 = {
|
|
63904
63904
|
schema_version: 1,
|
|
@@ -63909,10 +63909,10 @@ async function scanDocIndex(directory) {
|
|
|
63909
63909
|
}
|
|
63910
63910
|
const entries = rawEntries.filter((e) => typeof e === "string");
|
|
63911
63911
|
for (const entry of entries) {
|
|
63912
|
-
const fullPath =
|
|
63912
|
+
const fullPath = path62.join(directory, entry);
|
|
63913
63913
|
let stat5;
|
|
63914
63914
|
try {
|
|
63915
|
-
stat5 =
|
|
63915
|
+
stat5 = fs44.statSync(fullPath);
|
|
63916
63916
|
} catch {
|
|
63917
63917
|
continue;
|
|
63918
63918
|
}
|
|
@@ -63941,11 +63941,11 @@ async function scanDocIndex(directory) {
|
|
|
63941
63941
|
}
|
|
63942
63942
|
let content;
|
|
63943
63943
|
try {
|
|
63944
|
-
content =
|
|
63944
|
+
content = fs44.readFileSync(fullPath, "utf-8");
|
|
63945
63945
|
} catch {
|
|
63946
63946
|
continue;
|
|
63947
63947
|
}
|
|
63948
|
-
const { title, summary } = extractTitleAndSummary(content,
|
|
63948
|
+
const { title, summary } = extractTitleAndSummary(content, path62.basename(entry));
|
|
63949
63949
|
const lineCount = content.split(`
|
|
63950
63950
|
`).length;
|
|
63951
63951
|
discoveredFiles.push({
|
|
@@ -63971,7 +63971,7 @@ async function scanDocIndex(directory) {
|
|
|
63971
63971
|
files: discoveredFiles
|
|
63972
63972
|
};
|
|
63973
63973
|
try {
|
|
63974
|
-
await mkdir10(
|
|
63974
|
+
await mkdir10(path62.dirname(manifestPath), { recursive: true });
|
|
63975
63975
|
await writeFile9(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
63976
63976
|
} catch {}
|
|
63977
63977
|
return { manifest, cached: false };
|
|
@@ -64010,7 +64010,7 @@ function extractConstraintsFromContent(content) {
|
|
|
64010
64010
|
return constraints;
|
|
64011
64011
|
}
|
|
64012
64012
|
async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
64013
|
-
const manifestPath =
|
|
64013
|
+
const manifestPath = path62.join(directory, ".swarm", "doc-manifest.json");
|
|
64014
64014
|
let manifest;
|
|
64015
64015
|
try {
|
|
64016
64016
|
const content = await readFile10(manifestPath, "utf-8");
|
|
@@ -64036,7 +64036,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64036
64036
|
}
|
|
64037
64037
|
let fullContent;
|
|
64038
64038
|
try {
|
|
64039
|
-
fullContent = await readFile10(
|
|
64039
|
+
fullContent = await readFile10(path62.join(directory, docFile.path), "utf-8");
|
|
64040
64040
|
} catch {
|
|
64041
64041
|
skippedCount++;
|
|
64042
64042
|
continue;
|
|
@@ -64059,7 +64059,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64059
64059
|
tier: "swarm",
|
|
64060
64060
|
lesson: constraint,
|
|
64061
64061
|
category: "architecture",
|
|
64062
|
-
tags: ["doc-scan",
|
|
64062
|
+
tags: ["doc-scan", path62.basename(docFile.path)],
|
|
64063
64063
|
scope: "global",
|
|
64064
64064
|
confidence: 0.5,
|
|
64065
64065
|
status: "candidate",
|
|
@@ -64132,9 +64132,9 @@ var init_doc_scan = __esm(() => {
|
|
|
64132
64132
|
}
|
|
64133
64133
|
} catch {}
|
|
64134
64134
|
if (force) {
|
|
64135
|
-
const manifestPath =
|
|
64135
|
+
const manifestPath = path62.join(directory, ".swarm", "doc-manifest.json");
|
|
64136
64136
|
try {
|
|
64137
|
-
|
|
64137
|
+
fs44.unlinkSync(manifestPath);
|
|
64138
64138
|
} catch {}
|
|
64139
64139
|
}
|
|
64140
64140
|
const { manifest, cached: cached3 } = await scanDocIndex(directory);
|
|
@@ -64322,11 +64322,11 @@ __export(exports_curator_drift, {
|
|
|
64322
64322
|
readPriorDriftReports: () => readPriorDriftReports,
|
|
64323
64323
|
buildDriftInjectionText: () => buildDriftInjectionText
|
|
64324
64324
|
});
|
|
64325
|
-
import * as
|
|
64326
|
-
import * as
|
|
64325
|
+
import * as fs47 from "node:fs";
|
|
64326
|
+
import * as path65 from "node:path";
|
|
64327
64327
|
async function readPriorDriftReports(directory) {
|
|
64328
|
-
const swarmDir =
|
|
64329
|
-
const entries = await
|
|
64328
|
+
const swarmDir = path65.join(directory, ".swarm");
|
|
64329
|
+
const entries = await fs47.promises.readdir(swarmDir).catch(() => null);
|
|
64330
64330
|
if (entries === null)
|
|
64331
64331
|
return [];
|
|
64332
64332
|
const reportFiles = entries.filter((name2) => name2.startsWith(DRIFT_REPORT_PREFIX) && name2.endsWith(".json")).sort();
|
|
@@ -64352,10 +64352,10 @@ async function readPriorDriftReports(directory) {
|
|
|
64352
64352
|
async function writeDriftReport(directory, report) {
|
|
64353
64353
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
64354
64354
|
const filePath = validateSwarmPath(directory, filename);
|
|
64355
|
-
const swarmDir =
|
|
64356
|
-
await
|
|
64355
|
+
const swarmDir = path65.dirname(filePath);
|
|
64356
|
+
await fs47.promises.mkdir(swarmDir, { recursive: true });
|
|
64357
64357
|
try {
|
|
64358
|
-
await
|
|
64358
|
+
await fs47.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
64359
64359
|
} catch (err2) {
|
|
64360
64360
|
throw new Error(`[curator-drift] Failed to write drift report to ${filePath}: ${String(err2)}`);
|
|
64361
64361
|
}
|
|
@@ -64486,8 +64486,7 @@ var init_curator_drift = __esm(() => {
|
|
|
64486
64486
|
// src/index.ts
|
|
64487
64487
|
init_package();
|
|
64488
64488
|
init_agents2();
|
|
64489
|
-
import * as
|
|
64490
|
-
import * as path107 from "node:path";
|
|
64489
|
+
import * as path108 from "node:path";
|
|
64491
64490
|
|
|
64492
64491
|
// src/background/index.ts
|
|
64493
64492
|
init_event_bus();
|
|
@@ -64906,6 +64905,64 @@ function createSwarmCommandHandler(directory, agents) {
|
|
|
64906
64905
|
// src/index.ts
|
|
64907
64906
|
init_config();
|
|
64908
64907
|
init_constants();
|
|
64908
|
+
|
|
64909
|
+
// src/config/project-init.ts
|
|
64910
|
+
init_constants();
|
|
64911
|
+
import * as fs31 from "node:fs";
|
|
64912
|
+
import * as path48 from "node:path";
|
|
64913
|
+
var STARTER_CONTENT = `{}
|
|
64914
|
+
`;
|
|
64915
|
+
function writeProjectConfigIfNew(directory, quiet = false) {
|
|
64916
|
+
try {
|
|
64917
|
+
const opencodeDir = path48.join(directory, ".opencode");
|
|
64918
|
+
const dest = path48.join(opencodeDir, "opencode-swarm.json");
|
|
64919
|
+
try {
|
|
64920
|
+
const stat4 = fs31.lstatSync(opencodeDir);
|
|
64921
|
+
if (stat4.isSymbolicLink())
|
|
64922
|
+
return;
|
|
64923
|
+
} catch (err2) {
|
|
64924
|
+
if (err2.code !== "ENOENT")
|
|
64925
|
+
return;
|
|
64926
|
+
}
|
|
64927
|
+
if (!fs31.existsSync(opencodeDir)) {
|
|
64928
|
+
fs31.mkdirSync(opencodeDir, { recursive: true });
|
|
64929
|
+
}
|
|
64930
|
+
try {
|
|
64931
|
+
fs31.writeFileSync(dest, STARTER_CONTENT, {
|
|
64932
|
+
encoding: "utf-8",
|
|
64933
|
+
flag: "wx"
|
|
64934
|
+
});
|
|
64935
|
+
if (!quiet) {
|
|
64936
|
+
console.warn("[opencode-swarm] Created .opencode/opencode-swarm.json — " + "edit it to customize agent LLMs for this project, or commit it to share settings with your team");
|
|
64937
|
+
}
|
|
64938
|
+
} catch (_writeErr) {}
|
|
64939
|
+
} catch {}
|
|
64940
|
+
}
|
|
64941
|
+
function writeSwarmConfigExampleIfNew(projectDirectory) {
|
|
64942
|
+
try {
|
|
64943
|
+
const swarmDir = path48.join(projectDirectory, ".swarm");
|
|
64944
|
+
const dest = path48.join(swarmDir, "config.example.json");
|
|
64945
|
+
if (fs31.existsSync(dest))
|
|
64946
|
+
return;
|
|
64947
|
+
if (!fs31.existsSync(swarmDir)) {
|
|
64948
|
+
fs31.mkdirSync(swarmDir, { recursive: true });
|
|
64949
|
+
}
|
|
64950
|
+
const example = {
|
|
64951
|
+
agents: Object.fromEntries(Object.entries(DEFAULT_MODELS).filter(([name2]) => name2 !== "default").map(([name2, model]) => [
|
|
64952
|
+
name2,
|
|
64953
|
+
{
|
|
64954
|
+
model,
|
|
64955
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
64956
|
+
}
|
|
64957
|
+
])),
|
|
64958
|
+
max_iterations: 5
|
|
64959
|
+
};
|
|
64960
|
+
fs31.writeFileSync(dest, `${JSON.stringify(example, null, 2)}
|
|
64961
|
+
`, "utf-8");
|
|
64962
|
+
} catch {}
|
|
64963
|
+
}
|
|
64964
|
+
|
|
64965
|
+
// src/index.ts
|
|
64909
64966
|
init_schema();
|
|
64910
64967
|
|
|
64911
64968
|
// src/hooks/agent-activity.ts
|
|
@@ -64983,11 +65040,11 @@ async function doFlush(directory) {
|
|
|
64983
65040
|
const activitySection = renderActivitySection();
|
|
64984
65041
|
const updated = replaceOrAppendSection(existing, "## Agent Activity", activitySection);
|
|
64985
65042
|
const flushedCount = swarmState.pendingEvents;
|
|
64986
|
-
const
|
|
64987
|
-
const tempPath = `${
|
|
65043
|
+
const path49 = nodePath2.join(directory, ".swarm", "context.md");
|
|
65044
|
+
const tempPath = `${path49}.tmp`;
|
|
64988
65045
|
try {
|
|
64989
65046
|
await bunWrite(tempPath, updated);
|
|
64990
|
-
renameSync11(tempPath,
|
|
65047
|
+
renameSync11(tempPath, path49);
|
|
64991
65048
|
} catch (writeError) {
|
|
64992
65049
|
try {
|
|
64993
65050
|
unlinkSync8(tempPath);
|
|
@@ -65037,8 +65094,8 @@ ${content.substring(endIndex + 1)}`;
|
|
|
65037
65094
|
// src/hooks/compaction-customizer.ts
|
|
65038
65095
|
init_manager();
|
|
65039
65096
|
init_utils2();
|
|
65040
|
-
import * as
|
|
65041
|
-
import { join as
|
|
65097
|
+
import * as fs32 from "node:fs";
|
|
65098
|
+
import { join as join45 } from "node:path";
|
|
65042
65099
|
function createCompactionCustomizerHook(config3, directory) {
|
|
65043
65100
|
const enabled = config3.hooks?.compaction !== false;
|
|
65044
65101
|
if (!enabled) {
|
|
@@ -65083,8 +65140,8 @@ function createCompactionCustomizerHook(config3, directory) {
|
|
|
65083
65140
|
}
|
|
65084
65141
|
}
|
|
65085
65142
|
try {
|
|
65086
|
-
const summariesDir =
|
|
65087
|
-
const files = await
|
|
65143
|
+
const summariesDir = join45(directory, ".swarm", "summaries");
|
|
65144
|
+
const files = await fs32.promises.readdir(summariesDir);
|
|
65088
65145
|
if (files.length > 0) {
|
|
65089
65146
|
const count = files.length;
|
|
65090
65147
|
output.context.push(`[CONTEXT OPTIMIZATION] Tool outputs from earlier in this session have been stored to disk. When compacting, replace any large tool output blocks (bash, test_runner, lint, diff results) with a one-line reference: "[Output stored — use /swarm retrieve to access full content]". Preserve the tool name, exit status, and any error messages. Discard raw output lines.`);
|
|
@@ -65570,7 +65627,7 @@ init_delegation_gate();
|
|
|
65570
65627
|
|
|
65571
65628
|
// src/hooks/delegation-sanitizer.ts
|
|
65572
65629
|
init_utils2();
|
|
65573
|
-
import * as
|
|
65630
|
+
import * as fs33 from "node:fs";
|
|
65574
65631
|
var SANITIZATION_PATTERNS = [
|
|
65575
65632
|
/\b\d+(st|nd|rd|th)\s+(attempt|try|time)\b/gi,
|
|
65576
65633
|
/\b(5th|fifth|final|last)\s+attempt\b/gi,
|
|
@@ -65641,7 +65698,7 @@ function createDelegationSanitizerHook(directory) {
|
|
|
65641
65698
|
stripped_patterns: result.stripped,
|
|
65642
65699
|
timestamp: new Date().toISOString()
|
|
65643
65700
|
};
|
|
65644
|
-
|
|
65701
|
+
fs33.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
65645
65702
|
`, "utf-8");
|
|
65646
65703
|
} catch {}
|
|
65647
65704
|
}
|
|
@@ -65708,7 +65765,7 @@ init_file_locks();
|
|
|
65708
65765
|
init_state();
|
|
65709
65766
|
init_telemetry();
|
|
65710
65767
|
init_utils2();
|
|
65711
|
-
import * as
|
|
65768
|
+
import * as fs34 from "node:fs";
|
|
65712
65769
|
var END_OF_SENTENCE_QUESTION_PATTERN = /\?\s*$/;
|
|
65713
65770
|
var PHASE_COMPLETION_PATTERNS = [
|
|
65714
65771
|
/Ready for Phase (?:\d+|\[?N\+1\]?)\??/i,
|
|
@@ -65902,7 +65959,7 @@ async function writeAutoOversightEvent(directory, architectOutput, criticVerdict
|
|
|
65902
65959
|
}
|
|
65903
65960
|
try {
|
|
65904
65961
|
const eventsPath = validateSwarmPath(dir, "events.jsonl");
|
|
65905
|
-
|
|
65962
|
+
fs34.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
65906
65963
|
`, "utf-8");
|
|
65907
65964
|
} catch (writeError) {
|
|
65908
65965
|
error48(`[full-auto-intercept] Warning: failed to write auto_oversight event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
@@ -66214,7 +66271,7 @@ async function writeEscalationReport(directory, reason, architectOutput, interac
|
|
|
66214
66271
|
if (currentPhase === undefined) {
|
|
66215
66272
|
try {
|
|
66216
66273
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
66217
|
-
const planContent =
|
|
66274
|
+
const planContent = fs34.readFileSync(planPath, "utf-8");
|
|
66218
66275
|
const plan = JSON.parse(planContent);
|
|
66219
66276
|
const incompletePhases = plan.phases.filter((p) => p.status !== "complete").sort((a, b) => b.id - a.id);
|
|
66220
66277
|
currentPhase = incompletePhases[0]?.id;
|
|
@@ -66253,7 +66310,7 @@ ${currentPhase !== undefined ? `- **Phase Status**: Pending completion` : ""}
|
|
|
66253
66310
|
This escalation requires human intervention. The swarm has been paused.
|
|
66254
66311
|
Please review the architect's output above and provide guidance.
|
|
66255
66312
|
`;
|
|
66256
|
-
|
|
66313
|
+
fs34.writeFileSync(reportPath, reportContent, "utf-8");
|
|
66257
66314
|
log(`[full-auto-intercept] Escalation report written to: ${reportPath}`);
|
|
66258
66315
|
} catch (error93) {
|
|
66259
66316
|
error48(`[full-auto-intercept] Failed to write escalation report:`, error93 instanceof Error ? error93.message : String(error93));
|
|
@@ -66347,7 +66404,7 @@ init_schema();
|
|
|
66347
66404
|
init_manager();
|
|
66348
66405
|
init_curator();
|
|
66349
66406
|
init_utils2();
|
|
66350
|
-
import * as
|
|
66407
|
+
import * as path50 from "node:path";
|
|
66351
66408
|
function createPhaseMonitorHook(directory, preflightManager, curatorRunner, delegateFactory) {
|
|
66352
66409
|
let lastKnownPhase = null;
|
|
66353
66410
|
const handler = async (input, _output) => {
|
|
@@ -66367,9 +66424,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner, dele
|
|
|
66367
66424
|
const llmDelegate = delegateFactory?.(sessionId);
|
|
66368
66425
|
const initResult = await runner(directory, curatorConfig, llmDelegate);
|
|
66369
66426
|
if (initResult.briefing) {
|
|
66370
|
-
const briefingPath =
|
|
66427
|
+
const briefingPath = path50.join(directory, ".swarm", "curator-briefing.md");
|
|
66371
66428
|
const { mkdir: mkdir8, writeFile: writeFile8 } = await import("node:fs/promises");
|
|
66372
|
-
await mkdir8(
|
|
66429
|
+
await mkdir8(path50.dirname(briefingPath), { recursive: true });
|
|
66373
66430
|
await writeFile8(briefingPath, initResult.briefing, "utf-8");
|
|
66374
66431
|
const { buildApprovedReceipt: buildApprovedReceipt2, persistReviewReceipt: persistReviewReceipt2 } = await Promise.resolve().then(() => (init_review_receipt(), exports_review_receipt));
|
|
66375
66432
|
const initReceipt = buildApprovedReceipt2({
|
|
@@ -66494,16 +66551,16 @@ ${originalText}`;
|
|
|
66494
66551
|
}
|
|
66495
66552
|
// src/hooks/repo-graph-builder.ts
|
|
66496
66553
|
init_constants();
|
|
66497
|
-
import * as
|
|
66554
|
+
import * as path53 from "node:path";
|
|
66498
66555
|
|
|
66499
66556
|
// src/tools/repo-graph.ts
|
|
66500
66557
|
init_utils2();
|
|
66501
66558
|
init_path_security();
|
|
66502
66559
|
import * as fsSync3 from "node:fs";
|
|
66503
|
-
import { constants as constants4, existsSync as
|
|
66560
|
+
import { constants as constants4, existsSync as existsSync29, realpathSync as realpathSync6 } from "node:fs";
|
|
66504
66561
|
import * as fsPromises5 from "node:fs/promises";
|
|
66505
66562
|
import * as os7 from "node:os";
|
|
66506
|
-
import * as
|
|
66563
|
+
import * as path52 from "node:path";
|
|
66507
66564
|
|
|
66508
66565
|
// src/utils/timeout.ts
|
|
66509
66566
|
async function withTimeout(promise3, ms, timeoutError) {
|
|
@@ -66534,8 +66591,8 @@ function yieldToEventLoop() {
|
|
|
66534
66591
|
init_zod();
|
|
66535
66592
|
init_create_tool();
|
|
66536
66593
|
init_path_security();
|
|
66537
|
-
import * as
|
|
66538
|
-
import * as
|
|
66594
|
+
import * as fs36 from "node:fs";
|
|
66595
|
+
import * as path51 from "node:path";
|
|
66539
66596
|
var MAX_FILE_SIZE_BYTES2 = 1024 * 1024;
|
|
66540
66597
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
66541
66598
|
function containsWindowsAttacks(str) {
|
|
@@ -66552,11 +66609,11 @@ function containsWindowsAttacks(str) {
|
|
|
66552
66609
|
}
|
|
66553
66610
|
function isPathInWorkspace(filePath, workspace) {
|
|
66554
66611
|
try {
|
|
66555
|
-
const resolvedPath =
|
|
66556
|
-
const realWorkspace =
|
|
66557
|
-
const realResolvedPath =
|
|
66558
|
-
const relativePath =
|
|
66559
|
-
if (relativePath.startsWith("..") ||
|
|
66612
|
+
const resolvedPath = path51.resolve(workspace, filePath);
|
|
66613
|
+
const realWorkspace = fs36.realpathSync(workspace);
|
|
66614
|
+
const realResolvedPath = fs36.realpathSync(resolvedPath);
|
|
66615
|
+
const relativePath = path51.relative(realWorkspace, realResolvedPath);
|
|
66616
|
+
if (relativePath.startsWith("..") || path51.isAbsolute(relativePath)) {
|
|
66560
66617
|
return false;
|
|
66561
66618
|
}
|
|
66562
66619
|
return true;
|
|
@@ -66568,17 +66625,17 @@ function validatePathForRead(filePath, workspace) {
|
|
|
66568
66625
|
return isPathInWorkspace(filePath, workspace);
|
|
66569
66626
|
}
|
|
66570
66627
|
function extractTSSymbols(filePath, cwd) {
|
|
66571
|
-
const fullPath =
|
|
66628
|
+
const fullPath = path51.join(cwd, filePath);
|
|
66572
66629
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
66573
66630
|
return [];
|
|
66574
66631
|
}
|
|
66575
66632
|
let content;
|
|
66576
66633
|
try {
|
|
66577
|
-
const stats =
|
|
66634
|
+
const stats = fs36.statSync(fullPath);
|
|
66578
66635
|
if (stats.size > MAX_FILE_SIZE_BYTES2) {
|
|
66579
66636
|
throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES2})`);
|
|
66580
66637
|
}
|
|
66581
|
-
content =
|
|
66638
|
+
content = fs36.readFileSync(fullPath, "utf-8");
|
|
66582
66639
|
} catch {
|
|
66583
66640
|
return [];
|
|
66584
66641
|
}
|
|
@@ -66720,17 +66777,17 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
66720
66777
|
});
|
|
66721
66778
|
}
|
|
66722
66779
|
function extractPythonSymbols(filePath, cwd) {
|
|
66723
|
-
const fullPath =
|
|
66780
|
+
const fullPath = path51.join(cwd, filePath);
|
|
66724
66781
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
66725
66782
|
return [];
|
|
66726
66783
|
}
|
|
66727
66784
|
let content;
|
|
66728
66785
|
try {
|
|
66729
|
-
const stats =
|
|
66786
|
+
const stats = fs36.statSync(fullPath);
|
|
66730
66787
|
if (stats.size > MAX_FILE_SIZE_BYTES2) {
|
|
66731
66788
|
throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES2})`);
|
|
66732
66789
|
}
|
|
66733
|
-
content =
|
|
66790
|
+
content = fs36.readFileSync(fullPath, "utf-8");
|
|
66734
66791
|
} catch {
|
|
66735
66792
|
return [];
|
|
66736
66793
|
}
|
|
@@ -66803,7 +66860,7 @@ var symbols = createSwarmTool({
|
|
|
66803
66860
|
}, null, 2);
|
|
66804
66861
|
}
|
|
66805
66862
|
const cwd = directory;
|
|
66806
|
-
const ext =
|
|
66863
|
+
const ext = path51.extname(file3);
|
|
66807
66864
|
if (containsControlChars(file3)) {
|
|
66808
66865
|
return JSON.stringify({
|
|
66809
66866
|
file: file3,
|
|
@@ -66867,7 +66924,7 @@ var symbols = createSwarmTool({
|
|
|
66867
66924
|
var WINDOWS_RENAME_MAX_RETRIES2 = 3;
|
|
66868
66925
|
var WINDOWS_RENAME_RETRY_DELAY_MS2 = 50;
|
|
66869
66926
|
function normalizeGraphPath(filePath) {
|
|
66870
|
-
return
|
|
66927
|
+
return path52.normalize(filePath).replace(/\\/g, "/");
|
|
66871
66928
|
}
|
|
66872
66929
|
var REPO_GRAPH_FILENAME = "repo-graph.json";
|
|
66873
66930
|
var GRAPH_SCHEMA_VERSION = "1.0.0";
|
|
@@ -66976,8 +67033,8 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
66976
67033
|
}
|
|
66977
67034
|
try {
|
|
66978
67035
|
if (specifier.startsWith(".")) {
|
|
66979
|
-
const sourceDir =
|
|
66980
|
-
let resolved =
|
|
67036
|
+
const sourceDir = path52.dirname(sourceFile);
|
|
67037
|
+
let resolved = path52.resolve(sourceDir, specifier);
|
|
66981
67038
|
let realResolved;
|
|
66982
67039
|
try {
|
|
66983
67040
|
realResolved = realpathSync6(resolved);
|
|
@@ -66988,9 +67045,9 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
66988
67045
|
try {
|
|
66989
67046
|
realRoot = realpathSync6(workspaceRoot);
|
|
66990
67047
|
} catch {
|
|
66991
|
-
realRoot =
|
|
67048
|
+
realRoot = path52.normalize(workspaceRoot);
|
|
66992
67049
|
}
|
|
66993
|
-
if (!
|
|
67050
|
+
if (!existsSync29(resolved)) {
|
|
66994
67051
|
const EXTENSIONS = [
|
|
66995
67052
|
".ts",
|
|
66996
67053
|
".tsx",
|
|
@@ -67004,7 +67061,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67004
67061
|
let found = null;
|
|
67005
67062
|
for (const ext of EXTENSIONS) {
|
|
67006
67063
|
const candidate = resolved + ext;
|
|
67007
|
-
if (
|
|
67064
|
+
if (existsSync29(candidate)) {
|
|
67008
67065
|
found = candidate;
|
|
67009
67066
|
break;
|
|
67010
67067
|
}
|
|
@@ -67020,9 +67077,9 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67020
67077
|
return null;
|
|
67021
67078
|
}
|
|
67022
67079
|
}
|
|
67023
|
-
const normalizedResolved =
|
|
67024
|
-
const normalizedRoot =
|
|
67025
|
-
if (!normalizedResolved.startsWith(normalizedRoot +
|
|
67080
|
+
const normalizedResolved = path52.normalize(realResolved);
|
|
67081
|
+
const normalizedRoot = path52.normalize(realRoot);
|
|
67082
|
+
if (!normalizedResolved.startsWith(normalizedRoot + path52.sep) && normalizedResolved !== normalizedRoot) {
|
|
67026
67083
|
return null;
|
|
67027
67084
|
}
|
|
67028
67085
|
return resolved;
|
|
@@ -67035,7 +67092,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67035
67092
|
function createEmptyGraph(workspaceRoot) {
|
|
67036
67093
|
return {
|
|
67037
67094
|
schema_version: GRAPH_SCHEMA_VERSION,
|
|
67038
|
-
workspaceRoot:
|
|
67095
|
+
workspaceRoot: path52.normalize(workspaceRoot),
|
|
67039
67096
|
nodes: {},
|
|
67040
67097
|
edges: [],
|
|
67041
67098
|
metadata: {
|
|
@@ -67069,10 +67126,10 @@ function addEdge(graph, edge) {
|
|
|
67069
67126
|
}
|
|
67070
67127
|
}
|
|
67071
67128
|
function getCachedGraph(workspace) {
|
|
67072
|
-
return graphCache.get(
|
|
67129
|
+
return graphCache.get(path52.normalize(workspace));
|
|
67073
67130
|
}
|
|
67074
67131
|
function setCachedGraph(workspace, graph, mtime) {
|
|
67075
|
-
const normalized =
|
|
67132
|
+
const normalized = path52.normalize(workspace);
|
|
67076
67133
|
graphCache.set(normalized, graph);
|
|
67077
67134
|
dirtyFlags.set(normalized, false);
|
|
67078
67135
|
if (mtime !== undefined) {
|
|
@@ -67080,10 +67137,10 @@ function setCachedGraph(workspace, graph, mtime) {
|
|
|
67080
67137
|
}
|
|
67081
67138
|
}
|
|
67082
67139
|
function isDirty(workspace) {
|
|
67083
|
-
return dirtyFlags.get(
|
|
67140
|
+
return dirtyFlags.get(path52.normalize(workspace)) ?? false;
|
|
67084
67141
|
}
|
|
67085
67142
|
function clearCache(workspace) {
|
|
67086
|
-
const normalized =
|
|
67143
|
+
const normalized = path52.normalize(workspace);
|
|
67087
67144
|
graphCache.delete(normalized);
|
|
67088
67145
|
dirtyFlags.delete(normalized);
|
|
67089
67146
|
mtimeCache.delete(normalized);
|
|
@@ -67096,12 +67153,12 @@ function getGraphPath(workspace) {
|
|
|
67096
67153
|
}
|
|
67097
67154
|
async function loadGraph(workspace) {
|
|
67098
67155
|
validateWorkspace(workspace);
|
|
67099
|
-
const normalized =
|
|
67156
|
+
const normalized = path52.normalize(workspace);
|
|
67100
67157
|
const cached3 = getCachedGraph(normalized);
|
|
67101
67158
|
if (cached3 && !isDirty(normalized)) {
|
|
67102
67159
|
try {
|
|
67103
67160
|
const graphPath = getGraphPath(workspace);
|
|
67104
|
-
if (
|
|
67161
|
+
if (existsSync29(graphPath)) {
|
|
67105
67162
|
const stats = await fsPromises5.stat(graphPath);
|
|
67106
67163
|
const cachedMtime = mtimeCache.get(normalized);
|
|
67107
67164
|
if (cachedMtime !== undefined && stats.mtimeMs !== cachedMtime) {
|
|
@@ -67118,7 +67175,7 @@ async function loadGraph(workspace) {
|
|
|
67118
67175
|
}
|
|
67119
67176
|
try {
|
|
67120
67177
|
const graphPath = getGraphPath(workspace);
|
|
67121
|
-
if (!
|
|
67178
|
+
if (!existsSync29(graphPath)) {
|
|
67122
67179
|
return null;
|
|
67123
67180
|
}
|
|
67124
67181
|
const stats = await fsPromises5.stat(graphPath);
|
|
@@ -67190,28 +67247,28 @@ async function saveGraph(workspace, graph, options) {
|
|
|
67190
67247
|
if (!Array.isArray(graph.edges)) {
|
|
67191
67248
|
throw new Error("Graph must have edges array");
|
|
67192
67249
|
}
|
|
67193
|
-
const normalizedWorkspace =
|
|
67250
|
+
const normalizedWorkspace = path52.normalize(workspace);
|
|
67194
67251
|
let realWorkspace;
|
|
67195
67252
|
try {
|
|
67196
67253
|
realWorkspace = realpathSync6(workspace);
|
|
67197
67254
|
} catch {
|
|
67198
67255
|
realWorkspace = normalizedWorkspace;
|
|
67199
67256
|
}
|
|
67200
|
-
const normalizedGraphRoot =
|
|
67257
|
+
const normalizedGraphRoot = path52.normalize(graph.workspaceRoot);
|
|
67201
67258
|
let realGraphRoot;
|
|
67202
67259
|
try {
|
|
67203
67260
|
realGraphRoot = realpathSync6(graph.workspaceRoot);
|
|
67204
67261
|
} catch {
|
|
67205
67262
|
realGraphRoot = normalizedGraphRoot;
|
|
67206
67263
|
}
|
|
67207
|
-
if (
|
|
67264
|
+
if (path52.normalize(realWorkspace) !== path52.normalize(realGraphRoot)) {
|
|
67208
67265
|
throw new Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);
|
|
67209
67266
|
}
|
|
67210
67267
|
const normalized = normalizedWorkspace;
|
|
67211
67268
|
const graphPath = getGraphPath(workspace);
|
|
67212
67269
|
updateGraphMetadata(graph);
|
|
67213
67270
|
const tempPath = `${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
67214
|
-
await fsPromises5.mkdir(
|
|
67271
|
+
await fsPromises5.mkdir(path52.dirname(tempPath), { recursive: true });
|
|
67215
67272
|
let lastError = null;
|
|
67216
67273
|
try {
|
|
67217
67274
|
if (options?.createAtomic) {
|
|
@@ -67295,12 +67352,12 @@ function isRefusedWorkspaceRoot(target) {
|
|
|
67295
67352
|
try {
|
|
67296
67353
|
resolved = realpathSync6(target);
|
|
67297
67354
|
} catch {
|
|
67298
|
-
resolved =
|
|
67355
|
+
resolved = path52.resolve(target);
|
|
67299
67356
|
}
|
|
67300
67357
|
const refused = new Set;
|
|
67301
67358
|
const add = (p) => {
|
|
67302
67359
|
if (typeof p === "string" && p.length > 0) {
|
|
67303
|
-
refused.add(
|
|
67360
|
+
refused.add(path52.resolve(p));
|
|
67304
67361
|
}
|
|
67305
67362
|
};
|
|
67306
67363
|
add(os7.homedir());
|
|
@@ -67419,7 +67476,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
67419
67476
|
ctx.stats.skippedDirs++;
|
|
67420
67477
|
continue;
|
|
67421
67478
|
}
|
|
67422
|
-
const fullPath =
|
|
67479
|
+
const fullPath = path52.join(current, entry.name);
|
|
67423
67480
|
if (entry.isSymbolicLink() && !ctx.followSymlinks) {
|
|
67424
67481
|
ctx.stats.skippedDirs++;
|
|
67425
67482
|
continue;
|
|
@@ -67427,7 +67484,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
67427
67484
|
if (entry.isDirectory()) {
|
|
67428
67485
|
queue.push(fullPath);
|
|
67429
67486
|
} else if (entry.isFile()) {
|
|
67430
|
-
const ext =
|
|
67487
|
+
const ext = path52.extname(fullPath).toLowerCase();
|
|
67431
67488
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
67432
67489
|
files.push(fullPath);
|
|
67433
67490
|
}
|
|
@@ -67444,11 +67501,11 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
67444
67501
|
return files;
|
|
67445
67502
|
}
|
|
67446
67503
|
function toModuleName(filePath, workspaceRoot) {
|
|
67447
|
-
const relative9 =
|
|
67448
|
-
return relative9.split(
|
|
67504
|
+
const relative9 = path52.relative(workspaceRoot, filePath);
|
|
67505
|
+
return relative9.split(path52.sep).join("/");
|
|
67449
67506
|
}
|
|
67450
67507
|
function getLanguage(filePath) {
|
|
67451
|
-
const ext =
|
|
67508
|
+
const ext = path52.extname(filePath).toLowerCase();
|
|
67452
67509
|
return EXTENSION_TO_LANGUAGE[ext] ?? "unknown";
|
|
67453
67510
|
}
|
|
67454
67511
|
function isBinaryContent(content) {
|
|
@@ -67463,8 +67520,8 @@ async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
|
67463
67520
|
const maxFiles = options?.maxFiles ?? DEFAULT_WALK_FILE_CAP;
|
|
67464
67521
|
const walkBudgetMs = options?.walkBudgetMs ?? DEFAULT_WALK_BUDGET_MS;
|
|
67465
67522
|
const followSymlinks = options?.followSymlinks ?? false;
|
|
67466
|
-
const absoluteRoot =
|
|
67467
|
-
if (!
|
|
67523
|
+
const absoluteRoot = path52.resolve(workspaceRoot);
|
|
67524
|
+
if (!existsSync29(absoluteRoot)) {
|
|
67468
67525
|
throw new Error(`Workspace directory does not exist: ${workspaceRoot}`);
|
|
67469
67526
|
}
|
|
67470
67527
|
if (isRefusedWorkspaceRoot(absoluteRoot)) {
|
|
@@ -67533,15 +67590,15 @@ function scanFile(filePath, absoluteRoot, maxFileSize) {
|
|
|
67533
67590
|
if (isBinaryContent(content)) {
|
|
67534
67591
|
return { node: null, edges: [] };
|
|
67535
67592
|
}
|
|
67536
|
-
const ext =
|
|
67593
|
+
const ext = path52.extname(filePath).toLowerCase();
|
|
67537
67594
|
let exports = [];
|
|
67538
67595
|
try {
|
|
67539
67596
|
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
67540
|
-
const relativePath =
|
|
67597
|
+
const relativePath = path52.relative(absoluteRoot, filePath);
|
|
67541
67598
|
const symbols2 = extractTSSymbols(relativePath, absoluteRoot);
|
|
67542
67599
|
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
67543
67600
|
} else if (ext === ".py") {
|
|
67544
|
-
const relativePath =
|
|
67601
|
+
const relativePath = path52.relative(absoluteRoot, filePath);
|
|
67545
67602
|
const symbols2 = extractPythonSymbols(relativePath, absoluteRoot);
|
|
67546
67603
|
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
67547
67604
|
}
|
|
@@ -67585,12 +67642,12 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
67585
67642
|
return graph2;
|
|
67586
67643
|
}
|
|
67587
67644
|
const graph = existingGraph;
|
|
67588
|
-
const absoluteRoot =
|
|
67645
|
+
const absoluteRoot = path52.resolve(workspaceRoot);
|
|
67589
67646
|
const maxFileSize = 1024 * 1024;
|
|
67590
67647
|
const updatedPaths = new Set;
|
|
67591
67648
|
for (const rawFilePath of filePaths) {
|
|
67592
67649
|
const normalizedPath = normalizeGraphPath(rawFilePath);
|
|
67593
|
-
const fileExists =
|
|
67650
|
+
const fileExists = existsSync29(rawFilePath);
|
|
67594
67651
|
if (fileExists) {
|
|
67595
67652
|
graph.edges = graph.edges.filter((e) => normalizeGraphPath(e.source) !== normalizedPath);
|
|
67596
67653
|
const result = scanFile(rawFilePath, absoluteRoot, maxFileSize);
|
|
@@ -67705,7 +67762,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
67705
67762
|
filePath = filePath.replace(/./g, ".").replace(///g, "/").replace(/․/g, ".");
|
|
67706
67763
|
if (!isSupportedSourceFile(filePath))
|
|
67707
67764
|
return;
|
|
67708
|
-
const absoluteFilePath =
|
|
67765
|
+
const absoluteFilePath = path53.isAbsolute(filePath) ? filePath : path53.resolve(workspaceRoot, filePath);
|
|
67709
67766
|
const normalizedAbsolute = absoluteFilePath.replace(/\\/g, "/");
|
|
67710
67767
|
const normalizedWorkspace = workspaceRoot.replace(/\\/g, "/");
|
|
67711
67768
|
if (!normalizedAbsolute.startsWith(`${normalizedWorkspace}/`) && normalizedAbsolute !== normalizedWorkspace) {
|
|
@@ -67713,7 +67770,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
67713
67770
|
}
|
|
67714
67771
|
try {
|
|
67715
67772
|
await _updateGraphForFiles(workspaceRoot, [absoluteFilePath]);
|
|
67716
|
-
log(`[repo-graph] Incremental update for ${
|
|
67773
|
+
log(`[repo-graph] Incremental update for ${path53.basename(filePath)}`);
|
|
67717
67774
|
} catch (error93) {
|
|
67718
67775
|
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
67719
67776
|
error48(`[repo-graph] Incremental update failed: ${message}`);
|
|
@@ -67731,15 +67788,15 @@ init_schema();
|
|
|
67731
67788
|
init_manager2();
|
|
67732
67789
|
init_detector();
|
|
67733
67790
|
init_manager();
|
|
67734
|
-
import * as
|
|
67735
|
-
import * as
|
|
67791
|
+
import * as fs45 from "node:fs";
|
|
67792
|
+
import * as path63 from "node:path";
|
|
67736
67793
|
|
|
67737
67794
|
// src/services/decision-drift-analyzer.ts
|
|
67738
67795
|
init_utils2();
|
|
67739
67796
|
init_manager();
|
|
67740
67797
|
init_utils();
|
|
67741
|
-
import * as
|
|
67742
|
-
import * as
|
|
67798
|
+
import * as fs37 from "node:fs";
|
|
67799
|
+
import * as path54 from "node:path";
|
|
67743
67800
|
var DEFAULT_DRIFT_CONFIG = {
|
|
67744
67801
|
staleThresholdPhases: 1,
|
|
67745
67802
|
detectContradictions: true,
|
|
@@ -67893,11 +67950,11 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
67893
67950
|
currentPhase = legacyPhase;
|
|
67894
67951
|
}
|
|
67895
67952
|
}
|
|
67896
|
-
const contextPath =
|
|
67953
|
+
const contextPath = path54.join(directory, ".swarm", "context.md");
|
|
67897
67954
|
let contextContent = "";
|
|
67898
67955
|
try {
|
|
67899
|
-
if (
|
|
67900
|
-
contextContent =
|
|
67956
|
+
if (fs37.existsSync(contextPath)) {
|
|
67957
|
+
contextContent = fs37.readFileSync(contextPath, "utf-8");
|
|
67901
67958
|
}
|
|
67902
67959
|
} catch (error93) {
|
|
67903
67960
|
log("[DecisionDriftAnalyzer] context file read failed", {
|
|
@@ -68031,8 +68088,8 @@ init_utils();
|
|
|
68031
68088
|
// src/hooks/adversarial-detector.ts
|
|
68032
68089
|
init_constants();
|
|
68033
68090
|
init_schema();
|
|
68034
|
-
import * as
|
|
68035
|
-
import * as
|
|
68091
|
+
import * as fs38 from "node:fs/promises";
|
|
68092
|
+
import * as path55 from "node:path";
|
|
68036
68093
|
function safeGet(obj, key) {
|
|
68037
68094
|
if (!obj || !Object.hasOwn(obj, key))
|
|
68038
68095
|
return;
|
|
@@ -68264,10 +68321,10 @@ async function handleDebuggingSpiral(match, taskId, directory) {
|
|
|
68264
68321
|
let eventLogged = false;
|
|
68265
68322
|
let checkpointCreated = false;
|
|
68266
68323
|
try {
|
|
68267
|
-
const swarmDir =
|
|
68268
|
-
await
|
|
68269
|
-
const eventsPath =
|
|
68270
|
-
await
|
|
68324
|
+
const swarmDir = path55.join(directory, ".swarm");
|
|
68325
|
+
await fs38.mkdir(swarmDir, { recursive: true });
|
|
68326
|
+
const eventsPath = path55.join(swarmDir, "events.jsonl");
|
|
68327
|
+
await fs38.appendFile(eventsPath, `${formatDebuggingSpiralEvent(match, taskId)}
|
|
68271
68328
|
`);
|
|
68272
68329
|
eventLogged = true;
|
|
68273
68330
|
} catch {}
|
|
@@ -68397,11 +68454,11 @@ function rankCandidates(candidates, config3) {
|
|
|
68397
68454
|
init_knowledge_store();
|
|
68398
68455
|
|
|
68399
68456
|
// src/hooks/repo-graph-injection.ts
|
|
68400
|
-
import * as
|
|
68457
|
+
import * as fs42 from "node:fs";
|
|
68401
68458
|
|
|
68402
68459
|
// src/graph/graph-builder.ts
|
|
68403
|
-
import * as
|
|
68404
|
-
import * as
|
|
68460
|
+
import * as fs40 from "node:fs";
|
|
68461
|
+
import * as path58 from "node:path";
|
|
68405
68462
|
|
|
68406
68463
|
// node_modules/yocto-queue/index.js
|
|
68407
68464
|
class Node {
|
|
@@ -68561,8 +68618,8 @@ function validateConcurrency(concurrency) {
|
|
|
68561
68618
|
|
|
68562
68619
|
// src/graph/import-extractor.ts
|
|
68563
68620
|
init_path_security();
|
|
68564
|
-
import * as
|
|
68565
|
-
import * as
|
|
68621
|
+
import * as fs39 from "node:fs";
|
|
68622
|
+
import * as path56 from "node:path";
|
|
68566
68623
|
var SOURCE_EXTENSIONS2 = [
|
|
68567
68624
|
".ts",
|
|
68568
68625
|
".tsx",
|
|
@@ -68607,27 +68664,27 @@ function getLanguageFromExtension(ext) {
|
|
|
68607
68664
|
return null;
|
|
68608
68665
|
}
|
|
68609
68666
|
function toRelForwardSlash(absPath, root) {
|
|
68610
|
-
return
|
|
68667
|
+
return path56.relative(root, absPath).replace(/\\/g, "/");
|
|
68611
68668
|
}
|
|
68612
68669
|
function tryResolveTSJS(rawModule, sourceFileAbs) {
|
|
68613
68670
|
if (!rawModule.startsWith(".") && !rawModule.startsWith("/")) {
|
|
68614
68671
|
return null;
|
|
68615
68672
|
}
|
|
68616
|
-
const sourceDir =
|
|
68617
|
-
const baseAbs =
|
|
68673
|
+
const sourceDir = path56.dirname(sourceFileAbs);
|
|
68674
|
+
const baseAbs = path56.resolve(sourceDir, rawModule);
|
|
68618
68675
|
const probe = (basePath) => {
|
|
68619
68676
|
for (const ext of RESOLVE_EXTENSION_CANDIDATES) {
|
|
68620
68677
|
const test = basePath + ext;
|
|
68621
68678
|
try {
|
|
68622
|
-
const stat5 =
|
|
68679
|
+
const stat5 = fs39.statSync(test);
|
|
68623
68680
|
if (stat5.isFile())
|
|
68624
68681
|
return test;
|
|
68625
68682
|
} catch {}
|
|
68626
68683
|
}
|
|
68627
68684
|
for (const indexFile of RESOLVE_INDEX_CANDIDATES) {
|
|
68628
|
-
const test =
|
|
68685
|
+
const test = path56.join(basePath, indexFile);
|
|
68629
68686
|
try {
|
|
68630
|
-
const stat5 =
|
|
68687
|
+
const stat5 = fs39.statSync(test);
|
|
68631
68688
|
if (stat5.isFile())
|
|
68632
68689
|
return test;
|
|
68633
68690
|
} catch {}
|
|
@@ -68655,13 +68712,13 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
68655
68712
|
}
|
|
68656
68713
|
const remainder = rawModule.slice(leadingDots).replace(/\./g, "/");
|
|
68657
68714
|
const upDirs = "../".repeat(Math.max(0, leadingDots - 1));
|
|
68658
|
-
const sourceDir =
|
|
68659
|
-
const baseAbs =
|
|
68715
|
+
const sourceDir = path56.dirname(sourceFileAbs);
|
|
68716
|
+
const baseAbs = path56.resolve(sourceDir, upDirs + remainder);
|
|
68660
68717
|
const accept = (test) => {
|
|
68661
68718
|
try {
|
|
68662
|
-
const stat5 =
|
|
68719
|
+
const stat5 = fs39.statSync(test);
|
|
68663
68720
|
if (stat5.isFile()) {
|
|
68664
|
-
const rel =
|
|
68721
|
+
const rel = path56.relative(workspaceRoot, test).replace(/\\/g, "/");
|
|
68665
68722
|
if (rel.startsWith(".."))
|
|
68666
68723
|
return null;
|
|
68667
68724
|
return test;
|
|
@@ -68675,7 +68732,7 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
68675
68732
|
return hit;
|
|
68676
68733
|
}
|
|
68677
68734
|
for (const indexFile of PY_INDEX_CANDIDATES) {
|
|
68678
|
-
const hit = accept(
|
|
68735
|
+
const hit = accept(path56.join(baseAbs, indexFile));
|
|
68679
68736
|
if (hit)
|
|
68680
68737
|
return hit;
|
|
68681
68738
|
}
|
|
@@ -69046,14 +69103,14 @@ function parseRustUses(content) {
|
|
|
69046
69103
|
}
|
|
69047
69104
|
function extractImports2(opts) {
|
|
69048
69105
|
const { absoluteFilePath, workspaceRoot } = opts;
|
|
69049
|
-
const ext =
|
|
69106
|
+
const ext = path56.extname(absoluteFilePath).toLowerCase();
|
|
69050
69107
|
const language = getLanguageFromExtension(ext);
|
|
69051
69108
|
if (!language)
|
|
69052
69109
|
return [];
|
|
69053
69110
|
let content = opts.content;
|
|
69054
69111
|
if (content === undefined) {
|
|
69055
69112
|
try {
|
|
69056
|
-
content =
|
|
69113
|
+
content = fs39.readFileSync(absoluteFilePath, "utf-8");
|
|
69057
69114
|
} catch {
|
|
69058
69115
|
return [];
|
|
69059
69116
|
}
|
|
@@ -69097,9 +69154,9 @@ function extractImports2(opts) {
|
|
|
69097
69154
|
}
|
|
69098
69155
|
|
|
69099
69156
|
// src/graph/symbol-extractor.ts
|
|
69100
|
-
import * as
|
|
69157
|
+
import * as path57 from "node:path";
|
|
69101
69158
|
function extractExportedSymbols(relativeFilePath, workspaceRoot) {
|
|
69102
|
-
const ext =
|
|
69159
|
+
const ext = path57.extname(relativeFilePath).toLowerCase();
|
|
69103
69160
|
const language = getLanguageFromExtension(ext);
|
|
69104
69161
|
if (!language)
|
|
69105
69162
|
return [];
|
|
@@ -69173,7 +69230,7 @@ function findSourceFiles(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
|
69173
69230
|
const dir = stack.pop();
|
|
69174
69231
|
let entries;
|
|
69175
69232
|
try {
|
|
69176
|
-
entries =
|
|
69233
|
+
entries = fs40.readdirSync(dir, { withFileTypes: true });
|
|
69177
69234
|
} catch {
|
|
69178
69235
|
continue;
|
|
69179
69236
|
}
|
|
@@ -69188,15 +69245,15 @@ function findSourceFiles(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
|
69188
69245
|
if (entry.isDirectory()) {
|
|
69189
69246
|
if (skipDirs.has(entry.name))
|
|
69190
69247
|
continue;
|
|
69191
|
-
stack.push(
|
|
69248
|
+
stack.push(path58.join(dir, entry.name));
|
|
69192
69249
|
continue;
|
|
69193
69250
|
}
|
|
69194
69251
|
if (!entry.isFile())
|
|
69195
69252
|
continue;
|
|
69196
|
-
const ext =
|
|
69253
|
+
const ext = path58.extname(entry.name).toLowerCase();
|
|
69197
69254
|
if (!SOURCE_EXT_SET.has(ext))
|
|
69198
69255
|
continue;
|
|
69199
|
-
out2.push(
|
|
69256
|
+
out2.push(path58.join(dir, entry.name));
|
|
69200
69257
|
}
|
|
69201
69258
|
}
|
|
69202
69259
|
return out2;
|
|
@@ -69224,13 +69281,13 @@ async function buildRepoGraph(workspaceRoot, options = {}) {
|
|
|
69224
69281
|
};
|
|
69225
69282
|
}
|
|
69226
69283
|
async function processFile(absoluteFilePath, workspaceRoot) {
|
|
69227
|
-
const ext =
|
|
69284
|
+
const ext = path58.extname(absoluteFilePath).toLowerCase();
|
|
69228
69285
|
const language = getLanguageFromExtension(ext);
|
|
69229
69286
|
if (!language)
|
|
69230
69287
|
return null;
|
|
69231
69288
|
let stats;
|
|
69232
69289
|
try {
|
|
69233
|
-
stats =
|
|
69290
|
+
stats = fs40.statSync(absoluteFilePath);
|
|
69234
69291
|
} catch {
|
|
69235
69292
|
return null;
|
|
69236
69293
|
}
|
|
@@ -69240,11 +69297,11 @@ async function processFile(absoluteFilePath, workspaceRoot) {
|
|
|
69240
69297
|
return null;
|
|
69241
69298
|
let content;
|
|
69242
69299
|
try {
|
|
69243
|
-
content =
|
|
69300
|
+
content = fs40.readFileSync(absoluteFilePath, "utf-8");
|
|
69244
69301
|
} catch {
|
|
69245
69302
|
return null;
|
|
69246
69303
|
}
|
|
69247
|
-
const relPath =
|
|
69304
|
+
const relPath = path58.relative(workspaceRoot, absoluteFilePath).replace(/\\/g, "/");
|
|
69248
69305
|
const imports = extractImports2({
|
|
69249
69306
|
absoluteFilePath,
|
|
69250
69307
|
workspaceRoot,
|
|
@@ -69485,17 +69542,17 @@ function formatSummary(opts) {
|
|
|
69485
69542
|
}
|
|
69486
69543
|
// src/graph/graph-store.ts
|
|
69487
69544
|
import * as crypto6 from "node:crypto";
|
|
69488
|
-
import * as
|
|
69489
|
-
import * as
|
|
69545
|
+
import * as fs41 from "node:fs";
|
|
69546
|
+
import * as path59 from "node:path";
|
|
69490
69547
|
var SWARM_DIR = ".swarm";
|
|
69491
69548
|
function getGraphPath2(workspaceRoot) {
|
|
69492
|
-
return
|
|
69549
|
+
return path59.join(workspaceRoot, SWARM_DIR, REPO_GRAPH_FILENAME2);
|
|
69493
69550
|
}
|
|
69494
69551
|
function loadGraph2(workspaceRoot) {
|
|
69495
69552
|
const file3 = getGraphPath2(workspaceRoot);
|
|
69496
69553
|
let raw;
|
|
69497
69554
|
try {
|
|
69498
|
-
raw =
|
|
69555
|
+
raw = fs41.readFileSync(file3, "utf-8");
|
|
69499
69556
|
} catch {
|
|
69500
69557
|
return null;
|
|
69501
69558
|
}
|
|
@@ -69511,9 +69568,9 @@ function loadGraph2(workspaceRoot) {
|
|
|
69511
69568
|
}
|
|
69512
69569
|
function saveGraph2(workspaceRoot, graph) {
|
|
69513
69570
|
const file3 = getGraphPath2(workspaceRoot);
|
|
69514
|
-
const dir =
|
|
69571
|
+
const dir = path59.dirname(file3);
|
|
69515
69572
|
try {
|
|
69516
|
-
const stat5 =
|
|
69573
|
+
const stat5 = fs41.lstatSync(dir);
|
|
69517
69574
|
if (stat5.isSymbolicLink()) {
|
|
69518
69575
|
throw new Error(`refusing to write graph: ${SWARM_DIR}/ is a symbolic link`);
|
|
69519
69576
|
}
|
|
@@ -69521,14 +69578,14 @@ function saveGraph2(workspaceRoot, graph) {
|
|
|
69521
69578
|
if (err2.code !== "ENOENT")
|
|
69522
69579
|
throw err2;
|
|
69523
69580
|
}
|
|
69524
|
-
|
|
69581
|
+
fs41.mkdirSync(dir, { recursive: true });
|
|
69525
69582
|
const tmp = `${file3}.tmp.${crypto6.randomUUID()}`;
|
|
69526
|
-
|
|
69583
|
+
fs41.writeFileSync(tmp, JSON.stringify(graph), "utf-8");
|
|
69527
69584
|
try {
|
|
69528
|
-
|
|
69585
|
+
fs41.renameSync(tmp, file3);
|
|
69529
69586
|
} catch (renameErr) {
|
|
69530
69587
|
try {
|
|
69531
|
-
|
|
69588
|
+
fs41.unlinkSync(tmp);
|
|
69532
69589
|
} catch {}
|
|
69533
69590
|
throw renameErr;
|
|
69534
69591
|
}
|
|
@@ -69552,7 +69609,7 @@ function getCachedGraph2(directory) {
|
|
|
69552
69609
|
const file3 = getGraphPath2(directory);
|
|
69553
69610
|
let stat5;
|
|
69554
69611
|
try {
|
|
69555
|
-
stat5 =
|
|
69612
|
+
stat5 = fs42.statSync(file3);
|
|
69556
69613
|
} catch {
|
|
69557
69614
|
cache.delete(directory);
|
|
69558
69615
|
return null;
|
|
@@ -69616,8 +69673,8 @@ function buildReviewerBlastRadiusBlock(directory, changedFiles) {
|
|
|
69616
69673
|
|
|
69617
69674
|
// src/hooks/semantic-diff-injection.ts
|
|
69618
69675
|
import * as child_process5 from "node:child_process";
|
|
69619
|
-
import * as
|
|
69620
|
-
import * as
|
|
69676
|
+
import * as fs43 from "node:fs";
|
|
69677
|
+
import * as path61 from "node:path";
|
|
69621
69678
|
|
|
69622
69679
|
// src/diff/ast-diff.ts
|
|
69623
69680
|
init_tree_sitter();
|
|
@@ -70364,17 +70421,17 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
70364
70421
|
const fileConsumers = {};
|
|
70365
70422
|
if (graph) {
|
|
70366
70423
|
for (const f of filesToProcess) {
|
|
70367
|
-
const relativePath =
|
|
70424
|
+
const relativePath = path61.isAbsolute(f) ? path61.relative(directory, f) : f;
|
|
70368
70425
|
const normalized = normalizeGraphPath2(relativePath);
|
|
70369
70426
|
fileConsumers[normalized] = getImporters(graph, normalized).length;
|
|
70370
70427
|
fileConsumers[f] = fileConsumers[normalized];
|
|
70371
70428
|
}
|
|
70372
70429
|
}
|
|
70373
70430
|
for (const filePath of filesToProcess) {
|
|
70374
|
-
const normalizedPath =
|
|
70375
|
-
const resolvedPath =
|
|
70376
|
-
const relativeToDir =
|
|
70377
|
-
if (relativeToDir.startsWith("..") ||
|
|
70431
|
+
const normalizedPath = path61.normalize(filePath);
|
|
70432
|
+
const resolvedPath = path61.resolve(directory, normalizedPath);
|
|
70433
|
+
const relativeToDir = path61.relative(directory, resolvedPath);
|
|
70434
|
+
if (relativeToDir.startsWith("..") || path61.isAbsolute(relativeToDir)) {
|
|
70378
70435
|
continue;
|
|
70379
70436
|
}
|
|
70380
70437
|
try {
|
|
@@ -70401,7 +70458,7 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
70401
70458
|
stdio: "pipe",
|
|
70402
70459
|
maxBuffer: 5 * 1024 * 1024
|
|
70403
70460
|
}) : "";
|
|
70404
|
-
const newContent =
|
|
70461
|
+
const newContent = fs43.readFileSync(path61.join(directory, filePath), "utf-8");
|
|
70405
70462
|
const astResult = await computeASTDiff(filePath, oldContent, newContent);
|
|
70406
70463
|
if (astResult && (astResult.changes.length > 0 || astResult.error !== undefined)) {
|
|
70407
70464
|
astDiffs.push(astResult);
|
|
@@ -70728,7 +70785,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
70728
70785
|
} catch {}
|
|
70729
70786
|
try {
|
|
70730
70787
|
const darkMatterPath = validateSwarmPath(directory, "dark-matter.md");
|
|
70731
|
-
if (!
|
|
70788
|
+
if (!fs45.existsSync(darkMatterPath)) {
|
|
70732
70789
|
const {
|
|
70733
70790
|
detectDarkMatter: detectDarkMatter2,
|
|
70734
70791
|
formatDarkMatterOutput: formatDarkMatterOutput2,
|
|
@@ -70740,10 +70797,10 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
70740
70797
|
});
|
|
70741
70798
|
if (darkMatter && darkMatter.length > 0) {
|
|
70742
70799
|
const darkMatterReport = formatDarkMatterOutput2(darkMatter);
|
|
70743
|
-
await
|
|
70800
|
+
await fs45.promises.writeFile(darkMatterPath, darkMatterReport, "utf-8");
|
|
70744
70801
|
warn(`[system-enhancer] Dark matter scan complete: ${darkMatter.length} co-change patterns found`);
|
|
70745
70802
|
try {
|
|
70746
|
-
const projectName =
|
|
70803
|
+
const projectName = path63.basename(path63.resolve(directory));
|
|
70747
70804
|
const knowledgeEntries = darkMatterToKnowledgeEntries2(darkMatter, projectName);
|
|
70748
70805
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
70749
70806
|
const existingEntries = await readKnowledge(knowledgePath);
|
|
@@ -70807,14 +70864,14 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
70807
70864
|
if (handoffContent) {
|
|
70808
70865
|
const handoffPath = validateSwarmPath(directory, "handoff.md");
|
|
70809
70866
|
const consumedPath = validateSwarmPath(directory, "handoff-consumed.md");
|
|
70810
|
-
if (
|
|
70867
|
+
if (fs45.existsSync(consumedPath)) {
|
|
70811
70868
|
warn("Duplicate handoff detected: handoff-consumed.md already exists");
|
|
70812
|
-
|
|
70869
|
+
fs45.unlinkSync(consumedPath);
|
|
70813
70870
|
}
|
|
70814
|
-
|
|
70871
|
+
fs45.renameSync(handoffPath, consumedPath);
|
|
70815
70872
|
try {
|
|
70816
70873
|
const promptPath = validateSwarmPath(directory, "handoff-prompt.md");
|
|
70817
|
-
|
|
70874
|
+
fs45.unlinkSync(promptPath);
|
|
70818
70875
|
} catch {}
|
|
70819
70876
|
const handoffBlock = `## HANDOFF — Resuming from model switch
|
|
70820
70877
|
The previous model's session ended. Here is your starting context:
|
|
@@ -70942,9 +70999,9 @@ ${lines.join(`
|
|
|
70942
70999
|
try {
|
|
70943
71000
|
const taskId_ccp = ccpSession?.currentTaskId;
|
|
70944
71001
|
if (taskId_ccp && !taskId_ccp.includes("..") && !taskId_ccp.includes("/") && !taskId_ccp.includes("\\") && !taskId_ccp.includes("\x00")) {
|
|
70945
|
-
const evidencePath =
|
|
70946
|
-
if (
|
|
70947
|
-
const evidenceContent =
|
|
71002
|
+
const evidencePath = path63.join(directory, ".swarm", "evidence", `${taskId_ccp}.json`);
|
|
71003
|
+
if (fs45.existsSync(evidencePath)) {
|
|
71004
|
+
const evidenceContent = fs45.readFileSync(evidencePath, "utf-8");
|
|
70948
71005
|
const evidenceData = JSON.parse(evidenceContent);
|
|
70949
71006
|
const rejections = (evidenceData.bundle?.entries ?? []).filter((e) => e.type === "gate" && e.gate_type === "reviewer" && e.verdict === "reject");
|
|
70950
71007
|
if (rejections.length > 0) {
|
|
@@ -71208,11 +71265,11 @@ ${budgetWarning}`);
|
|
|
71208
71265
|
if (handoffContent) {
|
|
71209
71266
|
const handoffPath = validateSwarmPath(directory, "handoff.md");
|
|
71210
71267
|
const consumedPath = validateSwarmPath(directory, "handoff-consumed.md");
|
|
71211
|
-
if (
|
|
71268
|
+
if (fs45.existsSync(consumedPath)) {
|
|
71212
71269
|
warn("Duplicate handoff detected: handoff-consumed.md already exists");
|
|
71213
|
-
|
|
71270
|
+
fs45.unlinkSync(consumedPath);
|
|
71214
71271
|
}
|
|
71215
|
-
|
|
71272
|
+
fs45.renameSync(handoffPath, consumedPath);
|
|
71216
71273
|
const handoffBlock = `## HANDOFF — Resuming from model switch
|
|
71217
71274
|
The previous model's session ended. Here is your starting context:
|
|
71218
71275
|
|
|
@@ -72089,8 +72146,8 @@ init_guardrails();
|
|
|
72089
72146
|
init_hive_promoter();
|
|
72090
72147
|
|
|
72091
72148
|
// src/hooks/incremental-verify.ts
|
|
72092
|
-
import * as
|
|
72093
|
-
import * as
|
|
72149
|
+
import * as fs46 from "node:fs";
|
|
72150
|
+
import * as path64 from "node:path";
|
|
72094
72151
|
|
|
72095
72152
|
// src/hooks/spawn-helper.ts
|
|
72096
72153
|
import * as child_process6 from "node:child_process";
|
|
@@ -72168,21 +72225,21 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
72168
72225
|
// src/hooks/incremental-verify.ts
|
|
72169
72226
|
var emittedSkipAdvisories = new Set;
|
|
72170
72227
|
function detectPackageManager(projectDir) {
|
|
72171
|
-
if (
|
|
72228
|
+
if (fs46.existsSync(path64.join(projectDir, "bun.lockb")))
|
|
72172
72229
|
return "bun";
|
|
72173
|
-
if (
|
|
72230
|
+
if (fs46.existsSync(path64.join(projectDir, "pnpm-lock.yaml")))
|
|
72174
72231
|
return "pnpm";
|
|
72175
|
-
if (
|
|
72232
|
+
if (fs46.existsSync(path64.join(projectDir, "yarn.lock")))
|
|
72176
72233
|
return "yarn";
|
|
72177
|
-
if (
|
|
72234
|
+
if (fs46.existsSync(path64.join(projectDir, "package-lock.json")))
|
|
72178
72235
|
return "npm";
|
|
72179
72236
|
return "bun";
|
|
72180
72237
|
}
|
|
72181
72238
|
function detectTypecheckCommand(projectDir) {
|
|
72182
|
-
const pkgPath =
|
|
72183
|
-
if (
|
|
72239
|
+
const pkgPath = path64.join(projectDir, "package.json");
|
|
72240
|
+
if (fs46.existsSync(pkgPath)) {
|
|
72184
72241
|
try {
|
|
72185
|
-
const pkg = JSON.parse(
|
|
72242
|
+
const pkg = JSON.parse(fs46.readFileSync(pkgPath, "utf8"));
|
|
72186
72243
|
const scripts = pkg.scripts;
|
|
72187
72244
|
if (scripts?.typecheck) {
|
|
72188
72245
|
const pm = detectPackageManager(projectDir);
|
|
@@ -72196,8 +72253,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
72196
72253
|
...pkg.dependencies,
|
|
72197
72254
|
...pkg.devDependencies
|
|
72198
72255
|
};
|
|
72199
|
-
if (!deps?.typescript && !
|
|
72200
|
-
const hasTSMarkers = deps?.typescript ||
|
|
72256
|
+
if (!deps?.typescript && !fs46.existsSync(path64.join(projectDir, "tsconfig.json"))) {}
|
|
72257
|
+
const hasTSMarkers = deps?.typescript || fs46.existsSync(path64.join(projectDir, "tsconfig.json"));
|
|
72201
72258
|
if (hasTSMarkers) {
|
|
72202
72259
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
72203
72260
|
}
|
|
@@ -72205,17 +72262,17 @@ function detectTypecheckCommand(projectDir) {
|
|
|
72205
72262
|
return null;
|
|
72206
72263
|
}
|
|
72207
72264
|
}
|
|
72208
|
-
if (
|
|
72265
|
+
if (fs46.existsSync(path64.join(projectDir, "go.mod"))) {
|
|
72209
72266
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
72210
72267
|
}
|
|
72211
|
-
if (
|
|
72268
|
+
if (fs46.existsSync(path64.join(projectDir, "Cargo.toml"))) {
|
|
72212
72269
|
return { command: ["cargo", "check"], language: "rust" };
|
|
72213
72270
|
}
|
|
72214
|
-
if (
|
|
72271
|
+
if (fs46.existsSync(path64.join(projectDir, "pyproject.toml")) || fs46.existsSync(path64.join(projectDir, "requirements.txt")) || fs46.existsSync(path64.join(projectDir, "setup.py"))) {
|
|
72215
72272
|
return { command: null, language: "python" };
|
|
72216
72273
|
}
|
|
72217
72274
|
try {
|
|
72218
|
-
const entries =
|
|
72275
|
+
const entries = fs46.readdirSync(projectDir);
|
|
72219
72276
|
if (entries.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
72220
72277
|
return {
|
|
72221
72278
|
command: ["dotnet", "build", "--no-restore"],
|
|
@@ -72561,7 +72618,7 @@ init_scope_persistence();
|
|
|
72561
72618
|
init_state();
|
|
72562
72619
|
init_delegation_gate();
|
|
72563
72620
|
init_normalize_tool_name();
|
|
72564
|
-
import * as
|
|
72621
|
+
import * as path66 from "node:path";
|
|
72565
72622
|
var WRITE_TOOLS = new Set(WRITE_TOOL_NAMES);
|
|
72566
72623
|
function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
72567
72624
|
const enabled = config3.enabled ?? true;
|
|
@@ -72619,13 +72676,13 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
|
72619
72676
|
}
|
|
72620
72677
|
function isFileInScope(filePath, scopeEntries, directory) {
|
|
72621
72678
|
const dir = directory ?? process.cwd();
|
|
72622
|
-
const resolvedFile =
|
|
72679
|
+
const resolvedFile = path66.resolve(dir, filePath);
|
|
72623
72680
|
return scopeEntries.some((scope) => {
|
|
72624
|
-
const resolvedScope =
|
|
72681
|
+
const resolvedScope = path66.resolve(dir, scope);
|
|
72625
72682
|
if (resolvedFile === resolvedScope)
|
|
72626
72683
|
return true;
|
|
72627
|
-
const rel =
|
|
72628
|
-
return rel.length > 0 && !rel.startsWith("..") && !
|
|
72684
|
+
const rel = path66.relative(resolvedScope, resolvedFile);
|
|
72685
|
+
return rel.length > 0 && !rel.startsWith("..") && !path66.isAbsolute(rel);
|
|
72629
72686
|
});
|
|
72630
72687
|
}
|
|
72631
72688
|
|
|
@@ -72676,8 +72733,8 @@ function createSelfReviewHook(config3, injectAdvisory) {
|
|
|
72676
72733
|
}
|
|
72677
72734
|
|
|
72678
72735
|
// src/hooks/slop-detector.ts
|
|
72679
|
-
import * as
|
|
72680
|
-
import * as
|
|
72736
|
+
import * as fs48 from "node:fs";
|
|
72737
|
+
import * as path67 from "node:path";
|
|
72681
72738
|
var WRITE_EDIT_TOOLS = new Set([
|
|
72682
72739
|
"write",
|
|
72683
72740
|
"edit",
|
|
@@ -72722,12 +72779,12 @@ function checkBoilerplateExplosion(content, taskDescription, threshold) {
|
|
|
72722
72779
|
function walkFiles(dir, exts, deadline) {
|
|
72723
72780
|
const results = [];
|
|
72724
72781
|
try {
|
|
72725
|
-
for (const entry of
|
|
72782
|
+
for (const entry of fs48.readdirSync(dir, { withFileTypes: true })) {
|
|
72726
72783
|
if (deadline !== undefined && Date.now() > deadline)
|
|
72727
72784
|
break;
|
|
72728
72785
|
if (entry.isSymbolicLink())
|
|
72729
72786
|
continue;
|
|
72730
|
-
const full =
|
|
72787
|
+
const full = path67.join(dir, entry.name);
|
|
72731
72788
|
if (entry.isDirectory()) {
|
|
72732
72789
|
if (entry.name === "node_modules" || entry.name === ".git")
|
|
72733
72790
|
continue;
|
|
@@ -72742,7 +72799,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
72742
72799
|
return results;
|
|
72743
72800
|
}
|
|
72744
72801
|
function checkDeadExports(content, projectDir, startTime) {
|
|
72745
|
-
const hasPackageJson =
|
|
72802
|
+
const hasPackageJson = fs48.existsSync(path67.join(projectDir, "package.json"));
|
|
72746
72803
|
if (!hasPackageJson)
|
|
72747
72804
|
return null;
|
|
72748
72805
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -72765,7 +72822,7 @@ function checkDeadExports(content, projectDir, startTime) {
|
|
|
72765
72822
|
if (found || Date.now() - startTime > 480)
|
|
72766
72823
|
break;
|
|
72767
72824
|
try {
|
|
72768
|
-
const text =
|
|
72825
|
+
const text = fs48.readFileSync(file3, "utf-8");
|
|
72769
72826
|
if (importPattern.test(text))
|
|
72770
72827
|
found = true;
|
|
72771
72828
|
importPattern.lastIndex = 0;
|
|
@@ -72856,17 +72913,17 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
|
|
|
72856
72913
|
for (const utilDir of utilityDirs) {
|
|
72857
72914
|
if (Date.now() > deadline)
|
|
72858
72915
|
break;
|
|
72859
|
-
const utilPath =
|
|
72860
|
-
if (!
|
|
72916
|
+
const utilPath = path67.join(projectDir, utilDir);
|
|
72917
|
+
if (!fs48.existsSync(utilPath))
|
|
72861
72918
|
continue;
|
|
72862
72919
|
const files = walkFiles(utilPath, [".ts", ".tsx", ".js", ".jsx"], deadline);
|
|
72863
72920
|
for (const file3 of files) {
|
|
72864
72921
|
if (Date.now() > deadline)
|
|
72865
72922
|
break;
|
|
72866
|
-
if (targetFile &&
|
|
72923
|
+
if (targetFile && path67.resolve(file3) === path67.resolve(targetFile))
|
|
72867
72924
|
continue;
|
|
72868
72925
|
try {
|
|
72869
|
-
const text =
|
|
72926
|
+
const text = fs48.readFileSync(file3, "utf-8");
|
|
72870
72927
|
for (const name2 of newExports) {
|
|
72871
72928
|
const exportPattern = new RegExp(`\\bexport\\s+(?:function|class|const|type|interface)\\s+${name2}\\b`);
|
|
72872
72929
|
if (exportPattern.test(text)) {
|
|
@@ -72949,7 +73006,7 @@ Review before proceeding.`;
|
|
|
72949
73006
|
// src/hooks/steering-consumed.ts
|
|
72950
73007
|
init_bun_compat();
|
|
72951
73008
|
init_utils2();
|
|
72952
|
-
import * as
|
|
73009
|
+
import * as fs49 from "node:fs";
|
|
72953
73010
|
function recordSteeringConsumed(directory, directiveId) {
|
|
72954
73011
|
try {
|
|
72955
73012
|
const eventsPath = validateSwarmPath(directory, "events.jsonl");
|
|
@@ -72958,7 +73015,7 @@ function recordSteeringConsumed(directory, directiveId) {
|
|
|
72958
73015
|
directiveId,
|
|
72959
73016
|
timestamp: new Date().toISOString()
|
|
72960
73017
|
};
|
|
72961
|
-
|
|
73018
|
+
fs49.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
72962
73019
|
`, "utf-8");
|
|
72963
73020
|
} catch {}
|
|
72964
73021
|
}
|
|
@@ -73000,15 +73057,15 @@ function createSteeringConsumedHook(directory) {
|
|
|
73000
73057
|
|
|
73001
73058
|
// src/hooks/trajectory-logger.ts
|
|
73002
73059
|
init_manager2();
|
|
73003
|
-
import * as
|
|
73004
|
-
import * as
|
|
73060
|
+
import * as fs51 from "node:fs/promises";
|
|
73061
|
+
import * as path69 from "node:path";
|
|
73005
73062
|
|
|
73006
73063
|
// src/prm/trajectory-store.ts
|
|
73007
73064
|
init_utils2();
|
|
73008
|
-
import * as
|
|
73009
|
-
import * as
|
|
73065
|
+
import * as fs50 from "node:fs/promises";
|
|
73066
|
+
import * as path68 from "node:path";
|
|
73010
73067
|
function getTrajectoryPath(sessionId, directory) {
|
|
73011
|
-
const relativePath =
|
|
73068
|
+
const relativePath = path68.join("trajectories", `${sessionId}.jsonl`);
|
|
73012
73069
|
return validateSwarmPath(directory, relativePath);
|
|
73013
73070
|
}
|
|
73014
73071
|
var _inMemoryTrajectoryCache = new Map;
|
|
@@ -73027,10 +73084,10 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
73027
73084
|
_inMemoryTrajectoryCache.set(sessionId, cached3);
|
|
73028
73085
|
}
|
|
73029
73086
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
73030
|
-
await
|
|
73087
|
+
await fs50.mkdir(path68.dirname(trajectoryPath), { recursive: true });
|
|
73031
73088
|
const line = `${JSON.stringify(entry)}
|
|
73032
73089
|
`;
|
|
73033
|
-
await
|
|
73090
|
+
await fs50.appendFile(trajectoryPath, line, "utf-8");
|
|
73034
73091
|
} catch (err2) {
|
|
73035
73092
|
console.warn(`[trajectory-store] Failed to append trajectory entry: ${err2}`);
|
|
73036
73093
|
}
|
|
@@ -73038,7 +73095,7 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
73038
73095
|
async function readTrajectory(sessionId, directory) {
|
|
73039
73096
|
try {
|
|
73040
73097
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
73041
|
-
const content = await
|
|
73098
|
+
const content = await fs50.readFile(trajectoryPath, "utf-8");
|
|
73042
73099
|
const lines = content.split(`
|
|
73043
73100
|
`).filter((line) => line.trim().length > 0);
|
|
73044
73101
|
const entries = [];
|
|
@@ -73062,15 +73119,15 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
|
|
|
73062
73119
|
for (const subdir of ["trajectories", "replays"]) {
|
|
73063
73120
|
try {
|
|
73064
73121
|
const dirPath = validateSwarmPath(directory, subdir);
|
|
73065
|
-
const entries = await
|
|
73122
|
+
const entries = await fs50.readdir(dirPath, { withFileTypes: true });
|
|
73066
73123
|
for (const entry of entries) {
|
|
73067
73124
|
if (!entry.isFile())
|
|
73068
73125
|
continue;
|
|
73069
|
-
const filePath =
|
|
73126
|
+
const filePath = path68.join(dirPath, entry.name);
|
|
73070
73127
|
try {
|
|
73071
|
-
const stat6 = await
|
|
73128
|
+
const stat6 = await fs50.stat(filePath);
|
|
73072
73129
|
if (now - stat6.mtimeMs > cutoffMs) {
|
|
73073
|
-
await
|
|
73130
|
+
await fs50.unlink(filePath);
|
|
73074
73131
|
}
|
|
73075
73132
|
} catch {}
|
|
73076
73133
|
}
|
|
@@ -73120,7 +73177,7 @@ function isSensitiveKey(key) {
|
|
|
73120
73177
|
}
|
|
73121
73178
|
async function truncateTrajectoryFile(filePath, maxLines) {
|
|
73122
73179
|
try {
|
|
73123
|
-
const content = await
|
|
73180
|
+
const content = await fs51.readFile(filePath, "utf-8");
|
|
73124
73181
|
const lines = content.split(`
|
|
73125
73182
|
`).filter((line) => line.trim().length > 0);
|
|
73126
73183
|
if (lines.length <= maxLines) {
|
|
@@ -73128,7 +73185,7 @@ async function truncateTrajectoryFile(filePath, maxLines) {
|
|
|
73128
73185
|
}
|
|
73129
73186
|
const keepCount = Math.floor(maxLines / 2);
|
|
73130
73187
|
const keptLines = lines.slice(-keepCount);
|
|
73131
|
-
await
|
|
73188
|
+
await fs51.writeFile(filePath, `${keptLines.join(`
|
|
73132
73189
|
`)}
|
|
73133
73190
|
`, "utf-8");
|
|
73134
73191
|
} catch {}
|
|
@@ -73258,13 +73315,13 @@ function createTrajectoryLoggerHook(config3, _directory) {
|
|
|
73258
73315
|
elapsed_ms
|
|
73259
73316
|
};
|
|
73260
73317
|
const sanitized = sanitizeTaskId2(taskId);
|
|
73261
|
-
const relativePath =
|
|
73318
|
+
const relativePath = path69.join("evidence", sanitized, "trajectory.jsonl");
|
|
73262
73319
|
const trajectoryPath = validateSwarmPath(_directory, relativePath);
|
|
73263
73320
|
try {
|
|
73264
|
-
await
|
|
73321
|
+
await fs51.mkdir(path69.dirname(trajectoryPath), { recursive: true });
|
|
73265
73322
|
const line = `${JSON.stringify(entry)}
|
|
73266
73323
|
`;
|
|
73267
|
-
await
|
|
73324
|
+
await fs51.appendFile(trajectoryPath, line, "utf-8");
|
|
73268
73325
|
await truncateTrajectoryFile(trajectoryPath, maxLines);
|
|
73269
73326
|
} catch {}
|
|
73270
73327
|
try {
|
|
@@ -73811,17 +73868,17 @@ init_state();
|
|
|
73811
73868
|
init_telemetry();
|
|
73812
73869
|
|
|
73813
73870
|
// src/prm/replay.ts
|
|
73814
|
-
import { promises as
|
|
73815
|
-
import
|
|
73871
|
+
import { promises as fs52 } from "node:fs";
|
|
73872
|
+
import path70 from "node:path";
|
|
73816
73873
|
function isPathSafe2(targetPath, basePath) {
|
|
73817
|
-
const resolvedTarget =
|
|
73818
|
-
const resolvedBase =
|
|
73819
|
-
const rel =
|
|
73820
|
-
return !rel.startsWith("..") && !
|
|
73874
|
+
const resolvedTarget = path70.resolve(targetPath);
|
|
73875
|
+
const resolvedBase = path70.resolve(basePath);
|
|
73876
|
+
const rel = path70.relative(resolvedBase, resolvedTarget);
|
|
73877
|
+
return !rel.startsWith("..") && !path70.isAbsolute(rel);
|
|
73821
73878
|
}
|
|
73822
73879
|
function isWithinReplaysDir(targetPath) {
|
|
73823
|
-
const resolved =
|
|
73824
|
-
const parts2 = resolved.split(
|
|
73880
|
+
const resolved = path70.resolve(targetPath);
|
|
73881
|
+
const parts2 = resolved.split(path70.sep);
|
|
73825
73882
|
for (let i2 = 0;i2 < parts2.length - 1; i2++) {
|
|
73826
73883
|
if (parts2[i2] === ".swarm" && parts2[i2 + 1] === "replays") {
|
|
73827
73884
|
return true;
|
|
@@ -73834,15 +73891,15 @@ function sanitizeFilename(input) {
|
|
|
73834
73891
|
}
|
|
73835
73892
|
async function startReplayRecording(sessionID, directory) {
|
|
73836
73893
|
try {
|
|
73837
|
-
const replayDir =
|
|
73894
|
+
const replayDir = path70.join(directory, ".swarm", "replays");
|
|
73838
73895
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
73839
73896
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
73840
|
-
const filepath =
|
|
73897
|
+
const filepath = path70.join(replayDir, filename);
|
|
73841
73898
|
if (!isPathSafe2(filepath, replayDir)) {
|
|
73842
73899
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
73843
73900
|
return null;
|
|
73844
73901
|
}
|
|
73845
|
-
await
|
|
73902
|
+
await fs52.mkdir(replayDir, { recursive: true });
|
|
73846
73903
|
return filepath;
|
|
73847
73904
|
} catch (err2) {
|
|
73848
73905
|
console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err2}`);
|
|
@@ -73862,7 +73919,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
|
|
|
73862
73919
|
};
|
|
73863
73920
|
const line = `${JSON.stringify(fullEntry)}
|
|
73864
73921
|
`;
|
|
73865
|
-
await
|
|
73922
|
+
await fs52.appendFile(artifactPath, line, "utf-8");
|
|
73866
73923
|
} catch (err2) {
|
|
73867
73924
|
console.warn(`[replay] Failed to record entry: ${err2}`);
|
|
73868
73925
|
}
|
|
@@ -74210,8 +74267,8 @@ init_telemetry();
|
|
|
74210
74267
|
// src/tools/batch-symbols.ts
|
|
74211
74268
|
init_dist();
|
|
74212
74269
|
init_create_tool();
|
|
74213
|
-
import * as
|
|
74214
|
-
import * as
|
|
74270
|
+
import * as fs53 from "node:fs";
|
|
74271
|
+
import * as path71 from "node:path";
|
|
74215
74272
|
init_path_security();
|
|
74216
74273
|
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
74217
74274
|
function containsWindowsAttacks2(str) {
|
|
@@ -74228,14 +74285,14 @@ function containsWindowsAttacks2(str) {
|
|
|
74228
74285
|
}
|
|
74229
74286
|
function isPathInWorkspace2(filePath, workspace) {
|
|
74230
74287
|
try {
|
|
74231
|
-
const resolvedPath =
|
|
74232
|
-
if (!
|
|
74288
|
+
const resolvedPath = path71.resolve(workspace, filePath);
|
|
74289
|
+
if (!fs53.existsSync(resolvedPath)) {
|
|
74233
74290
|
return true;
|
|
74234
74291
|
}
|
|
74235
|
-
const realWorkspace =
|
|
74236
|
-
const realResolvedPath =
|
|
74237
|
-
const relativePath =
|
|
74238
|
-
if (relativePath.startsWith("..") ||
|
|
74292
|
+
const realWorkspace = fs53.realpathSync(workspace);
|
|
74293
|
+
const realResolvedPath = fs53.realpathSync(resolvedPath);
|
|
74294
|
+
const relativePath = path71.relative(realWorkspace, realResolvedPath);
|
|
74295
|
+
if (relativePath.startsWith("..") || path71.isAbsolute(relativePath)) {
|
|
74239
74296
|
return false;
|
|
74240
74297
|
}
|
|
74241
74298
|
return true;
|
|
@@ -74244,7 +74301,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
74244
74301
|
}
|
|
74245
74302
|
}
|
|
74246
74303
|
function processFile2(file3, cwd, exportedOnly) {
|
|
74247
|
-
const ext =
|
|
74304
|
+
const ext = path71.extname(file3);
|
|
74248
74305
|
if (containsControlChars(file3)) {
|
|
74249
74306
|
return {
|
|
74250
74307
|
file: file3,
|
|
@@ -74277,8 +74334,8 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
74277
74334
|
errorType: "path-outside-workspace"
|
|
74278
74335
|
};
|
|
74279
74336
|
}
|
|
74280
|
-
const fullPath =
|
|
74281
|
-
if (!
|
|
74337
|
+
const fullPath = path71.join(cwd, file3);
|
|
74338
|
+
if (!fs53.existsSync(fullPath)) {
|
|
74282
74339
|
return {
|
|
74283
74340
|
file: file3,
|
|
74284
74341
|
success: false,
|
|
@@ -74309,14 +74366,14 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
74309
74366
|
}
|
|
74310
74367
|
let isEmptyFile = false;
|
|
74311
74368
|
try {
|
|
74312
|
-
const stats =
|
|
74369
|
+
const stats = fs53.statSync(fullPath);
|
|
74313
74370
|
if (stats.size === 0) {
|
|
74314
74371
|
isEmptyFile = true;
|
|
74315
74372
|
}
|
|
74316
74373
|
} catch {}
|
|
74317
74374
|
if (syms.length === 0) {
|
|
74318
74375
|
try {
|
|
74319
|
-
const content =
|
|
74376
|
+
const content = fs53.readFileSync(fullPath, "utf-8");
|
|
74320
74377
|
if (content.trim().length === 0) {
|
|
74321
74378
|
isEmptyFile = true;
|
|
74322
74379
|
}
|
|
@@ -74568,25 +74625,25 @@ init_manager2();
|
|
|
74568
74625
|
init_task_id();
|
|
74569
74626
|
init_create_tool();
|
|
74570
74627
|
init_resolve_working_directory();
|
|
74571
|
-
import * as
|
|
74572
|
-
import * as
|
|
74628
|
+
import * as fs54 from "node:fs";
|
|
74629
|
+
import * as path72 from "node:path";
|
|
74573
74630
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
74574
74631
|
function isValidTaskId3(taskId) {
|
|
74575
74632
|
return isStrictTaskId(taskId);
|
|
74576
74633
|
}
|
|
74577
74634
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
74578
|
-
const normalizedWorkspace =
|
|
74579
|
-
const swarmPath =
|
|
74580
|
-
const normalizedPath =
|
|
74635
|
+
const normalizedWorkspace = path72.resolve(workspaceRoot);
|
|
74636
|
+
const swarmPath = path72.join(normalizedWorkspace, ".swarm", "evidence");
|
|
74637
|
+
const normalizedPath = path72.resolve(filePath);
|
|
74581
74638
|
return normalizedPath.startsWith(swarmPath);
|
|
74582
74639
|
}
|
|
74583
74640
|
function readEvidenceFile(evidencePath) {
|
|
74584
|
-
if (!
|
|
74641
|
+
if (!fs54.existsSync(evidencePath)) {
|
|
74585
74642
|
return null;
|
|
74586
74643
|
}
|
|
74587
74644
|
let content;
|
|
74588
74645
|
try {
|
|
74589
|
-
content =
|
|
74646
|
+
content = fs54.readFileSync(evidencePath, "utf-8");
|
|
74590
74647
|
} catch {
|
|
74591
74648
|
return null;
|
|
74592
74649
|
}
|
|
@@ -74658,7 +74715,7 @@ var check_gate_status = createSwarmTool({
|
|
|
74658
74715
|
};
|
|
74659
74716
|
return JSON.stringify(errorResult, null, 2);
|
|
74660
74717
|
}
|
|
74661
|
-
const evidencePath =
|
|
74718
|
+
const evidencePath = path72.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
74662
74719
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
74663
74720
|
const errorResult = {
|
|
74664
74721
|
taskId: taskIdInput,
|
|
@@ -74754,8 +74811,8 @@ init_utils2();
|
|
|
74754
74811
|
init_state();
|
|
74755
74812
|
init_create_tool();
|
|
74756
74813
|
init_resolve_working_directory();
|
|
74757
|
-
import * as
|
|
74758
|
-
import * as
|
|
74814
|
+
import * as fs55 from "node:fs";
|
|
74815
|
+
import * as path73 from "node:path";
|
|
74759
74816
|
function extractMatches(regex, text) {
|
|
74760
74817
|
return Array.from(text.matchAll(regex));
|
|
74761
74818
|
}
|
|
@@ -74849,7 +74906,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74849
74906
|
let plan;
|
|
74850
74907
|
try {
|
|
74851
74908
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
74852
|
-
const planRaw =
|
|
74909
|
+
const planRaw = fs55.readFileSync(planPath, "utf-8");
|
|
74853
74910
|
plan = JSON.parse(planRaw);
|
|
74854
74911
|
} catch {
|
|
74855
74912
|
const result2 = {
|
|
@@ -74907,10 +74964,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74907
74964
|
let hasFileReadFailure = false;
|
|
74908
74965
|
for (const filePath of fileTargets) {
|
|
74909
74966
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
74910
|
-
const resolvedPath =
|
|
74911
|
-
const projectRoot =
|
|
74912
|
-
const relative16 =
|
|
74913
|
-
const withinProject = relative16 === "" || !relative16.startsWith("..") && !
|
|
74967
|
+
const resolvedPath = path73.resolve(directory, normalizedPath);
|
|
74968
|
+
const projectRoot = path73.resolve(directory);
|
|
74969
|
+
const relative16 = path73.relative(projectRoot, resolvedPath);
|
|
74970
|
+
const withinProject = relative16 === "" || !relative16.startsWith("..") && !path73.isAbsolute(relative16);
|
|
74914
74971
|
if (!withinProject) {
|
|
74915
74972
|
blockedTasks.push({
|
|
74916
74973
|
task_id: task.id,
|
|
@@ -74923,7 +74980,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74923
74980
|
}
|
|
74924
74981
|
let fileContent;
|
|
74925
74982
|
try {
|
|
74926
|
-
fileContent =
|
|
74983
|
+
fileContent = fs55.readFileSync(resolvedPath, "utf-8");
|
|
74927
74984
|
} catch {
|
|
74928
74985
|
blockedTasks.push({
|
|
74929
74986
|
task_id: task.id,
|
|
@@ -74965,9 +75022,9 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74965
75022
|
blockedTasks
|
|
74966
75023
|
};
|
|
74967
75024
|
try {
|
|
74968
|
-
const evidenceDir =
|
|
74969
|
-
const evidencePath =
|
|
74970
|
-
|
|
75025
|
+
const evidenceDir = path73.join(directory, ".swarm", "evidence", `${phase}`);
|
|
75026
|
+
const evidencePath = path73.join(evidenceDir, "completion-verify.json");
|
|
75027
|
+
fs55.mkdirSync(evidenceDir, { recursive: true });
|
|
74971
75028
|
const evidenceBundle = {
|
|
74972
75029
|
schema_version: "1.0.0",
|
|
74973
75030
|
task_id: "completion-verify",
|
|
@@ -74988,7 +75045,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74988
75045
|
}
|
|
74989
75046
|
]
|
|
74990
75047
|
};
|
|
74991
|
-
|
|
75048
|
+
fs55.writeFileSync(evidencePath, JSON.stringify(evidenceBundle, null, 2), "utf-8");
|
|
74992
75049
|
} catch {}
|
|
74993
75050
|
return JSON.stringify(result, null, 2);
|
|
74994
75051
|
}
|
|
@@ -75042,12 +75099,12 @@ var completion_verify = createSwarmTool({
|
|
|
75042
75099
|
});
|
|
75043
75100
|
// src/tools/complexity-hotspots.ts
|
|
75044
75101
|
init_zod();
|
|
75045
|
-
import * as
|
|
75046
|
-
import * as
|
|
75102
|
+
import * as fs57 from "node:fs";
|
|
75103
|
+
import * as path75 from "node:path";
|
|
75047
75104
|
|
|
75048
75105
|
// src/quality/metrics.ts
|
|
75049
|
-
import * as
|
|
75050
|
-
import * as
|
|
75106
|
+
import * as fs56 from "node:fs";
|
|
75107
|
+
import * as path74 from "node:path";
|
|
75051
75108
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
75052
75109
|
var MIN_DUPLICATION_LINES = 10;
|
|
75053
75110
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -75085,11 +75142,11 @@ function estimateCyclomaticComplexity(content) {
|
|
|
75085
75142
|
}
|
|
75086
75143
|
function getComplexityForFile(filePath) {
|
|
75087
75144
|
try {
|
|
75088
|
-
const stat6 =
|
|
75145
|
+
const stat6 = fs56.statSync(filePath);
|
|
75089
75146
|
if (stat6.size > MAX_FILE_SIZE_BYTES4) {
|
|
75090
75147
|
return null;
|
|
75091
75148
|
}
|
|
75092
|
-
const content =
|
|
75149
|
+
const content = fs56.readFileSync(filePath, "utf-8");
|
|
75093
75150
|
return estimateCyclomaticComplexity(content);
|
|
75094
75151
|
} catch {
|
|
75095
75152
|
return null;
|
|
@@ -75099,8 +75156,8 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
75099
75156
|
let totalComplexity = 0;
|
|
75100
75157
|
const analyzedFiles = [];
|
|
75101
75158
|
for (const file3 of files) {
|
|
75102
|
-
const fullPath =
|
|
75103
|
-
if (!
|
|
75159
|
+
const fullPath = path74.isAbsolute(file3) ? file3 : path74.join(workingDir, file3);
|
|
75160
|
+
if (!fs56.existsSync(fullPath)) {
|
|
75104
75161
|
continue;
|
|
75105
75162
|
}
|
|
75106
75163
|
const complexity = getComplexityForFile(fullPath);
|
|
@@ -75221,8 +75278,8 @@ function countGoExports(content) {
|
|
|
75221
75278
|
}
|
|
75222
75279
|
function getExportCountForFile(filePath) {
|
|
75223
75280
|
try {
|
|
75224
|
-
const content =
|
|
75225
|
-
const ext =
|
|
75281
|
+
const content = fs56.readFileSync(filePath, "utf-8");
|
|
75282
|
+
const ext = path74.extname(filePath).toLowerCase();
|
|
75226
75283
|
switch (ext) {
|
|
75227
75284
|
case ".ts":
|
|
75228
75285
|
case ".tsx":
|
|
@@ -75248,8 +75305,8 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
75248
75305
|
let totalExports = 0;
|
|
75249
75306
|
const analyzedFiles = [];
|
|
75250
75307
|
for (const file3 of files) {
|
|
75251
|
-
const fullPath =
|
|
75252
|
-
if (!
|
|
75308
|
+
const fullPath = path74.isAbsolute(file3) ? file3 : path74.join(workingDir, file3);
|
|
75309
|
+
if (!fs56.existsSync(fullPath)) {
|
|
75253
75310
|
continue;
|
|
75254
75311
|
}
|
|
75255
75312
|
const exports = getExportCountForFile(fullPath);
|
|
@@ -75282,16 +75339,16 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
75282
75339
|
let duplicateLines = 0;
|
|
75283
75340
|
const analyzedFiles = [];
|
|
75284
75341
|
for (const file3 of files) {
|
|
75285
|
-
const fullPath =
|
|
75286
|
-
if (!
|
|
75342
|
+
const fullPath = path74.isAbsolute(file3) ? file3 : path74.join(workingDir, file3);
|
|
75343
|
+
if (!fs56.existsSync(fullPath)) {
|
|
75287
75344
|
continue;
|
|
75288
75345
|
}
|
|
75289
75346
|
try {
|
|
75290
|
-
const stat6 =
|
|
75347
|
+
const stat6 = fs56.statSync(fullPath);
|
|
75291
75348
|
if (stat6.size > MAX_FILE_SIZE_BYTES4) {
|
|
75292
75349
|
continue;
|
|
75293
75350
|
}
|
|
75294
|
-
const content =
|
|
75351
|
+
const content = fs56.readFileSync(fullPath, "utf-8");
|
|
75295
75352
|
const lines = content.split(`
|
|
75296
75353
|
`).filter((line) => line.trim().length > 0);
|
|
75297
75354
|
if (lines.length < MIN_DUPLICATION_LINES) {
|
|
@@ -75315,8 +75372,8 @@ function countCodeLines(content) {
|
|
|
75315
75372
|
return lines.length;
|
|
75316
75373
|
}
|
|
75317
75374
|
function isTestFile(filePath) {
|
|
75318
|
-
const basename11 =
|
|
75319
|
-
const _ext =
|
|
75375
|
+
const basename11 = path74.basename(filePath);
|
|
75376
|
+
const _ext = path74.extname(filePath).toLowerCase();
|
|
75320
75377
|
const testPatterns = [
|
|
75321
75378
|
".test.",
|
|
75322
75379
|
".spec.",
|
|
@@ -75397,8 +75454,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
75397
75454
|
}
|
|
75398
75455
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
75399
75456
|
}
|
|
75400
|
-
function matchesGlobSegment(
|
|
75401
|
-
const normalizedPath =
|
|
75457
|
+
function matchesGlobSegment(path75, glob) {
|
|
75458
|
+
const normalizedPath = path75.replace(/\\/g, "/");
|
|
75402
75459
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
75403
75460
|
if (normalizedPath.includes("//")) {
|
|
75404
75461
|
return false;
|
|
@@ -75429,8 +75486,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
75429
75486
|
function hasGlobstar(glob) {
|
|
75430
75487
|
return glob.includes("**");
|
|
75431
75488
|
}
|
|
75432
|
-
function globMatches(
|
|
75433
|
-
const normalizedPath =
|
|
75489
|
+
function globMatches(path75, glob) {
|
|
75490
|
+
const normalizedPath = path75.replace(/\\/g, "/");
|
|
75434
75491
|
if (!glob || glob === "") {
|
|
75435
75492
|
if (normalizedPath.includes("//")) {
|
|
75436
75493
|
return false;
|
|
@@ -75466,31 +75523,31 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
75466
75523
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
75467
75524
|
let testLines = 0;
|
|
75468
75525
|
let codeLines = 0;
|
|
75469
|
-
const srcDir =
|
|
75470
|
-
if (
|
|
75526
|
+
const srcDir = path74.join(workingDir, "src");
|
|
75527
|
+
if (fs56.existsSync(srcDir)) {
|
|
75471
75528
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
75472
75529
|
codeLines += lines;
|
|
75473
75530
|
});
|
|
75474
75531
|
}
|
|
75475
75532
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
75476
75533
|
for (const dir of possibleSrcDirs) {
|
|
75477
|
-
const dirPath =
|
|
75478
|
-
if (
|
|
75534
|
+
const dirPath = path74.join(workingDir, dir);
|
|
75535
|
+
if (fs56.existsSync(dirPath)) {
|
|
75479
75536
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
75480
75537
|
codeLines += lines;
|
|
75481
75538
|
});
|
|
75482
75539
|
}
|
|
75483
75540
|
}
|
|
75484
|
-
const testsDir =
|
|
75485
|
-
if (
|
|
75541
|
+
const testsDir = path74.join(workingDir, "tests");
|
|
75542
|
+
if (fs56.existsSync(testsDir)) {
|
|
75486
75543
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
75487
75544
|
testLines += lines;
|
|
75488
75545
|
});
|
|
75489
75546
|
}
|
|
75490
75547
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
75491
75548
|
for (const dir of possibleTestDirs) {
|
|
75492
|
-
const dirPath =
|
|
75493
|
-
if (
|
|
75549
|
+
const dirPath = path74.join(workingDir, dir);
|
|
75550
|
+
if (fs56.existsSync(dirPath) && dirPath !== testsDir) {
|
|
75494
75551
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
75495
75552
|
testLines += lines;
|
|
75496
75553
|
});
|
|
@@ -75502,9 +75559,9 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
75502
75559
|
}
|
|
75503
75560
|
async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
|
|
75504
75561
|
try {
|
|
75505
|
-
const entries =
|
|
75562
|
+
const entries = fs56.readdirSync(dirPath, { withFileTypes: true });
|
|
75506
75563
|
for (const entry of entries) {
|
|
75507
|
-
const fullPath =
|
|
75564
|
+
const fullPath = path74.join(dirPath, entry.name);
|
|
75508
75565
|
if (entry.isDirectory()) {
|
|
75509
75566
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
75510
75567
|
continue;
|
|
@@ -75512,7 +75569,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
75512
75569
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
75513
75570
|
} else if (entry.isFile()) {
|
|
75514
75571
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
75515
|
-
const ext =
|
|
75572
|
+
const ext = path74.extname(entry.name).toLowerCase();
|
|
75516
75573
|
const validExts = [
|
|
75517
75574
|
".ts",
|
|
75518
75575
|
".tsx",
|
|
@@ -75548,7 +75605,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
75548
75605
|
continue;
|
|
75549
75606
|
}
|
|
75550
75607
|
try {
|
|
75551
|
-
const content =
|
|
75608
|
+
const content = fs56.readFileSync(fullPath, "utf-8");
|
|
75552
75609
|
const lines = countCodeLines(content);
|
|
75553
75610
|
callback(lines);
|
|
75554
75611
|
} catch {}
|
|
@@ -75748,11 +75805,11 @@ async function getGitChurn(days, directory) {
|
|
|
75748
75805
|
}
|
|
75749
75806
|
function getComplexityForFile2(filePath) {
|
|
75750
75807
|
try {
|
|
75751
|
-
const stat6 =
|
|
75808
|
+
const stat6 = fs57.statSync(filePath);
|
|
75752
75809
|
if (stat6.size > MAX_FILE_SIZE_BYTES5) {
|
|
75753
75810
|
return null;
|
|
75754
75811
|
}
|
|
75755
|
-
const content =
|
|
75812
|
+
const content = fs57.readFileSync(filePath, "utf-8");
|
|
75756
75813
|
return estimateCyclomaticComplexity(content);
|
|
75757
75814
|
} catch {
|
|
75758
75815
|
return null;
|
|
@@ -75763,7 +75820,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
75763
75820
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
75764
75821
|
const filteredChurn = new Map;
|
|
75765
75822
|
for (const [file3, count] of churnMap) {
|
|
75766
|
-
const ext =
|
|
75823
|
+
const ext = path75.extname(file3).toLowerCase();
|
|
75767
75824
|
if (extSet.has(ext)) {
|
|
75768
75825
|
filteredChurn.set(file3, count);
|
|
75769
75826
|
}
|
|
@@ -75773,8 +75830,8 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
75773
75830
|
let analyzedFiles = 0;
|
|
75774
75831
|
for (const [file3, churnCount] of filteredChurn) {
|
|
75775
75832
|
let fullPath = file3;
|
|
75776
|
-
if (!
|
|
75777
|
-
fullPath =
|
|
75833
|
+
if (!fs57.existsSync(fullPath)) {
|
|
75834
|
+
fullPath = path75.join(cwd, file3);
|
|
75778
75835
|
}
|
|
75779
75836
|
const complexity = getComplexityForFile2(fullPath);
|
|
75780
75837
|
if (complexity !== null) {
|
|
@@ -75943,12 +76000,12 @@ ${body2}`);
|
|
|
75943
76000
|
// src/council/council-evidence-writer.ts
|
|
75944
76001
|
import {
|
|
75945
76002
|
appendFileSync as appendFileSync6,
|
|
75946
|
-
existsSync as
|
|
75947
|
-
mkdirSync as
|
|
76003
|
+
existsSync as existsSync38,
|
|
76004
|
+
mkdirSync as mkdirSync19,
|
|
75948
76005
|
readFileSync as readFileSync36,
|
|
75949
|
-
writeFileSync as
|
|
76006
|
+
writeFileSync as writeFileSync12
|
|
75950
76007
|
} from "node:fs";
|
|
75951
|
-
import { join as
|
|
76008
|
+
import { join as join69 } from "node:path";
|
|
75952
76009
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
75953
76010
|
var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
|
|
75954
76011
|
var COUNCIL_GATE_NAME = "council";
|
|
@@ -75982,11 +76039,11 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
75982
76039
|
if (!VALID_TASK_ID.test(synthesis.taskId)) {
|
|
75983
76040
|
throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
|
|
75984
76041
|
}
|
|
75985
|
-
const dir =
|
|
75986
|
-
|
|
75987
|
-
const filePath =
|
|
76042
|
+
const dir = join69(workingDir, EVIDENCE_DIR2);
|
|
76043
|
+
mkdirSync19(dir, { recursive: true });
|
|
76044
|
+
const filePath = join69(dir, `${synthesis.taskId}.json`);
|
|
75988
76045
|
const existingRoot = Object.create(null);
|
|
75989
|
-
if (
|
|
76046
|
+
if (existsSync38(filePath)) {
|
|
75990
76047
|
try {
|
|
75991
76048
|
const parsed = JSON.parse(readFileSync36(filePath, "utf-8"));
|
|
75992
76049
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -76016,17 +76073,17 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76016
76073
|
updated.taskId = synthesis.taskId;
|
|
76017
76074
|
if (!Array.isArray(updated.required_gates))
|
|
76018
76075
|
updated.required_gates = [];
|
|
76019
|
-
|
|
76076
|
+
writeFileSync12(filePath, JSON.stringify(updated, null, 2));
|
|
76020
76077
|
try {
|
|
76021
|
-
const councilDir =
|
|
76022
|
-
|
|
76078
|
+
const councilDir = join69(workingDir, ".swarm", "council");
|
|
76079
|
+
mkdirSync19(councilDir, { recursive: true });
|
|
76023
76080
|
const auditLine = JSON.stringify({
|
|
76024
76081
|
round: synthesis.roundNumber,
|
|
76025
76082
|
verdict: synthesis.overallVerdict,
|
|
76026
76083
|
timestamp: synthesis.timestamp,
|
|
76027
76084
|
vetoedBy: synthesis.vetoedBy
|
|
76028
76085
|
});
|
|
76029
|
-
appendFileSync6(
|
|
76086
|
+
appendFileSync6(join69(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
|
|
76030
76087
|
`);
|
|
76031
76088
|
} catch (auditError) {
|
|
76032
76089
|
console.warn(`writeCouncilEvidence: failed to append round-history audit log: ${auditError instanceof Error ? auditError.message : String(auditError)}`);
|
|
@@ -76159,22 +76216,22 @@ function buildUnifiedFeedback(taskId, verdict, vetoedBy, requiredFixes, advisory
|
|
|
76159
76216
|
}
|
|
76160
76217
|
|
|
76161
76218
|
// src/council/criteria-store.ts
|
|
76162
|
-
import { existsSync as
|
|
76163
|
-
import { join as
|
|
76219
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync20, readFileSync as readFileSync37, writeFileSync as writeFileSync13 } from "node:fs";
|
|
76220
|
+
import { join as join70 } from "node:path";
|
|
76164
76221
|
var COUNCIL_DIR = ".swarm/council";
|
|
76165
76222
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
76166
|
-
const dir =
|
|
76167
|
-
|
|
76223
|
+
const dir = join70(workingDir, COUNCIL_DIR);
|
|
76224
|
+
mkdirSync20(dir, { recursive: true });
|
|
76168
76225
|
const payload = {
|
|
76169
76226
|
taskId,
|
|
76170
76227
|
criteria,
|
|
76171
76228
|
declaredAt: new Date().toISOString()
|
|
76172
76229
|
};
|
|
76173
|
-
|
|
76230
|
+
writeFileSync13(join70(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
|
|
76174
76231
|
}
|
|
76175
76232
|
function readCriteria(workingDir, taskId) {
|
|
76176
|
-
const filePath =
|
|
76177
|
-
if (!
|
|
76233
|
+
const filePath = join70(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
|
|
76234
|
+
if (!existsSync39(filePath))
|
|
76178
76235
|
return null;
|
|
76179
76236
|
try {
|
|
76180
76237
|
const parsed = JSON.parse(readFileSync37(filePath, "utf-8"));
|
|
@@ -76325,8 +76382,8 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
76325
76382
|
// src/tools/convene-general-council.ts
|
|
76326
76383
|
init_zod();
|
|
76327
76384
|
init_loader();
|
|
76328
|
-
import * as
|
|
76329
|
-
import * as
|
|
76385
|
+
import * as fs58 from "node:fs";
|
|
76386
|
+
import * as path76 from "node:path";
|
|
76330
76387
|
|
|
76331
76388
|
// src/council/general-council-advisory.ts
|
|
76332
76389
|
var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
|
|
@@ -76754,13 +76811,13 @@ var convene_general_council = createSwarmTool({
|
|
|
76754
76811
|
const round1 = input.round1Responses;
|
|
76755
76812
|
const round2 = input.round2Responses ?? [];
|
|
76756
76813
|
const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
|
|
76757
|
-
const evidenceDir =
|
|
76814
|
+
const evidenceDir = path76.join(workingDir, ".swarm", "council", "general");
|
|
76758
76815
|
const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
|
|
76759
76816
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
76760
|
-
const evidencePath =
|
|
76817
|
+
const evidencePath = path76.join(evidenceDir, evidenceFile);
|
|
76761
76818
|
try {
|
|
76762
|
-
await
|
|
76763
|
-
await
|
|
76819
|
+
await fs58.promises.mkdir(evidenceDir, { recursive: true });
|
|
76820
|
+
await fs58.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
76764
76821
|
} catch (err2) {
|
|
76765
76822
|
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
76766
76823
|
console.warn(`[convene_general_council] Failed to write evidence to ${evidencePath}: ${message}`);
|
|
@@ -76991,8 +77048,8 @@ init_scope_persistence();
|
|
|
76991
77048
|
init_state();
|
|
76992
77049
|
init_task_id();
|
|
76993
77050
|
init_create_tool();
|
|
76994
|
-
import * as
|
|
76995
|
-
import * as
|
|
77051
|
+
import * as fs59 from "node:fs";
|
|
77052
|
+
import * as path77 from "node:path";
|
|
76996
77053
|
function validateTaskIdFormat2(taskId) {
|
|
76997
77054
|
return validateTaskIdFormat(taskId);
|
|
76998
77055
|
}
|
|
@@ -77066,8 +77123,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77066
77123
|
};
|
|
77067
77124
|
}
|
|
77068
77125
|
}
|
|
77069
|
-
normalizedDir =
|
|
77070
|
-
const pathParts = normalizedDir.split(
|
|
77126
|
+
normalizedDir = path77.normalize(args2.working_directory);
|
|
77127
|
+
const pathParts = normalizedDir.split(path77.sep);
|
|
77071
77128
|
if (pathParts.includes("..")) {
|
|
77072
77129
|
return {
|
|
77073
77130
|
success: false,
|
|
@@ -77077,11 +77134,11 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77077
77134
|
]
|
|
77078
77135
|
};
|
|
77079
77136
|
}
|
|
77080
|
-
const resolvedDir =
|
|
77137
|
+
const resolvedDir = path77.resolve(normalizedDir);
|
|
77081
77138
|
try {
|
|
77082
|
-
const realPath =
|
|
77083
|
-
const planPath2 =
|
|
77084
|
-
if (!
|
|
77139
|
+
const realPath = fs59.realpathSync(resolvedDir);
|
|
77140
|
+
const planPath2 = path77.join(realPath, ".swarm", "plan.json");
|
|
77141
|
+
if (!fs59.existsSync(planPath2)) {
|
|
77085
77142
|
return {
|
|
77086
77143
|
success: false,
|
|
77087
77144
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -77104,8 +77161,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77104
77161
|
console.warn("[declare-scope] fallbackDir is undefined, falling back to process.cwd()");
|
|
77105
77162
|
}
|
|
77106
77163
|
const directory = normalizedDir || fallbackDir;
|
|
77107
|
-
const planPath =
|
|
77108
|
-
if (!
|
|
77164
|
+
const planPath = path77.resolve(directory, ".swarm", "plan.json");
|
|
77165
|
+
if (!fs59.existsSync(planPath)) {
|
|
77109
77166
|
return {
|
|
77110
77167
|
success: false,
|
|
77111
77168
|
message: "No plan found",
|
|
@@ -77114,7 +77171,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77114
77171
|
}
|
|
77115
77172
|
let planContent;
|
|
77116
77173
|
try {
|
|
77117
|
-
planContent = JSON.parse(
|
|
77174
|
+
planContent = JSON.parse(fs59.readFileSync(planPath, "utf-8"));
|
|
77118
77175
|
} catch {
|
|
77119
77176
|
return {
|
|
77120
77177
|
success: false,
|
|
@@ -77144,8 +77201,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77144
77201
|
const normalizeErrors = [];
|
|
77145
77202
|
const dir = normalizedDir || fallbackDir || process.cwd();
|
|
77146
77203
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
77147
|
-
if (
|
|
77148
|
-
const relativePath =
|
|
77204
|
+
if (path77.isAbsolute(file3)) {
|
|
77205
|
+
const relativePath = path77.relative(dir, file3).replace(/\\/g, "/");
|
|
77149
77206
|
if (relativePath.startsWith("..")) {
|
|
77150
77207
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
77151
77208
|
return file3;
|
|
@@ -77205,8 +77262,8 @@ var declare_scope = createSwarmTool({
|
|
|
77205
77262
|
// src/tools/diff.ts
|
|
77206
77263
|
init_zod();
|
|
77207
77264
|
import * as child_process7 from "node:child_process";
|
|
77208
|
-
import * as
|
|
77209
|
-
import * as
|
|
77265
|
+
import * as fs60 from "node:fs";
|
|
77266
|
+
import * as path78 from "node:path";
|
|
77210
77267
|
init_create_tool();
|
|
77211
77268
|
var MAX_DIFF_LINES = 500;
|
|
77212
77269
|
var DIFF_TIMEOUT_MS = 30000;
|
|
@@ -77235,20 +77292,20 @@ function validateBase(base) {
|
|
|
77235
77292
|
function validatePaths(paths) {
|
|
77236
77293
|
if (!paths)
|
|
77237
77294
|
return null;
|
|
77238
|
-
for (const
|
|
77239
|
-
if (!
|
|
77295
|
+
for (const path79 of paths) {
|
|
77296
|
+
if (!path79 || path79.length === 0) {
|
|
77240
77297
|
return "empty path not allowed";
|
|
77241
77298
|
}
|
|
77242
|
-
if (
|
|
77299
|
+
if (path79.length > MAX_PATH_LENGTH) {
|
|
77243
77300
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
77244
77301
|
}
|
|
77245
|
-
if (SHELL_METACHARACTERS2.test(
|
|
77302
|
+
if (SHELL_METACHARACTERS2.test(path79)) {
|
|
77246
77303
|
return "path contains shell metacharacters";
|
|
77247
77304
|
}
|
|
77248
|
-
if (
|
|
77305
|
+
if (path79.startsWith("-")) {
|
|
77249
77306
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
77250
77307
|
}
|
|
77251
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
77308
|
+
if (CONTROL_CHAR_PATTERN2.test(path79)) {
|
|
77252
77309
|
return "path contains control characters";
|
|
77253
77310
|
}
|
|
77254
77311
|
}
|
|
@@ -77354,8 +77411,8 @@ var diff = createSwarmTool({
|
|
|
77354
77411
|
if (parts2.length >= 3) {
|
|
77355
77412
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
77356
77413
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
77357
|
-
const
|
|
77358
|
-
files.push({ path:
|
|
77414
|
+
const path79 = parts2[2];
|
|
77415
|
+
files.push({ path: path79, additions, deletions });
|
|
77359
77416
|
}
|
|
77360
77417
|
}
|
|
77361
77418
|
const contractChanges = [];
|
|
@@ -77395,7 +77452,7 @@ var diff = createSwarmTool({
|
|
|
77395
77452
|
} else if (base === "unstaged") {
|
|
77396
77453
|
const oldRef = `:${file3.path}`;
|
|
77397
77454
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
77398
|
-
newContent =
|
|
77455
|
+
newContent = fs60.readFileSync(path78.join(directory, file3.path), "utf-8");
|
|
77399
77456
|
} else {
|
|
77400
77457
|
const oldRef = `${base}:${file3.path}`;
|
|
77401
77458
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -77469,8 +77526,8 @@ var diff = createSwarmTool({
|
|
|
77469
77526
|
// src/tools/diff-summary.ts
|
|
77470
77527
|
init_zod();
|
|
77471
77528
|
import * as child_process8 from "node:child_process";
|
|
77472
|
-
import * as
|
|
77473
|
-
import * as
|
|
77529
|
+
import * as fs61 from "node:fs";
|
|
77530
|
+
import * as path79 from "node:path";
|
|
77474
77531
|
init_create_tool();
|
|
77475
77532
|
var diff_summary = createSwarmTool({
|
|
77476
77533
|
description: "Generate a filtered semantic diff summary from AST analysis. Returns SemanticDiffSummary with optional filtering by classification or riskLevel.",
|
|
@@ -77518,7 +77575,7 @@ var diff_summary = createSwarmTool({
|
|
|
77518
77575
|
}
|
|
77519
77576
|
try {
|
|
77520
77577
|
let oldContent;
|
|
77521
|
-
const newContent =
|
|
77578
|
+
const newContent = fs61.readFileSync(path79.join(workingDir, filePath), "utf-8");
|
|
77522
77579
|
if (fileExistsInHead) {
|
|
77523
77580
|
oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
|
|
77524
77581
|
encoding: "utf-8",
|
|
@@ -77746,8 +77803,8 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
77746
77803
|
init_zod();
|
|
77747
77804
|
init_create_tool();
|
|
77748
77805
|
init_path_security();
|
|
77749
|
-
import * as
|
|
77750
|
-
import * as
|
|
77806
|
+
import * as fs62 from "node:fs";
|
|
77807
|
+
import * as path80 from "node:path";
|
|
77751
77808
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
77752
77809
|
var MAX_EVIDENCE_FILES = 1000;
|
|
77753
77810
|
var EVIDENCE_DIR3 = ".swarm/evidence";
|
|
@@ -77774,9 +77831,9 @@ function validateRequiredTypes(input) {
|
|
|
77774
77831
|
return null;
|
|
77775
77832
|
}
|
|
77776
77833
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
77777
|
-
const normalizedCwd =
|
|
77778
|
-
const swarmPath =
|
|
77779
|
-
const normalizedPath =
|
|
77834
|
+
const normalizedCwd = path80.resolve(cwd);
|
|
77835
|
+
const swarmPath = path80.join(normalizedCwd, ".swarm");
|
|
77836
|
+
const normalizedPath = path80.resolve(filePath);
|
|
77780
77837
|
return normalizedPath.startsWith(swarmPath);
|
|
77781
77838
|
}
|
|
77782
77839
|
function parseCompletedTasks(planContent) {
|
|
@@ -77792,12 +77849,12 @@ function parseCompletedTasks(planContent) {
|
|
|
77792
77849
|
}
|
|
77793
77850
|
function readEvidenceFiles(evidenceDir, _cwd) {
|
|
77794
77851
|
const evidence = [];
|
|
77795
|
-
if (!
|
|
77852
|
+
if (!fs62.existsSync(evidenceDir) || !fs62.statSync(evidenceDir).isDirectory()) {
|
|
77796
77853
|
return evidence;
|
|
77797
77854
|
}
|
|
77798
77855
|
let files;
|
|
77799
77856
|
try {
|
|
77800
|
-
files =
|
|
77857
|
+
files = fs62.readdirSync(evidenceDir);
|
|
77801
77858
|
} catch {
|
|
77802
77859
|
return evidence;
|
|
77803
77860
|
}
|
|
@@ -77806,14 +77863,14 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
77806
77863
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
77807
77864
|
continue;
|
|
77808
77865
|
}
|
|
77809
|
-
const filePath =
|
|
77866
|
+
const filePath = path80.join(evidenceDir, filename);
|
|
77810
77867
|
try {
|
|
77811
|
-
const resolvedPath =
|
|
77812
|
-
const evidenceDirResolved =
|
|
77868
|
+
const resolvedPath = path80.resolve(filePath);
|
|
77869
|
+
const evidenceDirResolved = path80.resolve(evidenceDir);
|
|
77813
77870
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
77814
77871
|
continue;
|
|
77815
77872
|
}
|
|
77816
|
-
const stat6 =
|
|
77873
|
+
const stat6 = fs62.lstatSync(filePath);
|
|
77817
77874
|
if (!stat6.isFile()) {
|
|
77818
77875
|
continue;
|
|
77819
77876
|
}
|
|
@@ -77822,7 +77879,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
77822
77879
|
}
|
|
77823
77880
|
let fileStat;
|
|
77824
77881
|
try {
|
|
77825
|
-
fileStat =
|
|
77882
|
+
fileStat = fs62.statSync(filePath);
|
|
77826
77883
|
if (fileStat.size > MAX_FILE_SIZE_BYTES6) {
|
|
77827
77884
|
continue;
|
|
77828
77885
|
}
|
|
@@ -77831,7 +77888,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
77831
77888
|
}
|
|
77832
77889
|
let content;
|
|
77833
77890
|
try {
|
|
77834
|
-
content =
|
|
77891
|
+
content = fs62.readFileSync(filePath, "utf-8");
|
|
77835
77892
|
} catch {
|
|
77836
77893
|
continue;
|
|
77837
77894
|
}
|
|
@@ -77927,7 +77984,7 @@ var evidence_check = createSwarmTool({
|
|
|
77927
77984
|
return JSON.stringify(errorResult, null, 2);
|
|
77928
77985
|
}
|
|
77929
77986
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
77930
|
-
const planPath =
|
|
77987
|
+
const planPath = path80.join(cwd, PLAN_FILE);
|
|
77931
77988
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
77932
77989
|
const errorResult = {
|
|
77933
77990
|
error: "plan file path validation failed",
|
|
@@ -77941,7 +77998,7 @@ var evidence_check = createSwarmTool({
|
|
|
77941
77998
|
}
|
|
77942
77999
|
let planContent;
|
|
77943
78000
|
try {
|
|
77944
|
-
planContent =
|
|
78001
|
+
planContent = fs62.readFileSync(planPath, "utf-8");
|
|
77945
78002
|
} catch {
|
|
77946
78003
|
const result2 = {
|
|
77947
78004
|
message: "No completed tasks found in plan.",
|
|
@@ -77959,7 +78016,7 @@ var evidence_check = createSwarmTool({
|
|
|
77959
78016
|
};
|
|
77960
78017
|
return JSON.stringify(result2, null, 2);
|
|
77961
78018
|
}
|
|
77962
|
-
const evidenceDir =
|
|
78019
|
+
const evidenceDir = path80.join(cwd, EVIDENCE_DIR3);
|
|
77963
78020
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
77964
78021
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
77965
78022
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -77976,8 +78033,8 @@ var evidence_check = createSwarmTool({
|
|
|
77976
78033
|
// src/tools/file-extractor.ts
|
|
77977
78034
|
init_zod();
|
|
77978
78035
|
init_create_tool();
|
|
77979
|
-
import * as
|
|
77980
|
-
import * as
|
|
78036
|
+
import * as fs63 from "node:fs";
|
|
78037
|
+
import * as path81 from "node:path";
|
|
77981
78038
|
var EXT_MAP = {
|
|
77982
78039
|
python: ".py",
|
|
77983
78040
|
py: ".py",
|
|
@@ -78039,8 +78096,8 @@ var extract_code_blocks = createSwarmTool({
|
|
|
78039
78096
|
execute: async (args2, directory) => {
|
|
78040
78097
|
const { content, output_dir, prefix } = args2;
|
|
78041
78098
|
const targetDir = output_dir || directory;
|
|
78042
|
-
if (!
|
|
78043
|
-
|
|
78099
|
+
if (!fs63.existsSync(targetDir)) {
|
|
78100
|
+
fs63.mkdirSync(targetDir, { recursive: true });
|
|
78044
78101
|
}
|
|
78045
78102
|
if (!content) {
|
|
78046
78103
|
return "Error: content is required";
|
|
@@ -78058,16 +78115,16 @@ var extract_code_blocks = createSwarmTool({
|
|
|
78058
78115
|
if (prefix) {
|
|
78059
78116
|
filename = `${prefix}_${filename}`;
|
|
78060
78117
|
}
|
|
78061
|
-
let filepath =
|
|
78062
|
-
const base =
|
|
78063
|
-
const ext =
|
|
78118
|
+
let filepath = path81.join(targetDir, filename);
|
|
78119
|
+
const base = path81.basename(filepath, path81.extname(filepath));
|
|
78120
|
+
const ext = path81.extname(filepath);
|
|
78064
78121
|
let counter = 1;
|
|
78065
|
-
while (
|
|
78066
|
-
filepath =
|
|
78122
|
+
while (fs63.existsSync(filepath)) {
|
|
78123
|
+
filepath = path81.join(targetDir, `${base}_${counter}${ext}`);
|
|
78067
78124
|
counter++;
|
|
78068
78125
|
}
|
|
78069
78126
|
try {
|
|
78070
|
-
|
|
78127
|
+
fs63.writeFileSync(filepath, code.trim(), "utf-8");
|
|
78071
78128
|
savedFiles.push(filepath);
|
|
78072
78129
|
} catch (error93) {
|
|
78073
78130
|
errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
@@ -78326,8 +78383,8 @@ var gitingest = createSwarmTool({
|
|
|
78326
78383
|
init_zod();
|
|
78327
78384
|
init_create_tool();
|
|
78328
78385
|
init_path_security();
|
|
78329
|
-
import * as
|
|
78330
|
-
import * as
|
|
78386
|
+
import * as fs64 from "node:fs";
|
|
78387
|
+
import * as path82 from "node:path";
|
|
78331
78388
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
78332
78389
|
var MAX_SYMBOL_LENGTH = 256;
|
|
78333
78390
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -78375,7 +78432,7 @@ function validateSymbolInput(symbol3) {
|
|
|
78375
78432
|
return null;
|
|
78376
78433
|
}
|
|
78377
78434
|
function isBinaryFile2(filePath, buffer) {
|
|
78378
|
-
const ext =
|
|
78435
|
+
const ext = path82.extname(filePath).toLowerCase();
|
|
78379
78436
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
78380
78437
|
return false;
|
|
78381
78438
|
}
|
|
@@ -78399,15 +78456,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
78399
78456
|
const imports = [];
|
|
78400
78457
|
let _resolvedTarget;
|
|
78401
78458
|
try {
|
|
78402
|
-
_resolvedTarget =
|
|
78459
|
+
_resolvedTarget = path82.resolve(targetFile);
|
|
78403
78460
|
} catch {
|
|
78404
78461
|
_resolvedTarget = targetFile;
|
|
78405
78462
|
}
|
|
78406
|
-
const targetBasename =
|
|
78463
|
+
const targetBasename = path82.basename(targetFile, path82.extname(targetFile));
|
|
78407
78464
|
const targetWithExt = targetFile;
|
|
78408
78465
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
78409
|
-
const normalizedTargetWithExt =
|
|
78410
|
-
const normalizedTargetWithoutExt =
|
|
78466
|
+
const normalizedTargetWithExt = path82.normalize(targetWithExt).replace(/\\/g, "/");
|
|
78467
|
+
const normalizedTargetWithoutExt = path82.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
78411
78468
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
78412
78469
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
78413
78470
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -78430,9 +78487,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
78430
78487
|
}
|
|
78431
78488
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
78432
78489
|
let isMatch = false;
|
|
78433
|
-
const _targetDir =
|
|
78434
|
-
const targetExt =
|
|
78435
|
-
const targetBasenameNoExt =
|
|
78490
|
+
const _targetDir = path82.dirname(targetFile);
|
|
78491
|
+
const targetExt = path82.extname(targetFile);
|
|
78492
|
+
const targetBasenameNoExt = path82.basename(targetFile, targetExt);
|
|
78436
78493
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
78437
78494
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
78438
78495
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -78489,7 +78546,7 @@ var SKIP_DIRECTORIES4 = new Set([
|
|
|
78489
78546
|
function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
|
|
78490
78547
|
let entries;
|
|
78491
78548
|
try {
|
|
78492
|
-
entries =
|
|
78549
|
+
entries = fs64.readdirSync(dir);
|
|
78493
78550
|
} catch (e) {
|
|
78494
78551
|
stats.fileErrors.push({
|
|
78495
78552
|
path: dir,
|
|
@@ -78500,13 +78557,13 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
78500
78557
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
78501
78558
|
for (const entry of entries) {
|
|
78502
78559
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
78503
|
-
stats.skippedDirs.push(
|
|
78560
|
+
stats.skippedDirs.push(path82.join(dir, entry));
|
|
78504
78561
|
continue;
|
|
78505
78562
|
}
|
|
78506
|
-
const fullPath =
|
|
78563
|
+
const fullPath = path82.join(dir, entry);
|
|
78507
78564
|
let stat6;
|
|
78508
78565
|
try {
|
|
78509
|
-
stat6 =
|
|
78566
|
+
stat6 = fs64.statSync(fullPath);
|
|
78510
78567
|
} catch (e) {
|
|
78511
78568
|
stats.fileErrors.push({
|
|
78512
78569
|
path: fullPath,
|
|
@@ -78517,7 +78574,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
78517
78574
|
if (stat6.isDirectory()) {
|
|
78518
78575
|
findSourceFiles2(fullPath, files, stats);
|
|
78519
78576
|
} else if (stat6.isFile()) {
|
|
78520
|
-
const ext =
|
|
78577
|
+
const ext = path82.extname(fullPath).toLowerCase();
|
|
78521
78578
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
78522
78579
|
files.push(fullPath);
|
|
78523
78580
|
}
|
|
@@ -78574,8 +78631,8 @@ var imports = createSwarmTool({
|
|
|
78574
78631
|
return JSON.stringify(errorResult, null, 2);
|
|
78575
78632
|
}
|
|
78576
78633
|
try {
|
|
78577
|
-
const targetFile =
|
|
78578
|
-
if (!
|
|
78634
|
+
const targetFile = path82.resolve(file3);
|
|
78635
|
+
if (!fs64.existsSync(targetFile)) {
|
|
78579
78636
|
const errorResult = {
|
|
78580
78637
|
error: `target file not found: ${file3}`,
|
|
78581
78638
|
target: file3,
|
|
@@ -78585,7 +78642,7 @@ var imports = createSwarmTool({
|
|
|
78585
78642
|
};
|
|
78586
78643
|
return JSON.stringify(errorResult, null, 2);
|
|
78587
78644
|
}
|
|
78588
|
-
const targetStat =
|
|
78645
|
+
const targetStat = fs64.statSync(targetFile);
|
|
78589
78646
|
if (!targetStat.isFile()) {
|
|
78590
78647
|
const errorResult = {
|
|
78591
78648
|
error: "target must be a file, not a directory",
|
|
@@ -78596,7 +78653,7 @@ var imports = createSwarmTool({
|
|
|
78596
78653
|
};
|
|
78597
78654
|
return JSON.stringify(errorResult, null, 2);
|
|
78598
78655
|
}
|
|
78599
|
-
const baseDir =
|
|
78656
|
+
const baseDir = path82.dirname(targetFile);
|
|
78600
78657
|
const scanStats = {
|
|
78601
78658
|
skippedDirs: [],
|
|
78602
78659
|
skippedFiles: 0,
|
|
@@ -78611,12 +78668,12 @@ var imports = createSwarmTool({
|
|
|
78611
78668
|
if (consumers.length >= MAX_CONSUMERS)
|
|
78612
78669
|
break;
|
|
78613
78670
|
try {
|
|
78614
|
-
const stat6 =
|
|
78671
|
+
const stat6 = fs64.statSync(filePath);
|
|
78615
78672
|
if (stat6.size > MAX_FILE_SIZE_BYTES7) {
|
|
78616
78673
|
skippedFileCount++;
|
|
78617
78674
|
continue;
|
|
78618
78675
|
}
|
|
78619
|
-
const buffer =
|
|
78676
|
+
const buffer = fs64.readFileSync(filePath);
|
|
78620
78677
|
if (isBinaryFile2(filePath, buffer)) {
|
|
78621
78678
|
skippedFileCount++;
|
|
78622
78679
|
continue;
|
|
@@ -78829,7 +78886,7 @@ init_zod();
|
|
|
78829
78886
|
init_config();
|
|
78830
78887
|
init_knowledge_store();
|
|
78831
78888
|
init_create_tool();
|
|
78832
|
-
import { existsSync as
|
|
78889
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
78833
78890
|
var DEFAULT_LIMIT = 10;
|
|
78834
78891
|
var MAX_LESSON_LENGTH = 200;
|
|
78835
78892
|
var VALID_CATEGORIES3 = [
|
|
@@ -78899,14 +78956,14 @@ function validateLimit(limit) {
|
|
|
78899
78956
|
}
|
|
78900
78957
|
async function readSwarmKnowledge(directory) {
|
|
78901
78958
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
78902
|
-
if (!
|
|
78959
|
+
if (!existsSync44(swarmPath)) {
|
|
78903
78960
|
return [];
|
|
78904
78961
|
}
|
|
78905
78962
|
return readKnowledge(swarmPath);
|
|
78906
78963
|
}
|
|
78907
78964
|
async function readHiveKnowledge() {
|
|
78908
78965
|
const hivePath = resolveHiveKnowledgePath();
|
|
78909
|
-
if (!
|
|
78966
|
+
if (!existsSync44(hivePath)) {
|
|
78910
78967
|
return [];
|
|
78911
78968
|
}
|
|
78912
78969
|
return readKnowledge(hivePath);
|
|
@@ -79141,8 +79198,8 @@ init_schema();
|
|
|
79141
79198
|
init_qa_gate_profile();
|
|
79142
79199
|
init_manager2();
|
|
79143
79200
|
init_curator();
|
|
79144
|
-
import * as
|
|
79145
|
-
import * as
|
|
79201
|
+
import * as fs66 from "node:fs";
|
|
79202
|
+
import * as path84 from "node:path";
|
|
79146
79203
|
init_knowledge_curator();
|
|
79147
79204
|
init_knowledge_reader();
|
|
79148
79205
|
init_knowledge_store();
|
|
@@ -79154,20 +79211,20 @@ init_file_locks();
|
|
|
79154
79211
|
init_plan_schema();
|
|
79155
79212
|
init_ledger();
|
|
79156
79213
|
init_manager();
|
|
79157
|
-
import * as
|
|
79158
|
-
import * as
|
|
79214
|
+
import * as fs65 from "node:fs";
|
|
79215
|
+
import * as path83 from "node:path";
|
|
79159
79216
|
async function writeCheckpoint(directory) {
|
|
79160
79217
|
try {
|
|
79161
79218
|
const plan = await loadPlan(directory);
|
|
79162
79219
|
if (!plan)
|
|
79163
79220
|
return;
|
|
79164
|
-
const swarmDir =
|
|
79165
|
-
|
|
79166
|
-
const jsonPath =
|
|
79167
|
-
const mdPath =
|
|
79168
|
-
|
|
79221
|
+
const swarmDir = path83.join(directory, ".swarm");
|
|
79222
|
+
fs65.mkdirSync(swarmDir, { recursive: true });
|
|
79223
|
+
const jsonPath = path83.join(swarmDir, "SWARM_PLAN.json");
|
|
79224
|
+
const mdPath = path83.join(swarmDir, "SWARM_PLAN.md");
|
|
79225
|
+
fs65.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
79169
79226
|
const md = derivePlanMarkdown(plan);
|
|
79170
|
-
|
|
79227
|
+
fs65.writeFileSync(mdPath, md, "utf8");
|
|
79171
79228
|
} catch (error93) {
|
|
79172
79229
|
console.warn(`[checkpoint] Failed to write SWARM_PLAN checkpoint: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
79173
79230
|
}
|
|
@@ -79399,8 +79456,8 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79399
79456
|
let driftCheckEnabled = true;
|
|
79400
79457
|
let driftHasSpecMd = false;
|
|
79401
79458
|
try {
|
|
79402
|
-
const specMdPath =
|
|
79403
|
-
driftHasSpecMd =
|
|
79459
|
+
const specMdPath = path84.join(dir, ".swarm", "spec.md");
|
|
79460
|
+
driftHasSpecMd = fs66.existsSync(specMdPath);
|
|
79404
79461
|
const gatePlan = await loadPlan(dir);
|
|
79405
79462
|
if (gatePlan) {
|
|
79406
79463
|
const gatePlanId = `${gatePlan.swarm}-${gatePlan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
@@ -79421,9 +79478,9 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79421
79478
|
} else {
|
|
79422
79479
|
let phaseType;
|
|
79423
79480
|
try {
|
|
79424
|
-
const planPath =
|
|
79425
|
-
if (
|
|
79426
|
-
const planRaw =
|
|
79481
|
+
const planPath = path84.join(dir, ".swarm", "plan.json");
|
|
79482
|
+
if (fs66.existsSync(planPath)) {
|
|
79483
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
79427
79484
|
const plan = JSON.parse(planRaw);
|
|
79428
79485
|
const targetPhase = plan.phases?.find((p) => p.id === phase);
|
|
79429
79486
|
phaseType = targetPhase?.type;
|
|
@@ -79434,11 +79491,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79434
79491
|
warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
|
|
79435
79492
|
} else {
|
|
79436
79493
|
try {
|
|
79437
|
-
const driftEvidencePath =
|
|
79494
|
+
const driftEvidencePath = path84.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
79438
79495
|
let driftVerdictFound = false;
|
|
79439
79496
|
let driftVerdictApproved = false;
|
|
79440
79497
|
try {
|
|
79441
|
-
const driftEvidenceContent =
|
|
79498
|
+
const driftEvidenceContent = fs66.readFileSync(driftEvidencePath, "utf-8");
|
|
79442
79499
|
const driftEvidence = JSON.parse(driftEvidenceContent);
|
|
79443
79500
|
const entries = driftEvidence.entries ?? [];
|
|
79444
79501
|
for (const entry of entries) {
|
|
@@ -79472,9 +79529,9 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79472
79529
|
let incompleteTaskCount = 0;
|
|
79473
79530
|
let planParseable = false;
|
|
79474
79531
|
try {
|
|
79475
|
-
const planPath =
|
|
79476
|
-
if (
|
|
79477
|
-
const planRaw =
|
|
79532
|
+
const planPath = path84.join(dir, ".swarm", "plan.json");
|
|
79533
|
+
if (fs66.existsSync(planPath)) {
|
|
79534
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
79478
79535
|
const plan = JSON.parse(planRaw);
|
|
79479
79536
|
planParseable = true;
|
|
79480
79537
|
const planPhase = plan.phases?.find((p) => p.id === phase);
|
|
@@ -79539,11 +79596,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79539
79596
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
79540
79597
|
const effective = getEffectiveGates(profile, overrides);
|
|
79541
79598
|
if (effective.hallucination_guard === true) {
|
|
79542
|
-
const hgPath =
|
|
79599
|
+
const hgPath = path84.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
79543
79600
|
let hgVerdictFound = false;
|
|
79544
79601
|
let hgVerdictApproved = false;
|
|
79545
79602
|
try {
|
|
79546
|
-
const hgContent =
|
|
79603
|
+
const hgContent = fs66.readFileSync(hgPath, "utf-8");
|
|
79547
79604
|
const hgBundle = JSON.parse(hgContent);
|
|
79548
79605
|
for (const entry of hgBundle.entries ?? []) {
|
|
79549
79606
|
if (typeof entry.type === "string" && entry.type.includes("hallucination") && typeof entry.verdict === "string") {
|
|
@@ -79611,11 +79668,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79611
79668
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
79612
79669
|
const effective = getEffectiveGates(profile, overrides);
|
|
79613
79670
|
if (effective.mutation_test === true) {
|
|
79614
|
-
const mgPath =
|
|
79671
|
+
const mgPath = path84.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
79615
79672
|
let mgVerdictFound = false;
|
|
79616
79673
|
let mgVerdict;
|
|
79617
79674
|
try {
|
|
79618
|
-
const mgContent =
|
|
79675
|
+
const mgContent = fs66.readFileSync(mgPath, "utf-8");
|
|
79619
79676
|
const mgBundle = JSON.parse(mgContent);
|
|
79620
79677
|
for (const entry of mgBundle.entries ?? []) {
|
|
79621
79678
|
if (typeof entry.type === "string" && entry.type === "mutation-gate" && typeof entry.verdict === "string") {
|
|
@@ -79685,14 +79742,14 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79685
79742
|
const effective = getEffectiveGates(profile, overrides);
|
|
79686
79743
|
if (effective.council_mode === true) {
|
|
79687
79744
|
councilModeEnabled = true;
|
|
79688
|
-
const pcPath =
|
|
79745
|
+
const pcPath = path84.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
79689
79746
|
let pcVerdictFound = false;
|
|
79690
79747
|
let _pcVerdict;
|
|
79691
79748
|
let pcQuorumSize;
|
|
79692
79749
|
let pcTimestamp;
|
|
79693
79750
|
let pcPhaseNumber;
|
|
79694
79751
|
try {
|
|
79695
|
-
const pcContent =
|
|
79752
|
+
const pcContent = fs66.readFileSync(pcPath, "utf-8");
|
|
79696
79753
|
const pcBundle = JSON.parse(pcContent);
|
|
79697
79754
|
for (const entry of pcBundle.entries ?? []) {
|
|
79698
79755
|
if (typeof entry.type === "string" && entry.type === "phase-council" && typeof entry.verdict === "string") {
|
|
@@ -79887,7 +79944,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
79887
79944
|
}
|
|
79888
79945
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
79889
79946
|
try {
|
|
79890
|
-
const projectName =
|
|
79947
|
+
const projectName = path84.basename(dir);
|
|
79891
79948
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
79892
79949
|
if (curationResult) {
|
|
79893
79950
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -79967,7 +80024,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
79967
80024
|
let phaseRequiredAgents;
|
|
79968
80025
|
try {
|
|
79969
80026
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
79970
|
-
const planRaw =
|
|
80027
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
79971
80028
|
const plan = JSON.parse(planRaw);
|
|
79972
80029
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
79973
80030
|
phaseRequiredAgents = phaseObj?.required_agents;
|
|
@@ -79982,7 +80039,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
79982
80039
|
if (agentsMissing.length > 0) {
|
|
79983
80040
|
try {
|
|
79984
80041
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
79985
|
-
const planRaw =
|
|
80042
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
79986
80043
|
const plan = JSON.parse(planRaw);
|
|
79987
80044
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
79988
80045
|
if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
|
|
@@ -80022,7 +80079,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80022
80079
|
if (phaseCompleteConfig.regression_sweep?.enforce) {
|
|
80023
80080
|
try {
|
|
80024
80081
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
80025
|
-
const planRaw =
|
|
80082
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
80026
80083
|
const plan = JSON.parse(planRaw);
|
|
80027
80084
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
80028
80085
|
if (targetPhase) {
|
|
@@ -80076,7 +80133,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80076
80133
|
}
|
|
80077
80134
|
try {
|
|
80078
80135
|
const eventsPath = validateSwarmPath(dir, "events.jsonl");
|
|
80079
|
-
|
|
80136
|
+
fs66.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
80080
80137
|
`, "utf-8");
|
|
80081
80138
|
} catch (writeError) {
|
|
80082
80139
|
warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
@@ -80151,12 +80208,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80151
80208
|
warnings.push(`Warning: failed to update plan.json phase status`);
|
|
80152
80209
|
try {
|
|
80153
80210
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
80154
|
-
const planRaw =
|
|
80211
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
80155
80212
|
const plan2 = JSON.parse(planRaw);
|
|
80156
80213
|
const phaseObj = plan2.phases.find((p) => p.id === phase);
|
|
80157
80214
|
if (phaseObj) {
|
|
80158
80215
|
phaseObj.status = "complete";
|
|
80159
|
-
|
|
80216
|
+
fs66.writeFileSync(planPath, JSON.stringify(plan2, null, 2), "utf-8");
|
|
80160
80217
|
}
|
|
80161
80218
|
} catch {}
|
|
80162
80219
|
} else if (plan) {
|
|
@@ -80193,12 +80250,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80193
80250
|
warnings.push(`Warning: failed to update plan.json phase status`);
|
|
80194
80251
|
try {
|
|
80195
80252
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
80196
|
-
const planRaw =
|
|
80253
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
80197
80254
|
const plan = JSON.parse(planRaw);
|
|
80198
80255
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
80199
80256
|
if (phaseObj) {
|
|
80200
80257
|
phaseObj.status = "complete";
|
|
80201
|
-
|
|
80258
|
+
fs66.writeFileSync(planPath, JSON.stringify(plan, null, 2), "utf-8");
|
|
80202
80259
|
}
|
|
80203
80260
|
} catch {}
|
|
80204
80261
|
}
|
|
@@ -80256,8 +80313,8 @@ init_discovery();
|
|
|
80256
80313
|
init_utils();
|
|
80257
80314
|
init_bun_compat();
|
|
80258
80315
|
init_create_tool();
|
|
80259
|
-
import * as
|
|
80260
|
-
import * as
|
|
80316
|
+
import * as fs67 from "node:fs";
|
|
80317
|
+
import * as path85 from "node:path";
|
|
80261
80318
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
80262
80319
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
80263
80320
|
function isValidEcosystem(value) {
|
|
@@ -80285,31 +80342,31 @@ function validateArgs3(args2) {
|
|
|
80285
80342
|
function detectEcosystems(directory) {
|
|
80286
80343
|
const ecosystems = [];
|
|
80287
80344
|
const cwd = directory;
|
|
80288
|
-
if (
|
|
80345
|
+
if (fs67.existsSync(path85.join(cwd, "package.json"))) {
|
|
80289
80346
|
ecosystems.push("npm");
|
|
80290
80347
|
}
|
|
80291
|
-
if (
|
|
80348
|
+
if (fs67.existsSync(path85.join(cwd, "pyproject.toml")) || fs67.existsSync(path85.join(cwd, "requirements.txt"))) {
|
|
80292
80349
|
ecosystems.push("pip");
|
|
80293
80350
|
}
|
|
80294
|
-
if (
|
|
80351
|
+
if (fs67.existsSync(path85.join(cwd, "Cargo.toml"))) {
|
|
80295
80352
|
ecosystems.push("cargo");
|
|
80296
80353
|
}
|
|
80297
|
-
if (
|
|
80354
|
+
if (fs67.existsSync(path85.join(cwd, "go.mod"))) {
|
|
80298
80355
|
ecosystems.push("go");
|
|
80299
80356
|
}
|
|
80300
80357
|
try {
|
|
80301
|
-
const files =
|
|
80358
|
+
const files = fs67.readdirSync(cwd);
|
|
80302
80359
|
if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
80303
80360
|
ecosystems.push("dotnet");
|
|
80304
80361
|
}
|
|
80305
80362
|
} catch {}
|
|
80306
|
-
if (
|
|
80363
|
+
if (fs67.existsSync(path85.join(cwd, "Gemfile")) || fs67.existsSync(path85.join(cwd, "Gemfile.lock"))) {
|
|
80307
80364
|
ecosystems.push("ruby");
|
|
80308
80365
|
}
|
|
80309
|
-
if (
|
|
80366
|
+
if (fs67.existsSync(path85.join(cwd, "pubspec.yaml"))) {
|
|
80310
80367
|
ecosystems.push("dart");
|
|
80311
80368
|
}
|
|
80312
|
-
if (
|
|
80369
|
+
if (fs67.existsSync(path85.join(cwd, "composer.lock"))) {
|
|
80313
80370
|
ecosystems.push("composer");
|
|
80314
80371
|
}
|
|
80315
80372
|
return ecosystems;
|
|
@@ -81444,8 +81501,8 @@ var pkg_audit = createSwarmTool({
|
|
|
81444
81501
|
// src/tools/placeholder-scan.ts
|
|
81445
81502
|
init_zod();
|
|
81446
81503
|
init_manager2();
|
|
81447
|
-
import * as
|
|
81448
|
-
import * as
|
|
81504
|
+
import * as fs68 from "node:fs";
|
|
81505
|
+
import * as path86 from "node:path";
|
|
81449
81506
|
init_utils();
|
|
81450
81507
|
init_create_tool();
|
|
81451
81508
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -81568,7 +81625,7 @@ function isScaffoldFile(filePath) {
|
|
|
81568
81625
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
81569
81626
|
return true;
|
|
81570
81627
|
}
|
|
81571
|
-
const filename =
|
|
81628
|
+
const filename = path86.basename(filePath);
|
|
81572
81629
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
81573
81630
|
return true;
|
|
81574
81631
|
}
|
|
@@ -81585,7 +81642,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
81585
81642
|
if (regex.test(normalizedPath)) {
|
|
81586
81643
|
return true;
|
|
81587
81644
|
}
|
|
81588
|
-
const filename =
|
|
81645
|
+
const filename = path86.basename(filePath);
|
|
81589
81646
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
81590
81647
|
if (filenameRegex.test(filename)) {
|
|
81591
81648
|
return true;
|
|
@@ -81594,7 +81651,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
81594
81651
|
return false;
|
|
81595
81652
|
}
|
|
81596
81653
|
function isParserSupported(filePath) {
|
|
81597
|
-
const ext =
|
|
81654
|
+
const ext = path86.extname(filePath).toLowerCase();
|
|
81598
81655
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
81599
81656
|
}
|
|
81600
81657
|
function isPlanFile(filePath) {
|
|
@@ -81841,28 +81898,28 @@ async function placeholderScan(input, directory) {
|
|
|
81841
81898
|
let filesScanned = 0;
|
|
81842
81899
|
const filesWithFindings = new Set;
|
|
81843
81900
|
for (const filePath of changed_files) {
|
|
81844
|
-
const fullPath =
|
|
81845
|
-
const resolvedDirectory =
|
|
81846
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
81901
|
+
const fullPath = path86.isAbsolute(filePath) ? filePath : path86.resolve(directory, filePath);
|
|
81902
|
+
const resolvedDirectory = path86.resolve(directory);
|
|
81903
|
+
if (!fullPath.startsWith(resolvedDirectory + path86.sep) && fullPath !== resolvedDirectory) {
|
|
81847
81904
|
continue;
|
|
81848
81905
|
}
|
|
81849
|
-
if (!
|
|
81906
|
+
if (!fs68.existsSync(fullPath)) {
|
|
81850
81907
|
continue;
|
|
81851
81908
|
}
|
|
81852
81909
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
81853
81910
|
continue;
|
|
81854
81911
|
}
|
|
81855
|
-
const relativeFilePath =
|
|
81912
|
+
const relativeFilePath = path86.relative(directory, fullPath).replace(/\\/g, "/");
|
|
81856
81913
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
81857
81914
|
continue;
|
|
81858
81915
|
}
|
|
81859
81916
|
let content;
|
|
81860
81917
|
try {
|
|
81861
|
-
const stat6 =
|
|
81918
|
+
const stat6 = fs68.statSync(fullPath);
|
|
81862
81919
|
if (stat6.size > MAX_FILE_SIZE) {
|
|
81863
81920
|
continue;
|
|
81864
81921
|
}
|
|
81865
|
-
content =
|
|
81922
|
+
content = fs68.readFileSync(fullPath, "utf-8");
|
|
81866
81923
|
} catch {
|
|
81867
81924
|
continue;
|
|
81868
81925
|
}
|
|
@@ -81923,8 +81980,8 @@ var placeholder_scan = createSwarmTool({
|
|
|
81923
81980
|
}
|
|
81924
81981
|
});
|
|
81925
81982
|
// src/tools/pre-check-batch.ts
|
|
81926
|
-
import * as
|
|
81927
|
-
import * as
|
|
81983
|
+
import * as fs71 from "node:fs";
|
|
81984
|
+
import * as path89 from "node:path";
|
|
81928
81985
|
init_zod();
|
|
81929
81986
|
init_manager2();
|
|
81930
81987
|
init_utils();
|
|
@@ -82061,8 +82118,8 @@ var quality_budget = createSwarmTool({
|
|
|
82061
82118
|
init_zod();
|
|
82062
82119
|
init_manager2();
|
|
82063
82120
|
init_detector();
|
|
82064
|
-
import * as
|
|
82065
|
-
import * as
|
|
82121
|
+
import * as fs70 from "node:fs";
|
|
82122
|
+
import * as path88 from "node:path";
|
|
82066
82123
|
import { extname as extname18 } from "node:path";
|
|
82067
82124
|
|
|
82068
82125
|
// src/sast/rules/c.ts
|
|
@@ -82955,25 +83012,25 @@ init_create_tool();
|
|
|
82955
83012
|
// src/tools/sast-baseline.ts
|
|
82956
83013
|
init_utils2();
|
|
82957
83014
|
import * as crypto8 from "node:crypto";
|
|
82958
|
-
import * as
|
|
82959
|
-
import * as
|
|
83015
|
+
import * as fs69 from "node:fs";
|
|
83016
|
+
import * as path87 from "node:path";
|
|
82960
83017
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
82961
83018
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
82962
83019
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
82963
83020
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
82964
83021
|
function normalizeFindingPath(directory, file3) {
|
|
82965
|
-
const resolved =
|
|
82966
|
-
const rel =
|
|
83022
|
+
const resolved = path87.isAbsolute(file3) ? file3 : path87.resolve(directory, file3);
|
|
83023
|
+
const rel = path87.relative(path87.resolve(directory), resolved);
|
|
82967
83024
|
return rel.replace(/\\/g, "/");
|
|
82968
83025
|
}
|
|
82969
83026
|
function baselineRelPath(phase) {
|
|
82970
|
-
return
|
|
83027
|
+
return path87.join("evidence", String(phase), "sast-baseline.json");
|
|
82971
83028
|
}
|
|
82972
83029
|
function tempRelPath(phase) {
|
|
82973
|
-
return
|
|
83030
|
+
return path87.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
82974
83031
|
}
|
|
82975
83032
|
function lockRelPath(phase) {
|
|
82976
|
-
return
|
|
83033
|
+
return path87.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
82977
83034
|
}
|
|
82978
83035
|
function getLine(lines, idx) {
|
|
82979
83036
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -82990,7 +83047,7 @@ function fingerprintFinding(finding, directory, occurrenceIndex) {
|
|
|
82990
83047
|
}
|
|
82991
83048
|
const lineNum = finding.location.line;
|
|
82992
83049
|
try {
|
|
82993
|
-
const content =
|
|
83050
|
+
const content = fs69.readFileSync(finding.location.file, "utf-8");
|
|
82994
83051
|
const lines = content.split(`
|
|
82995
83052
|
`);
|
|
82996
83053
|
const idx = lineNum - 1;
|
|
@@ -83021,7 +83078,7 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
83021
83078
|
try {
|
|
83022
83079
|
if (relFile.startsWith(".."))
|
|
83023
83080
|
throw new Error("escapes workspace");
|
|
83024
|
-
const content =
|
|
83081
|
+
const content = fs69.readFileSync(finding.location.file, "utf-8");
|
|
83025
83082
|
const lines = content.split(`
|
|
83026
83083
|
`);
|
|
83027
83084
|
const idx = lineNum - 1;
|
|
@@ -83050,11 +83107,11 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
83050
83107
|
async function acquireLock(lockPath) {
|
|
83051
83108
|
for (let attempt = 0;attempt <= LOCK_RETRY_DELAYS_MS.length; attempt++) {
|
|
83052
83109
|
try {
|
|
83053
|
-
const fd =
|
|
83054
|
-
|
|
83110
|
+
const fd = fs69.openSync(lockPath, "wx");
|
|
83111
|
+
fs69.closeSync(fd);
|
|
83055
83112
|
return () => {
|
|
83056
83113
|
try {
|
|
83057
|
-
|
|
83114
|
+
fs69.unlinkSync(lockPath);
|
|
83058
83115
|
} catch {}
|
|
83059
83116
|
};
|
|
83060
83117
|
} catch {
|
|
@@ -83094,13 +83151,13 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
83094
83151
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
83095
83152
|
};
|
|
83096
83153
|
}
|
|
83097
|
-
|
|
83098
|
-
|
|
83154
|
+
fs69.mkdirSync(path87.dirname(baselinePath), { recursive: true });
|
|
83155
|
+
fs69.mkdirSync(path87.dirname(tempPath), { recursive: true });
|
|
83099
83156
|
const releaseLock = await acquireLock(lockPath);
|
|
83100
83157
|
try {
|
|
83101
83158
|
let existing = null;
|
|
83102
83159
|
try {
|
|
83103
|
-
const raw =
|
|
83160
|
+
const raw = fs69.readFileSync(baselinePath, "utf-8");
|
|
83104
83161
|
const parsed = JSON.parse(raw);
|
|
83105
83162
|
if (parsed.schema_version === BASELINE_SCHEMA_VERSION) {
|
|
83106
83163
|
existing = parsed;
|
|
@@ -83160,8 +83217,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
83160
83217
|
message: `Baseline would exceed size cap (${json4.length} bytes > ${MAX_BASELINE_BYTES})`
|
|
83161
83218
|
};
|
|
83162
83219
|
}
|
|
83163
|
-
|
|
83164
|
-
|
|
83220
|
+
fs69.writeFileSync(tempPath, json4, "utf-8");
|
|
83221
|
+
fs69.renameSync(tempPath, baselinePath);
|
|
83165
83222
|
return {
|
|
83166
83223
|
status: "merged",
|
|
83167
83224
|
path: baselinePath,
|
|
@@ -83192,8 +83249,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
83192
83249
|
message: `Baseline would exceed size cap (${json3.length} bytes > ${MAX_BASELINE_BYTES})`
|
|
83193
83250
|
};
|
|
83194
83251
|
}
|
|
83195
|
-
|
|
83196
|
-
|
|
83252
|
+
fs69.writeFileSync(tempPath, json3, "utf-8");
|
|
83253
|
+
fs69.renameSync(tempPath, baselinePath);
|
|
83197
83254
|
return {
|
|
83198
83255
|
status: "written",
|
|
83199
83256
|
path: baselinePath,
|
|
@@ -83218,7 +83275,7 @@ function loadBaseline(directory, phase) {
|
|
|
83218
83275
|
};
|
|
83219
83276
|
}
|
|
83220
83277
|
try {
|
|
83221
|
-
const raw =
|
|
83278
|
+
const raw = fs69.readFileSync(baselinePath, "utf-8");
|
|
83222
83279
|
const parsed = JSON.parse(raw);
|
|
83223
83280
|
if (parsed.schema_version !== BASELINE_SCHEMA_VERSION) {
|
|
83224
83281
|
return {
|
|
@@ -83260,17 +83317,17 @@ var SEVERITY_ORDER = {
|
|
|
83260
83317
|
};
|
|
83261
83318
|
function shouldSkipFile(filePath) {
|
|
83262
83319
|
try {
|
|
83263
|
-
const stats =
|
|
83320
|
+
const stats = fs70.statSync(filePath);
|
|
83264
83321
|
if (stats.size > MAX_FILE_SIZE_BYTES8) {
|
|
83265
83322
|
return { skip: true, reason: "file too large" };
|
|
83266
83323
|
}
|
|
83267
83324
|
if (stats.size === 0) {
|
|
83268
83325
|
return { skip: true, reason: "empty file" };
|
|
83269
83326
|
}
|
|
83270
|
-
const fd =
|
|
83327
|
+
const fd = fs70.openSync(filePath, "r");
|
|
83271
83328
|
const buffer = Buffer.alloc(8192);
|
|
83272
|
-
const bytesRead =
|
|
83273
|
-
|
|
83329
|
+
const bytesRead = fs70.readSync(fd, buffer, 0, 8192, 0);
|
|
83330
|
+
fs70.closeSync(fd);
|
|
83274
83331
|
if (bytesRead > 0) {
|
|
83275
83332
|
let nullCount = 0;
|
|
83276
83333
|
for (let i2 = 0;i2 < bytesRead; i2++) {
|
|
@@ -83309,7 +83366,7 @@ function countBySeverity(findings) {
|
|
|
83309
83366
|
}
|
|
83310
83367
|
function scanFileWithTierA(filePath, language) {
|
|
83311
83368
|
try {
|
|
83312
|
-
const content =
|
|
83369
|
+
const content = fs70.readFileSync(filePath, "utf-8");
|
|
83313
83370
|
const findings = executeRulesSync(filePath, content, language);
|
|
83314
83371
|
return findings.map((f) => ({
|
|
83315
83372
|
rule_id: f.rule_id,
|
|
@@ -83362,13 +83419,13 @@ async function sastScan(input, directory, config3) {
|
|
|
83362
83419
|
_filesSkipped++;
|
|
83363
83420
|
continue;
|
|
83364
83421
|
}
|
|
83365
|
-
const resolvedPath =
|
|
83366
|
-
const resolvedDirectory =
|
|
83367
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
83422
|
+
const resolvedPath = path88.isAbsolute(filePath) ? filePath : path88.resolve(directory, filePath);
|
|
83423
|
+
const resolvedDirectory = path88.resolve(directory);
|
|
83424
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path88.sep) && resolvedPath !== resolvedDirectory) {
|
|
83368
83425
|
_filesSkipped++;
|
|
83369
83426
|
continue;
|
|
83370
83427
|
}
|
|
83371
|
-
if (!
|
|
83428
|
+
if (!fs70.existsSync(resolvedPath)) {
|
|
83372
83429
|
_filesSkipped++;
|
|
83373
83430
|
continue;
|
|
83374
83431
|
}
|
|
@@ -83675,18 +83732,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
83675
83732
|
let resolved;
|
|
83676
83733
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
83677
83734
|
if (isWinAbs) {
|
|
83678
|
-
resolved =
|
|
83679
|
-
} else if (
|
|
83680
|
-
resolved =
|
|
83735
|
+
resolved = path89.win32.resolve(inputPath);
|
|
83736
|
+
} else if (path89.isAbsolute(inputPath)) {
|
|
83737
|
+
resolved = path89.resolve(inputPath);
|
|
83681
83738
|
} else {
|
|
83682
|
-
resolved =
|
|
83739
|
+
resolved = path89.resolve(baseDir, inputPath);
|
|
83683
83740
|
}
|
|
83684
|
-
const workspaceResolved =
|
|
83741
|
+
const workspaceResolved = path89.resolve(workspaceDir);
|
|
83685
83742
|
let relative20;
|
|
83686
83743
|
if (isWinAbs) {
|
|
83687
|
-
relative20 =
|
|
83744
|
+
relative20 = path89.win32.relative(workspaceResolved, resolved);
|
|
83688
83745
|
} else {
|
|
83689
|
-
relative20 =
|
|
83746
|
+
relative20 = path89.relative(workspaceResolved, resolved);
|
|
83690
83747
|
}
|
|
83691
83748
|
if (relative20.startsWith("..")) {
|
|
83692
83749
|
return "path traversal detected";
|
|
@@ -83751,7 +83808,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
83751
83808
|
if (typeof file3 !== "string") {
|
|
83752
83809
|
continue;
|
|
83753
83810
|
}
|
|
83754
|
-
const resolvedPath =
|
|
83811
|
+
const resolvedPath = path89.resolve(file3);
|
|
83755
83812
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
83756
83813
|
if (validationError) {
|
|
83757
83814
|
continue;
|
|
@@ -83908,7 +83965,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
83908
83965
|
skippedFiles++;
|
|
83909
83966
|
continue;
|
|
83910
83967
|
}
|
|
83911
|
-
const resolvedPath =
|
|
83968
|
+
const resolvedPath = path89.resolve(file3);
|
|
83912
83969
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
83913
83970
|
if (validationError) {
|
|
83914
83971
|
skippedFiles++;
|
|
@@ -83926,14 +83983,14 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
83926
83983
|
};
|
|
83927
83984
|
}
|
|
83928
83985
|
for (const file3 of validatedFiles) {
|
|
83929
|
-
const ext =
|
|
83986
|
+
const ext = path89.extname(file3).toLowerCase();
|
|
83930
83987
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
83931
83988
|
skippedFiles++;
|
|
83932
83989
|
continue;
|
|
83933
83990
|
}
|
|
83934
83991
|
let stat6;
|
|
83935
83992
|
try {
|
|
83936
|
-
stat6 =
|
|
83993
|
+
stat6 = fs71.statSync(file3);
|
|
83937
83994
|
} catch {
|
|
83938
83995
|
skippedFiles++;
|
|
83939
83996
|
continue;
|
|
@@ -83944,7 +84001,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
83944
84001
|
}
|
|
83945
84002
|
let content;
|
|
83946
84003
|
try {
|
|
83947
|
-
const buffer =
|
|
84004
|
+
const buffer = fs71.readFileSync(file3);
|
|
83948
84005
|
if (buffer.includes(0)) {
|
|
83949
84006
|
skippedFiles++;
|
|
83950
84007
|
continue;
|
|
@@ -84145,7 +84202,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
84145
84202
|
const preexistingFindings = [];
|
|
84146
84203
|
for (const finding of findings) {
|
|
84147
84204
|
const filePath = finding.location.file;
|
|
84148
|
-
const normalised =
|
|
84205
|
+
const normalised = path89.relative(directory, filePath).replace(/\\/g, "/");
|
|
84149
84206
|
const changedLines = changedLineRanges.get(normalised);
|
|
84150
84207
|
if (changedLines?.has(finding.location.line)) {
|
|
84151
84208
|
newFindings.push(finding);
|
|
@@ -84196,7 +84253,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
84196
84253
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
84197
84254
|
continue;
|
|
84198
84255
|
}
|
|
84199
|
-
changedFiles.push(
|
|
84256
|
+
changedFiles.push(path89.resolve(directory, file3));
|
|
84200
84257
|
}
|
|
84201
84258
|
if (changedFiles.length === 0) {
|
|
84202
84259
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -84397,7 +84454,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
84397
84454
|
};
|
|
84398
84455
|
return JSON.stringify(errorResult, null, 2);
|
|
84399
84456
|
}
|
|
84400
|
-
const resolvedDirectory =
|
|
84457
|
+
const resolvedDirectory = path89.resolve(typedArgs.directory);
|
|
84401
84458
|
const workspaceAnchor = resolvedDirectory;
|
|
84402
84459
|
const dirError = validateDirectory2(resolvedDirectory, workspaceAnchor);
|
|
84403
84460
|
if (dirError) {
|
|
@@ -84438,7 +84495,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
84438
84495
|
});
|
|
84439
84496
|
// src/tools/repo-map.ts
|
|
84440
84497
|
init_zod();
|
|
84441
|
-
import * as
|
|
84498
|
+
import * as path90 from "node:path";
|
|
84442
84499
|
init_path_security();
|
|
84443
84500
|
init_create_tool();
|
|
84444
84501
|
var VALID_ACTIONS = [
|
|
@@ -84463,7 +84520,7 @@ function validateFile(p) {
|
|
|
84463
84520
|
return "file contains control characters";
|
|
84464
84521
|
if (containsPathTraversal(p))
|
|
84465
84522
|
return "file contains path traversal";
|
|
84466
|
-
if (
|
|
84523
|
+
if (path90.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
84467
84524
|
return "file must be a workspace-relative path, not absolute";
|
|
84468
84525
|
}
|
|
84469
84526
|
return null;
|
|
@@ -84486,8 +84543,8 @@ function ok(action, payload) {
|
|
|
84486
84543
|
}
|
|
84487
84544
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
84488
84545
|
const normalized = input.replace(/\\/g, "/");
|
|
84489
|
-
if (
|
|
84490
|
-
const rel =
|
|
84546
|
+
if (path90.isAbsolute(normalized)) {
|
|
84547
|
+
const rel = path90.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
84491
84548
|
return normalizeGraphPath2(rel);
|
|
84492
84549
|
}
|
|
84493
84550
|
return normalizeGraphPath2(normalized);
|
|
@@ -84631,8 +84688,8 @@ var repo_map = createSwarmTool({
|
|
|
84631
84688
|
// src/tools/req-coverage.ts
|
|
84632
84689
|
init_zod();
|
|
84633
84690
|
init_create_tool();
|
|
84634
|
-
import * as
|
|
84635
|
-
import * as
|
|
84691
|
+
import * as fs72 from "node:fs";
|
|
84692
|
+
import * as path91 from "node:path";
|
|
84636
84693
|
var SPEC_FILE = ".swarm/spec.md";
|
|
84637
84694
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
84638
84695
|
var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -84691,19 +84748,19 @@ function extractObligationAndText(id, lineText) {
|
|
|
84691
84748
|
var PHASE_TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
|
|
84692
84749
|
function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
84693
84750
|
const touchedFiles = new Set;
|
|
84694
|
-
if (!
|
|
84751
|
+
if (!fs72.existsSync(evidenceDir) || !fs72.statSync(evidenceDir).isDirectory()) {
|
|
84695
84752
|
return [];
|
|
84696
84753
|
}
|
|
84697
84754
|
let entries;
|
|
84698
84755
|
try {
|
|
84699
|
-
entries =
|
|
84756
|
+
entries = fs72.readdirSync(evidenceDir);
|
|
84700
84757
|
} catch {
|
|
84701
84758
|
return [];
|
|
84702
84759
|
}
|
|
84703
84760
|
for (const entry of entries) {
|
|
84704
|
-
const entryPath =
|
|
84761
|
+
const entryPath = path91.join(evidenceDir, entry);
|
|
84705
84762
|
try {
|
|
84706
|
-
const stat6 =
|
|
84763
|
+
const stat6 = fs72.statSync(entryPath);
|
|
84707
84764
|
if (!stat6.isDirectory()) {
|
|
84708
84765
|
continue;
|
|
84709
84766
|
}
|
|
@@ -84717,14 +84774,14 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
84717
84774
|
if (entryPhase !== String(phase)) {
|
|
84718
84775
|
continue;
|
|
84719
84776
|
}
|
|
84720
|
-
const evidenceFilePath =
|
|
84777
|
+
const evidenceFilePath = path91.join(entryPath, "evidence.json");
|
|
84721
84778
|
try {
|
|
84722
|
-
const resolvedPath =
|
|
84723
|
-
const evidenceDirResolved =
|
|
84724
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
84779
|
+
const resolvedPath = path91.resolve(evidenceFilePath);
|
|
84780
|
+
const evidenceDirResolved = path91.resolve(evidenceDir);
|
|
84781
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path91.sep)) {
|
|
84725
84782
|
continue;
|
|
84726
84783
|
}
|
|
84727
|
-
const stat6 =
|
|
84784
|
+
const stat6 = fs72.lstatSync(evidenceFilePath);
|
|
84728
84785
|
if (!stat6.isFile()) {
|
|
84729
84786
|
continue;
|
|
84730
84787
|
}
|
|
@@ -84736,7 +84793,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
84736
84793
|
}
|
|
84737
84794
|
let content;
|
|
84738
84795
|
try {
|
|
84739
|
-
content =
|
|
84796
|
+
content = fs72.readFileSync(evidenceFilePath, "utf-8");
|
|
84740
84797
|
} catch {
|
|
84741
84798
|
continue;
|
|
84742
84799
|
}
|
|
@@ -84755,7 +84812,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
84755
84812
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
84756
84813
|
for (const file3 of diffEntry.files_changed) {
|
|
84757
84814
|
if (typeof file3 === "string") {
|
|
84758
|
-
touchedFiles.add(
|
|
84815
|
+
touchedFiles.add(path91.resolve(cwd, file3));
|
|
84759
84816
|
}
|
|
84760
84817
|
}
|
|
84761
84818
|
}
|
|
@@ -84768,12 +84825,12 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
84768
84825
|
}
|
|
84769
84826
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
84770
84827
|
try {
|
|
84771
|
-
const resolvedPath =
|
|
84772
|
-
const cwdResolved =
|
|
84828
|
+
const resolvedPath = path91.resolve(filePath);
|
|
84829
|
+
const cwdResolved = path91.resolve(cwd);
|
|
84773
84830
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
84774
84831
|
return false;
|
|
84775
84832
|
}
|
|
84776
|
-
const content =
|
|
84833
|
+
const content = fs72.readFileSync(resolvedPath, "utf-8");
|
|
84777
84834
|
for (const keyword of keywords) {
|
|
84778
84835
|
const regex = new RegExp(`\\b${keyword}\\b`, "i");
|
|
84779
84836
|
if (regex.test(content)) {
|
|
@@ -84903,10 +84960,10 @@ var req_coverage = createSwarmTool({
|
|
|
84903
84960
|
}, null, 2);
|
|
84904
84961
|
}
|
|
84905
84962
|
const cwd = inputDirectory || directory;
|
|
84906
|
-
const specPath =
|
|
84963
|
+
const specPath = path91.join(cwd, SPEC_FILE);
|
|
84907
84964
|
let specContent;
|
|
84908
84965
|
try {
|
|
84909
|
-
specContent =
|
|
84966
|
+
specContent = fs72.readFileSync(specPath, "utf-8");
|
|
84910
84967
|
} catch (readError) {
|
|
84911
84968
|
return JSON.stringify({
|
|
84912
84969
|
success: false,
|
|
@@ -84930,7 +84987,7 @@ var req_coverage = createSwarmTool({
|
|
|
84930
84987
|
message: "No FR requirements found in spec.md"
|
|
84931
84988
|
}, null, 2);
|
|
84932
84989
|
}
|
|
84933
|
-
const evidenceDir =
|
|
84990
|
+
const evidenceDir = path91.join(cwd, EVIDENCE_DIR4);
|
|
84934
84991
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
84935
84992
|
const analyzedRequirements = [];
|
|
84936
84993
|
let coveredCount = 0;
|
|
@@ -84956,12 +85013,12 @@ var req_coverage = createSwarmTool({
|
|
|
84956
85013
|
requirements: analyzedRequirements
|
|
84957
85014
|
};
|
|
84958
85015
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
84959
|
-
const reportPath =
|
|
85016
|
+
const reportPath = path91.join(evidenceDir, reportFilename);
|
|
84960
85017
|
try {
|
|
84961
|
-
if (!
|
|
84962
|
-
|
|
85018
|
+
if (!fs72.existsSync(evidenceDir)) {
|
|
85019
|
+
fs72.mkdirSync(evidenceDir, { recursive: true });
|
|
84963
85020
|
}
|
|
84964
|
-
|
|
85021
|
+
fs72.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8");
|
|
84965
85022
|
} catch (writeError) {
|
|
84966
85023
|
console.warn(`Failed to write coverage report: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
84967
85024
|
}
|
|
@@ -85043,8 +85100,8 @@ init_plan_schema();
|
|
|
85043
85100
|
init_qa_gate_profile();
|
|
85044
85101
|
init_file_locks();
|
|
85045
85102
|
import * as crypto9 from "node:crypto";
|
|
85046
|
-
import * as
|
|
85047
|
-
import * as
|
|
85103
|
+
import * as fs73 from "node:fs";
|
|
85104
|
+
import * as path92 from "node:path";
|
|
85048
85105
|
init_ledger();
|
|
85049
85106
|
init_manager();
|
|
85050
85107
|
init_state();
|
|
@@ -85122,17 +85179,17 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85122
85179
|
};
|
|
85123
85180
|
}
|
|
85124
85181
|
if (args2.working_directory && fallbackDir) {
|
|
85125
|
-
const resolvedTarget =
|
|
85126
|
-
const resolvedRoot =
|
|
85182
|
+
const resolvedTarget = path92.resolve(args2.working_directory);
|
|
85183
|
+
const resolvedRoot = path92.resolve(fallbackDir);
|
|
85127
85184
|
let fallbackExists = false;
|
|
85128
85185
|
try {
|
|
85129
|
-
|
|
85186
|
+
fs73.accessSync(resolvedRoot, fs73.constants.F_OK);
|
|
85130
85187
|
fallbackExists = true;
|
|
85131
85188
|
} catch {
|
|
85132
85189
|
fallbackExists = false;
|
|
85133
85190
|
}
|
|
85134
85191
|
if (fallbackExists) {
|
|
85135
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
85192
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path92.sep);
|
|
85136
85193
|
if (isSubdirectory) {
|
|
85137
85194
|
return {
|
|
85138
85195
|
success: false,
|
|
@@ -85148,11 +85205,11 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85148
85205
|
let specMtime;
|
|
85149
85206
|
let specHash;
|
|
85150
85207
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
85151
|
-
const specPath =
|
|
85208
|
+
const specPath = path92.join(targetWorkspace, ".swarm", "spec.md");
|
|
85152
85209
|
try {
|
|
85153
|
-
const stat6 = await
|
|
85210
|
+
const stat6 = await fs73.promises.stat(specPath);
|
|
85154
85211
|
specMtime = stat6.mtime.toISOString();
|
|
85155
|
-
const content = await
|
|
85212
|
+
const content = await fs73.promises.readFile(specPath, "utf8");
|
|
85156
85213
|
specHash = crypto9.createHash("sha256").update(content).digest("hex");
|
|
85157
85214
|
} catch {
|
|
85158
85215
|
return {
|
|
@@ -85164,10 +85221,10 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85164
85221
|
}
|
|
85165
85222
|
}
|
|
85166
85223
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
85167
|
-
const contextPath =
|
|
85224
|
+
const contextPath = path92.join(targetWorkspace, ".swarm", "context.md");
|
|
85168
85225
|
let contextContent = "";
|
|
85169
85226
|
try {
|
|
85170
|
-
contextContent = await
|
|
85227
|
+
contextContent = await fs73.promises.readFile(contextPath, "utf8");
|
|
85171
85228
|
} catch {}
|
|
85172
85229
|
const hasPendingSection = contextContent.includes("## Pending QA Gate Selection");
|
|
85173
85230
|
if (!hasPendingSection) {
|
|
@@ -85314,14 +85371,14 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85314
85371
|
}
|
|
85315
85372
|
await writeCheckpoint(dir).catch(() => {});
|
|
85316
85373
|
try {
|
|
85317
|
-
const markerPath =
|
|
85374
|
+
const markerPath = path92.join(dir, ".swarm", ".plan-write-marker");
|
|
85318
85375
|
const marker = JSON.stringify({
|
|
85319
85376
|
source: "save_plan",
|
|
85320
85377
|
timestamp: new Date().toISOString(),
|
|
85321
85378
|
phases_count: plan.phases.length,
|
|
85322
85379
|
tasks_count: tasksCount
|
|
85323
85380
|
});
|
|
85324
|
-
await
|
|
85381
|
+
await fs73.promises.writeFile(markerPath, marker, "utf8");
|
|
85325
85382
|
} catch {}
|
|
85326
85383
|
const warnings = [];
|
|
85327
85384
|
let criticReviewFound = false;
|
|
@@ -85337,7 +85394,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85337
85394
|
return {
|
|
85338
85395
|
success: true,
|
|
85339
85396
|
message: "Plan saved successfully",
|
|
85340
|
-
plan_path:
|
|
85397
|
+
plan_path: path92.join(dir, ".swarm", "plan.json"),
|
|
85341
85398
|
phases_count: plan.phases.length,
|
|
85342
85399
|
tasks_count: tasksCount,
|
|
85343
85400
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -85389,8 +85446,8 @@ var save_plan = createSwarmTool({
|
|
|
85389
85446
|
// src/tools/sbom-generate.ts
|
|
85390
85447
|
init_zod();
|
|
85391
85448
|
init_manager2();
|
|
85392
|
-
import * as
|
|
85393
|
-
import * as
|
|
85449
|
+
import * as fs74 from "node:fs";
|
|
85450
|
+
import * as path93 from "node:path";
|
|
85394
85451
|
|
|
85395
85452
|
// src/sbom/detectors/index.ts
|
|
85396
85453
|
init_utils();
|
|
@@ -86238,9 +86295,9 @@ function findManifestFiles(rootDir) {
|
|
|
86238
86295
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
86239
86296
|
function searchDir(dir) {
|
|
86240
86297
|
try {
|
|
86241
|
-
const entries =
|
|
86298
|
+
const entries = fs74.readdirSync(dir, { withFileTypes: true });
|
|
86242
86299
|
for (const entry of entries) {
|
|
86243
|
-
const fullPath =
|
|
86300
|
+
const fullPath = path93.join(dir, entry.name);
|
|
86244
86301
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
86245
86302
|
continue;
|
|
86246
86303
|
}
|
|
@@ -86249,7 +86306,7 @@ function findManifestFiles(rootDir) {
|
|
|
86249
86306
|
} else if (entry.isFile()) {
|
|
86250
86307
|
for (const pattern of patterns) {
|
|
86251
86308
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
86252
|
-
manifestFiles.push(
|
|
86309
|
+
manifestFiles.push(path93.relative(rootDir, fullPath));
|
|
86253
86310
|
break;
|
|
86254
86311
|
}
|
|
86255
86312
|
}
|
|
@@ -86265,13 +86322,13 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
86265
86322
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
86266
86323
|
for (const dir of directories) {
|
|
86267
86324
|
try {
|
|
86268
|
-
const entries =
|
|
86325
|
+
const entries = fs74.readdirSync(dir, { withFileTypes: true });
|
|
86269
86326
|
for (const entry of entries) {
|
|
86270
|
-
const fullPath =
|
|
86327
|
+
const fullPath = path93.join(dir, entry.name);
|
|
86271
86328
|
if (entry.isFile()) {
|
|
86272
86329
|
for (const pattern of patterns) {
|
|
86273
86330
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
86274
|
-
found.push(
|
|
86331
|
+
found.push(path93.relative(workingDir, fullPath));
|
|
86275
86332
|
break;
|
|
86276
86333
|
}
|
|
86277
86334
|
}
|
|
@@ -86284,11 +86341,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
86284
86341
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
86285
86342
|
const dirs = new Set;
|
|
86286
86343
|
for (const file3 of changedFiles) {
|
|
86287
|
-
let currentDir =
|
|
86344
|
+
let currentDir = path93.dirname(file3);
|
|
86288
86345
|
while (true) {
|
|
86289
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
86290
|
-
dirs.add(
|
|
86291
|
-
const parent =
|
|
86346
|
+
if (currentDir && currentDir !== "." && currentDir !== path93.sep) {
|
|
86347
|
+
dirs.add(path93.join(workingDir, currentDir));
|
|
86348
|
+
const parent = path93.dirname(currentDir);
|
|
86292
86349
|
if (parent === currentDir)
|
|
86293
86350
|
break;
|
|
86294
86351
|
currentDir = parent;
|
|
@@ -86302,7 +86359,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
|
86302
86359
|
}
|
|
86303
86360
|
function ensureOutputDir(outputDir) {
|
|
86304
86361
|
try {
|
|
86305
|
-
|
|
86362
|
+
fs74.mkdirSync(outputDir, { recursive: true });
|
|
86306
86363
|
} catch (error93) {
|
|
86307
86364
|
if (!error93 || error93.code !== "EEXIST") {
|
|
86308
86365
|
throw error93;
|
|
@@ -86372,7 +86429,7 @@ var sbom_generate = createSwarmTool({
|
|
|
86372
86429
|
const changedFiles = obj.changed_files;
|
|
86373
86430
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
86374
86431
|
const workingDir = directory;
|
|
86375
|
-
const outputDir =
|
|
86432
|
+
const outputDir = path93.isAbsolute(relativeOutputDir) ? relativeOutputDir : path93.join(workingDir, relativeOutputDir);
|
|
86376
86433
|
let manifestFiles = [];
|
|
86377
86434
|
if (scope === "all") {
|
|
86378
86435
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -86395,11 +86452,11 @@ var sbom_generate = createSwarmTool({
|
|
|
86395
86452
|
const processedFiles = [];
|
|
86396
86453
|
for (const manifestFile of manifestFiles) {
|
|
86397
86454
|
try {
|
|
86398
|
-
const fullPath =
|
|
86399
|
-
if (!
|
|
86455
|
+
const fullPath = path93.isAbsolute(manifestFile) ? manifestFile : path93.join(workingDir, manifestFile);
|
|
86456
|
+
if (!fs74.existsSync(fullPath)) {
|
|
86400
86457
|
continue;
|
|
86401
86458
|
}
|
|
86402
|
-
const content =
|
|
86459
|
+
const content = fs74.readFileSync(fullPath, "utf-8");
|
|
86403
86460
|
const components = detectComponents(manifestFile, content);
|
|
86404
86461
|
processedFiles.push(manifestFile);
|
|
86405
86462
|
if (components.length > 0) {
|
|
@@ -86412,8 +86469,8 @@ var sbom_generate = createSwarmTool({
|
|
|
86412
86469
|
const bom = generateCycloneDX(allComponents);
|
|
86413
86470
|
const bomJson = serializeCycloneDX(bom);
|
|
86414
86471
|
const filename = generateSbomFilename();
|
|
86415
|
-
const outputPath =
|
|
86416
|
-
|
|
86472
|
+
const outputPath = path93.join(outputDir, filename);
|
|
86473
|
+
fs74.writeFileSync(outputPath, bomJson, "utf-8");
|
|
86417
86474
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
86418
86475
|
try {
|
|
86419
86476
|
const timestamp = new Date().toISOString();
|
|
@@ -86455,8 +86512,8 @@ var sbom_generate = createSwarmTool({
|
|
|
86455
86512
|
// src/tools/schema-drift.ts
|
|
86456
86513
|
init_zod();
|
|
86457
86514
|
init_create_tool();
|
|
86458
|
-
import * as
|
|
86459
|
-
import * as
|
|
86515
|
+
import * as fs75 from "node:fs";
|
|
86516
|
+
import * as path94 from "node:path";
|
|
86460
86517
|
var SPEC_CANDIDATES = [
|
|
86461
86518
|
"openapi.json",
|
|
86462
86519
|
"openapi.yaml",
|
|
@@ -86488,28 +86545,28 @@ function normalizePath3(p) {
|
|
|
86488
86545
|
}
|
|
86489
86546
|
function discoverSpecFile(cwd, specFileArg) {
|
|
86490
86547
|
if (specFileArg) {
|
|
86491
|
-
const resolvedPath =
|
|
86492
|
-
const normalizedCwd = cwd.endsWith(
|
|
86548
|
+
const resolvedPath = path94.resolve(cwd, specFileArg);
|
|
86549
|
+
const normalizedCwd = cwd.endsWith(path94.sep) ? cwd : cwd + path94.sep;
|
|
86493
86550
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
86494
86551
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
86495
86552
|
}
|
|
86496
|
-
const ext =
|
|
86553
|
+
const ext = path94.extname(resolvedPath).toLowerCase();
|
|
86497
86554
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
86498
86555
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
86499
86556
|
}
|
|
86500
|
-
const stats =
|
|
86557
|
+
const stats = fs75.statSync(resolvedPath);
|
|
86501
86558
|
if (stats.size > MAX_SPEC_SIZE) {
|
|
86502
86559
|
throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
|
|
86503
86560
|
}
|
|
86504
|
-
if (!
|
|
86561
|
+
if (!fs75.existsSync(resolvedPath)) {
|
|
86505
86562
|
throw new Error(`Spec file not found: ${resolvedPath}`);
|
|
86506
86563
|
}
|
|
86507
86564
|
return resolvedPath;
|
|
86508
86565
|
}
|
|
86509
86566
|
for (const candidate of SPEC_CANDIDATES) {
|
|
86510
|
-
const candidatePath =
|
|
86511
|
-
if (
|
|
86512
|
-
const stats =
|
|
86567
|
+
const candidatePath = path94.resolve(cwd, candidate);
|
|
86568
|
+
if (fs75.existsSync(candidatePath)) {
|
|
86569
|
+
const stats = fs75.statSync(candidatePath);
|
|
86513
86570
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
86514
86571
|
return candidatePath;
|
|
86515
86572
|
}
|
|
@@ -86518,8 +86575,8 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
86518
86575
|
return null;
|
|
86519
86576
|
}
|
|
86520
86577
|
function parseSpec(specFile) {
|
|
86521
|
-
const content =
|
|
86522
|
-
const ext =
|
|
86578
|
+
const content = fs75.readFileSync(specFile, "utf-8");
|
|
86579
|
+
const ext = path94.extname(specFile).toLowerCase();
|
|
86523
86580
|
if (ext === ".json") {
|
|
86524
86581
|
return parseJsonSpec(content);
|
|
86525
86582
|
}
|
|
@@ -86590,12 +86647,12 @@ function extractRoutes(cwd) {
|
|
|
86590
86647
|
function walkDir(dir) {
|
|
86591
86648
|
let entries;
|
|
86592
86649
|
try {
|
|
86593
|
-
entries =
|
|
86650
|
+
entries = fs75.readdirSync(dir, { withFileTypes: true });
|
|
86594
86651
|
} catch {
|
|
86595
86652
|
return;
|
|
86596
86653
|
}
|
|
86597
86654
|
for (const entry of entries) {
|
|
86598
|
-
const fullPath =
|
|
86655
|
+
const fullPath = path94.join(dir, entry.name);
|
|
86599
86656
|
if (entry.isSymbolicLink()) {
|
|
86600
86657
|
continue;
|
|
86601
86658
|
}
|
|
@@ -86605,7 +86662,7 @@ function extractRoutes(cwd) {
|
|
|
86605
86662
|
}
|
|
86606
86663
|
walkDir(fullPath);
|
|
86607
86664
|
} else if (entry.isFile()) {
|
|
86608
|
-
const ext =
|
|
86665
|
+
const ext = path94.extname(entry.name).toLowerCase();
|
|
86609
86666
|
const baseName = entry.name.toLowerCase();
|
|
86610
86667
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
86611
86668
|
continue;
|
|
@@ -86623,7 +86680,7 @@ function extractRoutes(cwd) {
|
|
|
86623
86680
|
}
|
|
86624
86681
|
function extractRoutesFromFile(filePath) {
|
|
86625
86682
|
const routes = [];
|
|
86626
|
-
const content =
|
|
86683
|
+
const content = fs75.readFileSync(filePath, "utf-8");
|
|
86627
86684
|
const lines = content.split(/\r?\n/);
|
|
86628
86685
|
const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
86629
86686
|
const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
|
|
@@ -86772,8 +86829,8 @@ init_zod();
|
|
|
86772
86829
|
init_bun_compat();
|
|
86773
86830
|
init_path_security();
|
|
86774
86831
|
init_create_tool();
|
|
86775
|
-
import * as
|
|
86776
|
-
import * as
|
|
86832
|
+
import * as fs76 from "node:fs";
|
|
86833
|
+
import * as path95 from "node:path";
|
|
86777
86834
|
var DEFAULT_MAX_RESULTS = 100;
|
|
86778
86835
|
var DEFAULT_MAX_LINES = 200;
|
|
86779
86836
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -86809,11 +86866,11 @@ function containsWindowsAttacks3(str) {
|
|
|
86809
86866
|
}
|
|
86810
86867
|
function isPathInWorkspace3(filePath, workspace) {
|
|
86811
86868
|
try {
|
|
86812
|
-
const resolvedPath =
|
|
86813
|
-
const realWorkspace =
|
|
86814
|
-
const realResolvedPath =
|
|
86815
|
-
const relativePath =
|
|
86816
|
-
if (relativePath.startsWith("..") ||
|
|
86869
|
+
const resolvedPath = path95.resolve(workspace, filePath);
|
|
86870
|
+
const realWorkspace = fs76.realpathSync(workspace);
|
|
86871
|
+
const realResolvedPath = fs76.realpathSync(resolvedPath);
|
|
86872
|
+
const relativePath = path95.relative(realWorkspace, realResolvedPath);
|
|
86873
|
+
if (relativePath.startsWith("..") || path95.isAbsolute(relativePath)) {
|
|
86817
86874
|
return false;
|
|
86818
86875
|
}
|
|
86819
86876
|
return true;
|
|
@@ -86826,12 +86883,12 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
86826
86883
|
}
|
|
86827
86884
|
function findRgInEnvPath() {
|
|
86828
86885
|
const searchPath = process.env.PATH ?? "";
|
|
86829
|
-
for (const dir of searchPath.split(
|
|
86886
|
+
for (const dir of searchPath.split(path95.delimiter)) {
|
|
86830
86887
|
if (!dir)
|
|
86831
86888
|
continue;
|
|
86832
86889
|
const isWindows = process.platform === "win32";
|
|
86833
|
-
const candidate =
|
|
86834
|
-
if (
|
|
86890
|
+
const candidate = path95.join(dir, isWindows ? "rg.exe" : "rg");
|
|
86891
|
+
if (fs76.existsSync(candidate))
|
|
86835
86892
|
return candidate;
|
|
86836
86893
|
}
|
|
86837
86894
|
return null;
|
|
@@ -86958,10 +87015,10 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
86958
87015
|
return files;
|
|
86959
87016
|
}
|
|
86960
87017
|
try {
|
|
86961
|
-
const entries =
|
|
87018
|
+
const entries = fs76.readdirSync(dir, { withFileTypes: true });
|
|
86962
87019
|
for (const entry of entries) {
|
|
86963
|
-
const fullPath =
|
|
86964
|
-
const relativePath =
|
|
87020
|
+
const fullPath = path95.join(dir, entry.name);
|
|
87021
|
+
const relativePath = path95.relative(workspace, fullPath);
|
|
86965
87022
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
86966
87023
|
continue;
|
|
86967
87024
|
}
|
|
@@ -87002,13 +87059,13 @@ async function fallbackSearch(opts) {
|
|
|
87002
87059
|
const matches = [];
|
|
87003
87060
|
let total = 0;
|
|
87004
87061
|
for (const file3 of files) {
|
|
87005
|
-
const fullPath =
|
|
87062
|
+
const fullPath = path95.join(opts.workspace, file3);
|
|
87006
87063
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
87007
87064
|
continue;
|
|
87008
87065
|
}
|
|
87009
87066
|
let stats;
|
|
87010
87067
|
try {
|
|
87011
|
-
stats =
|
|
87068
|
+
stats = fs76.statSync(fullPath);
|
|
87012
87069
|
if (stats.size > MAX_FILE_SIZE_BYTES10) {
|
|
87013
87070
|
continue;
|
|
87014
87071
|
}
|
|
@@ -87017,7 +87074,7 @@ async function fallbackSearch(opts) {
|
|
|
87017
87074
|
}
|
|
87018
87075
|
let content;
|
|
87019
87076
|
try {
|
|
87020
|
-
content =
|
|
87077
|
+
content = fs76.readFileSync(fullPath, "utf-8");
|
|
87021
87078
|
} catch {
|
|
87022
87079
|
continue;
|
|
87023
87080
|
}
|
|
@@ -87129,7 +87186,7 @@ var search = createSwarmTool({
|
|
|
87129
87186
|
message: "Exclude pattern contains invalid Windows-specific sequence"
|
|
87130
87187
|
}, null, 2);
|
|
87131
87188
|
}
|
|
87132
|
-
if (!
|
|
87189
|
+
if (!fs76.existsSync(directory)) {
|
|
87133
87190
|
return JSON.stringify({
|
|
87134
87191
|
error: true,
|
|
87135
87192
|
type: "unknown",
|
|
@@ -87258,8 +87315,8 @@ var set_qa_gates = createSwarmTool({
|
|
|
87258
87315
|
init_zod();
|
|
87259
87316
|
init_path_security();
|
|
87260
87317
|
init_create_tool();
|
|
87261
|
-
import * as
|
|
87262
|
-
import * as
|
|
87318
|
+
import * as fs77 from "node:fs";
|
|
87319
|
+
import * as path96 from "node:path";
|
|
87263
87320
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
87264
87321
|
function containsWindowsAttacks4(str) {
|
|
87265
87322
|
if (/:[^\\/]/.test(str))
|
|
@@ -87273,14 +87330,14 @@ function containsWindowsAttacks4(str) {
|
|
|
87273
87330
|
}
|
|
87274
87331
|
function isPathInWorkspace4(filePath, workspace) {
|
|
87275
87332
|
try {
|
|
87276
|
-
const resolvedPath =
|
|
87277
|
-
if (!
|
|
87333
|
+
const resolvedPath = path96.resolve(workspace, filePath);
|
|
87334
|
+
if (!fs77.existsSync(resolvedPath)) {
|
|
87278
87335
|
return true;
|
|
87279
87336
|
}
|
|
87280
|
-
const realWorkspace =
|
|
87281
|
-
const realResolvedPath =
|
|
87282
|
-
const relativePath =
|
|
87283
|
-
if (relativePath.startsWith("..") ||
|
|
87337
|
+
const realWorkspace = fs77.realpathSync(workspace);
|
|
87338
|
+
const realResolvedPath = fs77.realpathSync(resolvedPath);
|
|
87339
|
+
const relativePath = path96.relative(realWorkspace, realResolvedPath);
|
|
87340
|
+
if (relativePath.startsWith("..") || path96.isAbsolute(relativePath)) {
|
|
87284
87341
|
return false;
|
|
87285
87342
|
}
|
|
87286
87343
|
return true;
|
|
@@ -87452,7 +87509,7 @@ var suggestPatch = createSwarmTool({
|
|
|
87452
87509
|
message: "changes cannot be empty"
|
|
87453
87510
|
}, null, 2);
|
|
87454
87511
|
}
|
|
87455
|
-
if (!
|
|
87512
|
+
if (!fs77.existsSync(directory)) {
|
|
87456
87513
|
return JSON.stringify({
|
|
87457
87514
|
success: false,
|
|
87458
87515
|
error: true,
|
|
@@ -87488,8 +87545,8 @@ var suggestPatch = createSwarmTool({
|
|
|
87488
87545
|
});
|
|
87489
87546
|
continue;
|
|
87490
87547
|
}
|
|
87491
|
-
const fullPath =
|
|
87492
|
-
if (!
|
|
87548
|
+
const fullPath = path96.resolve(directory, change.file);
|
|
87549
|
+
if (!fs77.existsSync(fullPath)) {
|
|
87493
87550
|
errors5.push({
|
|
87494
87551
|
success: false,
|
|
87495
87552
|
error: true,
|
|
@@ -87503,7 +87560,7 @@ var suggestPatch = createSwarmTool({
|
|
|
87503
87560
|
}
|
|
87504
87561
|
let content;
|
|
87505
87562
|
try {
|
|
87506
|
-
content =
|
|
87563
|
+
content = fs77.readFileSync(fullPath, "utf-8");
|
|
87507
87564
|
} catch (err3) {
|
|
87508
87565
|
errors5.push({
|
|
87509
87566
|
success: false,
|
|
@@ -87750,8 +87807,8 @@ var generate_mutants = createSwarmTool({
|
|
|
87750
87807
|
// src/tools/lint-spec.ts
|
|
87751
87808
|
init_spec_schema();
|
|
87752
87809
|
init_create_tool();
|
|
87753
|
-
import * as
|
|
87754
|
-
import * as
|
|
87810
|
+
import * as fs78 from "node:fs";
|
|
87811
|
+
import * as path97 from "node:path";
|
|
87755
87812
|
var SPEC_FILE_NAME = "spec.md";
|
|
87756
87813
|
var SWARM_DIR2 = ".swarm";
|
|
87757
87814
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -87804,8 +87861,8 @@ var lint_spec = createSwarmTool({
|
|
|
87804
87861
|
async execute(_args, directory) {
|
|
87805
87862
|
const errors5 = [];
|
|
87806
87863
|
const warnings = [];
|
|
87807
|
-
const specPath =
|
|
87808
|
-
if (!
|
|
87864
|
+
const specPath = path97.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
87865
|
+
if (!fs78.existsSync(specPath)) {
|
|
87809
87866
|
const result2 = {
|
|
87810
87867
|
valid: false,
|
|
87811
87868
|
specMtime: null,
|
|
@@ -87824,12 +87881,12 @@ var lint_spec = createSwarmTool({
|
|
|
87824
87881
|
}
|
|
87825
87882
|
let specMtime = null;
|
|
87826
87883
|
try {
|
|
87827
|
-
const stats =
|
|
87884
|
+
const stats = fs78.statSync(specPath);
|
|
87828
87885
|
specMtime = stats.mtime.toISOString();
|
|
87829
87886
|
} catch {}
|
|
87830
87887
|
let content;
|
|
87831
87888
|
try {
|
|
87832
|
-
content =
|
|
87889
|
+
content = fs78.readFileSync(specPath, "utf-8");
|
|
87833
87890
|
} catch (e) {
|
|
87834
87891
|
const result2 = {
|
|
87835
87892
|
valid: false,
|
|
@@ -87874,13 +87931,13 @@ var lint_spec = createSwarmTool({
|
|
|
87874
87931
|
});
|
|
87875
87932
|
// src/tools/mutation-test.ts
|
|
87876
87933
|
init_zod();
|
|
87877
|
-
import * as
|
|
87878
|
-
import * as
|
|
87934
|
+
import * as fs79 from "node:fs";
|
|
87935
|
+
import * as path99 from "node:path";
|
|
87879
87936
|
|
|
87880
87937
|
// src/mutation/engine.ts
|
|
87881
87938
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
87882
|
-
import { unlinkSync as unlinkSync13, writeFileSync as
|
|
87883
|
-
import * as
|
|
87939
|
+
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync20 } from "node:fs";
|
|
87940
|
+
import * as path98 from "node:path";
|
|
87884
87941
|
|
|
87885
87942
|
// src/mutation/equivalence.ts
|
|
87886
87943
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -88015,9 +88072,9 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
88015
88072
|
let patchFile;
|
|
88016
88073
|
try {
|
|
88017
88074
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
88018
|
-
patchFile =
|
|
88075
|
+
patchFile = path98.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
88019
88076
|
try {
|
|
88020
|
-
|
|
88077
|
+
writeFileSync20(patchFile, patch.patch);
|
|
88021
88078
|
} catch (writeErr) {
|
|
88022
88079
|
error93 = `Failed to write patch file: ${writeErr}`;
|
|
88023
88080
|
outcome = "error";
|
|
@@ -88409,8 +88466,8 @@ var mutation_test = createSwarmTool({
|
|
|
88409
88466
|
];
|
|
88410
88467
|
for (const filePath of uniquePaths) {
|
|
88411
88468
|
try {
|
|
88412
|
-
const resolvedPath =
|
|
88413
|
-
sourceFiles.set(filePath,
|
|
88469
|
+
const resolvedPath = path99.resolve(cwd, filePath);
|
|
88470
|
+
sourceFiles.set(filePath, fs79.readFileSync(resolvedPath, "utf-8"));
|
|
88414
88471
|
} catch {}
|
|
88415
88472
|
}
|
|
88416
88473
|
const report = await executeMutationSuite(typedArgs.patches, typedArgs.test_command, typedArgs.files, cwd, undefined, undefined, sourceFiles.size > 0 ? sourceFiles : undefined);
|
|
@@ -88428,8 +88485,8 @@ var mutation_test = createSwarmTool({
|
|
|
88428
88485
|
init_zod();
|
|
88429
88486
|
init_manager2();
|
|
88430
88487
|
init_detector();
|
|
88431
|
-
import * as
|
|
88432
|
-
import * as
|
|
88488
|
+
import * as fs80 from "node:fs";
|
|
88489
|
+
import * as path100 from "node:path";
|
|
88433
88490
|
init_create_tool();
|
|
88434
88491
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
88435
88492
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -88495,7 +88552,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
88495
88552
|
if (languages?.length) {
|
|
88496
88553
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
88497
88554
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
88498
|
-
const ext =
|
|
88555
|
+
const ext = path100.extname(file3.path).toLowerCase();
|
|
88499
88556
|
const langDef = getLanguageForExtension(ext);
|
|
88500
88557
|
const fileProfile = getProfileForFile(file3.path);
|
|
88501
88558
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -88508,7 +88565,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
88508
88565
|
let skippedCount = 0;
|
|
88509
88566
|
for (const fileInfo of filesToCheck) {
|
|
88510
88567
|
const { path: filePath } = fileInfo;
|
|
88511
|
-
const fullPath =
|
|
88568
|
+
const fullPath = path100.isAbsolute(filePath) ? filePath : path100.join(directory, filePath);
|
|
88512
88569
|
const result = {
|
|
88513
88570
|
path: filePath,
|
|
88514
88571
|
language: "",
|
|
@@ -88538,7 +88595,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
88538
88595
|
}
|
|
88539
88596
|
let content;
|
|
88540
88597
|
try {
|
|
88541
|
-
content =
|
|
88598
|
+
content = fs80.readFileSync(fullPath, "utf8");
|
|
88542
88599
|
} catch {
|
|
88543
88600
|
result.skipped_reason = "file_read_error";
|
|
88544
88601
|
skippedCount++;
|
|
@@ -88557,7 +88614,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
88557
88614
|
results.push(result);
|
|
88558
88615
|
continue;
|
|
88559
88616
|
}
|
|
88560
|
-
const ext =
|
|
88617
|
+
const ext = path100.extname(filePath).toLowerCase();
|
|
88561
88618
|
const langDef = getLanguageForExtension(ext);
|
|
88562
88619
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
88563
88620
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -88649,8 +88706,8 @@ init_zod();
|
|
|
88649
88706
|
init_utils();
|
|
88650
88707
|
init_create_tool();
|
|
88651
88708
|
init_path_security();
|
|
88652
|
-
import * as
|
|
88653
|
-
import * as
|
|
88709
|
+
import * as fs81 from "node:fs";
|
|
88710
|
+
import * as path101 from "node:path";
|
|
88654
88711
|
var MAX_TEXT_LENGTH = 200;
|
|
88655
88712
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
88656
88713
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -88716,9 +88773,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
88716
88773
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
88717
88774
|
}
|
|
88718
88775
|
try {
|
|
88719
|
-
const resolvedPath =
|
|
88720
|
-
const normalizedCwd =
|
|
88721
|
-
const normalizedResolved =
|
|
88776
|
+
const resolvedPath = path101.resolve(paths);
|
|
88777
|
+
const normalizedCwd = path101.resolve(cwd);
|
|
88778
|
+
const normalizedResolved = path101.resolve(resolvedPath);
|
|
88722
88779
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
88723
88780
|
return {
|
|
88724
88781
|
error: "paths must be within the current working directory",
|
|
@@ -88734,13 +88791,13 @@ function validatePathsInput(paths, cwd) {
|
|
|
88734
88791
|
}
|
|
88735
88792
|
}
|
|
88736
88793
|
function isSupportedExtension(filePath) {
|
|
88737
|
-
const ext =
|
|
88794
|
+
const ext = path101.extname(filePath).toLowerCase();
|
|
88738
88795
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
88739
88796
|
}
|
|
88740
88797
|
function findSourceFiles3(dir, files = []) {
|
|
88741
88798
|
let entries;
|
|
88742
88799
|
try {
|
|
88743
|
-
entries =
|
|
88800
|
+
entries = fs81.readdirSync(dir);
|
|
88744
88801
|
} catch {
|
|
88745
88802
|
return files;
|
|
88746
88803
|
}
|
|
@@ -88749,10 +88806,10 @@ function findSourceFiles3(dir, files = []) {
|
|
|
88749
88806
|
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
88750
88807
|
continue;
|
|
88751
88808
|
}
|
|
88752
|
-
const fullPath =
|
|
88809
|
+
const fullPath = path101.join(dir, entry);
|
|
88753
88810
|
let stat6;
|
|
88754
88811
|
try {
|
|
88755
|
-
stat6 =
|
|
88812
|
+
stat6 = fs81.statSync(fullPath);
|
|
88756
88813
|
} catch {
|
|
88757
88814
|
continue;
|
|
88758
88815
|
}
|
|
@@ -88845,7 +88902,7 @@ var todo_extract = createSwarmTool({
|
|
|
88845
88902
|
return JSON.stringify(errorResult, null, 2);
|
|
88846
88903
|
}
|
|
88847
88904
|
const scanPath = resolvedPath;
|
|
88848
|
-
if (!
|
|
88905
|
+
if (!fs81.existsSync(scanPath)) {
|
|
88849
88906
|
const errorResult = {
|
|
88850
88907
|
error: `path not found: ${pathsInput}`,
|
|
88851
88908
|
total: 0,
|
|
@@ -88855,13 +88912,13 @@ var todo_extract = createSwarmTool({
|
|
|
88855
88912
|
return JSON.stringify(errorResult, null, 2);
|
|
88856
88913
|
}
|
|
88857
88914
|
const filesToScan = [];
|
|
88858
|
-
const stat6 =
|
|
88915
|
+
const stat6 = fs81.statSync(scanPath);
|
|
88859
88916
|
if (stat6.isFile()) {
|
|
88860
88917
|
if (isSupportedExtension(scanPath)) {
|
|
88861
88918
|
filesToScan.push(scanPath);
|
|
88862
88919
|
} else {
|
|
88863
88920
|
const errorResult = {
|
|
88864
|
-
error: `unsupported file extension: ${
|
|
88921
|
+
error: `unsupported file extension: ${path101.extname(scanPath)}`,
|
|
88865
88922
|
total: 0,
|
|
88866
88923
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
88867
88924
|
entries: []
|
|
@@ -88874,11 +88931,11 @@ var todo_extract = createSwarmTool({
|
|
|
88874
88931
|
const allEntries = [];
|
|
88875
88932
|
for (const filePath of filesToScan) {
|
|
88876
88933
|
try {
|
|
88877
|
-
const fileStat =
|
|
88934
|
+
const fileStat = fs81.statSync(filePath);
|
|
88878
88935
|
if (fileStat.size > MAX_FILE_SIZE_BYTES11) {
|
|
88879
88936
|
continue;
|
|
88880
88937
|
}
|
|
88881
|
-
const content =
|
|
88938
|
+
const content = fs81.readFileSync(filePath, "utf-8");
|
|
88882
88939
|
const entries = parseTodoComments(content, filePath, tagsSet);
|
|
88883
88940
|
allEntries.push(...entries);
|
|
88884
88941
|
} catch {}
|
|
@@ -88909,19 +88966,19 @@ init_loader();
|
|
|
88909
88966
|
init_schema();
|
|
88910
88967
|
init_qa_gate_profile();
|
|
88911
88968
|
init_gate_evidence();
|
|
88912
|
-
import * as
|
|
88913
|
-
import * as
|
|
88969
|
+
import * as fs83 from "node:fs";
|
|
88970
|
+
import * as path103 from "node:path";
|
|
88914
88971
|
|
|
88915
88972
|
// src/hooks/diff-scope.ts
|
|
88916
88973
|
init_bun_compat();
|
|
88917
|
-
import * as
|
|
88918
|
-
import * as
|
|
88974
|
+
import * as fs82 from "node:fs";
|
|
88975
|
+
import * as path102 from "node:path";
|
|
88919
88976
|
function getDeclaredScope(taskId, directory) {
|
|
88920
88977
|
try {
|
|
88921
|
-
const planPath =
|
|
88922
|
-
if (!
|
|
88978
|
+
const planPath = path102.join(directory, ".swarm", "plan.json");
|
|
88979
|
+
if (!fs82.existsSync(planPath))
|
|
88923
88980
|
return null;
|
|
88924
|
-
const raw =
|
|
88981
|
+
const raw = fs82.readFileSync(planPath, "utf-8");
|
|
88925
88982
|
const plan = JSON.parse(raw);
|
|
88926
88983
|
for (const phase of plan.phases ?? []) {
|
|
88927
88984
|
for (const task of phase.tasks ?? []) {
|
|
@@ -89037,7 +89094,7 @@ var TIER_3_PATTERNS = [
|
|
|
89037
89094
|
];
|
|
89038
89095
|
function matchesTier3Pattern(files) {
|
|
89039
89096
|
for (const file3 of files) {
|
|
89040
|
-
const fileName =
|
|
89097
|
+
const fileName = path103.basename(file3);
|
|
89041
89098
|
for (const pattern of TIER_3_PATTERNS) {
|
|
89042
89099
|
if (pattern.test(fileName)) {
|
|
89043
89100
|
return true;
|
|
@@ -89051,8 +89108,8 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
89051
89108
|
if (hasActiveTurboMode()) {
|
|
89052
89109
|
const resolvedDir2 = workingDirectory;
|
|
89053
89110
|
try {
|
|
89054
|
-
const planPath =
|
|
89055
|
-
const planRaw =
|
|
89111
|
+
const planPath = path103.join(resolvedDir2, ".swarm", "plan.json");
|
|
89112
|
+
const planRaw = fs83.readFileSync(planPath, "utf-8");
|
|
89056
89113
|
const plan = JSON.parse(planRaw);
|
|
89057
89114
|
for (const planPhase of plan.phases ?? []) {
|
|
89058
89115
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -89121,8 +89178,8 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
89121
89178
|
}
|
|
89122
89179
|
try {
|
|
89123
89180
|
const resolvedDir2 = workingDirectory;
|
|
89124
|
-
const planPath =
|
|
89125
|
-
const planRaw =
|
|
89181
|
+
const planPath = path103.join(resolvedDir2, ".swarm", "plan.json");
|
|
89182
|
+
const planRaw = fs83.readFileSync(planPath, "utf-8");
|
|
89126
89183
|
const plan = JSON.parse(planRaw);
|
|
89127
89184
|
for (const planPhase of plan.phases ?? []) {
|
|
89128
89185
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -89279,8 +89336,8 @@ function checkCouncilGate(workingDirectory, taskId) {
|
|
|
89279
89336
|
return { blocked: false, reason: "" };
|
|
89280
89337
|
}
|
|
89281
89338
|
try {
|
|
89282
|
-
const planPath =
|
|
89283
|
-
const planRaw =
|
|
89339
|
+
const planPath = path103.join(workingDirectory, ".swarm", "plan.json");
|
|
89340
|
+
const planRaw = fs83.readFileSync(planPath, "utf-8");
|
|
89284
89341
|
const planObj = JSON.parse(planRaw);
|
|
89285
89342
|
if (planObj.swarm && planObj.title) {
|
|
89286
89343
|
const planId = `${planObj.swarm}-${planObj.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
@@ -89370,8 +89427,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
89370
89427
|
};
|
|
89371
89428
|
}
|
|
89372
89429
|
}
|
|
89373
|
-
normalizedDir =
|
|
89374
|
-
const pathParts = normalizedDir.split(
|
|
89430
|
+
normalizedDir = path103.normalize(args2.working_directory);
|
|
89431
|
+
const pathParts = normalizedDir.split(path103.sep);
|
|
89375
89432
|
if (pathParts.includes("..")) {
|
|
89376
89433
|
return {
|
|
89377
89434
|
success: false,
|
|
@@ -89381,11 +89438,11 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
89381
89438
|
]
|
|
89382
89439
|
};
|
|
89383
89440
|
}
|
|
89384
|
-
const resolvedDir =
|
|
89441
|
+
const resolvedDir = path103.resolve(normalizedDir);
|
|
89385
89442
|
try {
|
|
89386
|
-
const realPath =
|
|
89387
|
-
const planPath =
|
|
89388
|
-
if (!
|
|
89443
|
+
const realPath = fs83.realpathSync(resolvedDir);
|
|
89444
|
+
const planPath = path103.join(realPath, ".swarm", "plan.json");
|
|
89445
|
+
if (!fs83.existsSync(planPath)) {
|
|
89389
89446
|
return {
|
|
89390
89447
|
success: false,
|
|
89391
89448
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -89416,22 +89473,22 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
89416
89473
|
}
|
|
89417
89474
|
if (args2.status === "in_progress") {
|
|
89418
89475
|
try {
|
|
89419
|
-
const evidencePath =
|
|
89420
|
-
|
|
89421
|
-
const fd =
|
|
89476
|
+
const evidencePath = path103.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
89477
|
+
fs83.mkdirSync(path103.dirname(evidencePath), { recursive: true });
|
|
89478
|
+
const fd = fs83.openSync(evidencePath, "wx");
|
|
89422
89479
|
let writeOk = false;
|
|
89423
89480
|
try {
|
|
89424
|
-
|
|
89481
|
+
fs83.writeSync(fd, JSON.stringify({
|
|
89425
89482
|
taskId: args2.task_id,
|
|
89426
89483
|
required_gates: ["reviewer", "test_engineer"],
|
|
89427
89484
|
gates: {}
|
|
89428
89485
|
}, null, 2));
|
|
89429
89486
|
writeOk = true;
|
|
89430
89487
|
} finally {
|
|
89431
|
-
|
|
89488
|
+
fs83.closeSync(fd);
|
|
89432
89489
|
if (!writeOk) {
|
|
89433
89490
|
try {
|
|
89434
|
-
|
|
89491
|
+
fs83.unlinkSync(evidencePath);
|
|
89435
89492
|
} catch {}
|
|
89436
89493
|
}
|
|
89437
89494
|
}
|
|
@@ -89441,8 +89498,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
89441
89498
|
recoverTaskStateFromDelegations(args2.task_id);
|
|
89442
89499
|
let phaseRequiresReviewer = true;
|
|
89443
89500
|
try {
|
|
89444
|
-
const planPath =
|
|
89445
|
-
const planRaw =
|
|
89501
|
+
const planPath = path103.join(directory, ".swarm", "plan.json");
|
|
89502
|
+
const planRaw = fs83.readFileSync(planPath, "utf-8");
|
|
89446
89503
|
const plan = JSON.parse(planRaw);
|
|
89447
89504
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
89448
89505
|
if (taskPhase?.required_agents && !taskPhase.required_agents.includes("reviewer")) {
|
|
@@ -89760,8 +89817,8 @@ init_utils2();
|
|
|
89760
89817
|
init_ledger();
|
|
89761
89818
|
init_manager();
|
|
89762
89819
|
init_create_tool();
|
|
89763
|
-
import
|
|
89764
|
-
import
|
|
89820
|
+
import fs84 from "node:fs";
|
|
89821
|
+
import path104 from "node:path";
|
|
89765
89822
|
function derivePlanId5(plan) {
|
|
89766
89823
|
return `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
89767
89824
|
}
|
|
@@ -89812,7 +89869,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
89812
89869
|
entries: [evidenceEntry]
|
|
89813
89870
|
};
|
|
89814
89871
|
const filename = "drift-verifier.json";
|
|
89815
|
-
const relativePath =
|
|
89872
|
+
const relativePath = path104.join("evidence", String(phase), filename);
|
|
89816
89873
|
let validatedPath;
|
|
89817
89874
|
try {
|
|
89818
89875
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -89823,12 +89880,12 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
89823
89880
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
89824
89881
|
}, null, 2);
|
|
89825
89882
|
}
|
|
89826
|
-
const evidenceDir =
|
|
89883
|
+
const evidenceDir = path104.dirname(validatedPath);
|
|
89827
89884
|
try {
|
|
89828
|
-
await
|
|
89829
|
-
const tempPath =
|
|
89830
|
-
await
|
|
89831
|
-
await
|
|
89885
|
+
await fs84.promises.mkdir(evidenceDir, { recursive: true });
|
|
89886
|
+
const tempPath = path104.join(evidenceDir, `.${filename}.tmp`);
|
|
89887
|
+
await fs84.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
89888
|
+
await fs84.promises.rename(tempPath, validatedPath);
|
|
89832
89889
|
let snapshotInfo;
|
|
89833
89890
|
let snapshotError;
|
|
89834
89891
|
let qaProfileLocked;
|
|
@@ -89922,8 +89979,8 @@ var write_drift_evidence = createSwarmTool({
|
|
|
89922
89979
|
init_zod();
|
|
89923
89980
|
init_utils2();
|
|
89924
89981
|
init_create_tool();
|
|
89925
|
-
import
|
|
89926
|
-
import
|
|
89982
|
+
import fs85 from "node:fs";
|
|
89983
|
+
import path105 from "node:path";
|
|
89927
89984
|
function normalizeVerdict2(verdict) {
|
|
89928
89985
|
switch (verdict) {
|
|
89929
89986
|
case "APPROVED":
|
|
@@ -89971,7 +90028,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
89971
90028
|
entries: [evidenceEntry]
|
|
89972
90029
|
};
|
|
89973
90030
|
const filename = "hallucination-guard.json";
|
|
89974
|
-
const relativePath =
|
|
90031
|
+
const relativePath = path105.join("evidence", String(phase), filename);
|
|
89975
90032
|
let validatedPath;
|
|
89976
90033
|
try {
|
|
89977
90034
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -89982,12 +90039,12 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
89982
90039
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
89983
90040
|
}, null, 2);
|
|
89984
90041
|
}
|
|
89985
|
-
const evidenceDir =
|
|
90042
|
+
const evidenceDir = path105.dirname(validatedPath);
|
|
89986
90043
|
try {
|
|
89987
|
-
await
|
|
89988
|
-
const tempPath =
|
|
89989
|
-
await
|
|
89990
|
-
await
|
|
90044
|
+
await fs85.promises.mkdir(evidenceDir, { recursive: true });
|
|
90045
|
+
const tempPath = path105.join(evidenceDir, `.${filename}.tmp`);
|
|
90046
|
+
await fs85.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
90047
|
+
await fs85.promises.rename(tempPath, validatedPath);
|
|
89991
90048
|
return JSON.stringify({
|
|
89992
90049
|
success: true,
|
|
89993
90050
|
phase,
|
|
@@ -90033,8 +90090,8 @@ var write_hallucination_evidence = createSwarmTool({
|
|
|
90033
90090
|
init_zod();
|
|
90034
90091
|
init_utils2();
|
|
90035
90092
|
init_create_tool();
|
|
90036
|
-
import
|
|
90037
|
-
import
|
|
90093
|
+
import fs86 from "node:fs";
|
|
90094
|
+
import path106 from "node:path";
|
|
90038
90095
|
function normalizeVerdict3(verdict) {
|
|
90039
90096
|
switch (verdict) {
|
|
90040
90097
|
case "PASS":
|
|
@@ -90108,7 +90165,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
90108
90165
|
entries: [evidenceEntry]
|
|
90109
90166
|
};
|
|
90110
90167
|
const filename = "mutation-gate.json";
|
|
90111
|
-
const relativePath =
|
|
90168
|
+
const relativePath = path106.join("evidence", String(phase), filename);
|
|
90112
90169
|
let validatedPath;
|
|
90113
90170
|
try {
|
|
90114
90171
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -90119,12 +90176,12 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
90119
90176
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
90120
90177
|
}, null, 2);
|
|
90121
90178
|
}
|
|
90122
|
-
const evidenceDir =
|
|
90179
|
+
const evidenceDir = path106.dirname(validatedPath);
|
|
90123
90180
|
try {
|
|
90124
|
-
await
|
|
90125
|
-
const tempPath =
|
|
90126
|
-
await
|
|
90127
|
-
await
|
|
90181
|
+
await fs86.promises.mkdir(evidenceDir, { recursive: true });
|
|
90182
|
+
const tempPath = path106.join(evidenceDir, `.${filename}.tmp`);
|
|
90183
|
+
await fs86.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
90184
|
+
await fs86.promises.rename(tempPath, validatedPath);
|
|
90128
90185
|
return JSON.stringify({
|
|
90129
90186
|
success: true,
|
|
90130
90187
|
phase,
|
|
@@ -90178,20 +90235,20 @@ init_write_retro();
|
|
|
90178
90235
|
init_utils();
|
|
90179
90236
|
|
|
90180
90237
|
// src/utils/gitignore-warning.ts
|
|
90181
|
-
import * as
|
|
90182
|
-
import * as
|
|
90238
|
+
import * as fs87 from "node:fs";
|
|
90239
|
+
import * as path107 from "node:path";
|
|
90183
90240
|
var _gitignoreWarningEmitted = false;
|
|
90184
90241
|
function findGitRoot(startDir) {
|
|
90185
90242
|
let current = startDir;
|
|
90186
90243
|
while (true) {
|
|
90187
90244
|
try {
|
|
90188
|
-
const gitPath =
|
|
90189
|
-
const stat6 =
|
|
90245
|
+
const gitPath = path107.join(current, ".git");
|
|
90246
|
+
const stat6 = fs87.statSync(gitPath);
|
|
90190
90247
|
if (stat6.isDirectory()) {
|
|
90191
90248
|
return current;
|
|
90192
90249
|
}
|
|
90193
90250
|
} catch {}
|
|
90194
|
-
const parent =
|
|
90251
|
+
const parent = path107.dirname(current);
|
|
90195
90252
|
if (parent === current) {
|
|
90196
90253
|
return null;
|
|
90197
90254
|
}
|
|
@@ -90211,7 +90268,7 @@ function fileCoversSwarm(content) {
|
|
|
90211
90268
|
}
|
|
90212
90269
|
function readFileSafe(filePath) {
|
|
90213
90270
|
try {
|
|
90214
|
-
return
|
|
90271
|
+
return fs87.readFileSync(filePath, "utf8");
|
|
90215
90272
|
} catch {
|
|
90216
90273
|
return null;
|
|
90217
90274
|
}
|
|
@@ -90223,12 +90280,12 @@ function warnIfSwarmNotGitignored(directory, quiet = false) {
|
|
|
90223
90280
|
const gitRoot = findGitRoot(directory);
|
|
90224
90281
|
if (!gitRoot)
|
|
90225
90282
|
return;
|
|
90226
|
-
const gitignoreContent = readFileSafe(
|
|
90283
|
+
const gitignoreContent = readFileSafe(path107.join(gitRoot, ".gitignore"));
|
|
90227
90284
|
if (gitignoreContent !== null && fileCoversSwarm(gitignoreContent)) {
|
|
90228
90285
|
_gitignoreWarningEmitted = true;
|
|
90229
90286
|
return;
|
|
90230
90287
|
}
|
|
90231
|
-
const excludeContent = readFileSafe(
|
|
90288
|
+
const excludeContent = readFileSafe(path107.join(gitRoot, ".git", "info", "exclude"));
|
|
90232
90289
|
if (excludeContent !== null && fileCoversSwarm(excludeContent)) {
|
|
90233
90290
|
_gitignoreWarningEmitted = true;
|
|
90234
90291
|
return;
|
|
@@ -90274,26 +90331,6 @@ ${footerLines.join(`
|
|
|
90274
90331
|
// src/index.ts
|
|
90275
90332
|
init_warning_buffer();
|
|
90276
90333
|
var _heartbeatTimers = new Map;
|
|
90277
|
-
function writeSwarmConfigExampleIfNew(projectDirectory) {
|
|
90278
|
-
try {
|
|
90279
|
-
const swarmDir = path107.join(projectDirectory, ".swarm");
|
|
90280
|
-
const dest = path107.join(swarmDir, "config.example.json");
|
|
90281
|
-
if (fs87.existsSync(dest))
|
|
90282
|
-
return;
|
|
90283
|
-
const example = {
|
|
90284
|
-
agents: Object.fromEntries(Object.entries(DEFAULT_MODELS).filter(([name2]) => name2 !== "default").map(([name2, model]) => [
|
|
90285
|
-
name2,
|
|
90286
|
-
{
|
|
90287
|
-
model,
|
|
90288
|
-
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
90289
|
-
}
|
|
90290
|
-
])),
|
|
90291
|
-
max_iterations: 5
|
|
90292
|
-
};
|
|
90293
|
-
fs87.writeFileSync(dest, `${JSON.stringify(example, null, 2)}
|
|
90294
|
-
`, "utf-8");
|
|
90295
|
-
} catch {}
|
|
90296
|
-
}
|
|
90297
90334
|
var OpenCodeSwarm = async (ctx) => {
|
|
90298
90335
|
try {
|
|
90299
90336
|
return await initializeOpenCodeSwarm(ctx);
|
|
@@ -90365,6 +90402,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
90365
90402
|
});
|
|
90366
90403
|
initTelemetry(ctx.directory);
|
|
90367
90404
|
writeSwarmConfigExampleIfNew(ctx.directory);
|
|
90405
|
+
writeProjectConfigIfNew(ctx.directory, config3.quiet);
|
|
90368
90406
|
warnIfSwarmNotGitignored(ctx.directory, config3.quiet);
|
|
90369
90407
|
if (config3.version_check !== false) {
|
|
90370
90408
|
scheduleVersionCheck(package_default.version, (msg) => {
|
|
@@ -90492,7 +90530,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
90492
90530
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
90493
90531
|
preflightTriggerManager = new PTM(automationConfig);
|
|
90494
90532
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
90495
|
-
const swarmDir =
|
|
90533
|
+
const swarmDir = path108.resolve(ctx.directory, ".swarm");
|
|
90496
90534
|
statusArtifact = new ASA(swarmDir);
|
|
90497
90535
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
90498
90536
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|