opencode-swarm 7.4.3 → 7.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +1 -1
- package/dist/index.js +887 -814
- package/dist/tools/repo-graph/builder.d.ts +92 -0
- package/dist/tools/repo-graph/cache.d.ts +48 -0
- package/dist/tools/repo-graph/incremental.d.ts +24 -0
- package/dist/tools/repo-graph/storage.d.ts +56 -0
- package/dist/tools/repo-graph/types.d.ts +87 -0
- package/dist/tools/repo-graph/validation.d.ts +27 -0
- package/dist/tools/repo-graph.d.ts +23 -239
- 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.5.1",
|
|
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",
|
|
@@ -22637,7 +22637,7 @@ var init_quick_lru = __esm(() => {
|
|
|
22637
22637
|
// src/context/zone-classifier.ts
|
|
22638
22638
|
function classifyFile(filePath) {
|
|
22639
22639
|
const normalized = filePath.toLowerCase().replace(/\\/g, "/");
|
|
22640
|
-
if (normalized.endsWith(".wasm") || normalized.includes("/dist/") || normalized.includes("/build/") || normalized.includes(".swarm/checkpoints/")) {
|
|
22640
|
+
if (normalized.endsWith(".wasm") || normalized.startsWith("dist/") || normalized.includes("/dist/") || normalized.startsWith("build/") || normalized.includes("/build/") || normalized.includes(".swarm/checkpoints/")) {
|
|
22641
22641
|
return {
|
|
22642
22642
|
filePath,
|
|
22643
22643
|
zone: "generated",
|
|
@@ -25225,6 +25225,16 @@ function checkFileAuthorityWithRules(agentName, filePath, cwd, effectiveRules, o
|
|
|
25225
25225
|
return { allowed: true };
|
|
25226
25226
|
}
|
|
25227
25227
|
}
|
|
25228
|
+
if (rules.blockedZones && rules.blockedZones.length > 0) {
|
|
25229
|
+
const { zone } = classifyFile(normalizedPath);
|
|
25230
|
+
if (rules.blockedZones.includes(zone)) {
|
|
25231
|
+
return {
|
|
25232
|
+
allowed: false,
|
|
25233
|
+
reason: `Path blocked: ${normalizedPath} is in ${zone} zone`,
|
|
25234
|
+
zone
|
|
25235
|
+
};
|
|
25236
|
+
}
|
|
25237
|
+
}
|
|
25228
25238
|
if (rules.allowedGlobs && rules.allowedGlobs.length > 0) {
|
|
25229
25239
|
const isGlobAllowed = rules.allowedGlobs.some((glob) => {
|
|
25230
25240
|
const matcher = getGlobMatcher(glob);
|
|
@@ -25262,16 +25272,6 @@ function checkFileAuthorityWithRules(agentName, filePath, cwd, effectiveRules, o
|
|
|
25262
25272
|
};
|
|
25263
25273
|
}
|
|
25264
25274
|
}
|
|
25265
|
-
if (rules.blockedZones && rules.blockedZones.length > 0) {
|
|
25266
|
-
const { zone } = classifyFile(normalizedPath);
|
|
25267
|
-
if (rules.blockedZones.includes(zone)) {
|
|
25268
|
-
return {
|
|
25269
|
-
allowed: false,
|
|
25270
|
-
reason: `Path blocked: ${normalizedPath} is in ${zone} zone`,
|
|
25271
|
-
zone
|
|
25272
|
-
};
|
|
25273
|
-
}
|
|
25274
|
-
}
|
|
25275
25275
|
return { allowed: true };
|
|
25276
25276
|
}
|
|
25277
25277
|
var import_picomatch, storedInputArgs, TRANSIENT_MODEL_ERROR_PATTERN, toolCallsSinceLastWrite, noOpWarningIssued, consecutiveNoToolTurns, DC_MAX_UNWRAP_DEPTH = 5, DC_SAFE_TARGETS, DC_BLOCKED_ABSOLUTE_PREFIXES, DC_FS_ROOTS, DC_REMOTE_PREFIXES, pathNormalizationCache, globMatcherCache, DEFAULT_AGENT_AUTHORITY_RULES;
|
|
@@ -25390,15 +25390,24 @@ var init_guardrails = __esm(() => {
|
|
|
25390
25390
|
test_engineer: {
|
|
25391
25391
|
blockedExact: [".swarm/plan.md", ".swarm/plan.json"],
|
|
25392
25392
|
blockedPrefix: ["src/"],
|
|
25393
|
-
allowedPrefix: ["tests/", ".swarm/evidence/"],
|
|
25393
|
+
allowedPrefix: ["tests/", "test/", ".swarm/evidence/"],
|
|
25394
|
+
allowedGlobs: [
|
|
25395
|
+
"**/tests/**",
|
|
25396
|
+
"**/test/**",
|
|
25397
|
+
"**/__tests__/**",
|
|
25398
|
+
"**/*.test.*",
|
|
25399
|
+
"**/*.spec.*"
|
|
25400
|
+
],
|
|
25394
25401
|
blockedZones: ["generated"]
|
|
25395
25402
|
},
|
|
25396
25403
|
docs: {
|
|
25397
25404
|
allowedPrefix: ["docs/", ".swarm/outputs/"],
|
|
25405
|
+
allowedGlobs: ["**/docs/**", "**/*.md", "**/*.mdx", "**/*.rst"],
|
|
25398
25406
|
blockedZones: ["generated"]
|
|
25399
25407
|
},
|
|
25400
25408
|
designer: {
|
|
25401
25409
|
allowedPrefix: ["docs/", ".swarm/outputs/"],
|
|
25410
|
+
allowedGlobs: ["**/docs/**", "**/*.md", "**/*.mdx", "**/*.rst"],
|
|
25402
25411
|
blockedZones: ["generated"]
|
|
25403
25412
|
},
|
|
25404
25413
|
critic: {
|
|
@@ -62656,8 +62665,8 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62656
62665
|
var moduleRtn;
|
|
62657
62666
|
var Module = moduleArg;
|
|
62658
62667
|
var readyPromiseResolve, readyPromiseReject;
|
|
62659
|
-
var readyPromise = new Promise((
|
|
62660
|
-
readyPromiseResolve =
|
|
62668
|
+
var readyPromise = new Promise((resolve22, reject) => {
|
|
62669
|
+
readyPromiseResolve = resolve22;
|
|
62661
62670
|
readyPromiseReject = reject;
|
|
62662
62671
|
});
|
|
62663
62672
|
var ENVIRONMENT_IS_WEB = typeof window == "object";
|
|
@@ -62679,11 +62688,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62679
62688
|
throw toThrow;
|
|
62680
62689
|
}, "quit_");
|
|
62681
62690
|
var scriptDirectory = "";
|
|
62682
|
-
function locateFile(
|
|
62691
|
+
function locateFile(path65) {
|
|
62683
62692
|
if (Module["locateFile"]) {
|
|
62684
|
-
return Module["locateFile"](
|
|
62693
|
+
return Module["locateFile"](path65, scriptDirectory);
|
|
62685
62694
|
}
|
|
62686
|
-
return scriptDirectory +
|
|
62695
|
+
return scriptDirectory + path65;
|
|
62687
62696
|
}
|
|
62688
62697
|
__name(locateFile, "locateFile");
|
|
62689
62698
|
var readAsync, readBinary;
|
|
@@ -62737,13 +62746,13 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62737
62746
|
}
|
|
62738
62747
|
readAsync = /* @__PURE__ */ __name(async (url3) => {
|
|
62739
62748
|
if (isFileURI(url3)) {
|
|
62740
|
-
return new Promise((
|
|
62749
|
+
return new Promise((resolve22, reject) => {
|
|
62741
62750
|
var xhr = new XMLHttpRequest;
|
|
62742
62751
|
xhr.open("GET", url3, true);
|
|
62743
62752
|
xhr.responseType = "arraybuffer";
|
|
62744
62753
|
xhr.onload = () => {
|
|
62745
62754
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
62746
|
-
|
|
62755
|
+
resolve22(xhr.response);
|
|
62747
62756
|
return;
|
|
62748
62757
|
}
|
|
62749
62758
|
reject(xhr.status);
|
|
@@ -62963,10 +62972,10 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62963
62972
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
62964
62973
|
var info2 = getWasmImports();
|
|
62965
62974
|
if (Module["instantiateWasm"]) {
|
|
62966
|
-
return new Promise((
|
|
62975
|
+
return new Promise((resolve22, reject) => {
|
|
62967
62976
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
62968
62977
|
receiveInstance(mod, inst);
|
|
62969
|
-
|
|
62978
|
+
resolve22(mod.exports);
|
|
62970
62979
|
});
|
|
62971
62980
|
});
|
|
62972
62981
|
}
|
|
@@ -64432,13 +64441,13 @@ __export(exports_runtime, {
|
|
|
64432
64441
|
getInitializedLanguages: () => getInitializedLanguages,
|
|
64433
64442
|
clearParserCache: () => clearParserCache
|
|
64434
64443
|
});
|
|
64435
|
-
import * as
|
|
64444
|
+
import * as path65 from "node:path";
|
|
64436
64445
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
64437
64446
|
async function initTreeSitter() {
|
|
64438
64447
|
if (treeSitterInitialized) {
|
|
64439
64448
|
return;
|
|
64440
64449
|
}
|
|
64441
|
-
const thisDir =
|
|
64450
|
+
const thisDir = path65.dirname(fileURLToPath2(import.meta.url));
|
|
64442
64451
|
const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
|
|
64443
64452
|
if (isSource) {
|
|
64444
64453
|
await Parser.init();
|
|
@@ -64446,7 +64455,7 @@ async function initTreeSitter() {
|
|
|
64446
64455
|
const grammarsDir = getGrammarsDirAbsolute();
|
|
64447
64456
|
await Parser.init({
|
|
64448
64457
|
locateFile(scriptName) {
|
|
64449
|
-
return
|
|
64458
|
+
return path65.join(grammarsDir, scriptName);
|
|
64450
64459
|
}
|
|
64451
64460
|
});
|
|
64452
64461
|
}
|
|
@@ -64467,11 +64476,11 @@ function getWasmFileName(languageId) {
|
|
|
64467
64476
|
return `tree-sitter-${sanitized}.wasm`;
|
|
64468
64477
|
}
|
|
64469
64478
|
function getGrammarsDirAbsolute() {
|
|
64470
|
-
const thisDir =
|
|
64479
|
+
const thisDir = path65.dirname(fileURLToPath2(import.meta.url));
|
|
64471
64480
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
64472
64481
|
const isSource = normalized.endsWith("/src/lang");
|
|
64473
64482
|
const isCliBundle = normalized.endsWith("/cli");
|
|
64474
|
-
return isSource ?
|
|
64483
|
+
return isSource ? path65.join(thisDir, "grammars") : isCliBundle ? path65.join(thisDir, "..", "lang", "grammars") : path65.join(thisDir, "lang", "grammars");
|
|
64475
64484
|
}
|
|
64476
64485
|
async function loadGrammar(languageId) {
|
|
64477
64486
|
if (typeof languageId !== "string" || languageId.length > 100) {
|
|
@@ -64487,9 +64496,9 @@ async function loadGrammar(languageId) {
|
|
|
64487
64496
|
await initTreeSitter();
|
|
64488
64497
|
const parser = new Parser;
|
|
64489
64498
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
64490
|
-
const wasmPath =
|
|
64491
|
-
const { existsSync:
|
|
64492
|
-
if (!
|
|
64499
|
+
const wasmPath = path65.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
64500
|
+
const { existsSync: existsSync33 } = await import("node:fs");
|
|
64501
|
+
if (!existsSync33(wasmPath)) {
|
|
64493
64502
|
throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
|
|
64494
64503
|
Make sure to run 'bun run build' to copy grammar files to dist/lang/grammars/`);
|
|
64495
64504
|
}
|
|
@@ -64522,7 +64531,7 @@ async function isGrammarAvailable(languageId) {
|
|
|
64522
64531
|
}
|
|
64523
64532
|
try {
|
|
64524
64533
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
64525
|
-
const wasmPath =
|
|
64534
|
+
const wasmPath = path65.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
64526
64535
|
const { statSync: statSync19 } = await import("node:fs");
|
|
64527
64536
|
statSync19(wasmPath);
|
|
64528
64537
|
return true;
|
|
@@ -64581,13 +64590,13 @@ __export(exports_doc_scan, {
|
|
|
64581
64590
|
import * as crypto7 from "node:crypto";
|
|
64582
64591
|
import * as fs45 from "node:fs";
|
|
64583
64592
|
import { mkdir as mkdir10, readFile as readFile10, writeFile as writeFile9 } from "node:fs/promises";
|
|
64584
|
-
import * as
|
|
64593
|
+
import * as path67 from "node:path";
|
|
64585
64594
|
function normalizeSeparators(filePath) {
|
|
64586
64595
|
return filePath.replace(/\\/g, "/");
|
|
64587
64596
|
}
|
|
64588
64597
|
function matchesDocPattern(filePath, patterns) {
|
|
64589
64598
|
const normalizedPath = normalizeSeparators(filePath);
|
|
64590
|
-
const basename9 =
|
|
64599
|
+
const basename9 = path67.basename(filePath);
|
|
64591
64600
|
for (const pattern of patterns) {
|
|
64592
64601
|
if (!pattern.includes("/") && !pattern.includes("\\")) {
|
|
64593
64602
|
if (basename9 === pattern) {
|
|
@@ -64643,7 +64652,7 @@ function stripMarkdown(text) {
|
|
|
64643
64652
|
return text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s*[-*•]\s+/gm, "").replace(/^\s*\d+\.\s+/gm, "").trim();
|
|
64644
64653
|
}
|
|
64645
64654
|
async function scanDocIndex(directory) {
|
|
64646
|
-
const manifestPath =
|
|
64655
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64647
64656
|
const defaultPatterns = DocsConfigSchema.parse({}).doc_patterns;
|
|
64648
64657
|
const extraPatterns = [
|
|
64649
64658
|
"ARCHITECTURE.md",
|
|
@@ -64660,9 +64669,9 @@ async function scanDocIndex(directory) {
|
|
|
64660
64669
|
let cacheValid = true;
|
|
64661
64670
|
for (const file3 of existingManifest.files) {
|
|
64662
64671
|
try {
|
|
64663
|
-
const fullPath =
|
|
64664
|
-
const
|
|
64665
|
-
if (
|
|
64672
|
+
const fullPath = path67.join(directory, file3.path);
|
|
64673
|
+
const stat6 = fs45.statSync(fullPath);
|
|
64674
|
+
if (stat6.mtimeMs > file3.mtime) {
|
|
64666
64675
|
cacheValid = false;
|
|
64667
64676
|
break;
|
|
64668
64677
|
}
|
|
@@ -64690,14 +64699,14 @@ async function scanDocIndex(directory) {
|
|
|
64690
64699
|
}
|
|
64691
64700
|
const entries = rawEntries.filter((e) => typeof e === "string");
|
|
64692
64701
|
for (const entry of entries) {
|
|
64693
|
-
const fullPath =
|
|
64694
|
-
let
|
|
64702
|
+
const fullPath = path67.join(directory, entry);
|
|
64703
|
+
let stat6;
|
|
64695
64704
|
try {
|
|
64696
|
-
|
|
64705
|
+
stat6 = fs45.statSync(fullPath);
|
|
64697
64706
|
} catch {
|
|
64698
64707
|
continue;
|
|
64699
64708
|
}
|
|
64700
|
-
if (!
|
|
64709
|
+
if (!stat6.isFile())
|
|
64701
64710
|
continue;
|
|
64702
64711
|
const pathParts = normalizeSeparators(entry).split("/");
|
|
64703
64712
|
let skipThisFile = false;
|
|
@@ -64726,7 +64735,7 @@ async function scanDocIndex(directory) {
|
|
|
64726
64735
|
} catch {
|
|
64727
64736
|
continue;
|
|
64728
64737
|
}
|
|
64729
|
-
const { title, summary } = extractTitleAndSummary(content,
|
|
64738
|
+
const { title, summary } = extractTitleAndSummary(content, path67.basename(entry));
|
|
64730
64739
|
const lineCount = content.split(`
|
|
64731
64740
|
`).length;
|
|
64732
64741
|
discoveredFiles.push({
|
|
@@ -64734,7 +64743,7 @@ async function scanDocIndex(directory) {
|
|
|
64734
64743
|
title,
|
|
64735
64744
|
summary,
|
|
64736
64745
|
lines: lineCount,
|
|
64737
|
-
mtime:
|
|
64746
|
+
mtime: stat6.mtimeMs
|
|
64738
64747
|
});
|
|
64739
64748
|
}
|
|
64740
64749
|
discoveredFiles.sort((a, b) => a.path.toLowerCase().localeCompare(b.path.toLowerCase()));
|
|
@@ -64752,7 +64761,7 @@ async function scanDocIndex(directory) {
|
|
|
64752
64761
|
files: discoveredFiles
|
|
64753
64762
|
};
|
|
64754
64763
|
try {
|
|
64755
|
-
await mkdir10(
|
|
64764
|
+
await mkdir10(path67.dirname(manifestPath), { recursive: true });
|
|
64756
64765
|
await writeFile9(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
64757
64766
|
} catch {}
|
|
64758
64767
|
return { manifest, cached: false };
|
|
@@ -64791,7 +64800,7 @@ function extractConstraintsFromContent(content) {
|
|
|
64791
64800
|
return constraints;
|
|
64792
64801
|
}
|
|
64793
64802
|
async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
64794
|
-
const manifestPath =
|
|
64803
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64795
64804
|
let manifest;
|
|
64796
64805
|
try {
|
|
64797
64806
|
const content = await readFile10(manifestPath, "utf-8");
|
|
@@ -64817,7 +64826,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64817
64826
|
}
|
|
64818
64827
|
let fullContent;
|
|
64819
64828
|
try {
|
|
64820
|
-
fullContent = await readFile10(
|
|
64829
|
+
fullContent = await readFile10(path67.join(directory, docFile.path), "utf-8");
|
|
64821
64830
|
} catch {
|
|
64822
64831
|
skippedCount++;
|
|
64823
64832
|
continue;
|
|
@@ -64840,7 +64849,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64840
64849
|
tier: "swarm",
|
|
64841
64850
|
lesson: constraint,
|
|
64842
64851
|
category: "architecture",
|
|
64843
|
-
tags: ["doc-scan",
|
|
64852
|
+
tags: ["doc-scan", path67.basename(docFile.path)],
|
|
64844
64853
|
scope: "global",
|
|
64845
64854
|
confidence: 0.5,
|
|
64846
64855
|
status: "candidate",
|
|
@@ -64913,7 +64922,7 @@ var init_doc_scan = __esm(() => {
|
|
|
64913
64922
|
}
|
|
64914
64923
|
} catch {}
|
|
64915
64924
|
if (force) {
|
|
64916
|
-
const manifestPath =
|
|
64925
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64917
64926
|
try {
|
|
64918
64927
|
fs45.unlinkSync(manifestPath);
|
|
64919
64928
|
} catch {}
|
|
@@ -65104,9 +65113,9 @@ __export(exports_curator_drift, {
|
|
|
65104
65113
|
buildDriftInjectionText: () => buildDriftInjectionText
|
|
65105
65114
|
});
|
|
65106
65115
|
import * as fs48 from "node:fs";
|
|
65107
|
-
import * as
|
|
65116
|
+
import * as path70 from "node:path";
|
|
65108
65117
|
async function readPriorDriftReports(directory) {
|
|
65109
|
-
const swarmDir =
|
|
65118
|
+
const swarmDir = path70.join(directory, ".swarm");
|
|
65110
65119
|
const entries = await fs48.promises.readdir(swarmDir).catch(() => null);
|
|
65111
65120
|
if (entries === null)
|
|
65112
65121
|
return [];
|
|
@@ -65133,7 +65142,7 @@ async function readPriorDriftReports(directory) {
|
|
|
65133
65142
|
async function writeDriftReport(directory, report) {
|
|
65134
65143
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
65135
65144
|
const filePath = validateSwarmPath(directory, filename);
|
|
65136
|
-
const swarmDir =
|
|
65145
|
+
const swarmDir = path70.dirname(filePath);
|
|
65137
65146
|
await fs48.promises.mkdir(swarmDir, { recursive: true });
|
|
65138
65147
|
try {
|
|
65139
65148
|
await fs48.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
@@ -65267,7 +65276,7 @@ var init_curator_drift = __esm(() => {
|
|
|
65267
65276
|
// src/index.ts
|
|
65268
65277
|
init_package();
|
|
65269
65278
|
init_agents2();
|
|
65270
|
-
import * as
|
|
65279
|
+
import * as path114 from "node:path";
|
|
65271
65280
|
|
|
65272
65281
|
// src/background/index.ts
|
|
65273
65282
|
init_event_bus();
|
|
@@ -67400,16 +67409,16 @@ ${originalText}`;
|
|
|
67400
67409
|
}
|
|
67401
67410
|
// src/hooks/repo-graph-builder.ts
|
|
67402
67411
|
init_constants();
|
|
67403
|
-
import
|
|
67412
|
+
import { realpathSync as realpathSync8 } from "node:fs";
|
|
67413
|
+
import * as path58 from "node:path";
|
|
67404
67414
|
|
|
67405
|
-
// src/tools/repo-graph.ts
|
|
67406
|
-
init_utils2();
|
|
67415
|
+
// src/tools/repo-graph/builder.ts
|
|
67407
67416
|
init_path_security();
|
|
67408
67417
|
import * as fsSync3 from "node:fs";
|
|
67409
|
-
import {
|
|
67418
|
+
import { existsSync as existsSync29, realpathSync as realpathSync6 } from "node:fs";
|
|
67410
67419
|
import * as fsPromises5 from "node:fs/promises";
|
|
67411
67420
|
import * as os7 from "node:os";
|
|
67412
|
-
import * as
|
|
67421
|
+
import * as path54 from "node:path";
|
|
67413
67422
|
|
|
67414
67423
|
// src/utils/timeout.ts
|
|
67415
67424
|
async function withTimeout(promise3, ms, timeoutError) {
|
|
@@ -67769,17 +67778,38 @@ var symbols = createSwarmTool({
|
|
|
67769
67778
|
}
|
|
67770
67779
|
});
|
|
67771
67780
|
|
|
67772
|
-
// src/tools/repo-graph.ts
|
|
67773
|
-
|
|
67774
|
-
var
|
|
67781
|
+
// src/tools/repo-graph/types.ts
|
|
67782
|
+
import * as path53 from "node:path";
|
|
67783
|
+
var REPO_GRAPH_FILENAME = "repo-graph.json";
|
|
67784
|
+
var GRAPH_SCHEMA_VERSION = "1.0.0";
|
|
67775
67785
|
function normalizeGraphPath(filePath) {
|
|
67776
67786
|
return path53.normalize(filePath).replace(/\\/g, "/");
|
|
67777
67787
|
}
|
|
67778
|
-
|
|
67779
|
-
|
|
67780
|
-
|
|
67781
|
-
|
|
67782
|
-
|
|
67788
|
+
function createEmptyGraph(workspaceRoot) {
|
|
67789
|
+
return {
|
|
67790
|
+
schema_version: GRAPH_SCHEMA_VERSION,
|
|
67791
|
+
workspaceRoot: path53.normalize(workspaceRoot),
|
|
67792
|
+
nodes: {},
|
|
67793
|
+
edges: [],
|
|
67794
|
+
metadata: {
|
|
67795
|
+
generatedAt: new Date().toISOString(),
|
|
67796
|
+
generator: "repo-graph",
|
|
67797
|
+
nodeCount: 0,
|
|
67798
|
+
edgeCount: 0
|
|
67799
|
+
}
|
|
67800
|
+
};
|
|
67801
|
+
}
|
|
67802
|
+
function updateGraphMetadata(graph) {
|
|
67803
|
+
graph.metadata = {
|
|
67804
|
+
generatedAt: new Date().toISOString(),
|
|
67805
|
+
generator: "repo-graph",
|
|
67806
|
+
nodeCount: Object.keys(graph.nodes).length,
|
|
67807
|
+
edgeCount: graph.edges.length
|
|
67808
|
+
};
|
|
67809
|
+
}
|
|
67810
|
+
|
|
67811
|
+
// src/tools/repo-graph/validation.ts
|
|
67812
|
+
init_path_security();
|
|
67783
67813
|
function validateWorkspace(workspace) {
|
|
67784
67814
|
if (!workspace || typeof workspace !== "string" || workspace.trim() === "") {
|
|
67785
67815
|
throw new Error("Invalid workspace: must be a non-empty string");
|
|
@@ -67867,6 +67897,57 @@ function validateGraphEdge(edge) {
|
|
|
67867
67897
|
throw new Error("Invalid edge: control characters detected");
|
|
67868
67898
|
}
|
|
67869
67899
|
}
|
|
67900
|
+
|
|
67901
|
+
// src/tools/repo-graph/builder.ts
|
|
67902
|
+
var SKIP_DIRECTORIES2 = new Set([
|
|
67903
|
+
"node_modules",
|
|
67904
|
+
".git",
|
|
67905
|
+
"dist",
|
|
67906
|
+
"build",
|
|
67907
|
+
"out",
|
|
67908
|
+
"coverage",
|
|
67909
|
+
".next",
|
|
67910
|
+
".nuxt",
|
|
67911
|
+
".cache",
|
|
67912
|
+
"vendor",
|
|
67913
|
+
".svn",
|
|
67914
|
+
".hg"
|
|
67915
|
+
]);
|
|
67916
|
+
var SUPPORTED_EXTENSIONS = [
|
|
67917
|
+
".ts",
|
|
67918
|
+
".tsx",
|
|
67919
|
+
".js",
|
|
67920
|
+
".jsx",
|
|
67921
|
+
".mjs",
|
|
67922
|
+
".cjs",
|
|
67923
|
+
".py"
|
|
67924
|
+
];
|
|
67925
|
+
var DEFAULT_WALK_FILE_CAP = 1e4;
|
|
67926
|
+
var DEFAULT_WALK_BUDGET_MS = 5000;
|
|
67927
|
+
var ASYNC_WALK_YIELD_INTERVAL = 200;
|
|
67928
|
+
var EXTENSION_TO_LANGUAGE = {
|
|
67929
|
+
".ts": "typescript",
|
|
67930
|
+
".tsx": "typescript",
|
|
67931
|
+
".js": "javascript",
|
|
67932
|
+
".jsx": "javascript",
|
|
67933
|
+
".mjs": "javascript",
|
|
67934
|
+
".cjs": "javascript",
|
|
67935
|
+
".py": "python"
|
|
67936
|
+
};
|
|
67937
|
+
function upsertNode(graph, node) {
|
|
67938
|
+
validateGraphNode(node);
|
|
67939
|
+
const key = normalizeGraphPath(node.filePath);
|
|
67940
|
+
graph.nodes[key] = node;
|
|
67941
|
+
updateGraphMetadata(graph);
|
|
67942
|
+
}
|
|
67943
|
+
function addEdge(graph, edge) {
|
|
67944
|
+
validateGraphEdge(edge);
|
|
67945
|
+
const exists = graph.edges.some((e) => e.source === edge.source && e.target === edge.target && e.importSpecifier === edge.importSpecifier);
|
|
67946
|
+
if (!exists) {
|
|
67947
|
+
graph.edges.push(edge);
|
|
67948
|
+
updateGraphMetadata(graph);
|
|
67949
|
+
}
|
|
67950
|
+
}
|
|
67870
67951
|
function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
67871
67952
|
if (containsControlChars(specifier)) {
|
|
67872
67953
|
return null;
|
|
@@ -67882,8 +67963,8 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67882
67963
|
}
|
|
67883
67964
|
try {
|
|
67884
67965
|
if (specifier.startsWith(".")) {
|
|
67885
|
-
const sourceDir =
|
|
67886
|
-
let resolved =
|
|
67966
|
+
const sourceDir = path54.dirname(sourceFile);
|
|
67967
|
+
let resolved = path54.resolve(sourceDir, specifier);
|
|
67887
67968
|
let realResolved;
|
|
67888
67969
|
try {
|
|
67889
67970
|
realResolved = realpathSync6(resolved);
|
|
@@ -67894,7 +67975,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67894
67975
|
try {
|
|
67895
67976
|
realRoot = realpathSync6(workspaceRoot);
|
|
67896
67977
|
} catch {
|
|
67897
|
-
realRoot =
|
|
67978
|
+
realRoot = path54.normalize(workspaceRoot);
|
|
67898
67979
|
}
|
|
67899
67980
|
if (!existsSync29(resolved)) {
|
|
67900
67981
|
const EXTENSIONS = [
|
|
@@ -67926,9 +68007,9 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67926
68007
|
return null;
|
|
67927
68008
|
}
|
|
67928
68009
|
}
|
|
67929
|
-
const normalizedResolved =
|
|
67930
|
-
const normalizedRoot =
|
|
67931
|
-
if (!normalizedResolved.startsWith(normalizedRoot +
|
|
68010
|
+
const normalizedResolved = path54.normalize(realResolved);
|
|
68011
|
+
const normalizedRoot = path54.normalize(realRoot);
|
|
68012
|
+
if (!normalizedResolved.startsWith(normalizedRoot + path54.sep) && normalizedResolved !== normalizedRoot) {
|
|
67932
68013
|
return null;
|
|
67933
68014
|
}
|
|
67934
68015
|
return resolved;
|
|
@@ -67938,275 +68019,17 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67938
68019
|
return null;
|
|
67939
68020
|
}
|
|
67940
68021
|
}
|
|
67941
|
-
function createEmptyGraph(workspaceRoot) {
|
|
67942
|
-
return {
|
|
67943
|
-
schema_version: GRAPH_SCHEMA_VERSION,
|
|
67944
|
-
workspaceRoot: path53.normalize(workspaceRoot),
|
|
67945
|
-
nodes: {},
|
|
67946
|
-
edges: [],
|
|
67947
|
-
metadata: {
|
|
67948
|
-
generatedAt: new Date().toISOString(),
|
|
67949
|
-
generator: "repo-graph",
|
|
67950
|
-
nodeCount: 0,
|
|
67951
|
-
edgeCount: 0
|
|
67952
|
-
}
|
|
67953
|
-
};
|
|
67954
|
-
}
|
|
67955
|
-
function updateGraphMetadata(graph) {
|
|
67956
|
-
graph.metadata = {
|
|
67957
|
-
generatedAt: new Date().toISOString(),
|
|
67958
|
-
generator: "repo-graph",
|
|
67959
|
-
nodeCount: Object.keys(graph.nodes).length,
|
|
67960
|
-
edgeCount: graph.edges.length
|
|
67961
|
-
};
|
|
67962
|
-
}
|
|
67963
|
-
function upsertNode(graph, node) {
|
|
67964
|
-
validateGraphNode(node);
|
|
67965
|
-
const key = normalizeGraphPath(node.filePath);
|
|
67966
|
-
graph.nodes[key] = node;
|
|
67967
|
-
updateGraphMetadata(graph);
|
|
67968
|
-
}
|
|
67969
|
-
function addEdge(graph, edge) {
|
|
67970
|
-
validateGraphEdge(edge);
|
|
67971
|
-
const exists = graph.edges.some((e) => e.source === edge.source && e.target === edge.target && e.importSpecifier === edge.importSpecifier);
|
|
67972
|
-
if (!exists) {
|
|
67973
|
-
graph.edges.push(edge);
|
|
67974
|
-
updateGraphMetadata(graph);
|
|
67975
|
-
}
|
|
67976
|
-
}
|
|
67977
|
-
function getCachedGraph(workspace) {
|
|
67978
|
-
return graphCache.get(path53.normalize(workspace));
|
|
67979
|
-
}
|
|
67980
|
-
function setCachedGraph(workspace, graph, mtime) {
|
|
67981
|
-
const normalized = path53.normalize(workspace);
|
|
67982
|
-
graphCache.set(normalized, graph);
|
|
67983
|
-
dirtyFlags.set(normalized, false);
|
|
67984
|
-
if (mtime !== undefined) {
|
|
67985
|
-
mtimeCache.set(normalized, mtime);
|
|
67986
|
-
}
|
|
67987
|
-
}
|
|
67988
|
-
function isDirty(workspace) {
|
|
67989
|
-
return dirtyFlags.get(path53.normalize(workspace)) ?? false;
|
|
67990
|
-
}
|
|
67991
|
-
function clearCache(workspace) {
|
|
67992
|
-
const normalized = path53.normalize(workspace);
|
|
67993
|
-
graphCache.delete(normalized);
|
|
67994
|
-
dirtyFlags.delete(normalized);
|
|
67995
|
-
mtimeCache.delete(normalized);
|
|
67996
|
-
}
|
|
67997
|
-
function getGraphPath(workspace) {
|
|
67998
|
-
validateWorkspace(workspace);
|
|
67999
|
-
const basePath = validateSwarmPath(workspace, REPO_GRAPH_FILENAME);
|
|
68000
|
-
validateSymlinkBoundary(basePath, workspace);
|
|
68001
|
-
return basePath;
|
|
68002
|
-
}
|
|
68003
|
-
async function loadGraph(workspace) {
|
|
68004
|
-
validateWorkspace(workspace);
|
|
68005
|
-
const normalized = path53.normalize(workspace);
|
|
68006
|
-
const cached3 = getCachedGraph(normalized);
|
|
68007
|
-
if (cached3 && !isDirty(normalized)) {
|
|
68008
|
-
try {
|
|
68009
|
-
const graphPath = getGraphPath(workspace);
|
|
68010
|
-
if (existsSync29(graphPath)) {
|
|
68011
|
-
const stats = await fsPromises5.stat(graphPath);
|
|
68012
|
-
const cachedMtime = mtimeCache.get(normalized);
|
|
68013
|
-
if (cachedMtime !== undefined && stats.mtimeMs !== cachedMtime) {
|
|
68014
|
-
clearCache(normalized);
|
|
68015
|
-
} else {
|
|
68016
|
-
return cached3;
|
|
68017
|
-
}
|
|
68018
|
-
} else {
|
|
68019
|
-
clearCache(normalized);
|
|
68020
|
-
}
|
|
68021
|
-
} catch {
|
|
68022
|
-
clearCache(normalized);
|
|
68023
|
-
}
|
|
68024
|
-
}
|
|
68025
|
-
try {
|
|
68026
|
-
const graphPath = getGraphPath(workspace);
|
|
68027
|
-
if (!existsSync29(graphPath)) {
|
|
68028
|
-
return null;
|
|
68029
|
-
}
|
|
68030
|
-
const stats = await fsPromises5.stat(graphPath);
|
|
68031
|
-
const content = await fsPromises5.readFile(graphPath, "utf-8");
|
|
68032
|
-
if (content.includes("\x00") || content.includes("�")) {
|
|
68033
|
-
throw Object.assign(new Error("repo-graph.json contains null bytes or invalid encoding"), { code: "CORRUPTION" });
|
|
68034
|
-
}
|
|
68035
|
-
let parsed;
|
|
68036
|
-
try {
|
|
68037
|
-
parsed = JSON.parse(content);
|
|
68038
|
-
} catch {
|
|
68039
|
-
throw Object.assign(new Error("repo-graph.json contains invalid JSON"), {
|
|
68040
|
-
code: "CORRUPTION"
|
|
68041
|
-
});
|
|
68042
|
-
}
|
|
68043
|
-
if (!parsed.schema_version) {
|
|
68044
|
-
throw Object.assign(new Error("repo-graph.json missing schema_version"), {
|
|
68045
|
-
code: "CORRUPTION"
|
|
68046
|
-
});
|
|
68047
|
-
}
|
|
68048
|
-
if (!parsed.nodes || typeof parsed.nodes !== "object") {
|
|
68049
|
-
throw Object.assign(new Error("repo-graph.json missing or invalid nodes"), { code: "CORRUPTION" });
|
|
68050
|
-
}
|
|
68051
|
-
if (!Array.isArray(parsed.edges)) {
|
|
68052
|
-
throw Object.assign(new Error("repo-graph.json missing or invalid edges"), { code: "CORRUPTION" });
|
|
68053
|
-
}
|
|
68054
|
-
for (const [key, node] of Object.entries(parsed.nodes)) {
|
|
68055
|
-
if (!key || typeof key !== "string") {
|
|
68056
|
-
throw Object.assign(new Error("repo-graph.json contains invalid node key"), { code: "CORRUPTION" });
|
|
68057
|
-
}
|
|
68058
|
-
try {
|
|
68059
|
-
validateGraphNode(node);
|
|
68060
|
-
} catch (err2) {
|
|
68061
|
-
const msg = err2 instanceof Error ? err2.message : "Invalid node structure";
|
|
68062
|
-
throw Object.assign(new Error(`repo-graph.json node validation failed: ${msg}`), { code: "CORRUPTION" });
|
|
68063
|
-
}
|
|
68064
|
-
}
|
|
68065
|
-
for (const edge of parsed.edges) {
|
|
68066
|
-
try {
|
|
68067
|
-
validateGraphEdge(edge);
|
|
68068
|
-
} catch (err2) {
|
|
68069
|
-
const msg = err2 instanceof Error ? err2.message : "Invalid edge structure";
|
|
68070
|
-
throw Object.assign(new Error(`repo-graph.json edge validation failed: ${msg}`), { code: "CORRUPTION" });
|
|
68071
|
-
}
|
|
68072
|
-
}
|
|
68073
|
-
if (!parsed.metadata || typeof parsed.metadata !== "object" || typeof parsed.metadata.generatedAt !== "string" || typeof parsed.metadata.generator !== "string" || typeof parsed.metadata.nodeCount !== "number" || typeof parsed.metadata.edgeCount !== "number") {
|
|
68074
|
-
throw Object.assign(new Error("repo-graph.json missing or invalid metadata"), { code: "CORRUPTION" });
|
|
68075
|
-
}
|
|
68076
|
-
setCachedGraph(normalized, parsed, stats.mtimeMs);
|
|
68077
|
-
return parsed;
|
|
68078
|
-
} catch (error93) {
|
|
68079
|
-
if (error93 instanceof Error && "code" in error93 && error93.code === "CORRUPTION") {
|
|
68080
|
-
throw error93;
|
|
68081
|
-
}
|
|
68082
|
-
if (error93 instanceof Error && "code" in error93 && error93.code === "ENOENT") {
|
|
68083
|
-
return null;
|
|
68084
|
-
}
|
|
68085
|
-
throw error93;
|
|
68086
|
-
}
|
|
68087
|
-
}
|
|
68088
|
-
async function saveGraph(workspace, graph, options) {
|
|
68089
|
-
validateWorkspace(workspace);
|
|
68090
|
-
if (!graph.schema_version) {
|
|
68091
|
-
throw new Error("Graph must have schema_version");
|
|
68092
|
-
}
|
|
68093
|
-
if (!graph.nodes || typeof graph.nodes !== "object") {
|
|
68094
|
-
throw new Error("Graph must have nodes object");
|
|
68095
|
-
}
|
|
68096
|
-
if (!Array.isArray(graph.edges)) {
|
|
68097
|
-
throw new Error("Graph must have edges array");
|
|
68098
|
-
}
|
|
68099
|
-
const normalizedWorkspace = path53.normalize(workspace);
|
|
68100
|
-
let realWorkspace;
|
|
68101
|
-
try {
|
|
68102
|
-
realWorkspace = realpathSync6(workspace);
|
|
68103
|
-
} catch {
|
|
68104
|
-
realWorkspace = normalizedWorkspace;
|
|
68105
|
-
}
|
|
68106
|
-
const normalizedGraphRoot = path53.normalize(graph.workspaceRoot);
|
|
68107
|
-
let realGraphRoot;
|
|
68108
|
-
try {
|
|
68109
|
-
realGraphRoot = realpathSync6(graph.workspaceRoot);
|
|
68110
|
-
} catch {
|
|
68111
|
-
realGraphRoot = normalizedGraphRoot;
|
|
68112
|
-
}
|
|
68113
|
-
if (path53.normalize(realWorkspace) !== path53.normalize(realGraphRoot)) {
|
|
68114
|
-
throw new Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);
|
|
68115
|
-
}
|
|
68116
|
-
const normalized = normalizedWorkspace;
|
|
68117
|
-
const graphPath = getGraphPath(workspace);
|
|
68118
|
-
updateGraphMetadata(graph);
|
|
68119
|
-
const tempPath = `${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
68120
|
-
await fsPromises5.mkdir(path53.dirname(tempPath), { recursive: true });
|
|
68121
|
-
let lastError = null;
|
|
68122
|
-
try {
|
|
68123
|
-
if (options?.createAtomic) {
|
|
68124
|
-
try {
|
|
68125
|
-
const handle2 = await fsPromises5.open(tempPath, "wx", 420);
|
|
68126
|
-
await handle2.writeFile(JSON.stringify(graph, null, 2), "utf-8");
|
|
68127
|
-
await handle2.close();
|
|
68128
|
-
} catch (error93) {
|
|
68129
|
-
if (error93 instanceof Error && "code" in error93 && error93.code === "EEXIST") {
|
|
68130
|
-
throw new Error("file already exists");
|
|
68131
|
-
}
|
|
68132
|
-
throw error93;
|
|
68133
|
-
}
|
|
68134
|
-
} else {
|
|
68135
|
-
await fsPromises5.writeFile(tempPath, JSON.stringify(graph, null, 2), "utf-8");
|
|
68136
|
-
}
|
|
68137
|
-
if (options?.createAtomic) {
|
|
68138
|
-
try {
|
|
68139
|
-
await fsPromises5.copyFile(tempPath, graphPath, constants4.COPYFILE_EXCL);
|
|
68140
|
-
} catch (error93) {
|
|
68141
|
-
lastError = error93 instanceof Error ? error93 : new Error(String(error93));
|
|
68142
|
-
throw lastError;
|
|
68143
|
-
}
|
|
68144
|
-
} else {
|
|
68145
|
-
let retries = 0;
|
|
68146
|
-
while (retries < WINDOWS_RENAME_MAX_RETRIES2) {
|
|
68147
|
-
try {
|
|
68148
|
-
await fsPromises5.rename(tempPath, graphPath);
|
|
68149
|
-
break;
|
|
68150
|
-
} catch (error93) {
|
|
68151
|
-
lastError = error93 instanceof Error ? error93 : new Error(String(error93));
|
|
68152
|
-
if (lastError instanceof Error && "code" in lastError && lastError.code === "EEXIST" && retries < WINDOWS_RENAME_MAX_RETRIES2 - 1) {
|
|
68153
|
-
retries++;
|
|
68154
|
-
await new Promise((resolve18) => setTimeout(resolve18, WINDOWS_RENAME_RETRY_DELAY_MS2));
|
|
68155
|
-
continue;
|
|
68156
|
-
}
|
|
68157
|
-
throw lastError;
|
|
68158
|
-
}
|
|
68159
|
-
}
|
|
68160
|
-
}
|
|
68161
|
-
} finally {
|
|
68162
|
-
try {
|
|
68163
|
-
await fsPromises5.unlink(tempPath);
|
|
68164
|
-
} catch (error93) {
|
|
68165
|
-
if (error93 instanceof Error && "code" in error93 && error93.code !== "ENOENT") {
|
|
68166
|
-
error48(`Failed to clean up temp file ${tempPath}:`, error93);
|
|
68167
|
-
}
|
|
68168
|
-
}
|
|
68169
|
-
}
|
|
68170
|
-
const stats = await fsPromises5.stat(graphPath);
|
|
68171
|
-
setCachedGraph(normalized, graph, stats.mtimeMs);
|
|
68172
|
-
}
|
|
68173
|
-
var SKIP_DIRECTORIES2 = new Set([
|
|
68174
|
-
"node_modules",
|
|
68175
|
-
".git",
|
|
68176
|
-
"dist",
|
|
68177
|
-
"build",
|
|
68178
|
-
"out",
|
|
68179
|
-
"coverage",
|
|
68180
|
-
".next",
|
|
68181
|
-
".nuxt",
|
|
68182
|
-
".cache",
|
|
68183
|
-
"vendor",
|
|
68184
|
-
".svn",
|
|
68185
|
-
".hg"
|
|
68186
|
-
]);
|
|
68187
|
-
var SUPPORTED_EXTENSIONS = [
|
|
68188
|
-
".ts",
|
|
68189
|
-
".tsx",
|
|
68190
|
-
".js",
|
|
68191
|
-
".jsx",
|
|
68192
|
-
".mjs",
|
|
68193
|
-
".cjs",
|
|
68194
|
-
".py"
|
|
68195
|
-
];
|
|
68196
|
-
var DEFAULT_WALK_FILE_CAP = 1e4;
|
|
68197
|
-
var DEFAULT_WALK_BUDGET_MS = 5000;
|
|
68198
|
-
var ASYNC_WALK_YIELD_INTERVAL = 200;
|
|
68199
68022
|
function isRefusedWorkspaceRoot(target) {
|
|
68200
68023
|
let resolved;
|
|
68201
68024
|
try {
|
|
68202
68025
|
resolved = realpathSync6(target);
|
|
68203
68026
|
} catch {
|
|
68204
|
-
resolved =
|
|
68027
|
+
resolved = path54.resolve(target);
|
|
68205
68028
|
}
|
|
68206
68029
|
const refused = new Set;
|
|
68207
68030
|
const add = (p) => {
|
|
68208
68031
|
if (typeof p === "string" && p.length > 0) {
|
|
68209
|
-
refused.add(
|
|
68032
|
+
refused.add(path54.resolve(p));
|
|
68210
68033
|
}
|
|
68211
68034
|
};
|
|
68212
68035
|
add(os7.homedir());
|
|
@@ -68221,15 +68044,6 @@ function isRefusedWorkspaceRoot(target) {
|
|
|
68221
68044
|
}
|
|
68222
68045
|
return refused.has(resolved);
|
|
68223
68046
|
}
|
|
68224
|
-
var EXTENSION_TO_LANGUAGE = {
|
|
68225
|
-
".ts": "typescript",
|
|
68226
|
-
".tsx": "typescript",
|
|
68227
|
-
".js": "javascript",
|
|
68228
|
-
".jsx": "javascript",
|
|
68229
|
-
".mjs": "javascript",
|
|
68230
|
-
".cjs": "javascript",
|
|
68231
|
-
".py": "python"
|
|
68232
|
-
};
|
|
68233
68047
|
function parseFileImports(content) {
|
|
68234
68048
|
const imports = [];
|
|
68235
68049
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`\0\t\r\n]+)['"`]|import\s+['"`]([^'"`\0\t\r\n]+)['"`]|require\s*\(\s*['"`]([^'"`\0\t\r\n]+)['"`]\s*\)|export\s*\{[^}]*\}\s*from\s+['"`]([^'"`\0\t\r\n]+)['"`]|export\s+\*(?:\s+as\s+\w+)?\s+from\s+['"`]([^'"`\0\t\r\n]+)['"`]|import\s*\(\s*['"`]([^'"`\0\t\r\n]+)['"`]\s*\)/g;
|
|
@@ -68325,7 +68139,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68325
68139
|
ctx.stats.skippedDirs++;
|
|
68326
68140
|
continue;
|
|
68327
68141
|
}
|
|
68328
|
-
const fullPath =
|
|
68142
|
+
const fullPath = path54.join(current, entry.name);
|
|
68329
68143
|
if (entry.isSymbolicLink() && !ctx.followSymlinks) {
|
|
68330
68144
|
ctx.stats.skippedDirs++;
|
|
68331
68145
|
continue;
|
|
@@ -68333,7 +68147,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68333
68147
|
if (entry.isDirectory()) {
|
|
68334
68148
|
queue.push(fullPath);
|
|
68335
68149
|
} else if (entry.isFile()) {
|
|
68336
|
-
const ext =
|
|
68150
|
+
const ext = path54.extname(fullPath).toLowerCase();
|
|
68337
68151
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
68338
68152
|
files.push(fullPath);
|
|
68339
68153
|
}
|
|
@@ -68350,11 +68164,11 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68350
68164
|
return files;
|
|
68351
68165
|
}
|
|
68352
68166
|
function toModuleName(filePath, workspaceRoot) {
|
|
68353
|
-
const relative9 =
|
|
68354
|
-
return relative9.split(
|
|
68167
|
+
const relative9 = path54.relative(workspaceRoot, filePath);
|
|
68168
|
+
return relative9.split(path54.sep).join("/");
|
|
68355
68169
|
}
|
|
68356
68170
|
function getLanguage(filePath) {
|
|
68357
|
-
const ext =
|
|
68171
|
+
const ext = path54.extname(filePath).toLowerCase();
|
|
68358
68172
|
return EXTENSION_TO_LANGUAGE[ext] ?? "unknown";
|
|
68359
68173
|
}
|
|
68360
68174
|
function isBinaryContent(content) {
|
|
@@ -68363,13 +68177,67 @@ function isBinaryContent(content) {
|
|
|
68363
68177
|
}
|
|
68364
68178
|
return false;
|
|
68365
68179
|
}
|
|
68180
|
+
function scanFile(filePath, absoluteRoot, maxFileSize) {
|
|
68181
|
+
let content;
|
|
68182
|
+
let fileStats;
|
|
68183
|
+
try {
|
|
68184
|
+
fileStats = fsSync3.statSync(filePath);
|
|
68185
|
+
if (fileStats.size > maxFileSize) {
|
|
68186
|
+
return { node: null, edges: [] };
|
|
68187
|
+
}
|
|
68188
|
+
content = fsSync3.readFileSync(filePath, "utf-8");
|
|
68189
|
+
} catch {
|
|
68190
|
+
return { node: null, edges: [] };
|
|
68191
|
+
}
|
|
68192
|
+
if (isBinaryContent(content)) {
|
|
68193
|
+
return { node: null, edges: [] };
|
|
68194
|
+
}
|
|
68195
|
+
const ext = path54.extname(filePath).toLowerCase();
|
|
68196
|
+
let exports = [];
|
|
68197
|
+
try {
|
|
68198
|
+
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
68199
|
+
const relativePath = path54.relative(absoluteRoot, filePath);
|
|
68200
|
+
const symbols2 = extractTSSymbols(relativePath, absoluteRoot);
|
|
68201
|
+
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
68202
|
+
} else if (ext === ".py") {
|
|
68203
|
+
const relativePath = path54.relative(absoluteRoot, filePath);
|
|
68204
|
+
const symbols2 = extractPythonSymbols(relativePath, absoluteRoot);
|
|
68205
|
+
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
68206
|
+
}
|
|
68207
|
+
const parsedImports = parseFileImports(content);
|
|
68208
|
+
const node = {
|
|
68209
|
+
filePath,
|
|
68210
|
+
moduleName: toModuleName(filePath, absoluteRoot),
|
|
68211
|
+
exports,
|
|
68212
|
+
imports: parsedImports.map((p) => p.specifier),
|
|
68213
|
+
language: getLanguage(filePath),
|
|
68214
|
+
mtime: fileStats.mtime.toISOString()
|
|
68215
|
+
};
|
|
68216
|
+
const edges = [];
|
|
68217
|
+
const sortedImports = [...parsedImports].sort((a, b) => a.specifier.localeCompare(b.specifier));
|
|
68218
|
+
for (const parsed of sortedImports) {
|
|
68219
|
+
const resolvedTarget = resolveModuleSpecifier(absoluteRoot, filePath, parsed.specifier);
|
|
68220
|
+
if (resolvedTarget !== null) {
|
|
68221
|
+
edges.push({
|
|
68222
|
+
source: filePath,
|
|
68223
|
+
target: resolvedTarget,
|
|
68224
|
+
importSpecifier: parsed.specifier,
|
|
68225
|
+
importType: parsed.importType
|
|
68226
|
+
});
|
|
68227
|
+
}
|
|
68228
|
+
}
|
|
68229
|
+
return { node, edges };
|
|
68230
|
+
} catch {
|
|
68231
|
+
return { node: null, edges: [] };
|
|
68232
|
+
}
|
|
68233
|
+
}
|
|
68366
68234
|
async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
68367
68235
|
validateWorkspace(workspaceRoot);
|
|
68368
68236
|
const maxFileSize = options?.maxFileSizeBytes ?? 1024 * 1024;
|
|
68369
68237
|
const maxFiles = options?.maxFiles ?? DEFAULT_WALK_FILE_CAP;
|
|
68370
68238
|
const walkBudgetMs = options?.walkBudgetMs ?? DEFAULT_WALK_BUDGET_MS;
|
|
68371
68239
|
const followSymlinks = options?.followSymlinks ?? false;
|
|
68372
|
-
const absoluteRoot =
|
|
68240
|
+
const absoluteRoot = path54.resolve(workspaceRoot);
|
|
68373
68241
|
if (!existsSync29(absoluteRoot)) {
|
|
68374
68242
|
throw new Error(`Workspace directory does not exist: ${workspaceRoot}`);
|
|
68375
68243
|
}
|
|
@@ -68424,60 +68292,225 @@ async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
|
68424
68292
|
}
|
|
68425
68293
|
return graph;
|
|
68426
68294
|
}
|
|
68427
|
-
|
|
68428
|
-
|
|
68429
|
-
|
|
68295
|
+
// src/tools/repo-graph/cache.ts
|
|
68296
|
+
import * as path55 from "node:path";
|
|
68297
|
+
var graphCache = new Map;
|
|
68298
|
+
var dirtyFlags = new Map;
|
|
68299
|
+
var mtimeCache = new Map;
|
|
68300
|
+
function getCachedGraph(workspace) {
|
|
68301
|
+
return graphCache.get(path55.normalize(workspace));
|
|
68302
|
+
}
|
|
68303
|
+
function setCachedGraph(workspace, graph, mtime) {
|
|
68304
|
+
const normalized = path55.normalize(workspace);
|
|
68305
|
+
graphCache.set(normalized, graph);
|
|
68306
|
+
dirtyFlags.set(normalized, false);
|
|
68307
|
+
if (mtime !== undefined) {
|
|
68308
|
+
mtimeCache.set(normalized, mtime);
|
|
68309
|
+
}
|
|
68310
|
+
}
|
|
68311
|
+
function isDirty(workspace) {
|
|
68312
|
+
return dirtyFlags.get(path55.normalize(workspace)) ?? false;
|
|
68313
|
+
}
|
|
68314
|
+
function clearCache(workspace) {
|
|
68315
|
+
const normalized = path55.normalize(workspace);
|
|
68316
|
+
graphCache.delete(normalized);
|
|
68317
|
+
dirtyFlags.delete(normalized);
|
|
68318
|
+
mtimeCache.delete(normalized);
|
|
68319
|
+
}
|
|
68320
|
+
function getCachedMtime(workspace) {
|
|
68321
|
+
return mtimeCache.get(path55.normalize(workspace));
|
|
68322
|
+
}
|
|
68323
|
+
// src/tools/repo-graph/incremental.ts
|
|
68324
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
68325
|
+
import * as fsPromises7 from "node:fs/promises";
|
|
68326
|
+
import * as path57 from "node:path";
|
|
68327
|
+
|
|
68328
|
+
// src/tools/repo-graph/storage.ts
|
|
68329
|
+
init_utils2();
|
|
68330
|
+
init_path_security();
|
|
68331
|
+
import { constants as constants4, existsSync as existsSync30, realpathSync as realpathSync7 } from "node:fs";
|
|
68332
|
+
import * as fsPromises6 from "node:fs/promises";
|
|
68333
|
+
import * as path56 from "node:path";
|
|
68334
|
+
var WINDOWS_RENAME_MAX_RETRIES2 = 3;
|
|
68335
|
+
var WINDOWS_RENAME_RETRY_DELAY_MS2 = 50;
|
|
68336
|
+
function getGraphPath(workspace) {
|
|
68337
|
+
validateWorkspace(workspace);
|
|
68338
|
+
const basePath = validateSwarmPath(workspace, REPO_GRAPH_FILENAME);
|
|
68339
|
+
validateSymlinkBoundary(basePath, workspace);
|
|
68340
|
+
return basePath;
|
|
68341
|
+
}
|
|
68342
|
+
async function loadGraph(workspace) {
|
|
68343
|
+
validateWorkspace(workspace);
|
|
68344
|
+
const normalized = path56.normalize(workspace);
|
|
68345
|
+
const cached3 = getCachedGraph(normalized);
|
|
68346
|
+
if (cached3 && !isDirty(normalized)) {
|
|
68347
|
+
try {
|
|
68348
|
+
const graphPath = getGraphPath(workspace);
|
|
68349
|
+
if (existsSync30(graphPath)) {
|
|
68350
|
+
const stats = await fsPromises6.stat(graphPath);
|
|
68351
|
+
const cachedMtime = getCachedMtime(normalized);
|
|
68352
|
+
if (cachedMtime !== undefined && stats.mtimeMs !== cachedMtime) {
|
|
68353
|
+
clearCache(normalized);
|
|
68354
|
+
} else {
|
|
68355
|
+
return cached3;
|
|
68356
|
+
}
|
|
68357
|
+
} else {
|
|
68358
|
+
clearCache(normalized);
|
|
68359
|
+
}
|
|
68360
|
+
} catch {
|
|
68361
|
+
clearCache(normalized);
|
|
68362
|
+
}
|
|
68363
|
+
}
|
|
68430
68364
|
try {
|
|
68431
|
-
|
|
68432
|
-
if (
|
|
68433
|
-
return
|
|
68365
|
+
const graphPath = getGraphPath(workspace);
|
|
68366
|
+
if (!existsSync30(graphPath)) {
|
|
68367
|
+
return null;
|
|
68434
68368
|
}
|
|
68435
|
-
|
|
68369
|
+
const stats = await fsPromises6.stat(graphPath);
|
|
68370
|
+
const content = await fsPromises6.readFile(graphPath, "utf-8");
|
|
68371
|
+
if (content.includes("\x00") || content.includes("�")) {
|
|
68372
|
+
throw Object.assign(new Error("repo-graph.json contains null bytes or invalid encoding"), { code: "CORRUPTION" });
|
|
68373
|
+
}
|
|
68374
|
+
let parsed;
|
|
68375
|
+
try {
|
|
68376
|
+
parsed = JSON.parse(content);
|
|
68377
|
+
} catch {
|
|
68378
|
+
throw Object.assign(new Error("repo-graph.json contains invalid JSON"), {
|
|
68379
|
+
code: "CORRUPTION"
|
|
68380
|
+
});
|
|
68381
|
+
}
|
|
68382
|
+
if (!parsed.schema_version) {
|
|
68383
|
+
throw Object.assign(new Error("repo-graph.json missing schema_version"), {
|
|
68384
|
+
code: "CORRUPTION"
|
|
68385
|
+
});
|
|
68386
|
+
}
|
|
68387
|
+
if (!parsed.nodes || typeof parsed.nodes !== "object") {
|
|
68388
|
+
throw Object.assign(new Error("repo-graph.json missing or invalid nodes"), { code: "CORRUPTION" });
|
|
68389
|
+
}
|
|
68390
|
+
if (!Array.isArray(parsed.edges)) {
|
|
68391
|
+
throw Object.assign(new Error("repo-graph.json missing or invalid edges"), { code: "CORRUPTION" });
|
|
68392
|
+
}
|
|
68393
|
+
for (const [key, node] of Object.entries(parsed.nodes)) {
|
|
68394
|
+
if (!key || typeof key !== "string") {
|
|
68395
|
+
throw Object.assign(new Error("repo-graph.json contains invalid node key"), { code: "CORRUPTION" });
|
|
68396
|
+
}
|
|
68397
|
+
try {
|
|
68398
|
+
validateGraphNode(node);
|
|
68399
|
+
} catch (err2) {
|
|
68400
|
+
const msg = err2 instanceof Error ? err2.message : "Invalid node structure";
|
|
68401
|
+
throw Object.assign(new Error(`repo-graph.json node validation failed: ${msg}`), { code: "CORRUPTION" });
|
|
68402
|
+
}
|
|
68403
|
+
}
|
|
68404
|
+
for (const edge of parsed.edges) {
|
|
68405
|
+
try {
|
|
68406
|
+
validateGraphEdge(edge);
|
|
68407
|
+
} catch (err2) {
|
|
68408
|
+
const msg = err2 instanceof Error ? err2.message : "Invalid edge structure";
|
|
68409
|
+
throw Object.assign(new Error(`repo-graph.json edge validation failed: ${msg}`), { code: "CORRUPTION" });
|
|
68410
|
+
}
|
|
68411
|
+
}
|
|
68412
|
+
if (!parsed.metadata || typeof parsed.metadata !== "object" || typeof parsed.metadata.generatedAt !== "string" || typeof parsed.metadata.generator !== "string" || typeof parsed.metadata.nodeCount !== "number" || typeof parsed.metadata.edgeCount !== "number") {
|
|
68413
|
+
throw Object.assign(new Error("repo-graph.json missing or invalid metadata"), { code: "CORRUPTION" });
|
|
68414
|
+
}
|
|
68415
|
+
setCachedGraph(normalized, parsed, stats.mtimeMs);
|
|
68416
|
+
return parsed;
|
|
68417
|
+
} catch (error93) {
|
|
68418
|
+
if (error93 instanceof Error && "code" in error93 && error93.code === "CORRUPTION") {
|
|
68419
|
+
throw error93;
|
|
68420
|
+
}
|
|
68421
|
+
if (error93 instanceof Error && "code" in error93 && error93.code === "ENOENT") {
|
|
68422
|
+
return null;
|
|
68423
|
+
}
|
|
68424
|
+
throw error93;
|
|
68425
|
+
}
|
|
68426
|
+
}
|
|
68427
|
+
async function saveGraph(workspace, graph, options) {
|
|
68428
|
+
validateWorkspace(workspace);
|
|
68429
|
+
if (!graph.schema_version) {
|
|
68430
|
+
throw new Error("Graph must have schema_version");
|
|
68431
|
+
}
|
|
68432
|
+
if (!graph.nodes || typeof graph.nodes !== "object") {
|
|
68433
|
+
throw new Error("Graph must have nodes object");
|
|
68434
|
+
}
|
|
68435
|
+
if (!Array.isArray(graph.edges)) {
|
|
68436
|
+
throw new Error("Graph must have edges array");
|
|
68437
|
+
}
|
|
68438
|
+
const normalizedWorkspace = path56.normalize(workspace);
|
|
68439
|
+
let realWorkspace;
|
|
68440
|
+
try {
|
|
68441
|
+
realWorkspace = realpathSync7(workspace);
|
|
68436
68442
|
} catch {
|
|
68437
|
-
|
|
68443
|
+
realWorkspace = normalizedWorkspace;
|
|
68438
68444
|
}
|
|
68439
|
-
|
|
68440
|
-
|
|
68445
|
+
const normalizedGraphRoot = path56.normalize(graph.workspaceRoot);
|
|
68446
|
+
let realGraphRoot;
|
|
68447
|
+
try {
|
|
68448
|
+
realGraphRoot = realpathSync7(graph.workspaceRoot);
|
|
68449
|
+
} catch {
|
|
68450
|
+
realGraphRoot = normalizedGraphRoot;
|
|
68441
68451
|
}
|
|
68442
|
-
|
|
68443
|
-
|
|
68452
|
+
if (path56.normalize(realWorkspace) !== path56.normalize(realGraphRoot)) {
|
|
68453
|
+
throw new Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);
|
|
68454
|
+
}
|
|
68455
|
+
const normalized = normalizedWorkspace;
|
|
68456
|
+
const graphPath = getGraphPath(workspace);
|
|
68457
|
+
updateGraphMetadata(graph);
|
|
68458
|
+
const tempPath = `${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
68459
|
+
await fsPromises6.mkdir(path56.dirname(tempPath), { recursive: true });
|
|
68460
|
+
let lastError = null;
|
|
68444
68461
|
try {
|
|
68445
|
-
if (
|
|
68446
|
-
|
|
68447
|
-
|
|
68448
|
-
|
|
68449
|
-
|
|
68450
|
-
|
|
68451
|
-
|
|
68452
|
-
|
|
68462
|
+
if (options?.createAtomic) {
|
|
68463
|
+
try {
|
|
68464
|
+
const handle2 = await fsPromises6.open(tempPath, "wx", 420);
|
|
68465
|
+
await handle2.writeFile(JSON.stringify(graph, null, 2), "utf-8");
|
|
68466
|
+
await handle2.close();
|
|
68467
|
+
} catch (error93) {
|
|
68468
|
+
if (error93 instanceof Error && "code" in error93 && error93.code === "EEXIST") {
|
|
68469
|
+
throw new Error("file already exists");
|
|
68470
|
+
}
|
|
68471
|
+
throw error93;
|
|
68472
|
+
}
|
|
68473
|
+
} else {
|
|
68474
|
+
await fsPromises6.writeFile(tempPath, JSON.stringify(graph, null, 2), "utf-8");
|
|
68453
68475
|
}
|
|
68454
|
-
|
|
68455
|
-
|
|
68456
|
-
|
|
68457
|
-
|
|
68458
|
-
|
|
68459
|
-
|
|
68460
|
-
|
|
68461
|
-
|
|
68462
|
-
|
|
68463
|
-
|
|
68464
|
-
|
|
68465
|
-
|
|
68466
|
-
|
|
68467
|
-
|
|
68468
|
-
|
|
68469
|
-
|
|
68470
|
-
|
|
68471
|
-
|
|
68472
|
-
|
|
68473
|
-
|
|
68476
|
+
if (options?.createAtomic) {
|
|
68477
|
+
try {
|
|
68478
|
+
await fsPromises6.copyFile(tempPath, graphPath, constants4.COPYFILE_EXCL);
|
|
68479
|
+
} catch (error93) {
|
|
68480
|
+
lastError = error93 instanceof Error ? error93 : new Error(String(error93));
|
|
68481
|
+
throw lastError;
|
|
68482
|
+
}
|
|
68483
|
+
} else {
|
|
68484
|
+
let retries = 0;
|
|
68485
|
+
while (retries < WINDOWS_RENAME_MAX_RETRIES2) {
|
|
68486
|
+
try {
|
|
68487
|
+
await fsPromises6.rename(tempPath, graphPath);
|
|
68488
|
+
break;
|
|
68489
|
+
} catch (error93) {
|
|
68490
|
+
lastError = error93 instanceof Error ? error93 : new Error(String(error93));
|
|
68491
|
+
if (lastError instanceof Error && "code" in lastError && lastError.code === "EEXIST" && retries < WINDOWS_RENAME_MAX_RETRIES2 - 1) {
|
|
68492
|
+
retries++;
|
|
68493
|
+
await new Promise((resolve18) => setTimeout(resolve18, WINDOWS_RENAME_RETRY_DELAY_MS2));
|
|
68494
|
+
continue;
|
|
68495
|
+
}
|
|
68496
|
+
throw lastError;
|
|
68497
|
+
}
|
|
68498
|
+
}
|
|
68499
|
+
}
|
|
68500
|
+
} finally {
|
|
68501
|
+
try {
|
|
68502
|
+
await fsPromises6.unlink(tempPath);
|
|
68503
|
+
} catch (error93) {
|
|
68504
|
+
if (error93 instanceof Error && "code" in error93 && error93.code !== "ENOENT") {
|
|
68505
|
+
error48(`Failed to clean up temp file ${tempPath}:`, error93);
|
|
68474
68506
|
}
|
|
68475
68507
|
}
|
|
68476
|
-
return { node, edges };
|
|
68477
|
-
} catch {
|
|
68478
|
-
return { node: null, edges: [] };
|
|
68479
68508
|
}
|
|
68509
|
+
const stats = await fsPromises6.stat(graphPath);
|
|
68510
|
+
setCachedGraph(normalized, graph, stats.mtimeMs);
|
|
68480
68511
|
}
|
|
68512
|
+
|
|
68513
|
+
// src/tools/repo-graph/incremental.ts
|
|
68481
68514
|
async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
68482
68515
|
if (options?.forceRebuild) {
|
|
68483
68516
|
const graph2 = await buildWorkspaceGraphAsync(workspaceRoot);
|
|
@@ -68491,12 +68524,12 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
68491
68524
|
return graph2;
|
|
68492
68525
|
}
|
|
68493
68526
|
const graph = existingGraph;
|
|
68494
|
-
const absoluteRoot =
|
|
68527
|
+
const absoluteRoot = path57.resolve(workspaceRoot);
|
|
68495
68528
|
const maxFileSize = 1024 * 1024;
|
|
68496
68529
|
const updatedPaths = new Set;
|
|
68497
68530
|
for (const rawFilePath of filePaths) {
|
|
68498
68531
|
const normalizedPath = normalizeGraphPath(rawFilePath);
|
|
68499
|
-
const fileExists =
|
|
68532
|
+
const fileExists = existsSync31(rawFilePath);
|
|
68500
68533
|
if (fileExists) {
|
|
68501
68534
|
graph.edges = graph.edges.filter((e) => normalizeGraphPath(e.source) !== normalizedPath);
|
|
68502
68535
|
const result = scanFile(rawFilePath, absoluteRoot, maxFileSize);
|
|
@@ -68531,6 +68564,22 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
68531
68564
|
await saveGraph(workspaceRoot, rebuiltGraph);
|
|
68532
68565
|
return rebuiltGraph;
|
|
68533
68566
|
}
|
|
68567
|
+
const normalizedWorkspace = path57.normalize(workspaceRoot);
|
|
68568
|
+
const loadedMtime = getCachedMtime(normalizedWorkspace);
|
|
68569
|
+
if (loadedMtime !== undefined) {
|
|
68570
|
+
try {
|
|
68571
|
+
const graphPath = getGraphPath(workspaceRoot);
|
|
68572
|
+
if (existsSync31(graphPath)) {
|
|
68573
|
+
const currentStats = await fsPromises7.stat(graphPath);
|
|
68574
|
+
if (currentStats.mtimeMs !== loadedMtime) {
|
|
68575
|
+
warn(`[repo-graph] Concurrent modification detected — falling back to full rebuild`);
|
|
68576
|
+
const rebuiltGraph = await buildWorkspaceGraphAsync(workspaceRoot);
|
|
68577
|
+
await saveGraph(workspaceRoot, rebuiltGraph);
|
|
68578
|
+
return rebuiltGraph;
|
|
68579
|
+
}
|
|
68580
|
+
}
|
|
68581
|
+
} catch {}
|
|
68582
|
+
}
|
|
68534
68583
|
updateGraphMetadata(graph);
|
|
68535
68584
|
await saveGraph(workspaceRoot, graph);
|
|
68536
68585
|
return graph;
|
|
@@ -68549,9 +68598,20 @@ function extractFilePath(args2) {
|
|
|
68549
68598
|
if (!args2 || typeof args2 !== "object")
|
|
68550
68599
|
return null;
|
|
68551
68600
|
const a = args2;
|
|
68552
|
-
|
|
68601
|
+
let filePath = a.file_path ?? a.path ?? a.filePath;
|
|
68553
68602
|
if (!filePath || typeof filePath !== "string")
|
|
68554
68603
|
return null;
|
|
68604
|
+
for (let i2 = 0;i2 < 3; i2++) {
|
|
68605
|
+
try {
|
|
68606
|
+
const decoded = decodeURIComponent(filePath);
|
|
68607
|
+
if (decoded === filePath)
|
|
68608
|
+
break;
|
|
68609
|
+
filePath = decoded;
|
|
68610
|
+
} catch {
|
|
68611
|
+
break;
|
|
68612
|
+
}
|
|
68613
|
+
}
|
|
68614
|
+
filePath = filePath.replace(/./g, ".").replace(///g, "/").replace(/․/g, ".");
|
|
68555
68615
|
return filePath;
|
|
68556
68616
|
}
|
|
68557
68617
|
function isSupportedSourceFile(filePath) {
|
|
@@ -68564,6 +68624,8 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
68564
68624
|
const _updateGraphForFiles = deps?.updateGraphForFiles ?? updateGraphForFiles;
|
|
68565
68625
|
let initStarted = false;
|
|
68566
68626
|
let initPromise = Promise.resolve();
|
|
68627
|
+
let consecutiveFailures = 0;
|
|
68628
|
+
const FAILURE_ADVISORY_THRESHOLD = 3;
|
|
68567
68629
|
async function doInit() {
|
|
68568
68630
|
await yieldToEventLoop();
|
|
68569
68631
|
try {
|
|
@@ -68592,37 +68654,48 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
68592
68654
|
if (!WRITE_TOOL_NAMES.includes(input.tool)) {
|
|
68593
68655
|
return;
|
|
68594
68656
|
}
|
|
68595
|
-
const
|
|
68596
|
-
if (!
|
|
68657
|
+
const filePath = extractFilePath(input.args);
|
|
68658
|
+
if (!filePath)
|
|
68597
68659
|
return;
|
|
68598
|
-
if (
|
|
68660
|
+
if (filePath.includes("\x00"))
|
|
68599
68661
|
return;
|
|
68600
|
-
let filePath = rawFilePath;
|
|
68601
|
-
for (let i2 = 0;i2 < 3; i2++) {
|
|
68602
|
-
try {
|
|
68603
|
-
const decoded = decodeURIComponent(filePath);
|
|
68604
|
-
if (decoded === filePath)
|
|
68605
|
-
break;
|
|
68606
|
-
filePath = decoded;
|
|
68607
|
-
} catch {
|
|
68608
|
-
break;
|
|
68609
|
-
}
|
|
68610
|
-
}
|
|
68611
|
-
filePath = filePath.replace(/./g, ".").replace(///g, "/").replace(/․/g, ".");
|
|
68612
68662
|
if (!isSupportedSourceFile(filePath))
|
|
68613
68663
|
return;
|
|
68614
|
-
const absoluteFilePath =
|
|
68615
|
-
|
|
68616
|
-
|
|
68664
|
+
const absoluteFilePath = path58.isAbsolute(filePath) ? filePath : path58.resolve(workspaceRoot, filePath);
|
|
68665
|
+
let realFilePath;
|
|
68666
|
+
try {
|
|
68667
|
+
realFilePath = realpathSync8(absoluteFilePath);
|
|
68668
|
+
} catch (error93) {
|
|
68669
|
+
if (!(error93 instanceof Error) || error93.code !== "ENOENT") {
|
|
68670
|
+
return;
|
|
68671
|
+
}
|
|
68672
|
+
realFilePath = absoluteFilePath;
|
|
68673
|
+
}
|
|
68674
|
+
let realWorkspace;
|
|
68675
|
+
try {
|
|
68676
|
+
realWorkspace = realpathSync8(workspaceRoot);
|
|
68677
|
+
} catch (error93) {
|
|
68678
|
+
if (!(error93 instanceof Error) || error93.code !== "ENOENT") {
|
|
68679
|
+
return;
|
|
68680
|
+
}
|
|
68681
|
+
realWorkspace = workspaceRoot;
|
|
68682
|
+
}
|
|
68683
|
+
const normalizedAbsolute = realFilePath.replace(/\\/g, "/");
|
|
68684
|
+
const normalizedWorkspace = realWorkspace.replace(/\\/g, "/");
|
|
68617
68685
|
if (!normalizedAbsolute.startsWith(`${normalizedWorkspace}/`) && normalizedAbsolute !== normalizedWorkspace) {
|
|
68618
68686
|
return;
|
|
68619
68687
|
}
|
|
68620
68688
|
try {
|
|
68621
68689
|
await _updateGraphForFiles(workspaceRoot, [absoluteFilePath]);
|
|
68622
|
-
|
|
68690
|
+
consecutiveFailures = 0;
|
|
68691
|
+
log(`[repo-graph] Incremental update for ${path58.basename(filePath)}`);
|
|
68623
68692
|
} catch (error93) {
|
|
68624
68693
|
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
68694
|
+
consecutiveFailures++;
|
|
68625
68695
|
error48(`[repo-graph] Incremental update failed: ${message}`);
|
|
68696
|
+
if (consecutiveFailures >= FAILURE_ADVISORY_THRESHOLD) {
|
|
68697
|
+
warn(`[repo-graph] ${consecutiveFailures} consecutive incremental update failures. ` + `The dependency graph may be stale. Consider reloading the workspace.`);
|
|
68698
|
+
}
|
|
68626
68699
|
}
|
|
68627
68700
|
}
|
|
68628
68701
|
};
|
|
@@ -68638,14 +68711,14 @@ init_manager2();
|
|
|
68638
68711
|
init_detector();
|
|
68639
68712
|
init_manager();
|
|
68640
68713
|
import * as fs46 from "node:fs";
|
|
68641
|
-
import * as
|
|
68714
|
+
import * as path68 from "node:path";
|
|
68642
68715
|
|
|
68643
68716
|
// src/services/decision-drift-analyzer.ts
|
|
68644
68717
|
init_utils2();
|
|
68645
68718
|
init_manager();
|
|
68646
68719
|
init_utils();
|
|
68647
68720
|
import * as fs38 from "node:fs";
|
|
68648
|
-
import * as
|
|
68721
|
+
import * as path59 from "node:path";
|
|
68649
68722
|
var DEFAULT_DRIFT_CONFIG = {
|
|
68650
68723
|
staleThresholdPhases: 1,
|
|
68651
68724
|
detectContradictions: true,
|
|
@@ -68799,7 +68872,7 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
68799
68872
|
currentPhase = legacyPhase;
|
|
68800
68873
|
}
|
|
68801
68874
|
}
|
|
68802
|
-
const contextPath =
|
|
68875
|
+
const contextPath = path59.join(directory, ".swarm", "context.md");
|
|
68803
68876
|
let contextContent = "";
|
|
68804
68877
|
try {
|
|
68805
68878
|
if (fs38.existsSync(contextPath)) {
|
|
@@ -68938,7 +69011,7 @@ init_utils();
|
|
|
68938
69011
|
init_constants();
|
|
68939
69012
|
init_schema();
|
|
68940
69013
|
import * as fs39 from "node:fs/promises";
|
|
68941
|
-
import * as
|
|
69014
|
+
import * as path60 from "node:path";
|
|
68942
69015
|
function safeGet(obj, key) {
|
|
68943
69016
|
if (!obj || !Object.hasOwn(obj, key))
|
|
68944
69017
|
return;
|
|
@@ -69170,9 +69243,9 @@ async function handleDebuggingSpiral(match, taskId, directory) {
|
|
|
69170
69243
|
let eventLogged = false;
|
|
69171
69244
|
let checkpointCreated = false;
|
|
69172
69245
|
try {
|
|
69173
|
-
const swarmDir =
|
|
69246
|
+
const swarmDir = path60.join(directory, ".swarm");
|
|
69174
69247
|
await fs39.mkdir(swarmDir, { recursive: true });
|
|
69175
|
-
const eventsPath =
|
|
69248
|
+
const eventsPath = path60.join(swarmDir, "events.jsonl");
|
|
69176
69249
|
await fs39.appendFile(eventsPath, `${formatDebuggingSpiralEvent(match, taskId)}
|
|
69177
69250
|
`);
|
|
69178
69251
|
eventLogged = true;
|
|
@@ -69307,7 +69380,7 @@ import * as fs43 from "node:fs";
|
|
|
69307
69380
|
|
|
69308
69381
|
// src/graph/graph-builder.ts
|
|
69309
69382
|
import * as fs41 from "node:fs";
|
|
69310
|
-
import * as
|
|
69383
|
+
import * as path63 from "node:path";
|
|
69311
69384
|
|
|
69312
69385
|
// node_modules/yocto-queue/index.js
|
|
69313
69386
|
class Node {
|
|
@@ -69398,26 +69471,26 @@ function pLimit(concurrency) {
|
|
|
69398
69471
|
activeCount--;
|
|
69399
69472
|
resumeNext();
|
|
69400
69473
|
};
|
|
69401
|
-
const run2 = async (function_,
|
|
69474
|
+
const run2 = async (function_, resolve20, arguments_2) => {
|
|
69402
69475
|
const result = (async () => function_(...arguments_2))();
|
|
69403
|
-
|
|
69476
|
+
resolve20(result);
|
|
69404
69477
|
try {
|
|
69405
69478
|
await result;
|
|
69406
69479
|
} catch {}
|
|
69407
69480
|
next();
|
|
69408
69481
|
};
|
|
69409
|
-
const enqueue = (function_,
|
|
69482
|
+
const enqueue = (function_, resolve20, reject, arguments_2) => {
|
|
69410
69483
|
const queueItem = { reject };
|
|
69411
69484
|
new Promise((internalResolve) => {
|
|
69412
69485
|
queueItem.run = internalResolve;
|
|
69413
69486
|
queue.enqueue(queueItem);
|
|
69414
|
-
}).then(run2.bind(undefined, function_,
|
|
69487
|
+
}).then(run2.bind(undefined, function_, resolve20, arguments_2));
|
|
69415
69488
|
if (activeCount < concurrency) {
|
|
69416
69489
|
resumeNext();
|
|
69417
69490
|
}
|
|
69418
69491
|
};
|
|
69419
|
-
const generator = (function_, ...arguments_2) => new Promise((
|
|
69420
|
-
enqueue(function_,
|
|
69492
|
+
const generator = (function_, ...arguments_2) => new Promise((resolve20, reject) => {
|
|
69493
|
+
enqueue(function_, resolve20, reject, arguments_2);
|
|
69421
69494
|
});
|
|
69422
69495
|
Object.defineProperties(generator, {
|
|
69423
69496
|
activeCount: {
|
|
@@ -69468,7 +69541,7 @@ function validateConcurrency(concurrency) {
|
|
|
69468
69541
|
// src/graph/import-extractor.ts
|
|
69469
69542
|
init_path_security();
|
|
69470
69543
|
import * as fs40 from "node:fs";
|
|
69471
|
-
import * as
|
|
69544
|
+
import * as path61 from "node:path";
|
|
69472
69545
|
var SOURCE_EXTENSIONS2 = [
|
|
69473
69546
|
".ts",
|
|
69474
69547
|
".tsx",
|
|
@@ -69513,28 +69586,28 @@ function getLanguageFromExtension(ext) {
|
|
|
69513
69586
|
return null;
|
|
69514
69587
|
}
|
|
69515
69588
|
function toRelForwardSlash(absPath, root) {
|
|
69516
|
-
return
|
|
69589
|
+
return path61.relative(root, absPath).replace(/\\/g, "/");
|
|
69517
69590
|
}
|
|
69518
69591
|
function tryResolveTSJS(rawModule, sourceFileAbs) {
|
|
69519
69592
|
if (!rawModule.startsWith(".") && !rawModule.startsWith("/")) {
|
|
69520
69593
|
return null;
|
|
69521
69594
|
}
|
|
69522
|
-
const sourceDir =
|
|
69523
|
-
const baseAbs =
|
|
69595
|
+
const sourceDir = path61.dirname(sourceFileAbs);
|
|
69596
|
+
const baseAbs = path61.resolve(sourceDir, rawModule);
|
|
69524
69597
|
const probe = (basePath) => {
|
|
69525
69598
|
for (const ext of RESOLVE_EXTENSION_CANDIDATES) {
|
|
69526
69599
|
const test = basePath + ext;
|
|
69527
69600
|
try {
|
|
69528
|
-
const
|
|
69529
|
-
if (
|
|
69601
|
+
const stat6 = fs40.statSync(test);
|
|
69602
|
+
if (stat6.isFile())
|
|
69530
69603
|
return test;
|
|
69531
69604
|
} catch {}
|
|
69532
69605
|
}
|
|
69533
69606
|
for (const indexFile of RESOLVE_INDEX_CANDIDATES) {
|
|
69534
|
-
const test =
|
|
69607
|
+
const test = path61.join(basePath, indexFile);
|
|
69535
69608
|
try {
|
|
69536
|
-
const
|
|
69537
|
-
if (
|
|
69609
|
+
const stat6 = fs40.statSync(test);
|
|
69610
|
+
if (stat6.isFile())
|
|
69538
69611
|
return test;
|
|
69539
69612
|
} catch {}
|
|
69540
69613
|
}
|
|
@@ -69561,13 +69634,13 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
69561
69634
|
}
|
|
69562
69635
|
const remainder = rawModule.slice(leadingDots).replace(/\./g, "/");
|
|
69563
69636
|
const upDirs = "../".repeat(Math.max(0, leadingDots - 1));
|
|
69564
|
-
const sourceDir =
|
|
69565
|
-
const baseAbs =
|
|
69637
|
+
const sourceDir = path61.dirname(sourceFileAbs);
|
|
69638
|
+
const baseAbs = path61.resolve(sourceDir, upDirs + remainder);
|
|
69566
69639
|
const accept = (test) => {
|
|
69567
69640
|
try {
|
|
69568
|
-
const
|
|
69569
|
-
if (
|
|
69570
|
-
const rel =
|
|
69641
|
+
const stat6 = fs40.statSync(test);
|
|
69642
|
+
if (stat6.isFile()) {
|
|
69643
|
+
const rel = path61.relative(workspaceRoot, test).replace(/\\/g, "/");
|
|
69571
69644
|
if (rel.startsWith(".."))
|
|
69572
69645
|
return null;
|
|
69573
69646
|
return test;
|
|
@@ -69581,7 +69654,7 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
69581
69654
|
return hit;
|
|
69582
69655
|
}
|
|
69583
69656
|
for (const indexFile of PY_INDEX_CANDIDATES) {
|
|
69584
|
-
const hit = accept(
|
|
69657
|
+
const hit = accept(path61.join(baseAbs, indexFile));
|
|
69585
69658
|
if (hit)
|
|
69586
69659
|
return hit;
|
|
69587
69660
|
}
|
|
@@ -69952,7 +70025,7 @@ function parseRustUses(content) {
|
|
|
69952
70025
|
}
|
|
69953
70026
|
function extractImports2(opts) {
|
|
69954
70027
|
const { absoluteFilePath, workspaceRoot } = opts;
|
|
69955
|
-
const ext =
|
|
70028
|
+
const ext = path61.extname(absoluteFilePath).toLowerCase();
|
|
69956
70029
|
const language = getLanguageFromExtension(ext);
|
|
69957
70030
|
if (!language)
|
|
69958
70031
|
return [];
|
|
@@ -70003,9 +70076,9 @@ function extractImports2(opts) {
|
|
|
70003
70076
|
}
|
|
70004
70077
|
|
|
70005
70078
|
// src/graph/symbol-extractor.ts
|
|
70006
|
-
import * as
|
|
70079
|
+
import * as path62 from "node:path";
|
|
70007
70080
|
function extractExportedSymbols(relativeFilePath, workspaceRoot) {
|
|
70008
|
-
const ext =
|
|
70081
|
+
const ext = path62.extname(relativeFilePath).toLowerCase();
|
|
70009
70082
|
const language = getLanguageFromExtension(ext);
|
|
70010
70083
|
if (!language)
|
|
70011
70084
|
return [];
|
|
@@ -70094,15 +70167,15 @@ function findSourceFiles(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
|
70094
70167
|
if (entry.isDirectory()) {
|
|
70095
70168
|
if (skipDirs.has(entry.name))
|
|
70096
70169
|
continue;
|
|
70097
|
-
stack.push(
|
|
70170
|
+
stack.push(path63.join(dir, entry.name));
|
|
70098
70171
|
continue;
|
|
70099
70172
|
}
|
|
70100
70173
|
if (!entry.isFile())
|
|
70101
70174
|
continue;
|
|
70102
|
-
const ext =
|
|
70175
|
+
const ext = path63.extname(entry.name).toLowerCase();
|
|
70103
70176
|
if (!SOURCE_EXT_SET.has(ext))
|
|
70104
70177
|
continue;
|
|
70105
|
-
out2.push(
|
|
70178
|
+
out2.push(path63.join(dir, entry.name));
|
|
70106
70179
|
}
|
|
70107
70180
|
}
|
|
70108
70181
|
return out2;
|
|
@@ -70130,7 +70203,7 @@ async function buildRepoGraph(workspaceRoot, options = {}) {
|
|
|
70130
70203
|
};
|
|
70131
70204
|
}
|
|
70132
70205
|
async function processFile(absoluteFilePath, workspaceRoot) {
|
|
70133
|
-
const ext =
|
|
70206
|
+
const ext = path63.extname(absoluteFilePath).toLowerCase();
|
|
70134
70207
|
const language = getLanguageFromExtension(ext);
|
|
70135
70208
|
if (!language)
|
|
70136
70209
|
return null;
|
|
@@ -70150,7 +70223,7 @@ async function processFile(absoluteFilePath, workspaceRoot) {
|
|
|
70150
70223
|
} catch {
|
|
70151
70224
|
return null;
|
|
70152
70225
|
}
|
|
70153
|
-
const relPath =
|
|
70226
|
+
const relPath = path63.relative(workspaceRoot, absoluteFilePath).replace(/\\/g, "/");
|
|
70154
70227
|
const imports = extractImports2({
|
|
70155
70228
|
absoluteFilePath,
|
|
70156
70229
|
workspaceRoot,
|
|
@@ -70392,10 +70465,10 @@ function formatSummary(opts) {
|
|
|
70392
70465
|
// src/graph/graph-store.ts
|
|
70393
70466
|
import * as crypto6 from "node:crypto";
|
|
70394
70467
|
import * as fs42 from "node:fs";
|
|
70395
|
-
import * as
|
|
70468
|
+
import * as path64 from "node:path";
|
|
70396
70469
|
var SWARM_DIR = ".swarm";
|
|
70397
70470
|
function getGraphPath2(workspaceRoot) {
|
|
70398
|
-
return
|
|
70471
|
+
return path64.join(workspaceRoot, SWARM_DIR, REPO_GRAPH_FILENAME2);
|
|
70399
70472
|
}
|
|
70400
70473
|
function loadGraph2(workspaceRoot) {
|
|
70401
70474
|
const file3 = getGraphPath2(workspaceRoot);
|
|
@@ -70417,10 +70490,10 @@ function loadGraph2(workspaceRoot) {
|
|
|
70417
70490
|
}
|
|
70418
70491
|
function saveGraph2(workspaceRoot, graph) {
|
|
70419
70492
|
const file3 = getGraphPath2(workspaceRoot);
|
|
70420
|
-
const dir =
|
|
70493
|
+
const dir = path64.dirname(file3);
|
|
70421
70494
|
try {
|
|
70422
|
-
const
|
|
70423
|
-
if (
|
|
70495
|
+
const stat6 = fs42.lstatSync(dir);
|
|
70496
|
+
if (stat6.isSymbolicLink()) {
|
|
70424
70497
|
throw new Error(`refusing to write graph: ${SWARM_DIR}/ is a symbolic link`);
|
|
70425
70498
|
}
|
|
70426
70499
|
} catch (err2) {
|
|
@@ -70456,15 +70529,15 @@ function isGraphFresh(graph, maxAgeMs = 5 * 60 * 1000) {
|
|
|
70456
70529
|
var cache = new Map;
|
|
70457
70530
|
function getCachedGraph2(directory) {
|
|
70458
70531
|
const file3 = getGraphPath2(directory);
|
|
70459
|
-
let
|
|
70532
|
+
let stat6;
|
|
70460
70533
|
try {
|
|
70461
|
-
|
|
70534
|
+
stat6 = fs43.statSync(file3);
|
|
70462
70535
|
} catch {
|
|
70463
70536
|
cache.delete(directory);
|
|
70464
70537
|
return null;
|
|
70465
70538
|
}
|
|
70466
70539
|
const cached3 = cache.get(directory);
|
|
70467
|
-
if (cached3 && cached3.mtimeMs ===
|
|
70540
|
+
if (cached3 && cached3.mtimeMs === stat6.mtimeMs && cached3.size === stat6.size) {
|
|
70468
70541
|
return cached3.graph;
|
|
70469
70542
|
}
|
|
70470
70543
|
const graph = loadGraph2(directory);
|
|
@@ -70472,7 +70545,7 @@ function getCachedGraph2(directory) {
|
|
|
70472
70545
|
cache.delete(directory);
|
|
70473
70546
|
return null;
|
|
70474
70547
|
}
|
|
70475
|
-
cache.set(directory, { graph, mtimeMs:
|
|
70548
|
+
cache.set(directory, { graph, mtimeMs: stat6.mtimeMs, size: stat6.size });
|
|
70476
70549
|
return graph;
|
|
70477
70550
|
}
|
|
70478
70551
|
function buildCoderLocalizationBlock(directory, targetFile) {
|
|
@@ -70523,7 +70596,7 @@ function buildReviewerBlastRadiusBlock(directory, changedFiles) {
|
|
|
70523
70596
|
// src/hooks/semantic-diff-injection.ts
|
|
70524
70597
|
import * as child_process5 from "node:child_process";
|
|
70525
70598
|
import * as fs44 from "node:fs";
|
|
70526
|
-
import * as
|
|
70599
|
+
import * as path66 from "node:path";
|
|
70527
70600
|
|
|
70528
70601
|
// src/diff/ast-diff.ts
|
|
70529
70602
|
init_tree_sitter();
|
|
@@ -71270,17 +71343,17 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
71270
71343
|
const fileConsumers = {};
|
|
71271
71344
|
if (graph) {
|
|
71272
71345
|
for (const f of filesToProcess) {
|
|
71273
|
-
const relativePath =
|
|
71346
|
+
const relativePath = path66.isAbsolute(f) ? path66.relative(directory, f) : f;
|
|
71274
71347
|
const normalized = normalizeGraphPath2(relativePath);
|
|
71275
71348
|
fileConsumers[normalized] = getImporters(graph, normalized).length;
|
|
71276
71349
|
fileConsumers[f] = fileConsumers[normalized];
|
|
71277
71350
|
}
|
|
71278
71351
|
}
|
|
71279
71352
|
for (const filePath of filesToProcess) {
|
|
71280
|
-
const normalizedPath =
|
|
71281
|
-
const resolvedPath =
|
|
71282
|
-
const relativeToDir =
|
|
71283
|
-
if (relativeToDir.startsWith("..") ||
|
|
71353
|
+
const normalizedPath = path66.normalize(filePath);
|
|
71354
|
+
const resolvedPath = path66.resolve(directory, normalizedPath);
|
|
71355
|
+
const relativeToDir = path66.relative(directory, resolvedPath);
|
|
71356
|
+
if (relativeToDir.startsWith("..") || path66.isAbsolute(relativeToDir)) {
|
|
71284
71357
|
continue;
|
|
71285
71358
|
}
|
|
71286
71359
|
try {
|
|
@@ -71307,7 +71380,7 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
71307
71380
|
stdio: "pipe",
|
|
71308
71381
|
maxBuffer: 5 * 1024 * 1024
|
|
71309
71382
|
}) : "";
|
|
71310
|
-
const newContent = fs44.readFileSync(
|
|
71383
|
+
const newContent = fs44.readFileSync(path66.join(directory, filePath), "utf-8");
|
|
71311
71384
|
const astResult = await computeASTDiff(filePath, oldContent, newContent);
|
|
71312
71385
|
if (astResult && (astResult.changes.length > 0 || astResult.error !== undefined)) {
|
|
71313
71386
|
astDiffs.push(astResult);
|
|
@@ -71649,7 +71722,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
71649
71722
|
await fs46.promises.writeFile(darkMatterPath, darkMatterReport, "utf-8");
|
|
71650
71723
|
warn(`[system-enhancer] Dark matter scan complete: ${darkMatter.length} co-change patterns found`);
|
|
71651
71724
|
try {
|
|
71652
|
-
const projectName =
|
|
71725
|
+
const projectName = path68.basename(path68.resolve(directory));
|
|
71653
71726
|
const knowledgeEntries = darkMatterToKnowledgeEntries2(darkMatter, projectName);
|
|
71654
71727
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
71655
71728
|
const existingEntries = await readKnowledge(knowledgePath);
|
|
@@ -71848,7 +71921,7 @@ ${lines.join(`
|
|
|
71848
71921
|
try {
|
|
71849
71922
|
const taskId_ccp = ccpSession?.currentTaskId;
|
|
71850
71923
|
if (taskId_ccp && !taskId_ccp.includes("..") && !taskId_ccp.includes("/") && !taskId_ccp.includes("\\") && !taskId_ccp.includes("\x00")) {
|
|
71851
|
-
const evidencePath =
|
|
71924
|
+
const evidencePath = path68.join(directory, ".swarm", "evidence", `${taskId_ccp}.json`);
|
|
71852
71925
|
if (fs46.existsSync(evidencePath)) {
|
|
71853
71926
|
const evidenceContent = fs46.readFileSync(evidencePath, "utf-8");
|
|
71854
71927
|
const evidenceData = JSON.parse(evidenceContent);
|
|
@@ -72996,13 +73069,13 @@ init_hive_promoter();
|
|
|
72996
73069
|
|
|
72997
73070
|
// src/hooks/incremental-verify.ts
|
|
72998
73071
|
import * as fs47 from "node:fs";
|
|
72999
|
-
import * as
|
|
73072
|
+
import * as path69 from "node:path";
|
|
73000
73073
|
|
|
73001
73074
|
// src/hooks/spawn-helper.ts
|
|
73002
73075
|
import * as child_process6 from "node:child_process";
|
|
73003
73076
|
var WIN32_CMD_BINARIES = new Set(["npm", "npx", "pnpm", "yarn"]);
|
|
73004
73077
|
function spawnAsync(command, cwd, timeoutMs) {
|
|
73005
|
-
return new Promise((
|
|
73078
|
+
return new Promise((resolve24) => {
|
|
73006
73079
|
try {
|
|
73007
73080
|
const [rawCmd, ...args2] = command;
|
|
73008
73081
|
const cmd = process.platform === "win32" && WIN32_CMD_BINARIES.has(rawCmd) && !rawCmd.includes(".") ? `${rawCmd}.cmd` : rawCmd;
|
|
@@ -73049,24 +73122,24 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
73049
73122
|
try {
|
|
73050
73123
|
proc.kill();
|
|
73051
73124
|
} catch {}
|
|
73052
|
-
|
|
73125
|
+
resolve24(null);
|
|
73053
73126
|
}, timeoutMs);
|
|
73054
73127
|
proc.on("close", (code) => {
|
|
73055
73128
|
if (done)
|
|
73056
73129
|
return;
|
|
73057
73130
|
done = true;
|
|
73058
73131
|
clearTimeout(timer);
|
|
73059
|
-
|
|
73132
|
+
resolve24({ exitCode: code ?? 1, stdout, stderr });
|
|
73060
73133
|
});
|
|
73061
73134
|
proc.on("error", () => {
|
|
73062
73135
|
if (done)
|
|
73063
73136
|
return;
|
|
73064
73137
|
done = true;
|
|
73065
73138
|
clearTimeout(timer);
|
|
73066
|
-
|
|
73139
|
+
resolve24(null);
|
|
73067
73140
|
});
|
|
73068
73141
|
} catch {
|
|
73069
|
-
|
|
73142
|
+
resolve24(null);
|
|
73070
73143
|
}
|
|
73071
73144
|
});
|
|
73072
73145
|
}
|
|
@@ -73074,18 +73147,18 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
73074
73147
|
// src/hooks/incremental-verify.ts
|
|
73075
73148
|
var emittedSkipAdvisories = new Set;
|
|
73076
73149
|
function detectPackageManager(projectDir) {
|
|
73077
|
-
if (fs47.existsSync(
|
|
73150
|
+
if (fs47.existsSync(path69.join(projectDir, "bun.lockb")))
|
|
73078
73151
|
return "bun";
|
|
73079
|
-
if (fs47.existsSync(
|
|
73152
|
+
if (fs47.existsSync(path69.join(projectDir, "pnpm-lock.yaml")))
|
|
73080
73153
|
return "pnpm";
|
|
73081
|
-
if (fs47.existsSync(
|
|
73154
|
+
if (fs47.existsSync(path69.join(projectDir, "yarn.lock")))
|
|
73082
73155
|
return "yarn";
|
|
73083
|
-
if (fs47.existsSync(
|
|
73156
|
+
if (fs47.existsSync(path69.join(projectDir, "package-lock.json")))
|
|
73084
73157
|
return "npm";
|
|
73085
73158
|
return "bun";
|
|
73086
73159
|
}
|
|
73087
73160
|
function detectTypecheckCommand(projectDir) {
|
|
73088
|
-
const pkgPath =
|
|
73161
|
+
const pkgPath = path69.join(projectDir, "package.json");
|
|
73089
73162
|
if (fs47.existsSync(pkgPath)) {
|
|
73090
73163
|
try {
|
|
73091
73164
|
const pkg = JSON.parse(fs47.readFileSync(pkgPath, "utf8"));
|
|
@@ -73102,8 +73175,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
73102
73175
|
...pkg.dependencies,
|
|
73103
73176
|
...pkg.devDependencies
|
|
73104
73177
|
};
|
|
73105
|
-
if (!deps?.typescript && !fs47.existsSync(
|
|
73106
|
-
const hasTSMarkers = deps?.typescript || fs47.existsSync(
|
|
73178
|
+
if (!deps?.typescript && !fs47.existsSync(path69.join(projectDir, "tsconfig.json"))) {}
|
|
73179
|
+
const hasTSMarkers = deps?.typescript || fs47.existsSync(path69.join(projectDir, "tsconfig.json"));
|
|
73107
73180
|
if (hasTSMarkers) {
|
|
73108
73181
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
73109
73182
|
}
|
|
@@ -73111,13 +73184,13 @@ function detectTypecheckCommand(projectDir) {
|
|
|
73111
73184
|
return null;
|
|
73112
73185
|
}
|
|
73113
73186
|
}
|
|
73114
|
-
if (fs47.existsSync(
|
|
73187
|
+
if (fs47.existsSync(path69.join(projectDir, "go.mod"))) {
|
|
73115
73188
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
73116
73189
|
}
|
|
73117
|
-
if (fs47.existsSync(
|
|
73190
|
+
if (fs47.existsSync(path69.join(projectDir, "Cargo.toml"))) {
|
|
73118
73191
|
return { command: ["cargo", "check"], language: "rust" };
|
|
73119
73192
|
}
|
|
73120
|
-
if (fs47.existsSync(
|
|
73193
|
+
if (fs47.existsSync(path69.join(projectDir, "pyproject.toml")) || fs47.existsSync(path69.join(projectDir, "requirements.txt")) || fs47.existsSync(path69.join(projectDir, "setup.py"))) {
|
|
73121
73194
|
return { command: null, language: "python" };
|
|
73122
73195
|
}
|
|
73123
73196
|
try {
|
|
@@ -73467,7 +73540,7 @@ init_scope_persistence();
|
|
|
73467
73540
|
init_state();
|
|
73468
73541
|
init_delegation_gate();
|
|
73469
73542
|
init_normalize_tool_name();
|
|
73470
|
-
import * as
|
|
73543
|
+
import * as path71 from "node:path";
|
|
73471
73544
|
var WRITE_TOOLS = new Set(WRITE_TOOL_NAMES);
|
|
73472
73545
|
function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
73473
73546
|
const enabled = config3.enabled ?? true;
|
|
@@ -73525,13 +73598,13 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
|
73525
73598
|
}
|
|
73526
73599
|
function isFileInScope(filePath, scopeEntries, directory) {
|
|
73527
73600
|
const dir = directory ?? process.cwd();
|
|
73528
|
-
const resolvedFile =
|
|
73601
|
+
const resolvedFile = path71.resolve(dir, filePath);
|
|
73529
73602
|
return scopeEntries.some((scope) => {
|
|
73530
|
-
const resolvedScope =
|
|
73603
|
+
const resolvedScope = path71.resolve(dir, scope);
|
|
73531
73604
|
if (resolvedFile === resolvedScope)
|
|
73532
73605
|
return true;
|
|
73533
|
-
const rel =
|
|
73534
|
-
return rel.length > 0 && !rel.startsWith("..") && !
|
|
73606
|
+
const rel = path71.relative(resolvedScope, resolvedFile);
|
|
73607
|
+
return rel.length > 0 && !rel.startsWith("..") && !path71.isAbsolute(rel);
|
|
73535
73608
|
});
|
|
73536
73609
|
}
|
|
73537
73610
|
|
|
@@ -73583,7 +73656,7 @@ function createSelfReviewHook(config3, injectAdvisory) {
|
|
|
73583
73656
|
|
|
73584
73657
|
// src/hooks/slop-detector.ts
|
|
73585
73658
|
import * as fs49 from "node:fs";
|
|
73586
|
-
import * as
|
|
73659
|
+
import * as path72 from "node:path";
|
|
73587
73660
|
var WRITE_EDIT_TOOLS = new Set([
|
|
73588
73661
|
"write",
|
|
73589
73662
|
"edit",
|
|
@@ -73633,7 +73706,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
73633
73706
|
break;
|
|
73634
73707
|
if (entry.isSymbolicLink())
|
|
73635
73708
|
continue;
|
|
73636
|
-
const full =
|
|
73709
|
+
const full = path72.join(dir, entry.name);
|
|
73637
73710
|
if (entry.isDirectory()) {
|
|
73638
73711
|
if (entry.name === "node_modules" || entry.name === ".git")
|
|
73639
73712
|
continue;
|
|
@@ -73648,7 +73721,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
73648
73721
|
return results;
|
|
73649
73722
|
}
|
|
73650
73723
|
function checkDeadExports(content, projectDir, startTime) {
|
|
73651
|
-
const hasPackageJson = fs49.existsSync(
|
|
73724
|
+
const hasPackageJson = fs49.existsSync(path72.join(projectDir, "package.json"));
|
|
73652
73725
|
if (!hasPackageJson)
|
|
73653
73726
|
return null;
|
|
73654
73727
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -73762,14 +73835,14 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
|
|
|
73762
73835
|
for (const utilDir of utilityDirs) {
|
|
73763
73836
|
if (Date.now() > deadline)
|
|
73764
73837
|
break;
|
|
73765
|
-
const utilPath =
|
|
73838
|
+
const utilPath = path72.join(projectDir, utilDir);
|
|
73766
73839
|
if (!fs49.existsSync(utilPath))
|
|
73767
73840
|
continue;
|
|
73768
73841
|
const files = walkFiles(utilPath, [".ts", ".tsx", ".js", ".jsx"], deadline);
|
|
73769
73842
|
for (const file3 of files) {
|
|
73770
73843
|
if (Date.now() > deadline)
|
|
73771
73844
|
break;
|
|
73772
|
-
if (targetFile &&
|
|
73845
|
+
if (targetFile && path72.resolve(file3) === path72.resolve(targetFile))
|
|
73773
73846
|
continue;
|
|
73774
73847
|
try {
|
|
73775
73848
|
const text = fs49.readFileSync(file3, "utf-8");
|
|
@@ -73907,14 +73980,14 @@ function createSteeringConsumedHook(directory) {
|
|
|
73907
73980
|
// src/hooks/trajectory-logger.ts
|
|
73908
73981
|
init_manager2();
|
|
73909
73982
|
import * as fs52 from "node:fs/promises";
|
|
73910
|
-
import * as
|
|
73983
|
+
import * as path74 from "node:path";
|
|
73911
73984
|
|
|
73912
73985
|
// src/prm/trajectory-store.ts
|
|
73913
73986
|
init_utils2();
|
|
73914
73987
|
import * as fs51 from "node:fs/promises";
|
|
73915
|
-
import * as
|
|
73988
|
+
import * as path73 from "node:path";
|
|
73916
73989
|
function getTrajectoryPath(sessionId, directory) {
|
|
73917
|
-
const relativePath =
|
|
73990
|
+
const relativePath = path73.join("trajectories", `${sessionId}.jsonl`);
|
|
73918
73991
|
return validateSwarmPath(directory, relativePath);
|
|
73919
73992
|
}
|
|
73920
73993
|
var _inMemoryTrajectoryCache = new Map;
|
|
@@ -73933,7 +74006,7 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
73933
74006
|
_inMemoryTrajectoryCache.set(sessionId, cached3);
|
|
73934
74007
|
}
|
|
73935
74008
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
73936
|
-
await fs51.mkdir(
|
|
74009
|
+
await fs51.mkdir(path73.dirname(trajectoryPath), { recursive: true });
|
|
73937
74010
|
const line = `${JSON.stringify(entry)}
|
|
73938
74011
|
`;
|
|
73939
74012
|
await fs51.appendFile(trajectoryPath, line, "utf-8");
|
|
@@ -73972,10 +74045,10 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
|
|
|
73972
74045
|
for (const entry of entries) {
|
|
73973
74046
|
if (!entry.isFile())
|
|
73974
74047
|
continue;
|
|
73975
|
-
const filePath =
|
|
74048
|
+
const filePath = path73.join(dirPath, entry.name);
|
|
73976
74049
|
try {
|
|
73977
|
-
const
|
|
73978
|
-
if (now -
|
|
74050
|
+
const stat7 = await fs51.stat(filePath);
|
|
74051
|
+
if (now - stat7.mtimeMs > cutoffMs) {
|
|
73979
74052
|
await fs51.unlink(filePath);
|
|
73980
74053
|
}
|
|
73981
74054
|
} catch {}
|
|
@@ -74164,10 +74237,10 @@ function createTrajectoryLoggerHook(config3, _directory) {
|
|
|
74164
74237
|
elapsed_ms
|
|
74165
74238
|
};
|
|
74166
74239
|
const sanitized = sanitizeTaskId2(taskId);
|
|
74167
|
-
const relativePath =
|
|
74240
|
+
const relativePath = path74.join("evidence", sanitized, "trajectory.jsonl");
|
|
74168
74241
|
const trajectoryPath = validateSwarmPath(_directory, relativePath);
|
|
74169
74242
|
try {
|
|
74170
|
-
await fs52.mkdir(
|
|
74243
|
+
await fs52.mkdir(path74.dirname(trajectoryPath), { recursive: true });
|
|
74171
74244
|
const line = `${JSON.stringify(entry)}
|
|
74172
74245
|
`;
|
|
74173
74246
|
await fs52.appendFile(trajectoryPath, line, "utf-8");
|
|
@@ -74718,16 +74791,16 @@ init_telemetry();
|
|
|
74718
74791
|
|
|
74719
74792
|
// src/prm/replay.ts
|
|
74720
74793
|
import { promises as fs53 } from "node:fs";
|
|
74721
|
-
import
|
|
74794
|
+
import path75 from "node:path";
|
|
74722
74795
|
function isPathSafe2(targetPath, basePath) {
|
|
74723
|
-
const resolvedTarget =
|
|
74724
|
-
const resolvedBase =
|
|
74725
|
-
const rel =
|
|
74726
|
-
return !rel.startsWith("..") && !
|
|
74796
|
+
const resolvedTarget = path75.resolve(targetPath);
|
|
74797
|
+
const resolvedBase = path75.resolve(basePath);
|
|
74798
|
+
const rel = path75.relative(resolvedBase, resolvedTarget);
|
|
74799
|
+
return !rel.startsWith("..") && !path75.isAbsolute(rel);
|
|
74727
74800
|
}
|
|
74728
74801
|
function isWithinReplaysDir(targetPath) {
|
|
74729
|
-
const resolved =
|
|
74730
|
-
const parts2 = resolved.split(
|
|
74802
|
+
const resolved = path75.resolve(targetPath);
|
|
74803
|
+
const parts2 = resolved.split(path75.sep);
|
|
74731
74804
|
for (let i2 = 0;i2 < parts2.length - 1; i2++) {
|
|
74732
74805
|
if (parts2[i2] === ".swarm" && parts2[i2 + 1] === "replays") {
|
|
74733
74806
|
return true;
|
|
@@ -74740,10 +74813,10 @@ function sanitizeFilename(input) {
|
|
|
74740
74813
|
}
|
|
74741
74814
|
async function startReplayRecording(sessionID, directory) {
|
|
74742
74815
|
try {
|
|
74743
|
-
const replayDir =
|
|
74816
|
+
const replayDir = path75.join(directory, ".swarm", "replays");
|
|
74744
74817
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
74745
74818
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
74746
|
-
const filepath =
|
|
74819
|
+
const filepath = path75.join(replayDir, filename);
|
|
74747
74820
|
if (!isPathSafe2(filepath, replayDir)) {
|
|
74748
74821
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
74749
74822
|
return null;
|
|
@@ -75117,7 +75190,7 @@ init_telemetry();
|
|
|
75117
75190
|
init_dist();
|
|
75118
75191
|
init_create_tool();
|
|
75119
75192
|
import * as fs54 from "node:fs";
|
|
75120
|
-
import * as
|
|
75193
|
+
import * as path76 from "node:path";
|
|
75121
75194
|
init_path_security();
|
|
75122
75195
|
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
75123
75196
|
function containsWindowsAttacks2(str) {
|
|
@@ -75134,14 +75207,14 @@ function containsWindowsAttacks2(str) {
|
|
|
75134
75207
|
}
|
|
75135
75208
|
function isPathInWorkspace2(filePath, workspace) {
|
|
75136
75209
|
try {
|
|
75137
|
-
const resolvedPath =
|
|
75210
|
+
const resolvedPath = path76.resolve(workspace, filePath);
|
|
75138
75211
|
if (!fs54.existsSync(resolvedPath)) {
|
|
75139
75212
|
return true;
|
|
75140
75213
|
}
|
|
75141
75214
|
const realWorkspace = fs54.realpathSync(workspace);
|
|
75142
75215
|
const realResolvedPath = fs54.realpathSync(resolvedPath);
|
|
75143
|
-
const relativePath =
|
|
75144
|
-
if (relativePath.startsWith("..") ||
|
|
75216
|
+
const relativePath = path76.relative(realWorkspace, realResolvedPath);
|
|
75217
|
+
if (relativePath.startsWith("..") || path76.isAbsolute(relativePath)) {
|
|
75145
75218
|
return false;
|
|
75146
75219
|
}
|
|
75147
75220
|
return true;
|
|
@@ -75150,7 +75223,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
75150
75223
|
}
|
|
75151
75224
|
}
|
|
75152
75225
|
function processFile2(file3, cwd, exportedOnly) {
|
|
75153
|
-
const ext =
|
|
75226
|
+
const ext = path76.extname(file3);
|
|
75154
75227
|
if (containsControlChars(file3)) {
|
|
75155
75228
|
return {
|
|
75156
75229
|
file: file3,
|
|
@@ -75183,7 +75256,7 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
75183
75256
|
errorType: "path-outside-workspace"
|
|
75184
75257
|
};
|
|
75185
75258
|
}
|
|
75186
|
-
const fullPath =
|
|
75259
|
+
const fullPath = path76.join(cwd, file3);
|
|
75187
75260
|
if (!fs54.existsSync(fullPath)) {
|
|
75188
75261
|
return {
|
|
75189
75262
|
file: file3,
|
|
@@ -75475,15 +75548,15 @@ init_task_id();
|
|
|
75475
75548
|
init_create_tool();
|
|
75476
75549
|
init_resolve_working_directory();
|
|
75477
75550
|
import * as fs55 from "node:fs";
|
|
75478
|
-
import * as
|
|
75551
|
+
import * as path77 from "node:path";
|
|
75479
75552
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
75480
75553
|
function isValidTaskId3(taskId) {
|
|
75481
75554
|
return isStrictTaskId(taskId);
|
|
75482
75555
|
}
|
|
75483
75556
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
75484
|
-
const normalizedWorkspace =
|
|
75485
|
-
const swarmPath =
|
|
75486
|
-
const normalizedPath =
|
|
75557
|
+
const normalizedWorkspace = path77.resolve(workspaceRoot);
|
|
75558
|
+
const swarmPath = path77.join(normalizedWorkspace, ".swarm", "evidence");
|
|
75559
|
+
const normalizedPath = path77.resolve(filePath);
|
|
75487
75560
|
return normalizedPath.startsWith(swarmPath);
|
|
75488
75561
|
}
|
|
75489
75562
|
function readEvidenceFile(evidencePath) {
|
|
@@ -75564,7 +75637,7 @@ var check_gate_status = createSwarmTool({
|
|
|
75564
75637
|
};
|
|
75565
75638
|
return JSON.stringify(errorResult, null, 2);
|
|
75566
75639
|
}
|
|
75567
|
-
const evidencePath =
|
|
75640
|
+
const evidencePath = path77.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
75568
75641
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
75569
75642
|
const errorResult = {
|
|
75570
75643
|
taskId: taskIdInput,
|
|
@@ -75661,7 +75734,7 @@ init_state();
|
|
|
75661
75734
|
init_create_tool();
|
|
75662
75735
|
init_resolve_working_directory();
|
|
75663
75736
|
import * as fs56 from "node:fs";
|
|
75664
|
-
import * as
|
|
75737
|
+
import * as path78 from "node:path";
|
|
75665
75738
|
function extractMatches(regex, text) {
|
|
75666
75739
|
return Array.from(text.matchAll(regex));
|
|
75667
75740
|
}
|
|
@@ -75813,10 +75886,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
75813
75886
|
let hasFileReadFailure = false;
|
|
75814
75887
|
for (const filePath of fileTargets) {
|
|
75815
75888
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
75816
|
-
const resolvedPath =
|
|
75817
|
-
const projectRoot =
|
|
75818
|
-
const relative16 =
|
|
75819
|
-
const withinProject = relative16 === "" || !relative16.startsWith("..") && !
|
|
75889
|
+
const resolvedPath = path78.resolve(directory, normalizedPath);
|
|
75890
|
+
const projectRoot = path78.resolve(directory);
|
|
75891
|
+
const relative16 = path78.relative(projectRoot, resolvedPath);
|
|
75892
|
+
const withinProject = relative16 === "" || !relative16.startsWith("..") && !path78.isAbsolute(relative16);
|
|
75820
75893
|
if (!withinProject) {
|
|
75821
75894
|
blockedTasks.push({
|
|
75822
75895
|
task_id: task.id,
|
|
@@ -75871,8 +75944,8 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
75871
75944
|
blockedTasks
|
|
75872
75945
|
};
|
|
75873
75946
|
try {
|
|
75874
|
-
const evidenceDir =
|
|
75875
|
-
const evidencePath =
|
|
75947
|
+
const evidenceDir = path78.join(directory, ".swarm", "evidence", `${phase}`);
|
|
75948
|
+
const evidencePath = path78.join(evidenceDir, "completion-verify.json");
|
|
75876
75949
|
fs56.mkdirSync(evidenceDir, { recursive: true });
|
|
75877
75950
|
const evidenceBundle = {
|
|
75878
75951
|
schema_version: "1.0.0",
|
|
@@ -75949,11 +76022,11 @@ var completion_verify = createSwarmTool({
|
|
|
75949
76022
|
// src/tools/complexity-hotspots.ts
|
|
75950
76023
|
init_zod();
|
|
75951
76024
|
import * as fs58 from "node:fs";
|
|
75952
|
-
import * as
|
|
76025
|
+
import * as path80 from "node:path";
|
|
75953
76026
|
|
|
75954
76027
|
// src/quality/metrics.ts
|
|
75955
76028
|
import * as fs57 from "node:fs";
|
|
75956
|
-
import * as
|
|
76029
|
+
import * as path79 from "node:path";
|
|
75957
76030
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
75958
76031
|
var MIN_DUPLICATION_LINES = 10;
|
|
75959
76032
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -75991,8 +76064,8 @@ function estimateCyclomaticComplexity(content) {
|
|
|
75991
76064
|
}
|
|
75992
76065
|
function getComplexityForFile(filePath) {
|
|
75993
76066
|
try {
|
|
75994
|
-
const
|
|
75995
|
-
if (
|
|
76067
|
+
const stat7 = fs57.statSync(filePath);
|
|
76068
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES4) {
|
|
75996
76069
|
return null;
|
|
75997
76070
|
}
|
|
75998
76071
|
const content = fs57.readFileSync(filePath, "utf-8");
|
|
@@ -76005,7 +76078,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
76005
76078
|
let totalComplexity = 0;
|
|
76006
76079
|
const analyzedFiles = [];
|
|
76007
76080
|
for (const file3 of files) {
|
|
76008
|
-
const fullPath =
|
|
76081
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76009
76082
|
if (!fs57.existsSync(fullPath)) {
|
|
76010
76083
|
continue;
|
|
76011
76084
|
}
|
|
@@ -76128,7 +76201,7 @@ function countGoExports(content) {
|
|
|
76128
76201
|
function getExportCountForFile(filePath) {
|
|
76129
76202
|
try {
|
|
76130
76203
|
const content = fs57.readFileSync(filePath, "utf-8");
|
|
76131
|
-
const ext =
|
|
76204
|
+
const ext = path79.extname(filePath).toLowerCase();
|
|
76132
76205
|
switch (ext) {
|
|
76133
76206
|
case ".ts":
|
|
76134
76207
|
case ".tsx":
|
|
@@ -76154,7 +76227,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
76154
76227
|
let totalExports = 0;
|
|
76155
76228
|
const analyzedFiles = [];
|
|
76156
76229
|
for (const file3 of files) {
|
|
76157
|
-
const fullPath =
|
|
76230
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76158
76231
|
if (!fs57.existsSync(fullPath)) {
|
|
76159
76232
|
continue;
|
|
76160
76233
|
}
|
|
@@ -76188,13 +76261,13 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
76188
76261
|
let duplicateLines = 0;
|
|
76189
76262
|
const analyzedFiles = [];
|
|
76190
76263
|
for (const file3 of files) {
|
|
76191
|
-
const fullPath =
|
|
76264
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76192
76265
|
if (!fs57.existsSync(fullPath)) {
|
|
76193
76266
|
continue;
|
|
76194
76267
|
}
|
|
76195
76268
|
try {
|
|
76196
|
-
const
|
|
76197
|
-
if (
|
|
76269
|
+
const stat7 = fs57.statSync(fullPath);
|
|
76270
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES4) {
|
|
76198
76271
|
continue;
|
|
76199
76272
|
}
|
|
76200
76273
|
const content = fs57.readFileSync(fullPath, "utf-8");
|
|
@@ -76221,8 +76294,8 @@ function countCodeLines(content) {
|
|
|
76221
76294
|
return lines.length;
|
|
76222
76295
|
}
|
|
76223
76296
|
function isTestFile(filePath) {
|
|
76224
|
-
const basename11 =
|
|
76225
|
-
const _ext =
|
|
76297
|
+
const basename11 = path79.basename(filePath);
|
|
76298
|
+
const _ext = path79.extname(filePath).toLowerCase();
|
|
76226
76299
|
const testPatterns = [
|
|
76227
76300
|
".test.",
|
|
76228
76301
|
".spec.",
|
|
@@ -76303,8 +76376,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
76303
76376
|
}
|
|
76304
76377
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
76305
76378
|
}
|
|
76306
|
-
function matchesGlobSegment(
|
|
76307
|
-
const normalizedPath =
|
|
76379
|
+
function matchesGlobSegment(path80, glob) {
|
|
76380
|
+
const normalizedPath = path80.replace(/\\/g, "/");
|
|
76308
76381
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
76309
76382
|
if (normalizedPath.includes("//")) {
|
|
76310
76383
|
return false;
|
|
@@ -76335,8 +76408,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
76335
76408
|
function hasGlobstar(glob) {
|
|
76336
76409
|
return glob.includes("**");
|
|
76337
76410
|
}
|
|
76338
|
-
function globMatches(
|
|
76339
|
-
const normalizedPath =
|
|
76411
|
+
function globMatches(path80, glob) {
|
|
76412
|
+
const normalizedPath = path80.replace(/\\/g, "/");
|
|
76340
76413
|
if (!glob || glob === "") {
|
|
76341
76414
|
if (normalizedPath.includes("//")) {
|
|
76342
76415
|
return false;
|
|
@@ -76372,7 +76445,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
76372
76445
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
76373
76446
|
let testLines = 0;
|
|
76374
76447
|
let codeLines = 0;
|
|
76375
|
-
const srcDir =
|
|
76448
|
+
const srcDir = path79.join(workingDir, "src");
|
|
76376
76449
|
if (fs57.existsSync(srcDir)) {
|
|
76377
76450
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
76378
76451
|
codeLines += lines;
|
|
@@ -76380,14 +76453,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
76380
76453
|
}
|
|
76381
76454
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
76382
76455
|
for (const dir of possibleSrcDirs) {
|
|
76383
|
-
const dirPath =
|
|
76456
|
+
const dirPath = path79.join(workingDir, dir);
|
|
76384
76457
|
if (fs57.existsSync(dirPath)) {
|
|
76385
76458
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
76386
76459
|
codeLines += lines;
|
|
76387
76460
|
});
|
|
76388
76461
|
}
|
|
76389
76462
|
}
|
|
76390
|
-
const testsDir =
|
|
76463
|
+
const testsDir = path79.join(workingDir, "tests");
|
|
76391
76464
|
if (fs57.existsSync(testsDir)) {
|
|
76392
76465
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
76393
76466
|
testLines += lines;
|
|
@@ -76395,7 +76468,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
76395
76468
|
}
|
|
76396
76469
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
76397
76470
|
for (const dir of possibleTestDirs) {
|
|
76398
|
-
const dirPath =
|
|
76471
|
+
const dirPath = path79.join(workingDir, dir);
|
|
76399
76472
|
if (fs57.existsSync(dirPath) && dirPath !== testsDir) {
|
|
76400
76473
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
76401
76474
|
testLines += lines;
|
|
@@ -76410,7 +76483,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
76410
76483
|
try {
|
|
76411
76484
|
const entries = fs57.readdirSync(dirPath, { withFileTypes: true });
|
|
76412
76485
|
for (const entry of entries) {
|
|
76413
|
-
const fullPath =
|
|
76486
|
+
const fullPath = path79.join(dirPath, entry.name);
|
|
76414
76487
|
if (entry.isDirectory()) {
|
|
76415
76488
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
76416
76489
|
continue;
|
|
@@ -76418,7 +76491,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
76418
76491
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
76419
76492
|
} else if (entry.isFile()) {
|
|
76420
76493
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
76421
|
-
const ext =
|
|
76494
|
+
const ext = path79.extname(entry.name).toLowerCase();
|
|
76422
76495
|
const validExts = [
|
|
76423
76496
|
".ts",
|
|
76424
76497
|
".tsx",
|
|
@@ -76654,8 +76727,8 @@ async function getGitChurn(days, directory) {
|
|
|
76654
76727
|
}
|
|
76655
76728
|
function getComplexityForFile2(filePath) {
|
|
76656
76729
|
try {
|
|
76657
|
-
const
|
|
76658
|
-
if (
|
|
76730
|
+
const stat7 = fs58.statSync(filePath);
|
|
76731
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES5) {
|
|
76659
76732
|
return null;
|
|
76660
76733
|
}
|
|
76661
76734
|
const content = fs58.readFileSync(filePath, "utf-8");
|
|
@@ -76669,7 +76742,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
76669
76742
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
76670
76743
|
const filteredChurn = new Map;
|
|
76671
76744
|
for (const [file3, count] of churnMap) {
|
|
76672
|
-
const ext =
|
|
76745
|
+
const ext = path80.extname(file3).toLowerCase();
|
|
76673
76746
|
if (extSet.has(ext)) {
|
|
76674
76747
|
filteredChurn.set(file3, count);
|
|
76675
76748
|
}
|
|
@@ -76680,7 +76753,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
76680
76753
|
for (const [file3, churnCount] of filteredChurn) {
|
|
76681
76754
|
let fullPath = file3;
|
|
76682
76755
|
if (!fs58.existsSync(fullPath)) {
|
|
76683
|
-
fullPath =
|
|
76756
|
+
fullPath = path80.join(cwd, file3);
|
|
76684
76757
|
}
|
|
76685
76758
|
const complexity = getComplexityForFile2(fullPath);
|
|
76686
76759
|
if (complexity !== null) {
|
|
@@ -76849,7 +76922,7 @@ ${body2}`);
|
|
|
76849
76922
|
// src/council/council-evidence-writer.ts
|
|
76850
76923
|
import {
|
|
76851
76924
|
appendFileSync as appendFileSync6,
|
|
76852
|
-
existsSync as
|
|
76925
|
+
existsSync as existsSync40,
|
|
76853
76926
|
mkdirSync as mkdirSync19,
|
|
76854
76927
|
readFileSync as readFileSync36,
|
|
76855
76928
|
writeFileSync as writeFileSync12
|
|
@@ -76892,7 +76965,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76892
76965
|
mkdirSync19(dir, { recursive: true });
|
|
76893
76966
|
const filePath = join69(dir, `${synthesis.taskId}.json`);
|
|
76894
76967
|
const existingRoot = Object.create(null);
|
|
76895
|
-
if (
|
|
76968
|
+
if (existsSync40(filePath)) {
|
|
76896
76969
|
try {
|
|
76897
76970
|
const parsed = JSON.parse(readFileSync36(filePath, "utf-8"));
|
|
76898
76971
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -76941,7 +77014,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76941
77014
|
|
|
76942
77015
|
// src/council/council-service.ts
|
|
76943
77016
|
import fs59 from "node:fs";
|
|
76944
|
-
import
|
|
77017
|
+
import path81 from "node:path";
|
|
76945
77018
|
|
|
76946
77019
|
// src/council/types.ts
|
|
76947
77020
|
var COUNCIL_DEFAULTS = {
|
|
@@ -77101,9 +77174,9 @@ function synthesizePhaseCouncilAdvisory(phaseNumber, phaseSummary, verdicts, rou
|
|
|
77101
77174
|
const unifiedFeedbackMd = buildPhaseCouncilFeedback(phaseNumber, phaseSummary, overallVerdict, rejectingMembers, requiredFixes, advisoryFindings, unresolvedConflicts, roundNumber, cfg.maxRounds);
|
|
77102
77175
|
const evidencePath = `.swarm/evidence/${phaseNumber}/phase-council.json`;
|
|
77103
77176
|
const baseDir = workingDir ?? process.cwd();
|
|
77104
|
-
const evidenceDir =
|
|
77177
|
+
const evidenceDir = path81.join(baseDir, ".swarm", "evidence", String(phaseNumber));
|
|
77105
77178
|
fs59.mkdirSync(evidenceDir, { recursive: true });
|
|
77106
|
-
const evidenceFile =
|
|
77179
|
+
const evidenceFile = path81.join(evidenceDir, "phase-council.json");
|
|
77107
77180
|
const evidenceBundle = {
|
|
77108
77181
|
entries: [
|
|
77109
77182
|
{
|
|
@@ -77206,7 +77279,7 @@ function buildPhaseCouncilFeedback(phaseNumber, phaseSummary, verdict, vetoedBy,
|
|
|
77206
77279
|
}
|
|
77207
77280
|
|
|
77208
77281
|
// src/council/criteria-store.ts
|
|
77209
|
-
import { existsSync as
|
|
77282
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync20, readFileSync as readFileSync37, writeFileSync as writeFileSync13 } from "node:fs";
|
|
77210
77283
|
import { join as join70 } from "node:path";
|
|
77211
77284
|
var COUNCIL_DIR = ".swarm/council";
|
|
77212
77285
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
@@ -77221,7 +77294,7 @@ function writeCriteria(workingDir, taskId, criteria) {
|
|
|
77221
77294
|
}
|
|
77222
77295
|
function readCriteria(workingDir, taskId) {
|
|
77223
77296
|
const filePath = join70(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
|
|
77224
|
-
if (!
|
|
77297
|
+
if (!existsSync41(filePath))
|
|
77225
77298
|
return null;
|
|
77226
77299
|
try {
|
|
77227
77300
|
const parsed = JSON.parse(readFileSync37(filePath, "utf-8"));
|
|
@@ -77373,7 +77446,7 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
77373
77446
|
init_zod();
|
|
77374
77447
|
init_loader();
|
|
77375
77448
|
import * as fs60 from "node:fs";
|
|
77376
|
-
import * as
|
|
77449
|
+
import * as path82 from "node:path";
|
|
77377
77450
|
|
|
77378
77451
|
// src/council/general-council-advisory.ts
|
|
77379
77452
|
var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
|
|
@@ -77801,10 +77874,10 @@ var convene_general_council = createSwarmTool({
|
|
|
77801
77874
|
const round1 = input.round1Responses;
|
|
77802
77875
|
const round2 = input.round2Responses ?? [];
|
|
77803
77876
|
const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
|
|
77804
|
-
const evidenceDir =
|
|
77877
|
+
const evidenceDir = path82.join(workingDir, ".swarm", "council", "general");
|
|
77805
77878
|
const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
|
|
77806
77879
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
77807
|
-
const evidencePath =
|
|
77880
|
+
const evidencePath = path82.join(evidenceDir, evidenceFile);
|
|
77808
77881
|
try {
|
|
77809
77882
|
await fs60.promises.mkdir(evidenceDir, { recursive: true });
|
|
77810
77883
|
await fs60.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
@@ -78039,7 +78112,7 @@ init_state();
|
|
|
78039
78112
|
init_task_id();
|
|
78040
78113
|
init_create_tool();
|
|
78041
78114
|
import * as fs61 from "node:fs";
|
|
78042
|
-
import * as
|
|
78115
|
+
import * as path83 from "node:path";
|
|
78043
78116
|
function validateTaskIdFormat2(taskId) {
|
|
78044
78117
|
return validateTaskIdFormat(taskId);
|
|
78045
78118
|
}
|
|
@@ -78113,8 +78186,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78113
78186
|
};
|
|
78114
78187
|
}
|
|
78115
78188
|
}
|
|
78116
|
-
normalizedDir =
|
|
78117
|
-
const pathParts = normalizedDir.split(
|
|
78189
|
+
normalizedDir = path83.normalize(args2.working_directory);
|
|
78190
|
+
const pathParts = normalizedDir.split(path83.sep);
|
|
78118
78191
|
if (pathParts.includes("..")) {
|
|
78119
78192
|
return {
|
|
78120
78193
|
success: false,
|
|
@@ -78124,10 +78197,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78124
78197
|
]
|
|
78125
78198
|
};
|
|
78126
78199
|
}
|
|
78127
|
-
const resolvedDir =
|
|
78200
|
+
const resolvedDir = path83.resolve(normalizedDir);
|
|
78128
78201
|
try {
|
|
78129
78202
|
const realPath = fs61.realpathSync(resolvedDir);
|
|
78130
|
-
const planPath2 =
|
|
78203
|
+
const planPath2 = path83.join(realPath, ".swarm", "plan.json");
|
|
78131
78204
|
if (!fs61.existsSync(planPath2)) {
|
|
78132
78205
|
return {
|
|
78133
78206
|
success: false,
|
|
@@ -78151,7 +78224,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78151
78224
|
console.warn("[declare-scope] fallbackDir is undefined, falling back to process.cwd()");
|
|
78152
78225
|
}
|
|
78153
78226
|
const directory = normalizedDir || fallbackDir;
|
|
78154
|
-
const planPath =
|
|
78227
|
+
const planPath = path83.resolve(directory, ".swarm", "plan.json");
|
|
78155
78228
|
if (!fs61.existsSync(planPath)) {
|
|
78156
78229
|
return {
|
|
78157
78230
|
success: false,
|
|
@@ -78191,8 +78264,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78191
78264
|
const normalizeErrors = [];
|
|
78192
78265
|
const dir = normalizedDir || fallbackDir || process.cwd();
|
|
78193
78266
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
78194
|
-
if (
|
|
78195
|
-
const relativePath =
|
|
78267
|
+
if (path83.isAbsolute(file3)) {
|
|
78268
|
+
const relativePath = path83.relative(dir, file3).replace(/\\/g, "/");
|
|
78196
78269
|
if (relativePath.startsWith("..")) {
|
|
78197
78270
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
78198
78271
|
return file3;
|
|
@@ -78253,7 +78326,7 @@ var declare_scope = createSwarmTool({
|
|
|
78253
78326
|
init_zod();
|
|
78254
78327
|
import * as child_process7 from "node:child_process";
|
|
78255
78328
|
import * as fs62 from "node:fs";
|
|
78256
|
-
import * as
|
|
78329
|
+
import * as path84 from "node:path";
|
|
78257
78330
|
init_create_tool();
|
|
78258
78331
|
var MAX_DIFF_LINES = 500;
|
|
78259
78332
|
var DIFF_TIMEOUT_MS = 30000;
|
|
@@ -78282,20 +78355,20 @@ function validateBase(base) {
|
|
|
78282
78355
|
function validatePaths(paths) {
|
|
78283
78356
|
if (!paths)
|
|
78284
78357
|
return null;
|
|
78285
|
-
for (const
|
|
78286
|
-
if (!
|
|
78358
|
+
for (const path85 of paths) {
|
|
78359
|
+
if (!path85 || path85.length === 0) {
|
|
78287
78360
|
return "empty path not allowed";
|
|
78288
78361
|
}
|
|
78289
|
-
if (
|
|
78362
|
+
if (path85.length > MAX_PATH_LENGTH) {
|
|
78290
78363
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
78291
78364
|
}
|
|
78292
|
-
if (SHELL_METACHARACTERS2.test(
|
|
78365
|
+
if (SHELL_METACHARACTERS2.test(path85)) {
|
|
78293
78366
|
return "path contains shell metacharacters";
|
|
78294
78367
|
}
|
|
78295
|
-
if (
|
|
78368
|
+
if (path85.startsWith("-")) {
|
|
78296
78369
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
78297
78370
|
}
|
|
78298
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
78371
|
+
if (CONTROL_CHAR_PATTERN2.test(path85)) {
|
|
78299
78372
|
return "path contains control characters";
|
|
78300
78373
|
}
|
|
78301
78374
|
}
|
|
@@ -78401,8 +78474,8 @@ var diff = createSwarmTool({
|
|
|
78401
78474
|
if (parts2.length >= 3) {
|
|
78402
78475
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
78403
78476
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
78404
|
-
const
|
|
78405
|
-
files.push({ path:
|
|
78477
|
+
const path85 = parts2[2];
|
|
78478
|
+
files.push({ path: path85, additions, deletions });
|
|
78406
78479
|
}
|
|
78407
78480
|
}
|
|
78408
78481
|
const contractChanges = [];
|
|
@@ -78442,7 +78515,7 @@ var diff = createSwarmTool({
|
|
|
78442
78515
|
} else if (base === "unstaged") {
|
|
78443
78516
|
const oldRef = `:${file3.path}`;
|
|
78444
78517
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
78445
|
-
newContent = fs62.readFileSync(
|
|
78518
|
+
newContent = fs62.readFileSync(path84.join(directory, file3.path), "utf-8");
|
|
78446
78519
|
} else {
|
|
78447
78520
|
const oldRef = `${base}:${file3.path}`;
|
|
78448
78521
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -78517,7 +78590,7 @@ var diff = createSwarmTool({
|
|
|
78517
78590
|
init_zod();
|
|
78518
78591
|
import * as child_process8 from "node:child_process";
|
|
78519
78592
|
import * as fs63 from "node:fs";
|
|
78520
|
-
import * as
|
|
78593
|
+
import * as path85 from "node:path";
|
|
78521
78594
|
init_create_tool();
|
|
78522
78595
|
var diff_summary = createSwarmTool({
|
|
78523
78596
|
description: "Generate a filtered semantic diff summary from AST analysis. Returns SemanticDiffSummary with optional filtering by classification or riskLevel.",
|
|
@@ -78565,7 +78638,7 @@ var diff_summary = createSwarmTool({
|
|
|
78565
78638
|
}
|
|
78566
78639
|
try {
|
|
78567
78640
|
let oldContent;
|
|
78568
|
-
const newContent = fs63.readFileSync(
|
|
78641
|
+
const newContent = fs63.readFileSync(path85.join(workingDir, filePath), "utf-8");
|
|
78569
78642
|
if (fileExistsInHead) {
|
|
78570
78643
|
oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
|
|
78571
78644
|
encoding: "utf-8",
|
|
@@ -78794,7 +78867,7 @@ init_zod();
|
|
|
78794
78867
|
init_create_tool();
|
|
78795
78868
|
init_path_security();
|
|
78796
78869
|
import * as fs64 from "node:fs";
|
|
78797
|
-
import * as
|
|
78870
|
+
import * as path86 from "node:path";
|
|
78798
78871
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
78799
78872
|
var MAX_EVIDENCE_FILES = 1000;
|
|
78800
78873
|
var EVIDENCE_DIR3 = ".swarm/evidence";
|
|
@@ -78821,9 +78894,9 @@ function validateRequiredTypes(input) {
|
|
|
78821
78894
|
return null;
|
|
78822
78895
|
}
|
|
78823
78896
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
78824
|
-
const normalizedCwd =
|
|
78825
|
-
const swarmPath =
|
|
78826
|
-
const normalizedPath =
|
|
78897
|
+
const normalizedCwd = path86.resolve(cwd);
|
|
78898
|
+
const swarmPath = path86.join(normalizedCwd, ".swarm");
|
|
78899
|
+
const normalizedPath = path86.resolve(filePath);
|
|
78827
78900
|
return normalizedPath.startsWith(swarmPath);
|
|
78828
78901
|
}
|
|
78829
78902
|
function parseCompletedTasks(planContent) {
|
|
@@ -78853,15 +78926,15 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
78853
78926
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
78854
78927
|
continue;
|
|
78855
78928
|
}
|
|
78856
|
-
const filePath =
|
|
78929
|
+
const filePath = path86.join(evidenceDir, filename);
|
|
78857
78930
|
try {
|
|
78858
|
-
const resolvedPath =
|
|
78859
|
-
const evidenceDirResolved =
|
|
78931
|
+
const resolvedPath = path86.resolve(filePath);
|
|
78932
|
+
const evidenceDirResolved = path86.resolve(evidenceDir);
|
|
78860
78933
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
78861
78934
|
continue;
|
|
78862
78935
|
}
|
|
78863
|
-
const
|
|
78864
|
-
if (!
|
|
78936
|
+
const stat7 = fs64.lstatSync(filePath);
|
|
78937
|
+
if (!stat7.isFile()) {
|
|
78865
78938
|
continue;
|
|
78866
78939
|
}
|
|
78867
78940
|
} catch {
|
|
@@ -78974,7 +79047,7 @@ var evidence_check = createSwarmTool({
|
|
|
78974
79047
|
return JSON.stringify(errorResult, null, 2);
|
|
78975
79048
|
}
|
|
78976
79049
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
78977
|
-
const planPath =
|
|
79050
|
+
const planPath = path86.join(cwd, PLAN_FILE);
|
|
78978
79051
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
78979
79052
|
const errorResult = {
|
|
78980
79053
|
error: "plan file path validation failed",
|
|
@@ -79006,7 +79079,7 @@ var evidence_check = createSwarmTool({
|
|
|
79006
79079
|
};
|
|
79007
79080
|
return JSON.stringify(result2, null, 2);
|
|
79008
79081
|
}
|
|
79009
|
-
const evidenceDir =
|
|
79082
|
+
const evidenceDir = path86.join(cwd, EVIDENCE_DIR3);
|
|
79010
79083
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
79011
79084
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
79012
79085
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -79024,7 +79097,7 @@ var evidence_check = createSwarmTool({
|
|
|
79024
79097
|
init_zod();
|
|
79025
79098
|
init_create_tool();
|
|
79026
79099
|
import * as fs65 from "node:fs";
|
|
79027
|
-
import * as
|
|
79100
|
+
import * as path87 from "node:path";
|
|
79028
79101
|
var EXT_MAP = {
|
|
79029
79102
|
python: ".py",
|
|
79030
79103
|
py: ".py",
|
|
@@ -79105,12 +79178,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
79105
79178
|
if (prefix) {
|
|
79106
79179
|
filename = `${prefix}_${filename}`;
|
|
79107
79180
|
}
|
|
79108
|
-
let filepath =
|
|
79109
|
-
const base =
|
|
79110
|
-
const ext =
|
|
79181
|
+
let filepath = path87.join(targetDir, filename);
|
|
79182
|
+
const base = path87.basename(filepath, path87.extname(filepath));
|
|
79183
|
+
const ext = path87.extname(filepath);
|
|
79111
79184
|
let counter = 1;
|
|
79112
79185
|
while (fs65.existsSync(filepath)) {
|
|
79113
|
-
filepath =
|
|
79186
|
+
filepath = path87.join(targetDir, `${base}_${counter}${ext}`);
|
|
79114
79187
|
counter++;
|
|
79115
79188
|
}
|
|
79116
79189
|
try {
|
|
@@ -79286,7 +79359,7 @@ init_create_tool();
|
|
|
79286
79359
|
var GITINGEST_TIMEOUT_MS = 1e4;
|
|
79287
79360
|
var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
|
|
79288
79361
|
var GITINGEST_MAX_RETRIES = 2;
|
|
79289
|
-
var delay = (ms) => new Promise((
|
|
79362
|
+
var delay = (ms) => new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
79290
79363
|
async function fetchGitingest(args2) {
|
|
79291
79364
|
for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
|
|
79292
79365
|
try {
|
|
@@ -79374,7 +79447,7 @@ init_zod();
|
|
|
79374
79447
|
init_create_tool();
|
|
79375
79448
|
init_path_security();
|
|
79376
79449
|
import * as fs66 from "node:fs";
|
|
79377
|
-
import * as
|
|
79450
|
+
import * as path88 from "node:path";
|
|
79378
79451
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
79379
79452
|
var MAX_SYMBOL_LENGTH = 256;
|
|
79380
79453
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -79422,7 +79495,7 @@ function validateSymbolInput(symbol3) {
|
|
|
79422
79495
|
return null;
|
|
79423
79496
|
}
|
|
79424
79497
|
function isBinaryFile2(filePath, buffer) {
|
|
79425
|
-
const ext =
|
|
79498
|
+
const ext = path88.extname(filePath).toLowerCase();
|
|
79426
79499
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
79427
79500
|
return false;
|
|
79428
79501
|
}
|
|
@@ -79446,15 +79519,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
79446
79519
|
const imports = [];
|
|
79447
79520
|
let _resolvedTarget;
|
|
79448
79521
|
try {
|
|
79449
|
-
_resolvedTarget =
|
|
79522
|
+
_resolvedTarget = path88.resolve(targetFile);
|
|
79450
79523
|
} catch {
|
|
79451
79524
|
_resolvedTarget = targetFile;
|
|
79452
79525
|
}
|
|
79453
|
-
const targetBasename =
|
|
79526
|
+
const targetBasename = path88.basename(targetFile, path88.extname(targetFile));
|
|
79454
79527
|
const targetWithExt = targetFile;
|
|
79455
79528
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
79456
|
-
const normalizedTargetWithExt =
|
|
79457
|
-
const normalizedTargetWithoutExt =
|
|
79529
|
+
const normalizedTargetWithExt = path88.normalize(targetWithExt).replace(/\\/g, "/");
|
|
79530
|
+
const normalizedTargetWithoutExt = path88.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
79458
79531
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
79459
79532
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
79460
79533
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -79477,9 +79550,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
79477
79550
|
}
|
|
79478
79551
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
79479
79552
|
let isMatch = false;
|
|
79480
|
-
const _targetDir =
|
|
79481
|
-
const targetExt =
|
|
79482
|
-
const targetBasenameNoExt =
|
|
79553
|
+
const _targetDir = path88.dirname(targetFile);
|
|
79554
|
+
const targetExt = path88.extname(targetFile);
|
|
79555
|
+
const targetBasenameNoExt = path88.basename(targetFile, targetExt);
|
|
79483
79556
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
79484
79557
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
79485
79558
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -79547,13 +79620,13 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
79547
79620
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
79548
79621
|
for (const entry of entries) {
|
|
79549
79622
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
79550
|
-
stats.skippedDirs.push(
|
|
79623
|
+
stats.skippedDirs.push(path88.join(dir, entry));
|
|
79551
79624
|
continue;
|
|
79552
79625
|
}
|
|
79553
|
-
const fullPath =
|
|
79554
|
-
let
|
|
79626
|
+
const fullPath = path88.join(dir, entry);
|
|
79627
|
+
let stat7;
|
|
79555
79628
|
try {
|
|
79556
|
-
|
|
79629
|
+
stat7 = fs66.statSync(fullPath);
|
|
79557
79630
|
} catch (e) {
|
|
79558
79631
|
stats.fileErrors.push({
|
|
79559
79632
|
path: fullPath,
|
|
@@ -79561,10 +79634,10 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
79561
79634
|
});
|
|
79562
79635
|
continue;
|
|
79563
79636
|
}
|
|
79564
|
-
if (
|
|
79637
|
+
if (stat7.isDirectory()) {
|
|
79565
79638
|
findSourceFiles2(fullPath, files, stats);
|
|
79566
|
-
} else if (
|
|
79567
|
-
const ext =
|
|
79639
|
+
} else if (stat7.isFile()) {
|
|
79640
|
+
const ext = path88.extname(fullPath).toLowerCase();
|
|
79568
79641
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
79569
79642
|
files.push(fullPath);
|
|
79570
79643
|
}
|
|
@@ -79621,7 +79694,7 @@ var imports = createSwarmTool({
|
|
|
79621
79694
|
return JSON.stringify(errorResult, null, 2);
|
|
79622
79695
|
}
|
|
79623
79696
|
try {
|
|
79624
|
-
const targetFile =
|
|
79697
|
+
const targetFile = path88.resolve(file3);
|
|
79625
79698
|
if (!fs66.existsSync(targetFile)) {
|
|
79626
79699
|
const errorResult = {
|
|
79627
79700
|
error: `target file not found: ${file3}`,
|
|
@@ -79643,7 +79716,7 @@ var imports = createSwarmTool({
|
|
|
79643
79716
|
};
|
|
79644
79717
|
return JSON.stringify(errorResult, null, 2);
|
|
79645
79718
|
}
|
|
79646
|
-
const baseDir =
|
|
79719
|
+
const baseDir = path88.dirname(targetFile);
|
|
79647
79720
|
const scanStats = {
|
|
79648
79721
|
skippedDirs: [],
|
|
79649
79722
|
skippedFiles: 0,
|
|
@@ -79658,8 +79731,8 @@ var imports = createSwarmTool({
|
|
|
79658
79731
|
if (consumers.length >= MAX_CONSUMERS)
|
|
79659
79732
|
break;
|
|
79660
79733
|
try {
|
|
79661
|
-
const
|
|
79662
|
-
if (
|
|
79734
|
+
const stat7 = fs66.statSync(filePath);
|
|
79735
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES7) {
|
|
79663
79736
|
skippedFileCount++;
|
|
79664
79737
|
continue;
|
|
79665
79738
|
}
|
|
@@ -79876,7 +79949,7 @@ init_zod();
|
|
|
79876
79949
|
init_config();
|
|
79877
79950
|
init_knowledge_store();
|
|
79878
79951
|
init_create_tool();
|
|
79879
|
-
import { existsSync as
|
|
79952
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
79880
79953
|
var DEFAULT_LIMIT = 10;
|
|
79881
79954
|
var MAX_LESSON_LENGTH = 200;
|
|
79882
79955
|
var VALID_CATEGORIES3 = [
|
|
@@ -79946,14 +80019,14 @@ function validateLimit(limit) {
|
|
|
79946
80019
|
}
|
|
79947
80020
|
async function readSwarmKnowledge(directory) {
|
|
79948
80021
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
79949
|
-
if (!
|
|
80022
|
+
if (!existsSync46(swarmPath)) {
|
|
79950
80023
|
return [];
|
|
79951
80024
|
}
|
|
79952
80025
|
return readKnowledge(swarmPath);
|
|
79953
80026
|
}
|
|
79954
80027
|
async function readHiveKnowledge() {
|
|
79955
80028
|
const hivePath = resolveHiveKnowledgePath();
|
|
79956
|
-
if (!
|
|
80029
|
+
if (!existsSync46(hivePath)) {
|
|
79957
80030
|
return [];
|
|
79958
80031
|
}
|
|
79959
80032
|
return readKnowledge(hivePath);
|
|
@@ -80189,7 +80262,7 @@ init_qa_gate_profile();
|
|
|
80189
80262
|
init_manager2();
|
|
80190
80263
|
init_curator();
|
|
80191
80264
|
import * as fs68 from "node:fs";
|
|
80192
|
-
import * as
|
|
80265
|
+
import * as path90 from "node:path";
|
|
80193
80266
|
init_knowledge_curator();
|
|
80194
80267
|
init_knowledge_reader();
|
|
80195
80268
|
init_knowledge_store();
|
|
@@ -80202,16 +80275,16 @@ init_plan_schema();
|
|
|
80202
80275
|
init_ledger();
|
|
80203
80276
|
init_manager();
|
|
80204
80277
|
import * as fs67 from "node:fs";
|
|
80205
|
-
import * as
|
|
80278
|
+
import * as path89 from "node:path";
|
|
80206
80279
|
async function writeCheckpoint(directory) {
|
|
80207
80280
|
try {
|
|
80208
80281
|
const plan = await loadPlan(directory);
|
|
80209
80282
|
if (!plan)
|
|
80210
80283
|
return;
|
|
80211
|
-
const swarmDir =
|
|
80284
|
+
const swarmDir = path89.join(directory, ".swarm");
|
|
80212
80285
|
fs67.mkdirSync(swarmDir, { recursive: true });
|
|
80213
|
-
const jsonPath =
|
|
80214
|
-
const mdPath =
|
|
80286
|
+
const jsonPath = path89.join(swarmDir, "SWARM_PLAN.json");
|
|
80287
|
+
const mdPath = path89.join(swarmDir, "SWARM_PLAN.md");
|
|
80215
80288
|
fs67.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
80216
80289
|
const md = derivePlanMarkdown(plan);
|
|
80217
80290
|
fs67.writeFileSync(mdPath, md, "utf8");
|
|
@@ -80446,7 +80519,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80446
80519
|
let driftCheckEnabled = true;
|
|
80447
80520
|
let driftHasSpecMd = false;
|
|
80448
80521
|
try {
|
|
80449
|
-
const specMdPath =
|
|
80522
|
+
const specMdPath = path90.join(dir, ".swarm", "spec.md");
|
|
80450
80523
|
driftHasSpecMd = fs68.existsSync(specMdPath);
|
|
80451
80524
|
const gatePlan = await loadPlan(dir);
|
|
80452
80525
|
if (gatePlan) {
|
|
@@ -80468,7 +80541,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80468
80541
|
} else {
|
|
80469
80542
|
let phaseType;
|
|
80470
80543
|
try {
|
|
80471
|
-
const planPath =
|
|
80544
|
+
const planPath = path90.join(dir, ".swarm", "plan.json");
|
|
80472
80545
|
if (fs68.existsSync(planPath)) {
|
|
80473
80546
|
const planRaw = fs68.readFileSync(planPath, "utf-8");
|
|
80474
80547
|
const plan = JSON.parse(planRaw);
|
|
@@ -80481,7 +80554,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80481
80554
|
warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
|
|
80482
80555
|
} else {
|
|
80483
80556
|
try {
|
|
80484
|
-
const driftEvidencePath =
|
|
80557
|
+
const driftEvidencePath = path90.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
80485
80558
|
let driftVerdictFound = false;
|
|
80486
80559
|
let driftVerdictApproved = false;
|
|
80487
80560
|
try {
|
|
@@ -80519,7 +80592,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80519
80592
|
let incompleteTaskCount = 0;
|
|
80520
80593
|
let planParseable = false;
|
|
80521
80594
|
try {
|
|
80522
|
-
const planPath =
|
|
80595
|
+
const planPath = path90.join(dir, ".swarm", "plan.json");
|
|
80523
80596
|
if (fs68.existsSync(planPath)) {
|
|
80524
80597
|
const planRaw = fs68.readFileSync(planPath, "utf-8");
|
|
80525
80598
|
const plan = JSON.parse(planRaw);
|
|
@@ -80586,7 +80659,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80586
80659
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
80587
80660
|
const effective = getEffectiveGates(profile, overrides);
|
|
80588
80661
|
if (effective.hallucination_guard === true) {
|
|
80589
|
-
const hgPath =
|
|
80662
|
+
const hgPath = path90.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
80590
80663
|
let hgVerdictFound = false;
|
|
80591
80664
|
let hgVerdictApproved = false;
|
|
80592
80665
|
try {
|
|
@@ -80658,7 +80731,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80658
80731
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
80659
80732
|
const effective = getEffectiveGates(profile, overrides);
|
|
80660
80733
|
if (effective.mutation_test === true) {
|
|
80661
|
-
const mgPath =
|
|
80734
|
+
const mgPath = path90.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
80662
80735
|
let mgVerdictFound = false;
|
|
80663
80736
|
let mgVerdict;
|
|
80664
80737
|
try {
|
|
@@ -80732,7 +80805,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80732
80805
|
const effective = getEffectiveGates(profile, overrides);
|
|
80733
80806
|
if (effective.council_mode === true) {
|
|
80734
80807
|
councilModeEnabled = true;
|
|
80735
|
-
const pcPath =
|
|
80808
|
+
const pcPath = path90.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
80736
80809
|
let pcVerdictFound = false;
|
|
80737
80810
|
let _pcVerdict;
|
|
80738
80811
|
let pcQuorumSize;
|
|
@@ -80934,7 +81007,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80934
81007
|
}
|
|
80935
81008
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
80936
81009
|
try {
|
|
80937
|
-
const projectName =
|
|
81010
|
+
const projectName = path90.basename(dir);
|
|
80938
81011
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
80939
81012
|
if (curationResult) {
|
|
80940
81013
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -81304,7 +81377,7 @@ init_utils();
|
|
|
81304
81377
|
init_bun_compat();
|
|
81305
81378
|
init_create_tool();
|
|
81306
81379
|
import * as fs69 from "node:fs";
|
|
81307
|
-
import * as
|
|
81380
|
+
import * as path91 from "node:path";
|
|
81308
81381
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
81309
81382
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
81310
81383
|
function isValidEcosystem(value) {
|
|
@@ -81332,16 +81405,16 @@ function validateArgs3(args2) {
|
|
|
81332
81405
|
function detectEcosystems(directory) {
|
|
81333
81406
|
const ecosystems = [];
|
|
81334
81407
|
const cwd = directory;
|
|
81335
|
-
if (fs69.existsSync(
|
|
81408
|
+
if (fs69.existsSync(path91.join(cwd, "package.json"))) {
|
|
81336
81409
|
ecosystems.push("npm");
|
|
81337
81410
|
}
|
|
81338
|
-
if (fs69.existsSync(
|
|
81411
|
+
if (fs69.existsSync(path91.join(cwd, "pyproject.toml")) || fs69.existsSync(path91.join(cwd, "requirements.txt"))) {
|
|
81339
81412
|
ecosystems.push("pip");
|
|
81340
81413
|
}
|
|
81341
|
-
if (fs69.existsSync(
|
|
81414
|
+
if (fs69.existsSync(path91.join(cwd, "Cargo.toml"))) {
|
|
81342
81415
|
ecosystems.push("cargo");
|
|
81343
81416
|
}
|
|
81344
|
-
if (fs69.existsSync(
|
|
81417
|
+
if (fs69.existsSync(path91.join(cwd, "go.mod"))) {
|
|
81345
81418
|
ecosystems.push("go");
|
|
81346
81419
|
}
|
|
81347
81420
|
try {
|
|
@@ -81350,13 +81423,13 @@ function detectEcosystems(directory) {
|
|
|
81350
81423
|
ecosystems.push("dotnet");
|
|
81351
81424
|
}
|
|
81352
81425
|
} catch {}
|
|
81353
|
-
if (fs69.existsSync(
|
|
81426
|
+
if (fs69.existsSync(path91.join(cwd, "Gemfile")) || fs69.existsSync(path91.join(cwd, "Gemfile.lock"))) {
|
|
81354
81427
|
ecosystems.push("ruby");
|
|
81355
81428
|
}
|
|
81356
|
-
if (fs69.existsSync(
|
|
81429
|
+
if (fs69.existsSync(path91.join(cwd, "pubspec.yaml"))) {
|
|
81357
81430
|
ecosystems.push("dart");
|
|
81358
81431
|
}
|
|
81359
|
-
if (fs69.existsSync(
|
|
81432
|
+
if (fs69.existsSync(path91.join(cwd, "composer.lock"))) {
|
|
81360
81433
|
ecosystems.push("composer");
|
|
81361
81434
|
}
|
|
81362
81435
|
return ecosystems;
|
|
@@ -81369,7 +81442,7 @@ async function runNpmAudit(directory) {
|
|
|
81369
81442
|
stderr: "pipe",
|
|
81370
81443
|
cwd: directory
|
|
81371
81444
|
});
|
|
81372
|
-
const timeoutPromise = new Promise((
|
|
81445
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81373
81446
|
const result = await Promise.race([
|
|
81374
81447
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
81375
81448
|
timeoutPromise
|
|
@@ -81489,7 +81562,7 @@ async function runPipAudit(directory) {
|
|
|
81489
81562
|
stderr: "pipe",
|
|
81490
81563
|
cwd: directory
|
|
81491
81564
|
});
|
|
81492
|
-
const timeoutPromise = new Promise((
|
|
81565
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81493
81566
|
const result = await Promise.race([
|
|
81494
81567
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
81495
81568
|
timeoutPromise
|
|
@@ -81617,7 +81690,7 @@ async function runCargoAudit(directory) {
|
|
|
81617
81690
|
stderr: "pipe",
|
|
81618
81691
|
cwd: directory
|
|
81619
81692
|
});
|
|
81620
|
-
const timeoutPromise = new Promise((
|
|
81693
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81621
81694
|
const result = await Promise.race([
|
|
81622
81695
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81623
81696
|
timeoutPromise
|
|
@@ -81741,7 +81814,7 @@ async function runGoAudit(directory) {
|
|
|
81741
81814
|
stderr: "pipe",
|
|
81742
81815
|
cwd: directory
|
|
81743
81816
|
});
|
|
81744
|
-
const timeoutPromise = new Promise((
|
|
81817
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81745
81818
|
const result = await Promise.race([
|
|
81746
81819
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81747
81820
|
timeoutPromise
|
|
@@ -81874,7 +81947,7 @@ async function runDotnetAudit(directory) {
|
|
|
81874
81947
|
stderr: "pipe",
|
|
81875
81948
|
cwd: directory
|
|
81876
81949
|
});
|
|
81877
|
-
const timeoutPromise = new Promise((
|
|
81950
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81878
81951
|
const result = await Promise.race([
|
|
81879
81952
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81880
81953
|
timeoutPromise
|
|
@@ -81990,7 +82063,7 @@ async function runBundleAudit(directory) {
|
|
|
81990
82063
|
stderr: "pipe",
|
|
81991
82064
|
cwd: directory
|
|
81992
82065
|
});
|
|
81993
|
-
const timeoutPromise = new Promise((
|
|
82066
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81994
82067
|
const result = await Promise.race([
|
|
81995
82068
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81996
82069
|
timeoutPromise
|
|
@@ -82135,7 +82208,7 @@ async function runDartAudit(directory) {
|
|
|
82135
82208
|
stderr: "pipe",
|
|
82136
82209
|
cwd: directory
|
|
82137
82210
|
});
|
|
82138
|
-
const timeoutPromise = new Promise((
|
|
82211
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
82139
82212
|
const result = await Promise.race([
|
|
82140
82213
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
82141
82214
|
timeoutPromise
|
|
@@ -82250,7 +82323,7 @@ async function runComposerAudit(directory) {
|
|
|
82250
82323
|
stderr: "pipe",
|
|
82251
82324
|
cwd: directory
|
|
82252
82325
|
});
|
|
82253
|
-
const timeoutPromise = new Promise((
|
|
82326
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
82254
82327
|
const result = await Promise.race([
|
|
82255
82328
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
82256
82329
|
timeoutPromise
|
|
@@ -82492,7 +82565,7 @@ var pkg_audit = createSwarmTool({
|
|
|
82492
82565
|
init_zod();
|
|
82493
82566
|
init_manager2();
|
|
82494
82567
|
import * as fs70 from "node:fs";
|
|
82495
|
-
import * as
|
|
82568
|
+
import * as path92 from "node:path";
|
|
82496
82569
|
init_utils();
|
|
82497
82570
|
init_create_tool();
|
|
82498
82571
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -82615,7 +82688,7 @@ function isScaffoldFile(filePath) {
|
|
|
82615
82688
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
82616
82689
|
return true;
|
|
82617
82690
|
}
|
|
82618
|
-
const filename =
|
|
82691
|
+
const filename = path92.basename(filePath);
|
|
82619
82692
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
82620
82693
|
return true;
|
|
82621
82694
|
}
|
|
@@ -82632,7 +82705,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
82632
82705
|
if (regex.test(normalizedPath)) {
|
|
82633
82706
|
return true;
|
|
82634
82707
|
}
|
|
82635
|
-
const filename =
|
|
82708
|
+
const filename = path92.basename(filePath);
|
|
82636
82709
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
82637
82710
|
if (filenameRegex.test(filename)) {
|
|
82638
82711
|
return true;
|
|
@@ -82641,7 +82714,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
82641
82714
|
return false;
|
|
82642
82715
|
}
|
|
82643
82716
|
function isParserSupported(filePath) {
|
|
82644
|
-
const ext =
|
|
82717
|
+
const ext = path92.extname(filePath).toLowerCase();
|
|
82645
82718
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
82646
82719
|
}
|
|
82647
82720
|
function isPlanFile(filePath) {
|
|
@@ -82888,9 +82961,9 @@ async function placeholderScan(input, directory) {
|
|
|
82888
82961
|
let filesScanned = 0;
|
|
82889
82962
|
const filesWithFindings = new Set;
|
|
82890
82963
|
for (const filePath of changed_files) {
|
|
82891
|
-
const fullPath =
|
|
82892
|
-
const resolvedDirectory =
|
|
82893
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
82964
|
+
const fullPath = path92.isAbsolute(filePath) ? filePath : path92.resolve(directory, filePath);
|
|
82965
|
+
const resolvedDirectory = path92.resolve(directory);
|
|
82966
|
+
if (!fullPath.startsWith(resolvedDirectory + path92.sep) && fullPath !== resolvedDirectory) {
|
|
82894
82967
|
continue;
|
|
82895
82968
|
}
|
|
82896
82969
|
if (!fs70.existsSync(fullPath)) {
|
|
@@ -82899,14 +82972,14 @@ async function placeholderScan(input, directory) {
|
|
|
82899
82972
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
82900
82973
|
continue;
|
|
82901
82974
|
}
|
|
82902
|
-
const relativeFilePath =
|
|
82975
|
+
const relativeFilePath = path92.relative(directory, fullPath).replace(/\\/g, "/");
|
|
82903
82976
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
82904
82977
|
continue;
|
|
82905
82978
|
}
|
|
82906
82979
|
let content;
|
|
82907
82980
|
try {
|
|
82908
|
-
const
|
|
82909
|
-
if (
|
|
82981
|
+
const stat7 = fs70.statSync(fullPath);
|
|
82982
|
+
if (stat7.size > MAX_FILE_SIZE) {
|
|
82910
82983
|
continue;
|
|
82911
82984
|
}
|
|
82912
82985
|
content = fs70.readFileSync(fullPath, "utf-8");
|
|
@@ -82971,7 +83044,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
82971
83044
|
});
|
|
82972
83045
|
// src/tools/pre-check-batch.ts
|
|
82973
83046
|
import * as fs73 from "node:fs";
|
|
82974
|
-
import * as
|
|
83047
|
+
import * as path95 from "node:path";
|
|
82975
83048
|
init_zod();
|
|
82976
83049
|
init_manager2();
|
|
82977
83050
|
init_utils();
|
|
@@ -83109,7 +83182,7 @@ init_zod();
|
|
|
83109
83182
|
init_manager2();
|
|
83110
83183
|
init_detector();
|
|
83111
83184
|
import * as fs72 from "node:fs";
|
|
83112
|
-
import * as
|
|
83185
|
+
import * as path94 from "node:path";
|
|
83113
83186
|
import { extname as extname18 } from "node:path";
|
|
83114
83187
|
|
|
83115
83188
|
// src/sast/rules/c.ts
|
|
@@ -83890,7 +83963,7 @@ function mapSemgrepSeverity(severity) {
|
|
|
83890
83963
|
}
|
|
83891
83964
|
}
|
|
83892
83965
|
async function executeWithTimeout(command, args2, options) {
|
|
83893
|
-
return new Promise((
|
|
83966
|
+
return new Promise((resolve33) => {
|
|
83894
83967
|
const child = child_process9.spawn(command, args2, {
|
|
83895
83968
|
shell: false,
|
|
83896
83969
|
cwd: options.cwd
|
|
@@ -83899,7 +83972,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83899
83972
|
let stderr = "";
|
|
83900
83973
|
const timeout = setTimeout(() => {
|
|
83901
83974
|
child.kill("SIGTERM");
|
|
83902
|
-
|
|
83975
|
+
resolve33({
|
|
83903
83976
|
stdout,
|
|
83904
83977
|
stderr: "Process timed out",
|
|
83905
83978
|
exitCode: 124
|
|
@@ -83913,7 +83986,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83913
83986
|
});
|
|
83914
83987
|
child.on("close", (code) => {
|
|
83915
83988
|
clearTimeout(timeout);
|
|
83916
|
-
|
|
83989
|
+
resolve33({
|
|
83917
83990
|
stdout,
|
|
83918
83991
|
stderr,
|
|
83919
83992
|
exitCode: code ?? 0
|
|
@@ -83921,7 +83994,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83921
83994
|
});
|
|
83922
83995
|
child.on("error", (err2) => {
|
|
83923
83996
|
clearTimeout(timeout);
|
|
83924
|
-
|
|
83997
|
+
resolve33({
|
|
83925
83998
|
stdout,
|
|
83926
83999
|
stderr: err2.message,
|
|
83927
84000
|
exitCode: 1
|
|
@@ -84003,24 +84076,24 @@ init_create_tool();
|
|
|
84003
84076
|
init_utils2();
|
|
84004
84077
|
import * as crypto8 from "node:crypto";
|
|
84005
84078
|
import * as fs71 from "node:fs";
|
|
84006
|
-
import * as
|
|
84079
|
+
import * as path93 from "node:path";
|
|
84007
84080
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
84008
84081
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
84009
84082
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
84010
84083
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
84011
84084
|
function normalizeFindingPath(directory, file3) {
|
|
84012
|
-
const resolved =
|
|
84013
|
-
const rel =
|
|
84085
|
+
const resolved = path93.isAbsolute(file3) ? file3 : path93.resolve(directory, file3);
|
|
84086
|
+
const rel = path93.relative(path93.resolve(directory), resolved);
|
|
84014
84087
|
return rel.replace(/\\/g, "/");
|
|
84015
84088
|
}
|
|
84016
84089
|
function baselineRelPath(phase) {
|
|
84017
|
-
return
|
|
84090
|
+
return path93.join("evidence", String(phase), "sast-baseline.json");
|
|
84018
84091
|
}
|
|
84019
84092
|
function tempRelPath(phase) {
|
|
84020
|
-
return
|
|
84093
|
+
return path93.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
84021
84094
|
}
|
|
84022
84095
|
function lockRelPath(phase) {
|
|
84023
|
-
return
|
|
84096
|
+
return path93.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
84024
84097
|
}
|
|
84025
84098
|
function getLine(lines, idx) {
|
|
84026
84099
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -84106,7 +84179,7 @@ async function acquireLock(lockPath) {
|
|
|
84106
84179
|
};
|
|
84107
84180
|
} catch {
|
|
84108
84181
|
if (attempt < LOCK_RETRY_DELAYS_MS.length) {
|
|
84109
|
-
await new Promise((
|
|
84182
|
+
await new Promise((resolve34) => setTimeout(resolve34, LOCK_RETRY_DELAYS_MS[attempt]));
|
|
84110
84183
|
}
|
|
84111
84184
|
}
|
|
84112
84185
|
}
|
|
@@ -84141,8 +84214,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
84141
84214
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
84142
84215
|
};
|
|
84143
84216
|
}
|
|
84144
|
-
fs71.mkdirSync(
|
|
84145
|
-
fs71.mkdirSync(
|
|
84217
|
+
fs71.mkdirSync(path93.dirname(baselinePath), { recursive: true });
|
|
84218
|
+
fs71.mkdirSync(path93.dirname(tempPath), { recursive: true });
|
|
84146
84219
|
const releaseLock = await acquireLock(lockPath);
|
|
84147
84220
|
try {
|
|
84148
84221
|
let existing = null;
|
|
@@ -84409,9 +84482,9 @@ async function sastScan(input, directory, config3) {
|
|
|
84409
84482
|
_filesSkipped++;
|
|
84410
84483
|
continue;
|
|
84411
84484
|
}
|
|
84412
|
-
const resolvedPath =
|
|
84413
|
-
const resolvedDirectory =
|
|
84414
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
84485
|
+
const resolvedPath = path94.isAbsolute(filePath) ? filePath : path94.resolve(directory, filePath);
|
|
84486
|
+
const resolvedDirectory = path94.resolve(directory);
|
|
84487
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path94.sep) && resolvedPath !== resolvedDirectory) {
|
|
84415
84488
|
_filesSkipped++;
|
|
84416
84489
|
continue;
|
|
84417
84490
|
}
|
|
@@ -84722,18 +84795,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
84722
84795
|
let resolved;
|
|
84723
84796
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
84724
84797
|
if (isWinAbs) {
|
|
84725
|
-
resolved =
|
|
84726
|
-
} else if (
|
|
84727
|
-
resolved =
|
|
84798
|
+
resolved = path95.win32.resolve(inputPath);
|
|
84799
|
+
} else if (path95.isAbsolute(inputPath)) {
|
|
84800
|
+
resolved = path95.resolve(inputPath);
|
|
84728
84801
|
} else {
|
|
84729
|
-
resolved =
|
|
84802
|
+
resolved = path95.resolve(baseDir, inputPath);
|
|
84730
84803
|
}
|
|
84731
|
-
const workspaceResolved =
|
|
84804
|
+
const workspaceResolved = path95.resolve(workspaceDir);
|
|
84732
84805
|
let relative20;
|
|
84733
84806
|
if (isWinAbs) {
|
|
84734
|
-
relative20 =
|
|
84807
|
+
relative20 = path95.win32.relative(workspaceResolved, resolved);
|
|
84735
84808
|
} else {
|
|
84736
|
-
relative20 =
|
|
84809
|
+
relative20 = path95.relative(workspaceResolved, resolved);
|
|
84737
84810
|
}
|
|
84738
84811
|
if (relative20.startsWith("..")) {
|
|
84739
84812
|
return "path traversal detected";
|
|
@@ -84798,7 +84871,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
84798
84871
|
if (typeof file3 !== "string") {
|
|
84799
84872
|
continue;
|
|
84800
84873
|
}
|
|
84801
|
-
const resolvedPath =
|
|
84874
|
+
const resolvedPath = path95.resolve(file3);
|
|
84802
84875
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
84803
84876
|
if (validationError) {
|
|
84804
84877
|
continue;
|
|
@@ -84955,7 +85028,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
84955
85028
|
skippedFiles++;
|
|
84956
85029
|
continue;
|
|
84957
85030
|
}
|
|
84958
|
-
const resolvedPath =
|
|
85031
|
+
const resolvedPath = path95.resolve(file3);
|
|
84959
85032
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
84960
85033
|
if (validationError) {
|
|
84961
85034
|
skippedFiles++;
|
|
@@ -84973,19 +85046,19 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
84973
85046
|
};
|
|
84974
85047
|
}
|
|
84975
85048
|
for (const file3 of validatedFiles) {
|
|
84976
|
-
const ext =
|
|
85049
|
+
const ext = path95.extname(file3).toLowerCase();
|
|
84977
85050
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
84978
85051
|
skippedFiles++;
|
|
84979
85052
|
continue;
|
|
84980
85053
|
}
|
|
84981
|
-
let
|
|
85054
|
+
let stat7;
|
|
84982
85055
|
try {
|
|
84983
|
-
|
|
85056
|
+
stat7 = fs73.statSync(file3);
|
|
84984
85057
|
} catch {
|
|
84985
85058
|
skippedFiles++;
|
|
84986
85059
|
continue;
|
|
84987
85060
|
}
|
|
84988
|
-
if (
|
|
85061
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES9) {
|
|
84989
85062
|
skippedFiles++;
|
|
84990
85063
|
continue;
|
|
84991
85064
|
}
|
|
@@ -85192,7 +85265,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
85192
85265
|
const preexistingFindings = [];
|
|
85193
85266
|
for (const finding of findings) {
|
|
85194
85267
|
const filePath = finding.location.file;
|
|
85195
|
-
const normalised =
|
|
85268
|
+
const normalised = path95.relative(directory, filePath).replace(/\\/g, "/");
|
|
85196
85269
|
const changedLines = changedLineRanges.get(normalised);
|
|
85197
85270
|
if (changedLines?.has(finding.location.line)) {
|
|
85198
85271
|
newFindings.push(finding);
|
|
@@ -85243,7 +85316,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
85243
85316
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
85244
85317
|
continue;
|
|
85245
85318
|
}
|
|
85246
|
-
changedFiles.push(
|
|
85319
|
+
changedFiles.push(path95.resolve(directory, file3));
|
|
85247
85320
|
}
|
|
85248
85321
|
if (changedFiles.length === 0) {
|
|
85249
85322
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -85444,7 +85517,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
85444
85517
|
};
|
|
85445
85518
|
return JSON.stringify(errorResult, null, 2);
|
|
85446
85519
|
}
|
|
85447
|
-
const resolvedDirectory =
|
|
85520
|
+
const resolvedDirectory = path95.resolve(typedArgs.directory);
|
|
85448
85521
|
const workspaceAnchor = resolvedDirectory;
|
|
85449
85522
|
const dirError = validateDirectory2(resolvedDirectory, workspaceAnchor);
|
|
85450
85523
|
if (dirError) {
|
|
@@ -85485,7 +85558,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
85485
85558
|
});
|
|
85486
85559
|
// src/tools/repo-map.ts
|
|
85487
85560
|
init_zod();
|
|
85488
|
-
import * as
|
|
85561
|
+
import * as path96 from "node:path";
|
|
85489
85562
|
init_path_security();
|
|
85490
85563
|
init_create_tool();
|
|
85491
85564
|
var VALID_ACTIONS = [
|
|
@@ -85510,7 +85583,7 @@ function validateFile(p) {
|
|
|
85510
85583
|
return "file contains control characters";
|
|
85511
85584
|
if (containsPathTraversal(p))
|
|
85512
85585
|
return "file contains path traversal";
|
|
85513
|
-
if (
|
|
85586
|
+
if (path96.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
85514
85587
|
return "file must be a workspace-relative path, not absolute";
|
|
85515
85588
|
}
|
|
85516
85589
|
return null;
|
|
@@ -85533,8 +85606,8 @@ function ok(action, payload) {
|
|
|
85533
85606
|
}
|
|
85534
85607
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
85535
85608
|
const normalized = input.replace(/\\/g, "/");
|
|
85536
|
-
if (
|
|
85537
|
-
const rel =
|
|
85609
|
+
if (path96.isAbsolute(normalized)) {
|
|
85610
|
+
const rel = path96.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
85538
85611
|
return normalizeGraphPath2(rel);
|
|
85539
85612
|
}
|
|
85540
85613
|
return normalizeGraphPath2(normalized);
|
|
@@ -85679,7 +85752,7 @@ var repo_map = createSwarmTool({
|
|
|
85679
85752
|
init_zod();
|
|
85680
85753
|
init_create_tool();
|
|
85681
85754
|
import * as fs74 from "node:fs";
|
|
85682
|
-
import * as
|
|
85755
|
+
import * as path97 from "node:path";
|
|
85683
85756
|
var SPEC_FILE = ".swarm/spec.md";
|
|
85684
85757
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
85685
85758
|
var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -85748,10 +85821,10 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85748
85821
|
return [];
|
|
85749
85822
|
}
|
|
85750
85823
|
for (const entry of entries) {
|
|
85751
|
-
const entryPath =
|
|
85824
|
+
const entryPath = path97.join(evidenceDir, entry);
|
|
85752
85825
|
try {
|
|
85753
|
-
const
|
|
85754
|
-
if (!
|
|
85826
|
+
const stat7 = fs74.statSync(entryPath);
|
|
85827
|
+
if (!stat7.isDirectory()) {
|
|
85755
85828
|
continue;
|
|
85756
85829
|
}
|
|
85757
85830
|
} catch {
|
|
@@ -85764,18 +85837,18 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85764
85837
|
if (entryPhase !== String(phase)) {
|
|
85765
85838
|
continue;
|
|
85766
85839
|
}
|
|
85767
|
-
const evidenceFilePath =
|
|
85840
|
+
const evidenceFilePath = path97.join(entryPath, "evidence.json");
|
|
85768
85841
|
try {
|
|
85769
|
-
const resolvedPath =
|
|
85770
|
-
const evidenceDirResolved =
|
|
85771
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
85842
|
+
const resolvedPath = path97.resolve(evidenceFilePath);
|
|
85843
|
+
const evidenceDirResolved = path97.resolve(evidenceDir);
|
|
85844
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path97.sep)) {
|
|
85772
85845
|
continue;
|
|
85773
85846
|
}
|
|
85774
|
-
const
|
|
85775
|
-
if (!
|
|
85847
|
+
const stat7 = fs74.lstatSync(evidenceFilePath);
|
|
85848
|
+
if (!stat7.isFile()) {
|
|
85776
85849
|
continue;
|
|
85777
85850
|
}
|
|
85778
|
-
if (
|
|
85851
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES9) {
|
|
85779
85852
|
continue;
|
|
85780
85853
|
}
|
|
85781
85854
|
} catch {
|
|
@@ -85802,7 +85875,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85802
85875
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
85803
85876
|
for (const file3 of diffEntry.files_changed) {
|
|
85804
85877
|
if (typeof file3 === "string") {
|
|
85805
|
-
touchedFiles.add(
|
|
85878
|
+
touchedFiles.add(path97.resolve(cwd, file3));
|
|
85806
85879
|
}
|
|
85807
85880
|
}
|
|
85808
85881
|
}
|
|
@@ -85815,8 +85888,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85815
85888
|
}
|
|
85816
85889
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
85817
85890
|
try {
|
|
85818
|
-
const resolvedPath =
|
|
85819
|
-
const cwdResolved =
|
|
85891
|
+
const resolvedPath = path97.resolve(filePath);
|
|
85892
|
+
const cwdResolved = path97.resolve(cwd);
|
|
85820
85893
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
85821
85894
|
return false;
|
|
85822
85895
|
}
|
|
@@ -85950,7 +86023,7 @@ var req_coverage = createSwarmTool({
|
|
|
85950
86023
|
}, null, 2);
|
|
85951
86024
|
}
|
|
85952
86025
|
const cwd = inputDirectory || directory;
|
|
85953
|
-
const specPath =
|
|
86026
|
+
const specPath = path97.join(cwd, SPEC_FILE);
|
|
85954
86027
|
let specContent;
|
|
85955
86028
|
try {
|
|
85956
86029
|
specContent = fs74.readFileSync(specPath, "utf-8");
|
|
@@ -85977,7 +86050,7 @@ var req_coverage = createSwarmTool({
|
|
|
85977
86050
|
message: "No FR requirements found in spec.md"
|
|
85978
86051
|
}, null, 2);
|
|
85979
86052
|
}
|
|
85980
|
-
const evidenceDir =
|
|
86053
|
+
const evidenceDir = path97.join(cwd, EVIDENCE_DIR4);
|
|
85981
86054
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
85982
86055
|
const analyzedRequirements = [];
|
|
85983
86056
|
let coveredCount = 0;
|
|
@@ -86003,7 +86076,7 @@ var req_coverage = createSwarmTool({
|
|
|
86003
86076
|
requirements: analyzedRequirements
|
|
86004
86077
|
};
|
|
86005
86078
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
86006
|
-
const reportPath =
|
|
86079
|
+
const reportPath = path97.join(evidenceDir, reportFilename);
|
|
86007
86080
|
try {
|
|
86008
86081
|
if (!fs74.existsSync(evidenceDir)) {
|
|
86009
86082
|
fs74.mkdirSync(evidenceDir, { recursive: true });
|
|
@@ -86091,7 +86164,7 @@ init_qa_gate_profile();
|
|
|
86091
86164
|
init_file_locks();
|
|
86092
86165
|
import * as crypto9 from "node:crypto";
|
|
86093
86166
|
import * as fs75 from "node:fs";
|
|
86094
|
-
import * as
|
|
86167
|
+
import * as path98 from "node:path";
|
|
86095
86168
|
init_ledger();
|
|
86096
86169
|
init_manager();
|
|
86097
86170
|
init_state();
|
|
@@ -86169,8 +86242,8 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86169
86242
|
};
|
|
86170
86243
|
}
|
|
86171
86244
|
if (args2.working_directory && fallbackDir) {
|
|
86172
|
-
const resolvedTarget =
|
|
86173
|
-
const resolvedRoot =
|
|
86245
|
+
const resolvedTarget = path98.resolve(args2.working_directory);
|
|
86246
|
+
const resolvedRoot = path98.resolve(fallbackDir);
|
|
86174
86247
|
let fallbackExists = false;
|
|
86175
86248
|
try {
|
|
86176
86249
|
fs75.accessSync(resolvedRoot, fs75.constants.F_OK);
|
|
@@ -86179,7 +86252,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86179
86252
|
fallbackExists = false;
|
|
86180
86253
|
}
|
|
86181
86254
|
if (fallbackExists) {
|
|
86182
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
86255
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path98.sep);
|
|
86183
86256
|
if (isSubdirectory) {
|
|
86184
86257
|
return {
|
|
86185
86258
|
success: false,
|
|
@@ -86195,10 +86268,10 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86195
86268
|
let specMtime;
|
|
86196
86269
|
let specHash;
|
|
86197
86270
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
86198
|
-
const specPath =
|
|
86271
|
+
const specPath = path98.join(targetWorkspace, ".swarm", "spec.md");
|
|
86199
86272
|
try {
|
|
86200
|
-
const
|
|
86201
|
-
specMtime =
|
|
86273
|
+
const stat7 = await fs75.promises.stat(specPath);
|
|
86274
|
+
specMtime = stat7.mtime.toISOString();
|
|
86202
86275
|
const content = await fs75.promises.readFile(specPath, "utf8");
|
|
86203
86276
|
specHash = crypto9.createHash("sha256").update(content).digest("hex");
|
|
86204
86277
|
} catch {
|
|
@@ -86211,7 +86284,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86211
86284
|
}
|
|
86212
86285
|
}
|
|
86213
86286
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
86214
|
-
const contextPath =
|
|
86287
|
+
const contextPath = path98.join(targetWorkspace, ".swarm", "context.md");
|
|
86215
86288
|
let contextContent = "";
|
|
86216
86289
|
try {
|
|
86217
86290
|
contextContent = await fs75.promises.readFile(contextPath, "utf8");
|
|
@@ -86361,7 +86434,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86361
86434
|
}
|
|
86362
86435
|
await writeCheckpoint(dir).catch(() => {});
|
|
86363
86436
|
try {
|
|
86364
|
-
const markerPath =
|
|
86437
|
+
const markerPath = path98.join(dir, ".swarm", ".plan-write-marker");
|
|
86365
86438
|
const marker = JSON.stringify({
|
|
86366
86439
|
source: "save_plan",
|
|
86367
86440
|
timestamp: new Date().toISOString(),
|
|
@@ -86384,7 +86457,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86384
86457
|
return {
|
|
86385
86458
|
success: true,
|
|
86386
86459
|
message: "Plan saved successfully",
|
|
86387
|
-
plan_path:
|
|
86460
|
+
plan_path: path98.join(dir, ".swarm", "plan.json"),
|
|
86388
86461
|
phases_count: plan.phases.length,
|
|
86389
86462
|
tasks_count: tasksCount,
|
|
86390
86463
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -86437,7 +86510,7 @@ var save_plan = createSwarmTool({
|
|
|
86437
86510
|
init_zod();
|
|
86438
86511
|
init_manager2();
|
|
86439
86512
|
import * as fs76 from "node:fs";
|
|
86440
|
-
import * as
|
|
86513
|
+
import * as path99 from "node:path";
|
|
86441
86514
|
|
|
86442
86515
|
// src/sbom/detectors/index.ts
|
|
86443
86516
|
init_utils();
|
|
@@ -87287,7 +87360,7 @@ function findManifestFiles(rootDir) {
|
|
|
87287
87360
|
try {
|
|
87288
87361
|
const entries = fs76.readdirSync(dir, { withFileTypes: true });
|
|
87289
87362
|
for (const entry of entries) {
|
|
87290
|
-
const fullPath =
|
|
87363
|
+
const fullPath = path99.join(dir, entry.name);
|
|
87291
87364
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
87292
87365
|
continue;
|
|
87293
87366
|
}
|
|
@@ -87296,7 +87369,7 @@ function findManifestFiles(rootDir) {
|
|
|
87296
87369
|
} else if (entry.isFile()) {
|
|
87297
87370
|
for (const pattern of patterns) {
|
|
87298
87371
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
87299
|
-
manifestFiles.push(
|
|
87372
|
+
manifestFiles.push(path99.relative(rootDir, fullPath));
|
|
87300
87373
|
break;
|
|
87301
87374
|
}
|
|
87302
87375
|
}
|
|
@@ -87314,11 +87387,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
87314
87387
|
try {
|
|
87315
87388
|
const entries = fs76.readdirSync(dir, { withFileTypes: true });
|
|
87316
87389
|
for (const entry of entries) {
|
|
87317
|
-
const fullPath =
|
|
87390
|
+
const fullPath = path99.join(dir, entry.name);
|
|
87318
87391
|
if (entry.isFile()) {
|
|
87319
87392
|
for (const pattern of patterns) {
|
|
87320
87393
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
87321
|
-
found.push(
|
|
87394
|
+
found.push(path99.relative(workingDir, fullPath));
|
|
87322
87395
|
break;
|
|
87323
87396
|
}
|
|
87324
87397
|
}
|
|
@@ -87331,11 +87404,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
87331
87404
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
87332
87405
|
const dirs = new Set;
|
|
87333
87406
|
for (const file3 of changedFiles) {
|
|
87334
|
-
let currentDir =
|
|
87407
|
+
let currentDir = path99.dirname(file3);
|
|
87335
87408
|
while (true) {
|
|
87336
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
87337
|
-
dirs.add(
|
|
87338
|
-
const parent =
|
|
87409
|
+
if (currentDir && currentDir !== "." && currentDir !== path99.sep) {
|
|
87410
|
+
dirs.add(path99.join(workingDir, currentDir));
|
|
87411
|
+
const parent = path99.dirname(currentDir);
|
|
87339
87412
|
if (parent === currentDir)
|
|
87340
87413
|
break;
|
|
87341
87414
|
currentDir = parent;
|
|
@@ -87419,7 +87492,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87419
87492
|
const changedFiles = obj.changed_files;
|
|
87420
87493
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
87421
87494
|
const workingDir = directory;
|
|
87422
|
-
const outputDir =
|
|
87495
|
+
const outputDir = path99.isAbsolute(relativeOutputDir) ? relativeOutputDir : path99.join(workingDir, relativeOutputDir);
|
|
87423
87496
|
let manifestFiles = [];
|
|
87424
87497
|
if (scope === "all") {
|
|
87425
87498
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -87442,7 +87515,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87442
87515
|
const processedFiles = [];
|
|
87443
87516
|
for (const manifestFile of manifestFiles) {
|
|
87444
87517
|
try {
|
|
87445
|
-
const fullPath =
|
|
87518
|
+
const fullPath = path99.isAbsolute(manifestFile) ? manifestFile : path99.join(workingDir, manifestFile);
|
|
87446
87519
|
if (!fs76.existsSync(fullPath)) {
|
|
87447
87520
|
continue;
|
|
87448
87521
|
}
|
|
@@ -87459,7 +87532,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87459
87532
|
const bom = generateCycloneDX(allComponents);
|
|
87460
87533
|
const bomJson = serializeCycloneDX(bom);
|
|
87461
87534
|
const filename = generateSbomFilename();
|
|
87462
|
-
const outputPath =
|
|
87535
|
+
const outputPath = path99.join(outputDir, filename);
|
|
87463
87536
|
fs76.writeFileSync(outputPath, bomJson, "utf-8");
|
|
87464
87537
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
87465
87538
|
try {
|
|
@@ -87503,7 +87576,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87503
87576
|
init_zod();
|
|
87504
87577
|
init_create_tool();
|
|
87505
87578
|
import * as fs77 from "node:fs";
|
|
87506
|
-
import * as
|
|
87579
|
+
import * as path100 from "node:path";
|
|
87507
87580
|
var SPEC_CANDIDATES = [
|
|
87508
87581
|
"openapi.json",
|
|
87509
87582
|
"openapi.yaml",
|
|
@@ -87535,12 +87608,12 @@ function normalizePath3(p) {
|
|
|
87535
87608
|
}
|
|
87536
87609
|
function discoverSpecFile(cwd, specFileArg) {
|
|
87537
87610
|
if (specFileArg) {
|
|
87538
|
-
const resolvedPath =
|
|
87539
|
-
const normalizedCwd = cwd.endsWith(
|
|
87611
|
+
const resolvedPath = path100.resolve(cwd, specFileArg);
|
|
87612
|
+
const normalizedCwd = cwd.endsWith(path100.sep) ? cwd : cwd + path100.sep;
|
|
87540
87613
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
87541
87614
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
87542
87615
|
}
|
|
87543
|
-
const ext =
|
|
87616
|
+
const ext = path100.extname(resolvedPath).toLowerCase();
|
|
87544
87617
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
87545
87618
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
87546
87619
|
}
|
|
@@ -87554,7 +87627,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
87554
87627
|
return resolvedPath;
|
|
87555
87628
|
}
|
|
87556
87629
|
for (const candidate of SPEC_CANDIDATES) {
|
|
87557
|
-
const candidatePath =
|
|
87630
|
+
const candidatePath = path100.resolve(cwd, candidate);
|
|
87558
87631
|
if (fs77.existsSync(candidatePath)) {
|
|
87559
87632
|
const stats = fs77.statSync(candidatePath);
|
|
87560
87633
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -87566,7 +87639,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
87566
87639
|
}
|
|
87567
87640
|
function parseSpec(specFile) {
|
|
87568
87641
|
const content = fs77.readFileSync(specFile, "utf-8");
|
|
87569
|
-
const ext =
|
|
87642
|
+
const ext = path100.extname(specFile).toLowerCase();
|
|
87570
87643
|
if (ext === ".json") {
|
|
87571
87644
|
return parseJsonSpec(content);
|
|
87572
87645
|
}
|
|
@@ -87642,7 +87715,7 @@ function extractRoutes(cwd) {
|
|
|
87642
87715
|
return;
|
|
87643
87716
|
}
|
|
87644
87717
|
for (const entry of entries) {
|
|
87645
|
-
const fullPath =
|
|
87718
|
+
const fullPath = path100.join(dir, entry.name);
|
|
87646
87719
|
if (entry.isSymbolicLink()) {
|
|
87647
87720
|
continue;
|
|
87648
87721
|
}
|
|
@@ -87652,7 +87725,7 @@ function extractRoutes(cwd) {
|
|
|
87652
87725
|
}
|
|
87653
87726
|
walkDir(fullPath);
|
|
87654
87727
|
} else if (entry.isFile()) {
|
|
87655
|
-
const ext =
|
|
87728
|
+
const ext = path100.extname(entry.name).toLowerCase();
|
|
87656
87729
|
const baseName = entry.name.toLowerCase();
|
|
87657
87730
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
87658
87731
|
continue;
|
|
@@ -87820,7 +87893,7 @@ init_bun_compat();
|
|
|
87820
87893
|
init_path_security();
|
|
87821
87894
|
init_create_tool();
|
|
87822
87895
|
import * as fs78 from "node:fs";
|
|
87823
|
-
import * as
|
|
87896
|
+
import * as path101 from "node:path";
|
|
87824
87897
|
var DEFAULT_MAX_RESULTS = 100;
|
|
87825
87898
|
var DEFAULT_MAX_LINES = 200;
|
|
87826
87899
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -87856,11 +87929,11 @@ function containsWindowsAttacks3(str) {
|
|
|
87856
87929
|
}
|
|
87857
87930
|
function isPathInWorkspace3(filePath, workspace) {
|
|
87858
87931
|
try {
|
|
87859
|
-
const resolvedPath =
|
|
87932
|
+
const resolvedPath = path101.resolve(workspace, filePath);
|
|
87860
87933
|
const realWorkspace = fs78.realpathSync(workspace);
|
|
87861
87934
|
const realResolvedPath = fs78.realpathSync(resolvedPath);
|
|
87862
|
-
const relativePath =
|
|
87863
|
-
if (relativePath.startsWith("..") ||
|
|
87935
|
+
const relativePath = path101.relative(realWorkspace, realResolvedPath);
|
|
87936
|
+
if (relativePath.startsWith("..") || path101.isAbsolute(relativePath)) {
|
|
87864
87937
|
return false;
|
|
87865
87938
|
}
|
|
87866
87939
|
return true;
|
|
@@ -87873,11 +87946,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
87873
87946
|
}
|
|
87874
87947
|
function findRgInEnvPath() {
|
|
87875
87948
|
const searchPath = process.env.PATH ?? "";
|
|
87876
|
-
for (const dir of searchPath.split(
|
|
87949
|
+
for (const dir of searchPath.split(path101.delimiter)) {
|
|
87877
87950
|
if (!dir)
|
|
87878
87951
|
continue;
|
|
87879
87952
|
const isWindows = process.platform === "win32";
|
|
87880
|
-
const candidate =
|
|
87953
|
+
const candidate = path101.join(dir, isWindows ? "rg.exe" : "rg");
|
|
87881
87954
|
if (fs78.existsSync(candidate))
|
|
87882
87955
|
return candidate;
|
|
87883
87956
|
}
|
|
@@ -87932,7 +88005,7 @@ async function ripgrepSearch(opts) {
|
|
|
87932
88005
|
stderr: "pipe",
|
|
87933
88006
|
cwd: opts.workspace
|
|
87934
88007
|
});
|
|
87935
|
-
const timeout = new Promise((
|
|
88008
|
+
const timeout = new Promise((resolve40) => setTimeout(() => resolve40("timeout"), REGEX_TIMEOUT_MS));
|
|
87936
88009
|
const exitPromise = proc.exited;
|
|
87937
88010
|
const result = await Promise.race([exitPromise, timeout]);
|
|
87938
88011
|
if (result === "timeout") {
|
|
@@ -88007,8 +88080,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
88007
88080
|
try {
|
|
88008
88081
|
const entries = fs78.readdirSync(dir, { withFileTypes: true });
|
|
88009
88082
|
for (const entry of entries) {
|
|
88010
|
-
const fullPath =
|
|
88011
|
-
const relativePath =
|
|
88083
|
+
const fullPath = path101.join(dir, entry.name);
|
|
88084
|
+
const relativePath = path101.relative(workspace, fullPath);
|
|
88012
88085
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
88013
88086
|
continue;
|
|
88014
88087
|
}
|
|
@@ -88049,7 +88122,7 @@ async function fallbackSearch(opts) {
|
|
|
88049
88122
|
const matches = [];
|
|
88050
88123
|
let total = 0;
|
|
88051
88124
|
for (const file3 of files) {
|
|
88052
|
-
const fullPath =
|
|
88125
|
+
const fullPath = path101.join(opts.workspace, file3);
|
|
88053
88126
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
88054
88127
|
continue;
|
|
88055
88128
|
}
|
|
@@ -88430,7 +88503,7 @@ init_zod();
|
|
|
88430
88503
|
init_path_security();
|
|
88431
88504
|
init_create_tool();
|
|
88432
88505
|
import * as fs79 from "node:fs";
|
|
88433
|
-
import * as
|
|
88506
|
+
import * as path102 from "node:path";
|
|
88434
88507
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
88435
88508
|
function containsWindowsAttacks4(str) {
|
|
88436
88509
|
if (/:[^\\/]/.test(str))
|
|
@@ -88444,14 +88517,14 @@ function containsWindowsAttacks4(str) {
|
|
|
88444
88517
|
}
|
|
88445
88518
|
function isPathInWorkspace4(filePath, workspace) {
|
|
88446
88519
|
try {
|
|
88447
|
-
const resolvedPath =
|
|
88520
|
+
const resolvedPath = path102.resolve(workspace, filePath);
|
|
88448
88521
|
if (!fs79.existsSync(resolvedPath)) {
|
|
88449
88522
|
return true;
|
|
88450
88523
|
}
|
|
88451
88524
|
const realWorkspace = fs79.realpathSync(workspace);
|
|
88452
88525
|
const realResolvedPath = fs79.realpathSync(resolvedPath);
|
|
88453
|
-
const relativePath =
|
|
88454
|
-
if (relativePath.startsWith("..") ||
|
|
88526
|
+
const relativePath = path102.relative(realWorkspace, realResolvedPath);
|
|
88527
|
+
if (relativePath.startsWith("..") || path102.isAbsolute(relativePath)) {
|
|
88455
88528
|
return false;
|
|
88456
88529
|
}
|
|
88457
88530
|
return true;
|
|
@@ -88659,7 +88732,7 @@ var suggestPatch = createSwarmTool({
|
|
|
88659
88732
|
});
|
|
88660
88733
|
continue;
|
|
88661
88734
|
}
|
|
88662
|
-
const fullPath =
|
|
88735
|
+
const fullPath = path102.resolve(directory, change.file);
|
|
88663
88736
|
if (!fs79.existsSync(fullPath)) {
|
|
88664
88737
|
errors5.push({
|
|
88665
88738
|
success: false,
|
|
@@ -88922,7 +88995,7 @@ var generate_mutants = createSwarmTool({
|
|
|
88922
88995
|
init_spec_schema();
|
|
88923
88996
|
init_create_tool();
|
|
88924
88997
|
import * as fs80 from "node:fs";
|
|
88925
|
-
import * as
|
|
88998
|
+
import * as path103 from "node:path";
|
|
88926
88999
|
var SPEC_FILE_NAME = "spec.md";
|
|
88927
89000
|
var SWARM_DIR2 = ".swarm";
|
|
88928
89001
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -88975,7 +89048,7 @@ var lint_spec = createSwarmTool({
|
|
|
88975
89048
|
async execute(_args, directory) {
|
|
88976
89049
|
const errors5 = [];
|
|
88977
89050
|
const warnings = [];
|
|
88978
|
-
const specPath =
|
|
89051
|
+
const specPath = path103.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
88979
89052
|
if (!fs80.existsSync(specPath)) {
|
|
88980
89053
|
const result2 = {
|
|
88981
89054
|
valid: false,
|
|
@@ -89046,12 +89119,12 @@ var lint_spec = createSwarmTool({
|
|
|
89046
89119
|
// src/tools/mutation-test.ts
|
|
89047
89120
|
init_zod();
|
|
89048
89121
|
import * as fs81 from "node:fs";
|
|
89049
|
-
import * as
|
|
89122
|
+
import * as path105 from "node:path";
|
|
89050
89123
|
|
|
89051
89124
|
// src/mutation/engine.ts
|
|
89052
89125
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
89053
89126
|
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync20 } from "node:fs";
|
|
89054
|
-
import * as
|
|
89127
|
+
import * as path104 from "node:path";
|
|
89055
89128
|
|
|
89056
89129
|
// src/mutation/equivalence.ts
|
|
89057
89130
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -89186,7 +89259,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
89186
89259
|
let patchFile;
|
|
89187
89260
|
try {
|
|
89188
89261
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
89189
|
-
patchFile =
|
|
89262
|
+
patchFile = path104.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
89190
89263
|
try {
|
|
89191
89264
|
writeFileSync20(patchFile, patch.patch);
|
|
89192
89265
|
} catch (writeErr) {
|
|
@@ -89580,7 +89653,7 @@ var mutation_test = createSwarmTool({
|
|
|
89580
89653
|
];
|
|
89581
89654
|
for (const filePath of uniquePaths) {
|
|
89582
89655
|
try {
|
|
89583
|
-
const resolvedPath =
|
|
89656
|
+
const resolvedPath = path105.resolve(cwd, filePath);
|
|
89584
89657
|
sourceFiles.set(filePath, fs81.readFileSync(resolvedPath, "utf-8"));
|
|
89585
89658
|
} catch {}
|
|
89586
89659
|
}
|
|
@@ -89600,7 +89673,7 @@ init_zod();
|
|
|
89600
89673
|
init_manager2();
|
|
89601
89674
|
init_detector();
|
|
89602
89675
|
import * as fs82 from "node:fs";
|
|
89603
|
-
import * as
|
|
89676
|
+
import * as path106 from "node:path";
|
|
89604
89677
|
init_create_tool();
|
|
89605
89678
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
89606
89679
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -89666,7 +89739,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89666
89739
|
if (languages?.length) {
|
|
89667
89740
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
89668
89741
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
89669
|
-
const ext =
|
|
89742
|
+
const ext = path106.extname(file3.path).toLowerCase();
|
|
89670
89743
|
const langDef = getLanguageForExtension(ext);
|
|
89671
89744
|
const fileProfile = getProfileForFile(file3.path);
|
|
89672
89745
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -89679,7 +89752,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89679
89752
|
let skippedCount = 0;
|
|
89680
89753
|
for (const fileInfo of filesToCheck) {
|
|
89681
89754
|
const { path: filePath } = fileInfo;
|
|
89682
|
-
const fullPath =
|
|
89755
|
+
const fullPath = path106.isAbsolute(filePath) ? filePath : path106.join(directory, filePath);
|
|
89683
89756
|
const result = {
|
|
89684
89757
|
path: filePath,
|
|
89685
89758
|
language: "",
|
|
@@ -89728,7 +89801,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89728
89801
|
results.push(result);
|
|
89729
89802
|
continue;
|
|
89730
89803
|
}
|
|
89731
|
-
const ext =
|
|
89804
|
+
const ext = path106.extname(filePath).toLowerCase();
|
|
89732
89805
|
const langDef = getLanguageForExtension(ext);
|
|
89733
89806
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
89734
89807
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -89821,7 +89894,7 @@ init_utils();
|
|
|
89821
89894
|
init_create_tool();
|
|
89822
89895
|
init_path_security();
|
|
89823
89896
|
import * as fs83 from "node:fs";
|
|
89824
|
-
import * as
|
|
89897
|
+
import * as path107 from "node:path";
|
|
89825
89898
|
var MAX_TEXT_LENGTH = 200;
|
|
89826
89899
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
89827
89900
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -89887,9 +89960,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
89887
89960
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
89888
89961
|
}
|
|
89889
89962
|
try {
|
|
89890
|
-
const resolvedPath =
|
|
89891
|
-
const normalizedCwd =
|
|
89892
|
-
const normalizedResolved =
|
|
89963
|
+
const resolvedPath = path107.resolve(paths);
|
|
89964
|
+
const normalizedCwd = path107.resolve(cwd);
|
|
89965
|
+
const normalizedResolved = path107.resolve(resolvedPath);
|
|
89893
89966
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
89894
89967
|
return {
|
|
89895
89968
|
error: "paths must be within the current working directory",
|
|
@@ -89905,7 +89978,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
89905
89978
|
}
|
|
89906
89979
|
}
|
|
89907
89980
|
function isSupportedExtension(filePath) {
|
|
89908
|
-
const ext =
|
|
89981
|
+
const ext = path107.extname(filePath).toLowerCase();
|
|
89909
89982
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
89910
89983
|
}
|
|
89911
89984
|
function findSourceFiles3(dir, files = []) {
|
|
@@ -89920,16 +89993,16 @@ function findSourceFiles3(dir, files = []) {
|
|
|
89920
89993
|
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
89921
89994
|
continue;
|
|
89922
89995
|
}
|
|
89923
|
-
const fullPath =
|
|
89924
|
-
let
|
|
89996
|
+
const fullPath = path107.join(dir, entry);
|
|
89997
|
+
let stat7;
|
|
89925
89998
|
try {
|
|
89926
|
-
|
|
89999
|
+
stat7 = fs83.statSync(fullPath);
|
|
89927
90000
|
} catch {
|
|
89928
90001
|
continue;
|
|
89929
90002
|
}
|
|
89930
|
-
if (
|
|
90003
|
+
if (stat7.isDirectory()) {
|
|
89931
90004
|
findSourceFiles3(fullPath, files);
|
|
89932
|
-
} else if (
|
|
90005
|
+
} else if (stat7.isFile()) {
|
|
89933
90006
|
if (isSupportedExtension(fullPath)) {
|
|
89934
90007
|
files.push(fullPath);
|
|
89935
90008
|
}
|
|
@@ -90026,13 +90099,13 @@ var todo_extract = createSwarmTool({
|
|
|
90026
90099
|
return JSON.stringify(errorResult, null, 2);
|
|
90027
90100
|
}
|
|
90028
90101
|
const filesToScan = [];
|
|
90029
|
-
const
|
|
90030
|
-
if (
|
|
90102
|
+
const stat7 = fs83.statSync(scanPath);
|
|
90103
|
+
if (stat7.isFile()) {
|
|
90031
90104
|
if (isSupportedExtension(scanPath)) {
|
|
90032
90105
|
filesToScan.push(scanPath);
|
|
90033
90106
|
} else {
|
|
90034
90107
|
const errorResult = {
|
|
90035
|
-
error: `unsupported file extension: ${
|
|
90108
|
+
error: `unsupported file extension: ${path107.extname(scanPath)}`,
|
|
90036
90109
|
total: 0,
|
|
90037
90110
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
90038
90111
|
entries: []
|
|
@@ -90081,17 +90154,17 @@ init_schema();
|
|
|
90081
90154
|
init_qa_gate_profile();
|
|
90082
90155
|
init_gate_evidence();
|
|
90083
90156
|
import * as fs86 from "node:fs";
|
|
90084
|
-
import * as
|
|
90157
|
+
import * as path110 from "node:path";
|
|
90085
90158
|
|
|
90086
90159
|
// src/hooks/diff-scope.ts
|
|
90087
90160
|
init_bun_compat();
|
|
90088
90161
|
import * as fs85 from "node:fs";
|
|
90089
|
-
import * as
|
|
90162
|
+
import * as path109 from "node:path";
|
|
90090
90163
|
|
|
90091
90164
|
// src/utils/gitignore-warning.ts
|
|
90092
90165
|
init_bun_compat();
|
|
90093
90166
|
import * as fs84 from "node:fs";
|
|
90094
|
-
import * as
|
|
90167
|
+
import * as path108 from "node:path";
|
|
90095
90168
|
var _internals = { bunSpawn };
|
|
90096
90169
|
var _swarmGitExcludedChecked = false;
|
|
90097
90170
|
function fileCoversSwarm(content) {
|
|
@@ -90165,10 +90238,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
90165
90238
|
const excludeRelPath = excludePathRaw.trim();
|
|
90166
90239
|
if (!excludeRelPath)
|
|
90167
90240
|
return;
|
|
90168
|
-
const excludePath =
|
|
90241
|
+
const excludePath = path108.isAbsolute(excludeRelPath) ? excludeRelPath : path108.join(directory, excludeRelPath);
|
|
90169
90242
|
if (checkIgnoreExitCode !== 0) {
|
|
90170
90243
|
try {
|
|
90171
|
-
fs84.mkdirSync(
|
|
90244
|
+
fs84.mkdirSync(path108.dirname(excludePath), { recursive: true });
|
|
90172
90245
|
let existing = "";
|
|
90173
90246
|
try {
|
|
90174
90247
|
existing = fs84.readFileSync(excludePath, "utf8");
|
|
@@ -90212,7 +90285,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
90212
90285
|
var _internals2 = { bunSpawn };
|
|
90213
90286
|
function getDeclaredScope(taskId, directory) {
|
|
90214
90287
|
try {
|
|
90215
|
-
const planPath =
|
|
90288
|
+
const planPath = path109.join(directory, ".swarm", "plan.json");
|
|
90216
90289
|
if (!fs85.existsSync(planPath))
|
|
90217
90290
|
return null;
|
|
90218
90291
|
const raw = fs85.readFileSync(planPath, "utf-8");
|
|
@@ -90349,7 +90422,7 @@ var TIER_3_PATTERNS = [
|
|
|
90349
90422
|
];
|
|
90350
90423
|
function matchesTier3Pattern(files) {
|
|
90351
90424
|
for (const file3 of files) {
|
|
90352
|
-
const fileName =
|
|
90425
|
+
const fileName = path110.basename(file3);
|
|
90353
90426
|
for (const pattern of TIER_3_PATTERNS) {
|
|
90354
90427
|
if (pattern.test(fileName)) {
|
|
90355
90428
|
return true;
|
|
@@ -90363,7 +90436,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
90363
90436
|
if (hasActiveTurboMode()) {
|
|
90364
90437
|
const resolvedDir2 = workingDirectory;
|
|
90365
90438
|
try {
|
|
90366
|
-
const planPath =
|
|
90439
|
+
const planPath = path110.join(resolvedDir2, ".swarm", "plan.json");
|
|
90367
90440
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90368
90441
|
const plan = JSON.parse(planRaw);
|
|
90369
90442
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -90433,7 +90506,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
90433
90506
|
}
|
|
90434
90507
|
try {
|
|
90435
90508
|
const resolvedDir2 = workingDirectory;
|
|
90436
|
-
const planPath =
|
|
90509
|
+
const planPath = path110.join(resolvedDir2, ".swarm", "plan.json");
|
|
90437
90510
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90438
90511
|
const plan = JSON.parse(planRaw);
|
|
90439
90512
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -90623,8 +90696,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90623
90696
|
};
|
|
90624
90697
|
}
|
|
90625
90698
|
}
|
|
90626
|
-
normalizedDir =
|
|
90627
|
-
const pathParts = normalizedDir.split(
|
|
90699
|
+
normalizedDir = path110.normalize(args2.working_directory);
|
|
90700
|
+
const pathParts = normalizedDir.split(path110.sep);
|
|
90628
90701
|
if (pathParts.includes("..")) {
|
|
90629
90702
|
return {
|
|
90630
90703
|
success: false,
|
|
@@ -90634,10 +90707,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90634
90707
|
]
|
|
90635
90708
|
};
|
|
90636
90709
|
}
|
|
90637
|
-
const resolvedDir =
|
|
90710
|
+
const resolvedDir = path110.resolve(normalizedDir);
|
|
90638
90711
|
try {
|
|
90639
90712
|
const realPath = fs86.realpathSync(resolvedDir);
|
|
90640
|
-
const planPath =
|
|
90713
|
+
const planPath = path110.join(realPath, ".swarm", "plan.json");
|
|
90641
90714
|
if (!fs86.existsSync(planPath)) {
|
|
90642
90715
|
return {
|
|
90643
90716
|
success: false,
|
|
@@ -90669,8 +90742,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90669
90742
|
}
|
|
90670
90743
|
if (args2.status === "in_progress") {
|
|
90671
90744
|
try {
|
|
90672
|
-
const evidencePath =
|
|
90673
|
-
fs86.mkdirSync(
|
|
90745
|
+
const evidencePath = path110.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
90746
|
+
fs86.mkdirSync(path110.dirname(evidencePath), { recursive: true });
|
|
90674
90747
|
const fd = fs86.openSync(evidencePath, "wx");
|
|
90675
90748
|
let writeOk = false;
|
|
90676
90749
|
try {
|
|
@@ -90694,7 +90767,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90694
90767
|
recoverTaskStateFromDelegations(args2.task_id);
|
|
90695
90768
|
let phaseRequiresReviewer = true;
|
|
90696
90769
|
try {
|
|
90697
|
-
const planPath =
|
|
90770
|
+
const planPath = path110.join(directory, ".swarm", "plan.json");
|
|
90698
90771
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90699
90772
|
const plan = JSON.parse(planRaw);
|
|
90700
90773
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -91006,7 +91079,7 @@ init_ledger();
|
|
|
91006
91079
|
init_manager();
|
|
91007
91080
|
init_create_tool();
|
|
91008
91081
|
import fs87 from "node:fs";
|
|
91009
|
-
import
|
|
91082
|
+
import path111 from "node:path";
|
|
91010
91083
|
function derivePlanId5(plan) {
|
|
91011
91084
|
return `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
91012
91085
|
}
|
|
@@ -91057,7 +91130,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
91057
91130
|
entries: [evidenceEntry]
|
|
91058
91131
|
};
|
|
91059
91132
|
const filename = "drift-verifier.json";
|
|
91060
|
-
const relativePath =
|
|
91133
|
+
const relativePath = path111.join("evidence", String(phase), filename);
|
|
91061
91134
|
let validatedPath;
|
|
91062
91135
|
try {
|
|
91063
91136
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91068,10 +91141,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
91068
91141
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91069
91142
|
}, null, 2);
|
|
91070
91143
|
}
|
|
91071
|
-
const evidenceDir =
|
|
91144
|
+
const evidenceDir = path111.dirname(validatedPath);
|
|
91072
91145
|
try {
|
|
91073
91146
|
await fs87.promises.mkdir(evidenceDir, { recursive: true });
|
|
91074
|
-
const tempPath =
|
|
91147
|
+
const tempPath = path111.join(evidenceDir, `.${filename}.tmp`);
|
|
91075
91148
|
await fs87.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91076
91149
|
await fs87.promises.rename(tempPath, validatedPath);
|
|
91077
91150
|
let snapshotInfo;
|
|
@@ -91168,7 +91241,7 @@ init_zod();
|
|
|
91168
91241
|
init_utils2();
|
|
91169
91242
|
init_create_tool();
|
|
91170
91243
|
import fs88 from "node:fs";
|
|
91171
|
-
import
|
|
91244
|
+
import path112 from "node:path";
|
|
91172
91245
|
function normalizeVerdict2(verdict) {
|
|
91173
91246
|
switch (verdict) {
|
|
91174
91247
|
case "APPROVED":
|
|
@@ -91216,7 +91289,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
91216
91289
|
entries: [evidenceEntry]
|
|
91217
91290
|
};
|
|
91218
91291
|
const filename = "hallucination-guard.json";
|
|
91219
|
-
const relativePath =
|
|
91292
|
+
const relativePath = path112.join("evidence", String(phase), filename);
|
|
91220
91293
|
let validatedPath;
|
|
91221
91294
|
try {
|
|
91222
91295
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91227,10 +91300,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
91227
91300
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91228
91301
|
}, null, 2);
|
|
91229
91302
|
}
|
|
91230
|
-
const evidenceDir =
|
|
91303
|
+
const evidenceDir = path112.dirname(validatedPath);
|
|
91231
91304
|
try {
|
|
91232
91305
|
await fs88.promises.mkdir(evidenceDir, { recursive: true });
|
|
91233
|
-
const tempPath =
|
|
91306
|
+
const tempPath = path112.join(evidenceDir, `.${filename}.tmp`);
|
|
91234
91307
|
await fs88.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91235
91308
|
await fs88.promises.rename(tempPath, validatedPath);
|
|
91236
91309
|
return JSON.stringify({
|
|
@@ -91279,7 +91352,7 @@ init_zod();
|
|
|
91279
91352
|
init_utils2();
|
|
91280
91353
|
init_create_tool();
|
|
91281
91354
|
import fs89 from "node:fs";
|
|
91282
|
-
import
|
|
91355
|
+
import path113 from "node:path";
|
|
91283
91356
|
function normalizeVerdict3(verdict) {
|
|
91284
91357
|
switch (verdict) {
|
|
91285
91358
|
case "PASS":
|
|
@@ -91353,7 +91426,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
91353
91426
|
entries: [evidenceEntry]
|
|
91354
91427
|
};
|
|
91355
91428
|
const filename = "mutation-gate.json";
|
|
91356
|
-
const relativePath =
|
|
91429
|
+
const relativePath = path113.join("evidence", String(phase), filename);
|
|
91357
91430
|
let validatedPath;
|
|
91358
91431
|
try {
|
|
91359
91432
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91364,10 +91437,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
91364
91437
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91365
91438
|
}, null, 2);
|
|
91366
91439
|
}
|
|
91367
|
-
const evidenceDir =
|
|
91440
|
+
const evidenceDir = path113.dirname(validatedPath);
|
|
91368
91441
|
try {
|
|
91369
91442
|
await fs89.promises.mkdir(evidenceDir, { recursive: true });
|
|
91370
|
-
const tempPath =
|
|
91443
|
+
const tempPath = path113.join(evidenceDir, `.${filename}.tmp`);
|
|
91371
91444
|
await fs89.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91372
91445
|
await fs89.promises.rename(tempPath, validatedPath);
|
|
91373
91446
|
return JSON.stringify({
|
|
@@ -91661,7 +91734,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
91661
91734
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
91662
91735
|
preflightTriggerManager = new PTM(automationConfig);
|
|
91663
91736
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
91664
|
-
const swarmDir =
|
|
91737
|
+
const swarmDir = path114.resolve(ctx.directory, ".swarm");
|
|
91665
91738
|
statusArtifact = new ASA(swarmDir);
|
|
91666
91739
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
91667
91740
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|