opencode-swarm 7.4.3 → 7.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +1 -1
- package/dist/index.js +905 -841
- 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.0",
|
|
37
37
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
38
38
|
main: "dist/index.js",
|
|
39
39
|
types: "dist/index.d.ts",
|
|
@@ -62656,8 +62656,8 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62656
62656
|
var moduleRtn;
|
|
62657
62657
|
var Module = moduleArg;
|
|
62658
62658
|
var readyPromiseResolve, readyPromiseReject;
|
|
62659
|
-
var readyPromise = new Promise((
|
|
62660
|
-
readyPromiseResolve =
|
|
62659
|
+
var readyPromise = new Promise((resolve22, reject) => {
|
|
62660
|
+
readyPromiseResolve = resolve22;
|
|
62661
62661
|
readyPromiseReject = reject;
|
|
62662
62662
|
});
|
|
62663
62663
|
var ENVIRONMENT_IS_WEB = typeof window == "object";
|
|
@@ -62679,11 +62679,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62679
62679
|
throw toThrow;
|
|
62680
62680
|
}, "quit_");
|
|
62681
62681
|
var scriptDirectory = "";
|
|
62682
|
-
function locateFile(
|
|
62682
|
+
function locateFile(path65) {
|
|
62683
62683
|
if (Module["locateFile"]) {
|
|
62684
|
-
return Module["locateFile"](
|
|
62684
|
+
return Module["locateFile"](path65, scriptDirectory);
|
|
62685
62685
|
}
|
|
62686
|
-
return scriptDirectory +
|
|
62686
|
+
return scriptDirectory + path65;
|
|
62687
62687
|
}
|
|
62688
62688
|
__name(locateFile, "locateFile");
|
|
62689
62689
|
var readAsync, readBinary;
|
|
@@ -62737,13 +62737,13 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62737
62737
|
}
|
|
62738
62738
|
readAsync = /* @__PURE__ */ __name(async (url3) => {
|
|
62739
62739
|
if (isFileURI(url3)) {
|
|
62740
|
-
return new Promise((
|
|
62740
|
+
return new Promise((resolve22, reject) => {
|
|
62741
62741
|
var xhr = new XMLHttpRequest;
|
|
62742
62742
|
xhr.open("GET", url3, true);
|
|
62743
62743
|
xhr.responseType = "arraybuffer";
|
|
62744
62744
|
xhr.onload = () => {
|
|
62745
62745
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
62746
|
-
|
|
62746
|
+
resolve22(xhr.response);
|
|
62747
62747
|
return;
|
|
62748
62748
|
}
|
|
62749
62749
|
reject(xhr.status);
|
|
@@ -62963,10 +62963,10 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62963
62963
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
62964
62964
|
var info2 = getWasmImports();
|
|
62965
62965
|
if (Module["instantiateWasm"]) {
|
|
62966
|
-
return new Promise((
|
|
62966
|
+
return new Promise((resolve22, reject) => {
|
|
62967
62967
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
62968
62968
|
receiveInstance(mod, inst);
|
|
62969
|
-
|
|
62969
|
+
resolve22(mod.exports);
|
|
62970
62970
|
});
|
|
62971
62971
|
});
|
|
62972
62972
|
}
|
|
@@ -64432,13 +64432,13 @@ __export(exports_runtime, {
|
|
|
64432
64432
|
getInitializedLanguages: () => getInitializedLanguages,
|
|
64433
64433
|
clearParserCache: () => clearParserCache
|
|
64434
64434
|
});
|
|
64435
|
-
import * as
|
|
64435
|
+
import * as path65 from "node:path";
|
|
64436
64436
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
64437
64437
|
async function initTreeSitter() {
|
|
64438
64438
|
if (treeSitterInitialized) {
|
|
64439
64439
|
return;
|
|
64440
64440
|
}
|
|
64441
|
-
const thisDir =
|
|
64441
|
+
const thisDir = path65.dirname(fileURLToPath2(import.meta.url));
|
|
64442
64442
|
const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
|
|
64443
64443
|
if (isSource) {
|
|
64444
64444
|
await Parser.init();
|
|
@@ -64446,7 +64446,7 @@ async function initTreeSitter() {
|
|
|
64446
64446
|
const grammarsDir = getGrammarsDirAbsolute();
|
|
64447
64447
|
await Parser.init({
|
|
64448
64448
|
locateFile(scriptName) {
|
|
64449
|
-
return
|
|
64449
|
+
return path65.join(grammarsDir, scriptName);
|
|
64450
64450
|
}
|
|
64451
64451
|
});
|
|
64452
64452
|
}
|
|
@@ -64467,11 +64467,11 @@ function getWasmFileName(languageId) {
|
|
|
64467
64467
|
return `tree-sitter-${sanitized}.wasm`;
|
|
64468
64468
|
}
|
|
64469
64469
|
function getGrammarsDirAbsolute() {
|
|
64470
|
-
const thisDir =
|
|
64470
|
+
const thisDir = path65.dirname(fileURLToPath2(import.meta.url));
|
|
64471
64471
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
64472
64472
|
const isSource = normalized.endsWith("/src/lang");
|
|
64473
64473
|
const isCliBundle = normalized.endsWith("/cli");
|
|
64474
|
-
return isSource ?
|
|
64474
|
+
return isSource ? path65.join(thisDir, "grammars") : isCliBundle ? path65.join(thisDir, "..", "lang", "grammars") : path65.join(thisDir, "lang", "grammars");
|
|
64475
64475
|
}
|
|
64476
64476
|
async function loadGrammar(languageId) {
|
|
64477
64477
|
if (typeof languageId !== "string" || languageId.length > 100) {
|
|
@@ -64487,9 +64487,9 @@ async function loadGrammar(languageId) {
|
|
|
64487
64487
|
await initTreeSitter();
|
|
64488
64488
|
const parser = new Parser;
|
|
64489
64489
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
64490
|
-
const wasmPath =
|
|
64491
|
-
const { existsSync:
|
|
64492
|
-
if (!
|
|
64490
|
+
const wasmPath = path65.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
64491
|
+
const { existsSync: existsSync33 } = await import("node:fs");
|
|
64492
|
+
if (!existsSync33(wasmPath)) {
|
|
64493
64493
|
throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
|
|
64494
64494
|
Make sure to run 'bun run build' to copy grammar files to dist/lang/grammars/`);
|
|
64495
64495
|
}
|
|
@@ -64522,7 +64522,7 @@ async function isGrammarAvailable(languageId) {
|
|
|
64522
64522
|
}
|
|
64523
64523
|
try {
|
|
64524
64524
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
64525
|
-
const wasmPath =
|
|
64525
|
+
const wasmPath = path65.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
64526
64526
|
const { statSync: statSync19 } = await import("node:fs");
|
|
64527
64527
|
statSync19(wasmPath);
|
|
64528
64528
|
return true;
|
|
@@ -64581,13 +64581,13 @@ __export(exports_doc_scan, {
|
|
|
64581
64581
|
import * as crypto7 from "node:crypto";
|
|
64582
64582
|
import * as fs45 from "node:fs";
|
|
64583
64583
|
import { mkdir as mkdir10, readFile as readFile10, writeFile as writeFile9 } from "node:fs/promises";
|
|
64584
|
-
import * as
|
|
64584
|
+
import * as path67 from "node:path";
|
|
64585
64585
|
function normalizeSeparators(filePath) {
|
|
64586
64586
|
return filePath.replace(/\\/g, "/");
|
|
64587
64587
|
}
|
|
64588
64588
|
function matchesDocPattern(filePath, patterns) {
|
|
64589
64589
|
const normalizedPath = normalizeSeparators(filePath);
|
|
64590
|
-
const basename9 =
|
|
64590
|
+
const basename9 = path67.basename(filePath);
|
|
64591
64591
|
for (const pattern of patterns) {
|
|
64592
64592
|
if (!pattern.includes("/") && !pattern.includes("\\")) {
|
|
64593
64593
|
if (basename9 === pattern) {
|
|
@@ -64643,7 +64643,7 @@ function stripMarkdown(text) {
|
|
|
64643
64643
|
return text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s*[-*•]\s+/gm, "").replace(/^\s*\d+\.\s+/gm, "").trim();
|
|
64644
64644
|
}
|
|
64645
64645
|
async function scanDocIndex(directory) {
|
|
64646
|
-
const manifestPath =
|
|
64646
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64647
64647
|
const defaultPatterns = DocsConfigSchema.parse({}).doc_patterns;
|
|
64648
64648
|
const extraPatterns = [
|
|
64649
64649
|
"ARCHITECTURE.md",
|
|
@@ -64660,9 +64660,9 @@ async function scanDocIndex(directory) {
|
|
|
64660
64660
|
let cacheValid = true;
|
|
64661
64661
|
for (const file3 of existingManifest.files) {
|
|
64662
64662
|
try {
|
|
64663
|
-
const fullPath =
|
|
64664
|
-
const
|
|
64665
|
-
if (
|
|
64663
|
+
const fullPath = path67.join(directory, file3.path);
|
|
64664
|
+
const stat6 = fs45.statSync(fullPath);
|
|
64665
|
+
if (stat6.mtimeMs > file3.mtime) {
|
|
64666
64666
|
cacheValid = false;
|
|
64667
64667
|
break;
|
|
64668
64668
|
}
|
|
@@ -64690,14 +64690,14 @@ async function scanDocIndex(directory) {
|
|
|
64690
64690
|
}
|
|
64691
64691
|
const entries = rawEntries.filter((e) => typeof e === "string");
|
|
64692
64692
|
for (const entry of entries) {
|
|
64693
|
-
const fullPath =
|
|
64694
|
-
let
|
|
64693
|
+
const fullPath = path67.join(directory, entry);
|
|
64694
|
+
let stat6;
|
|
64695
64695
|
try {
|
|
64696
|
-
|
|
64696
|
+
stat6 = fs45.statSync(fullPath);
|
|
64697
64697
|
} catch {
|
|
64698
64698
|
continue;
|
|
64699
64699
|
}
|
|
64700
|
-
if (!
|
|
64700
|
+
if (!stat6.isFile())
|
|
64701
64701
|
continue;
|
|
64702
64702
|
const pathParts = normalizeSeparators(entry).split("/");
|
|
64703
64703
|
let skipThisFile = false;
|
|
@@ -64726,7 +64726,7 @@ async function scanDocIndex(directory) {
|
|
|
64726
64726
|
} catch {
|
|
64727
64727
|
continue;
|
|
64728
64728
|
}
|
|
64729
|
-
const { title, summary } = extractTitleAndSummary(content,
|
|
64729
|
+
const { title, summary } = extractTitleAndSummary(content, path67.basename(entry));
|
|
64730
64730
|
const lineCount = content.split(`
|
|
64731
64731
|
`).length;
|
|
64732
64732
|
discoveredFiles.push({
|
|
@@ -64734,7 +64734,7 @@ async function scanDocIndex(directory) {
|
|
|
64734
64734
|
title,
|
|
64735
64735
|
summary,
|
|
64736
64736
|
lines: lineCount,
|
|
64737
|
-
mtime:
|
|
64737
|
+
mtime: stat6.mtimeMs
|
|
64738
64738
|
});
|
|
64739
64739
|
}
|
|
64740
64740
|
discoveredFiles.sort((a, b) => a.path.toLowerCase().localeCompare(b.path.toLowerCase()));
|
|
@@ -64752,7 +64752,7 @@ async function scanDocIndex(directory) {
|
|
|
64752
64752
|
files: discoveredFiles
|
|
64753
64753
|
};
|
|
64754
64754
|
try {
|
|
64755
|
-
await mkdir10(
|
|
64755
|
+
await mkdir10(path67.dirname(manifestPath), { recursive: true });
|
|
64756
64756
|
await writeFile9(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
64757
64757
|
} catch {}
|
|
64758
64758
|
return { manifest, cached: false };
|
|
@@ -64791,7 +64791,7 @@ function extractConstraintsFromContent(content) {
|
|
|
64791
64791
|
return constraints;
|
|
64792
64792
|
}
|
|
64793
64793
|
async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
64794
|
-
const manifestPath =
|
|
64794
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64795
64795
|
let manifest;
|
|
64796
64796
|
try {
|
|
64797
64797
|
const content = await readFile10(manifestPath, "utf-8");
|
|
@@ -64817,7 +64817,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64817
64817
|
}
|
|
64818
64818
|
let fullContent;
|
|
64819
64819
|
try {
|
|
64820
|
-
fullContent = await readFile10(
|
|
64820
|
+
fullContent = await readFile10(path67.join(directory, docFile.path), "utf-8");
|
|
64821
64821
|
} catch {
|
|
64822
64822
|
skippedCount++;
|
|
64823
64823
|
continue;
|
|
@@ -64840,7 +64840,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64840
64840
|
tier: "swarm",
|
|
64841
64841
|
lesson: constraint,
|
|
64842
64842
|
category: "architecture",
|
|
64843
|
-
tags: ["doc-scan",
|
|
64843
|
+
tags: ["doc-scan", path67.basename(docFile.path)],
|
|
64844
64844
|
scope: "global",
|
|
64845
64845
|
confidence: 0.5,
|
|
64846
64846
|
status: "candidate",
|
|
@@ -64913,7 +64913,7 @@ var init_doc_scan = __esm(() => {
|
|
|
64913
64913
|
}
|
|
64914
64914
|
} catch {}
|
|
64915
64915
|
if (force) {
|
|
64916
|
-
const manifestPath =
|
|
64916
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64917
64917
|
try {
|
|
64918
64918
|
fs45.unlinkSync(manifestPath);
|
|
64919
64919
|
} catch {}
|
|
@@ -65104,9 +65104,9 @@ __export(exports_curator_drift, {
|
|
|
65104
65104
|
buildDriftInjectionText: () => buildDriftInjectionText
|
|
65105
65105
|
});
|
|
65106
65106
|
import * as fs48 from "node:fs";
|
|
65107
|
-
import * as
|
|
65107
|
+
import * as path70 from "node:path";
|
|
65108
65108
|
async function readPriorDriftReports(directory) {
|
|
65109
|
-
const swarmDir =
|
|
65109
|
+
const swarmDir = path70.join(directory, ".swarm");
|
|
65110
65110
|
const entries = await fs48.promises.readdir(swarmDir).catch(() => null);
|
|
65111
65111
|
if (entries === null)
|
|
65112
65112
|
return [];
|
|
@@ -65133,7 +65133,7 @@ async function readPriorDriftReports(directory) {
|
|
|
65133
65133
|
async function writeDriftReport(directory, report) {
|
|
65134
65134
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
65135
65135
|
const filePath = validateSwarmPath(directory, filename);
|
|
65136
|
-
const swarmDir =
|
|
65136
|
+
const swarmDir = path70.dirname(filePath);
|
|
65137
65137
|
await fs48.promises.mkdir(swarmDir, { recursive: true });
|
|
65138
65138
|
try {
|
|
65139
65139
|
await fs48.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
@@ -65267,7 +65267,7 @@ var init_curator_drift = __esm(() => {
|
|
|
65267
65267
|
// src/index.ts
|
|
65268
65268
|
init_package();
|
|
65269
65269
|
init_agents2();
|
|
65270
|
-
import * as
|
|
65270
|
+
import * as path114 from "node:path";
|
|
65271
65271
|
|
|
65272
65272
|
// src/background/index.ts
|
|
65273
65273
|
init_event_bus();
|
|
@@ -67400,16 +67400,16 @@ ${originalText}`;
|
|
|
67400
67400
|
}
|
|
67401
67401
|
// src/hooks/repo-graph-builder.ts
|
|
67402
67402
|
init_constants();
|
|
67403
|
-
import
|
|
67403
|
+
import { realpathSync as realpathSync8 } from "node:fs";
|
|
67404
|
+
import * as path58 from "node:path";
|
|
67404
67405
|
|
|
67405
|
-
// src/tools/repo-graph.ts
|
|
67406
|
-
init_utils2();
|
|
67406
|
+
// src/tools/repo-graph/builder.ts
|
|
67407
67407
|
init_path_security();
|
|
67408
67408
|
import * as fsSync3 from "node:fs";
|
|
67409
|
-
import {
|
|
67409
|
+
import { existsSync as existsSync29, realpathSync as realpathSync6 } from "node:fs";
|
|
67410
67410
|
import * as fsPromises5 from "node:fs/promises";
|
|
67411
67411
|
import * as os7 from "node:os";
|
|
67412
|
-
import * as
|
|
67412
|
+
import * as path54 from "node:path";
|
|
67413
67413
|
|
|
67414
67414
|
// src/utils/timeout.ts
|
|
67415
67415
|
async function withTimeout(promise3, ms, timeoutError) {
|
|
@@ -67769,17 +67769,38 @@ var symbols = createSwarmTool({
|
|
|
67769
67769
|
}
|
|
67770
67770
|
});
|
|
67771
67771
|
|
|
67772
|
-
// src/tools/repo-graph.ts
|
|
67773
|
-
|
|
67774
|
-
var
|
|
67772
|
+
// src/tools/repo-graph/types.ts
|
|
67773
|
+
import * as path53 from "node:path";
|
|
67774
|
+
var REPO_GRAPH_FILENAME = "repo-graph.json";
|
|
67775
|
+
var GRAPH_SCHEMA_VERSION = "1.0.0";
|
|
67775
67776
|
function normalizeGraphPath(filePath) {
|
|
67776
67777
|
return path53.normalize(filePath).replace(/\\/g, "/");
|
|
67777
67778
|
}
|
|
67778
|
-
|
|
67779
|
-
|
|
67780
|
-
|
|
67781
|
-
|
|
67782
|
-
|
|
67779
|
+
function createEmptyGraph(workspaceRoot) {
|
|
67780
|
+
return {
|
|
67781
|
+
schema_version: GRAPH_SCHEMA_VERSION,
|
|
67782
|
+
workspaceRoot: path53.normalize(workspaceRoot),
|
|
67783
|
+
nodes: {},
|
|
67784
|
+
edges: [],
|
|
67785
|
+
metadata: {
|
|
67786
|
+
generatedAt: new Date().toISOString(),
|
|
67787
|
+
generator: "repo-graph",
|
|
67788
|
+
nodeCount: 0,
|
|
67789
|
+
edgeCount: 0
|
|
67790
|
+
}
|
|
67791
|
+
};
|
|
67792
|
+
}
|
|
67793
|
+
function updateGraphMetadata(graph) {
|
|
67794
|
+
graph.metadata = {
|
|
67795
|
+
generatedAt: new Date().toISOString(),
|
|
67796
|
+
generator: "repo-graph",
|
|
67797
|
+
nodeCount: Object.keys(graph.nodes).length,
|
|
67798
|
+
edgeCount: graph.edges.length
|
|
67799
|
+
};
|
|
67800
|
+
}
|
|
67801
|
+
|
|
67802
|
+
// src/tools/repo-graph/validation.ts
|
|
67803
|
+
init_path_security();
|
|
67783
67804
|
function validateWorkspace(workspace) {
|
|
67784
67805
|
if (!workspace || typeof workspace !== "string" || workspace.trim() === "") {
|
|
67785
67806
|
throw new Error("Invalid workspace: must be a non-empty string");
|
|
@@ -67867,309 +67888,8 @@ function validateGraphEdge(edge) {
|
|
|
67867
67888
|
throw new Error("Invalid edge: control characters detected");
|
|
67868
67889
|
}
|
|
67869
67890
|
}
|
|
67870
|
-
|
|
67871
|
-
|
|
67872
|
-
return null;
|
|
67873
|
-
}
|
|
67874
|
-
if (specifier.startsWith("/") || specifier.startsWith("\\")) {
|
|
67875
|
-
return null;
|
|
67876
|
-
}
|
|
67877
|
-
if (/^[A-Za-z]:[/\\]/.test(specifier)) {
|
|
67878
|
-
return null;
|
|
67879
|
-
}
|
|
67880
|
-
if (specifier.startsWith("http://") || specifier.startsWith("https://")) {
|
|
67881
|
-
return null;
|
|
67882
|
-
}
|
|
67883
|
-
try {
|
|
67884
|
-
if (specifier.startsWith(".")) {
|
|
67885
|
-
const sourceDir = path53.dirname(sourceFile);
|
|
67886
|
-
let resolved = path53.resolve(sourceDir, specifier);
|
|
67887
|
-
let realResolved;
|
|
67888
|
-
try {
|
|
67889
|
-
realResolved = realpathSync6(resolved);
|
|
67890
|
-
} catch {
|
|
67891
|
-
realResolved = resolved;
|
|
67892
|
-
}
|
|
67893
|
-
let realRoot;
|
|
67894
|
-
try {
|
|
67895
|
-
realRoot = realpathSync6(workspaceRoot);
|
|
67896
|
-
} catch {
|
|
67897
|
-
realRoot = path53.normalize(workspaceRoot);
|
|
67898
|
-
}
|
|
67899
|
-
if (!existsSync29(resolved)) {
|
|
67900
|
-
const EXTENSIONS = [
|
|
67901
|
-
".ts",
|
|
67902
|
-
".tsx",
|
|
67903
|
-
".js",
|
|
67904
|
-
".jsx",
|
|
67905
|
-
".mjs",
|
|
67906
|
-
".cjs",
|
|
67907
|
-
".py",
|
|
67908
|
-
".json"
|
|
67909
|
-
];
|
|
67910
|
-
let found = null;
|
|
67911
|
-
for (const ext of EXTENSIONS) {
|
|
67912
|
-
const candidate = resolved + ext;
|
|
67913
|
-
if (existsSync29(candidate)) {
|
|
67914
|
-
found = candidate;
|
|
67915
|
-
break;
|
|
67916
|
-
}
|
|
67917
|
-
}
|
|
67918
|
-
if (found) {
|
|
67919
|
-
try {
|
|
67920
|
-
realResolved = realpathSync6(found);
|
|
67921
|
-
} catch {
|
|
67922
|
-
realResolved = found;
|
|
67923
|
-
}
|
|
67924
|
-
resolved = found;
|
|
67925
|
-
} else {
|
|
67926
|
-
return null;
|
|
67927
|
-
}
|
|
67928
|
-
}
|
|
67929
|
-
const normalizedResolved = path53.normalize(realResolved);
|
|
67930
|
-
const normalizedRoot = path53.normalize(realRoot);
|
|
67931
|
-
if (!normalizedResolved.startsWith(normalizedRoot + path53.sep) && normalizedResolved !== normalizedRoot) {
|
|
67932
|
-
return null;
|
|
67933
|
-
}
|
|
67934
|
-
return resolved;
|
|
67935
|
-
}
|
|
67936
|
-
return null;
|
|
67937
|
-
} catch {
|
|
67938
|
-
return null;
|
|
67939
|
-
}
|
|
67940
|
-
}
|
|
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
|
-
}
|
|
67891
|
+
|
|
67892
|
+
// src/tools/repo-graph/builder.ts
|
|
68173
67893
|
var SKIP_DIRECTORIES2 = new Set([
|
|
68174
67894
|
"node_modules",
|
|
68175
67895
|
".git",
|
|
@@ -68196,17 +67916,111 @@ var SUPPORTED_EXTENSIONS = [
|
|
|
68196
67916
|
var DEFAULT_WALK_FILE_CAP = 1e4;
|
|
68197
67917
|
var DEFAULT_WALK_BUDGET_MS = 5000;
|
|
68198
67918
|
var ASYNC_WALK_YIELD_INTERVAL = 200;
|
|
67919
|
+
var EXTENSION_TO_LANGUAGE = {
|
|
67920
|
+
".ts": "typescript",
|
|
67921
|
+
".tsx": "typescript",
|
|
67922
|
+
".js": "javascript",
|
|
67923
|
+
".jsx": "javascript",
|
|
67924
|
+
".mjs": "javascript",
|
|
67925
|
+
".cjs": "javascript",
|
|
67926
|
+
".py": "python"
|
|
67927
|
+
};
|
|
67928
|
+
function upsertNode(graph, node) {
|
|
67929
|
+
validateGraphNode(node);
|
|
67930
|
+
const key = normalizeGraphPath(node.filePath);
|
|
67931
|
+
graph.nodes[key] = node;
|
|
67932
|
+
updateGraphMetadata(graph);
|
|
67933
|
+
}
|
|
67934
|
+
function addEdge(graph, edge) {
|
|
67935
|
+
validateGraphEdge(edge);
|
|
67936
|
+
const exists = graph.edges.some((e) => e.source === edge.source && e.target === edge.target && e.importSpecifier === edge.importSpecifier);
|
|
67937
|
+
if (!exists) {
|
|
67938
|
+
graph.edges.push(edge);
|
|
67939
|
+
updateGraphMetadata(graph);
|
|
67940
|
+
}
|
|
67941
|
+
}
|
|
67942
|
+
function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
67943
|
+
if (containsControlChars(specifier)) {
|
|
67944
|
+
return null;
|
|
67945
|
+
}
|
|
67946
|
+
if (specifier.startsWith("/") || specifier.startsWith("\\")) {
|
|
67947
|
+
return null;
|
|
67948
|
+
}
|
|
67949
|
+
if (/^[A-Za-z]:[/\\]/.test(specifier)) {
|
|
67950
|
+
return null;
|
|
67951
|
+
}
|
|
67952
|
+
if (specifier.startsWith("http://") || specifier.startsWith("https://")) {
|
|
67953
|
+
return null;
|
|
67954
|
+
}
|
|
67955
|
+
try {
|
|
67956
|
+
if (specifier.startsWith(".")) {
|
|
67957
|
+
const sourceDir = path54.dirname(sourceFile);
|
|
67958
|
+
let resolved = path54.resolve(sourceDir, specifier);
|
|
67959
|
+
let realResolved;
|
|
67960
|
+
try {
|
|
67961
|
+
realResolved = realpathSync6(resolved);
|
|
67962
|
+
} catch {
|
|
67963
|
+
realResolved = resolved;
|
|
67964
|
+
}
|
|
67965
|
+
let realRoot;
|
|
67966
|
+
try {
|
|
67967
|
+
realRoot = realpathSync6(workspaceRoot);
|
|
67968
|
+
} catch {
|
|
67969
|
+
realRoot = path54.normalize(workspaceRoot);
|
|
67970
|
+
}
|
|
67971
|
+
if (!existsSync29(resolved)) {
|
|
67972
|
+
const EXTENSIONS = [
|
|
67973
|
+
".ts",
|
|
67974
|
+
".tsx",
|
|
67975
|
+
".js",
|
|
67976
|
+
".jsx",
|
|
67977
|
+
".mjs",
|
|
67978
|
+
".cjs",
|
|
67979
|
+
".py",
|
|
67980
|
+
".json"
|
|
67981
|
+
];
|
|
67982
|
+
let found = null;
|
|
67983
|
+
for (const ext of EXTENSIONS) {
|
|
67984
|
+
const candidate = resolved + ext;
|
|
67985
|
+
if (existsSync29(candidate)) {
|
|
67986
|
+
found = candidate;
|
|
67987
|
+
break;
|
|
67988
|
+
}
|
|
67989
|
+
}
|
|
67990
|
+
if (found) {
|
|
67991
|
+
try {
|
|
67992
|
+
realResolved = realpathSync6(found);
|
|
67993
|
+
} catch {
|
|
67994
|
+
realResolved = found;
|
|
67995
|
+
}
|
|
67996
|
+
resolved = found;
|
|
67997
|
+
} else {
|
|
67998
|
+
return null;
|
|
67999
|
+
}
|
|
68000
|
+
}
|
|
68001
|
+
const normalizedResolved = path54.normalize(realResolved);
|
|
68002
|
+
const normalizedRoot = path54.normalize(realRoot);
|
|
68003
|
+
if (!normalizedResolved.startsWith(normalizedRoot + path54.sep) && normalizedResolved !== normalizedRoot) {
|
|
68004
|
+
return null;
|
|
68005
|
+
}
|
|
68006
|
+
return resolved;
|
|
68007
|
+
}
|
|
68008
|
+
return null;
|
|
68009
|
+
} catch {
|
|
68010
|
+
return null;
|
|
68011
|
+
}
|
|
68012
|
+
}
|
|
68199
68013
|
function isRefusedWorkspaceRoot(target) {
|
|
68200
68014
|
let resolved;
|
|
68201
68015
|
try {
|
|
68202
68016
|
resolved = realpathSync6(target);
|
|
68203
68017
|
} catch {
|
|
68204
|
-
resolved =
|
|
68018
|
+
resolved = path54.resolve(target);
|
|
68205
68019
|
}
|
|
68206
68020
|
const refused = new Set;
|
|
68207
68021
|
const add = (p) => {
|
|
68208
68022
|
if (typeof p === "string" && p.length > 0) {
|
|
68209
|
-
refused.add(
|
|
68023
|
+
refused.add(path54.resolve(p));
|
|
68210
68024
|
}
|
|
68211
68025
|
};
|
|
68212
68026
|
add(os7.homedir());
|
|
@@ -68221,15 +68035,6 @@ function isRefusedWorkspaceRoot(target) {
|
|
|
68221
68035
|
}
|
|
68222
68036
|
return refused.has(resolved);
|
|
68223
68037
|
}
|
|
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
68038
|
function parseFileImports(content) {
|
|
68234
68039
|
const imports = [];
|
|
68235
68040
|
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 +68130,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68325
68130
|
ctx.stats.skippedDirs++;
|
|
68326
68131
|
continue;
|
|
68327
68132
|
}
|
|
68328
|
-
const fullPath =
|
|
68133
|
+
const fullPath = path54.join(current, entry.name);
|
|
68329
68134
|
if (entry.isSymbolicLink() && !ctx.followSymlinks) {
|
|
68330
68135
|
ctx.stats.skippedDirs++;
|
|
68331
68136
|
continue;
|
|
@@ -68333,7 +68138,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68333
68138
|
if (entry.isDirectory()) {
|
|
68334
68139
|
queue.push(fullPath);
|
|
68335
68140
|
} else if (entry.isFile()) {
|
|
68336
|
-
const ext =
|
|
68141
|
+
const ext = path54.extname(fullPath).toLowerCase();
|
|
68337
68142
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
68338
68143
|
files.push(fullPath);
|
|
68339
68144
|
}
|
|
@@ -68350,11 +68155,11 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68350
68155
|
return files;
|
|
68351
68156
|
}
|
|
68352
68157
|
function toModuleName(filePath, workspaceRoot) {
|
|
68353
|
-
const relative9 =
|
|
68354
|
-
return relative9.split(
|
|
68158
|
+
const relative9 = path54.relative(workspaceRoot, filePath);
|
|
68159
|
+
return relative9.split(path54.sep).join("/");
|
|
68355
68160
|
}
|
|
68356
68161
|
function getLanguage(filePath) {
|
|
68357
|
-
const ext =
|
|
68162
|
+
const ext = path54.extname(filePath).toLowerCase();
|
|
68358
68163
|
return EXTENSION_TO_LANGUAGE[ext] ?? "unknown";
|
|
68359
68164
|
}
|
|
68360
68165
|
function isBinaryContent(content) {
|
|
@@ -68363,13 +68168,67 @@ function isBinaryContent(content) {
|
|
|
68363
68168
|
}
|
|
68364
68169
|
return false;
|
|
68365
68170
|
}
|
|
68171
|
+
function scanFile(filePath, absoluteRoot, maxFileSize) {
|
|
68172
|
+
let content;
|
|
68173
|
+
let fileStats;
|
|
68174
|
+
try {
|
|
68175
|
+
fileStats = fsSync3.statSync(filePath);
|
|
68176
|
+
if (fileStats.size > maxFileSize) {
|
|
68177
|
+
return { node: null, edges: [] };
|
|
68178
|
+
}
|
|
68179
|
+
content = fsSync3.readFileSync(filePath, "utf-8");
|
|
68180
|
+
} catch {
|
|
68181
|
+
return { node: null, edges: [] };
|
|
68182
|
+
}
|
|
68183
|
+
if (isBinaryContent(content)) {
|
|
68184
|
+
return { node: null, edges: [] };
|
|
68185
|
+
}
|
|
68186
|
+
const ext = path54.extname(filePath).toLowerCase();
|
|
68187
|
+
let exports = [];
|
|
68188
|
+
try {
|
|
68189
|
+
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
68190
|
+
const relativePath = path54.relative(absoluteRoot, filePath);
|
|
68191
|
+
const symbols2 = extractTSSymbols(relativePath, absoluteRoot);
|
|
68192
|
+
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
68193
|
+
} else if (ext === ".py") {
|
|
68194
|
+
const relativePath = path54.relative(absoluteRoot, filePath);
|
|
68195
|
+
const symbols2 = extractPythonSymbols(relativePath, absoluteRoot);
|
|
68196
|
+
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
68197
|
+
}
|
|
68198
|
+
const parsedImports = parseFileImports(content);
|
|
68199
|
+
const node = {
|
|
68200
|
+
filePath,
|
|
68201
|
+
moduleName: toModuleName(filePath, absoluteRoot),
|
|
68202
|
+
exports,
|
|
68203
|
+
imports: parsedImports.map((p) => p.specifier),
|
|
68204
|
+
language: getLanguage(filePath),
|
|
68205
|
+
mtime: fileStats.mtime.toISOString()
|
|
68206
|
+
};
|
|
68207
|
+
const edges = [];
|
|
68208
|
+
const sortedImports = [...parsedImports].sort((a, b) => a.specifier.localeCompare(b.specifier));
|
|
68209
|
+
for (const parsed of sortedImports) {
|
|
68210
|
+
const resolvedTarget = resolveModuleSpecifier(absoluteRoot, filePath, parsed.specifier);
|
|
68211
|
+
if (resolvedTarget !== null) {
|
|
68212
|
+
edges.push({
|
|
68213
|
+
source: filePath,
|
|
68214
|
+
target: resolvedTarget,
|
|
68215
|
+
importSpecifier: parsed.specifier,
|
|
68216
|
+
importType: parsed.importType
|
|
68217
|
+
});
|
|
68218
|
+
}
|
|
68219
|
+
}
|
|
68220
|
+
return { node, edges };
|
|
68221
|
+
} catch {
|
|
68222
|
+
return { node: null, edges: [] };
|
|
68223
|
+
}
|
|
68224
|
+
}
|
|
68366
68225
|
async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
68367
68226
|
validateWorkspace(workspaceRoot);
|
|
68368
68227
|
const maxFileSize = options?.maxFileSizeBytes ?? 1024 * 1024;
|
|
68369
68228
|
const maxFiles = options?.maxFiles ?? DEFAULT_WALK_FILE_CAP;
|
|
68370
68229
|
const walkBudgetMs = options?.walkBudgetMs ?? DEFAULT_WALK_BUDGET_MS;
|
|
68371
68230
|
const followSymlinks = options?.followSymlinks ?? false;
|
|
68372
|
-
const absoluteRoot =
|
|
68231
|
+
const absoluteRoot = path54.resolve(workspaceRoot);
|
|
68373
68232
|
if (!existsSync29(absoluteRoot)) {
|
|
68374
68233
|
throw new Error(`Workspace directory does not exist: ${workspaceRoot}`);
|
|
68375
68234
|
}
|
|
@@ -68424,60 +68283,225 @@ async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
|
68424
68283
|
}
|
|
68425
68284
|
return graph;
|
|
68426
68285
|
}
|
|
68427
|
-
|
|
68428
|
-
|
|
68429
|
-
|
|
68286
|
+
// src/tools/repo-graph/cache.ts
|
|
68287
|
+
import * as path55 from "node:path";
|
|
68288
|
+
var graphCache = new Map;
|
|
68289
|
+
var dirtyFlags = new Map;
|
|
68290
|
+
var mtimeCache = new Map;
|
|
68291
|
+
function getCachedGraph(workspace) {
|
|
68292
|
+
return graphCache.get(path55.normalize(workspace));
|
|
68293
|
+
}
|
|
68294
|
+
function setCachedGraph(workspace, graph, mtime) {
|
|
68295
|
+
const normalized = path55.normalize(workspace);
|
|
68296
|
+
graphCache.set(normalized, graph);
|
|
68297
|
+
dirtyFlags.set(normalized, false);
|
|
68298
|
+
if (mtime !== undefined) {
|
|
68299
|
+
mtimeCache.set(normalized, mtime);
|
|
68300
|
+
}
|
|
68301
|
+
}
|
|
68302
|
+
function isDirty(workspace) {
|
|
68303
|
+
return dirtyFlags.get(path55.normalize(workspace)) ?? false;
|
|
68304
|
+
}
|
|
68305
|
+
function clearCache(workspace) {
|
|
68306
|
+
const normalized = path55.normalize(workspace);
|
|
68307
|
+
graphCache.delete(normalized);
|
|
68308
|
+
dirtyFlags.delete(normalized);
|
|
68309
|
+
mtimeCache.delete(normalized);
|
|
68310
|
+
}
|
|
68311
|
+
function getCachedMtime(workspace) {
|
|
68312
|
+
return mtimeCache.get(path55.normalize(workspace));
|
|
68313
|
+
}
|
|
68314
|
+
// src/tools/repo-graph/incremental.ts
|
|
68315
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
68316
|
+
import * as fsPromises7 from "node:fs/promises";
|
|
68317
|
+
import * as path57 from "node:path";
|
|
68318
|
+
|
|
68319
|
+
// src/tools/repo-graph/storage.ts
|
|
68320
|
+
init_utils2();
|
|
68321
|
+
init_path_security();
|
|
68322
|
+
import { constants as constants4, existsSync as existsSync30, realpathSync as realpathSync7 } from "node:fs";
|
|
68323
|
+
import * as fsPromises6 from "node:fs/promises";
|
|
68324
|
+
import * as path56 from "node:path";
|
|
68325
|
+
var WINDOWS_RENAME_MAX_RETRIES2 = 3;
|
|
68326
|
+
var WINDOWS_RENAME_RETRY_DELAY_MS2 = 50;
|
|
68327
|
+
function getGraphPath(workspace) {
|
|
68328
|
+
validateWorkspace(workspace);
|
|
68329
|
+
const basePath = validateSwarmPath(workspace, REPO_GRAPH_FILENAME);
|
|
68330
|
+
validateSymlinkBoundary(basePath, workspace);
|
|
68331
|
+
return basePath;
|
|
68332
|
+
}
|
|
68333
|
+
async function loadGraph(workspace) {
|
|
68334
|
+
validateWorkspace(workspace);
|
|
68335
|
+
const normalized = path56.normalize(workspace);
|
|
68336
|
+
const cached3 = getCachedGraph(normalized);
|
|
68337
|
+
if (cached3 && !isDirty(normalized)) {
|
|
68338
|
+
try {
|
|
68339
|
+
const graphPath = getGraphPath(workspace);
|
|
68340
|
+
if (existsSync30(graphPath)) {
|
|
68341
|
+
const stats = await fsPromises6.stat(graphPath);
|
|
68342
|
+
const cachedMtime = getCachedMtime(normalized);
|
|
68343
|
+
if (cachedMtime !== undefined && stats.mtimeMs !== cachedMtime) {
|
|
68344
|
+
clearCache(normalized);
|
|
68345
|
+
} else {
|
|
68346
|
+
return cached3;
|
|
68347
|
+
}
|
|
68348
|
+
} else {
|
|
68349
|
+
clearCache(normalized);
|
|
68350
|
+
}
|
|
68351
|
+
} catch {
|
|
68352
|
+
clearCache(normalized);
|
|
68353
|
+
}
|
|
68354
|
+
}
|
|
68430
68355
|
try {
|
|
68431
|
-
|
|
68432
|
-
if (
|
|
68433
|
-
return
|
|
68356
|
+
const graphPath = getGraphPath(workspace);
|
|
68357
|
+
if (!existsSync30(graphPath)) {
|
|
68358
|
+
return null;
|
|
68434
68359
|
}
|
|
68435
|
-
|
|
68360
|
+
const stats = await fsPromises6.stat(graphPath);
|
|
68361
|
+
const content = await fsPromises6.readFile(graphPath, "utf-8");
|
|
68362
|
+
if (content.includes("\x00") || content.includes("�")) {
|
|
68363
|
+
throw Object.assign(new Error("repo-graph.json contains null bytes or invalid encoding"), { code: "CORRUPTION" });
|
|
68364
|
+
}
|
|
68365
|
+
let parsed;
|
|
68366
|
+
try {
|
|
68367
|
+
parsed = JSON.parse(content);
|
|
68368
|
+
} catch {
|
|
68369
|
+
throw Object.assign(new Error("repo-graph.json contains invalid JSON"), {
|
|
68370
|
+
code: "CORRUPTION"
|
|
68371
|
+
});
|
|
68372
|
+
}
|
|
68373
|
+
if (!parsed.schema_version) {
|
|
68374
|
+
throw Object.assign(new Error("repo-graph.json missing schema_version"), {
|
|
68375
|
+
code: "CORRUPTION"
|
|
68376
|
+
});
|
|
68377
|
+
}
|
|
68378
|
+
if (!parsed.nodes || typeof parsed.nodes !== "object") {
|
|
68379
|
+
throw Object.assign(new Error("repo-graph.json missing or invalid nodes"), { code: "CORRUPTION" });
|
|
68380
|
+
}
|
|
68381
|
+
if (!Array.isArray(parsed.edges)) {
|
|
68382
|
+
throw Object.assign(new Error("repo-graph.json missing or invalid edges"), { code: "CORRUPTION" });
|
|
68383
|
+
}
|
|
68384
|
+
for (const [key, node] of Object.entries(parsed.nodes)) {
|
|
68385
|
+
if (!key || typeof key !== "string") {
|
|
68386
|
+
throw Object.assign(new Error("repo-graph.json contains invalid node key"), { code: "CORRUPTION" });
|
|
68387
|
+
}
|
|
68388
|
+
try {
|
|
68389
|
+
validateGraphNode(node);
|
|
68390
|
+
} catch (err2) {
|
|
68391
|
+
const msg = err2 instanceof Error ? err2.message : "Invalid node structure";
|
|
68392
|
+
throw Object.assign(new Error(`repo-graph.json node validation failed: ${msg}`), { code: "CORRUPTION" });
|
|
68393
|
+
}
|
|
68394
|
+
}
|
|
68395
|
+
for (const edge of parsed.edges) {
|
|
68396
|
+
try {
|
|
68397
|
+
validateGraphEdge(edge);
|
|
68398
|
+
} catch (err2) {
|
|
68399
|
+
const msg = err2 instanceof Error ? err2.message : "Invalid edge structure";
|
|
68400
|
+
throw Object.assign(new Error(`repo-graph.json edge validation failed: ${msg}`), { code: "CORRUPTION" });
|
|
68401
|
+
}
|
|
68402
|
+
}
|
|
68403
|
+
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") {
|
|
68404
|
+
throw Object.assign(new Error("repo-graph.json missing or invalid metadata"), { code: "CORRUPTION" });
|
|
68405
|
+
}
|
|
68406
|
+
setCachedGraph(normalized, parsed, stats.mtimeMs);
|
|
68407
|
+
return parsed;
|
|
68408
|
+
} catch (error93) {
|
|
68409
|
+
if (error93 instanceof Error && "code" in error93 && error93.code === "CORRUPTION") {
|
|
68410
|
+
throw error93;
|
|
68411
|
+
}
|
|
68412
|
+
if (error93 instanceof Error && "code" in error93 && error93.code === "ENOENT") {
|
|
68413
|
+
return null;
|
|
68414
|
+
}
|
|
68415
|
+
throw error93;
|
|
68416
|
+
}
|
|
68417
|
+
}
|
|
68418
|
+
async function saveGraph(workspace, graph, options) {
|
|
68419
|
+
validateWorkspace(workspace);
|
|
68420
|
+
if (!graph.schema_version) {
|
|
68421
|
+
throw new Error("Graph must have schema_version");
|
|
68422
|
+
}
|
|
68423
|
+
if (!graph.nodes || typeof graph.nodes !== "object") {
|
|
68424
|
+
throw new Error("Graph must have nodes object");
|
|
68425
|
+
}
|
|
68426
|
+
if (!Array.isArray(graph.edges)) {
|
|
68427
|
+
throw new Error("Graph must have edges array");
|
|
68428
|
+
}
|
|
68429
|
+
const normalizedWorkspace = path56.normalize(workspace);
|
|
68430
|
+
let realWorkspace;
|
|
68431
|
+
try {
|
|
68432
|
+
realWorkspace = realpathSync7(workspace);
|
|
68436
68433
|
} catch {
|
|
68437
|
-
|
|
68434
|
+
realWorkspace = normalizedWorkspace;
|
|
68438
68435
|
}
|
|
68439
|
-
|
|
68440
|
-
|
|
68436
|
+
const normalizedGraphRoot = path56.normalize(graph.workspaceRoot);
|
|
68437
|
+
let realGraphRoot;
|
|
68438
|
+
try {
|
|
68439
|
+
realGraphRoot = realpathSync7(graph.workspaceRoot);
|
|
68440
|
+
} catch {
|
|
68441
|
+
realGraphRoot = normalizedGraphRoot;
|
|
68441
68442
|
}
|
|
68442
|
-
|
|
68443
|
-
|
|
68443
|
+
if (path56.normalize(realWorkspace) !== path56.normalize(realGraphRoot)) {
|
|
68444
|
+
throw new Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);
|
|
68445
|
+
}
|
|
68446
|
+
const normalized = normalizedWorkspace;
|
|
68447
|
+
const graphPath = getGraphPath(workspace);
|
|
68448
|
+
updateGraphMetadata(graph);
|
|
68449
|
+
const tempPath = `${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
68450
|
+
await fsPromises6.mkdir(path56.dirname(tempPath), { recursive: true });
|
|
68451
|
+
let lastError = null;
|
|
68444
68452
|
try {
|
|
68445
|
-
if (
|
|
68446
|
-
|
|
68447
|
-
|
|
68448
|
-
|
|
68449
|
-
|
|
68450
|
-
|
|
68451
|
-
|
|
68452
|
-
|
|
68453
|
+
if (options?.createAtomic) {
|
|
68454
|
+
try {
|
|
68455
|
+
const handle2 = await fsPromises6.open(tempPath, "wx", 420);
|
|
68456
|
+
await handle2.writeFile(JSON.stringify(graph, null, 2), "utf-8");
|
|
68457
|
+
await handle2.close();
|
|
68458
|
+
} catch (error93) {
|
|
68459
|
+
if (error93 instanceof Error && "code" in error93 && error93.code === "EEXIST") {
|
|
68460
|
+
throw new Error("file already exists");
|
|
68461
|
+
}
|
|
68462
|
+
throw error93;
|
|
68463
|
+
}
|
|
68464
|
+
} else {
|
|
68465
|
+
await fsPromises6.writeFile(tempPath, JSON.stringify(graph, null, 2), "utf-8");
|
|
68453
68466
|
}
|
|
68454
|
-
|
|
68455
|
-
|
|
68456
|
-
|
|
68457
|
-
|
|
68458
|
-
|
|
68459
|
-
|
|
68460
|
-
|
|
68461
|
-
|
|
68462
|
-
|
|
68463
|
-
|
|
68464
|
-
|
|
68465
|
-
|
|
68466
|
-
|
|
68467
|
-
|
|
68468
|
-
|
|
68469
|
-
|
|
68470
|
-
|
|
68471
|
-
|
|
68472
|
-
|
|
68473
|
-
|
|
68467
|
+
if (options?.createAtomic) {
|
|
68468
|
+
try {
|
|
68469
|
+
await fsPromises6.copyFile(tempPath, graphPath, constants4.COPYFILE_EXCL);
|
|
68470
|
+
} catch (error93) {
|
|
68471
|
+
lastError = error93 instanceof Error ? error93 : new Error(String(error93));
|
|
68472
|
+
throw lastError;
|
|
68473
|
+
}
|
|
68474
|
+
} else {
|
|
68475
|
+
let retries = 0;
|
|
68476
|
+
while (retries < WINDOWS_RENAME_MAX_RETRIES2) {
|
|
68477
|
+
try {
|
|
68478
|
+
await fsPromises6.rename(tempPath, graphPath);
|
|
68479
|
+
break;
|
|
68480
|
+
} catch (error93) {
|
|
68481
|
+
lastError = error93 instanceof Error ? error93 : new Error(String(error93));
|
|
68482
|
+
if (lastError instanceof Error && "code" in lastError && lastError.code === "EEXIST" && retries < WINDOWS_RENAME_MAX_RETRIES2 - 1) {
|
|
68483
|
+
retries++;
|
|
68484
|
+
await new Promise((resolve18) => setTimeout(resolve18, WINDOWS_RENAME_RETRY_DELAY_MS2));
|
|
68485
|
+
continue;
|
|
68486
|
+
}
|
|
68487
|
+
throw lastError;
|
|
68488
|
+
}
|
|
68489
|
+
}
|
|
68490
|
+
}
|
|
68491
|
+
} finally {
|
|
68492
|
+
try {
|
|
68493
|
+
await fsPromises6.unlink(tempPath);
|
|
68494
|
+
} catch (error93) {
|
|
68495
|
+
if (error93 instanceof Error && "code" in error93 && error93.code !== "ENOENT") {
|
|
68496
|
+
error48(`Failed to clean up temp file ${tempPath}:`, error93);
|
|
68474
68497
|
}
|
|
68475
68498
|
}
|
|
68476
|
-
return { node, edges };
|
|
68477
|
-
} catch {
|
|
68478
|
-
return { node: null, edges: [] };
|
|
68479
68499
|
}
|
|
68500
|
+
const stats = await fsPromises6.stat(graphPath);
|
|
68501
|
+
setCachedGraph(normalized, graph, stats.mtimeMs);
|
|
68480
68502
|
}
|
|
68503
|
+
|
|
68504
|
+
// src/tools/repo-graph/incremental.ts
|
|
68481
68505
|
async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
68482
68506
|
if (options?.forceRebuild) {
|
|
68483
68507
|
const graph2 = await buildWorkspaceGraphAsync(workspaceRoot);
|
|
@@ -68491,12 +68515,12 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
68491
68515
|
return graph2;
|
|
68492
68516
|
}
|
|
68493
68517
|
const graph = existingGraph;
|
|
68494
|
-
const absoluteRoot =
|
|
68518
|
+
const absoluteRoot = path57.resolve(workspaceRoot);
|
|
68495
68519
|
const maxFileSize = 1024 * 1024;
|
|
68496
68520
|
const updatedPaths = new Set;
|
|
68497
68521
|
for (const rawFilePath of filePaths) {
|
|
68498
68522
|
const normalizedPath = normalizeGraphPath(rawFilePath);
|
|
68499
|
-
const fileExists =
|
|
68523
|
+
const fileExists = existsSync31(rawFilePath);
|
|
68500
68524
|
if (fileExists) {
|
|
68501
68525
|
graph.edges = graph.edges.filter((e) => normalizeGraphPath(e.source) !== normalizedPath);
|
|
68502
68526
|
const result = scanFile(rawFilePath, absoluteRoot, maxFileSize);
|
|
@@ -68531,6 +68555,22 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
68531
68555
|
await saveGraph(workspaceRoot, rebuiltGraph);
|
|
68532
68556
|
return rebuiltGraph;
|
|
68533
68557
|
}
|
|
68558
|
+
const normalizedWorkspace = path57.normalize(workspaceRoot);
|
|
68559
|
+
const loadedMtime = getCachedMtime(normalizedWorkspace);
|
|
68560
|
+
if (loadedMtime !== undefined) {
|
|
68561
|
+
try {
|
|
68562
|
+
const graphPath = getGraphPath(workspaceRoot);
|
|
68563
|
+
if (existsSync31(graphPath)) {
|
|
68564
|
+
const currentStats = await fsPromises7.stat(graphPath);
|
|
68565
|
+
if (currentStats.mtimeMs !== loadedMtime) {
|
|
68566
|
+
warn(`[repo-graph] Concurrent modification detected — falling back to full rebuild`);
|
|
68567
|
+
const rebuiltGraph = await buildWorkspaceGraphAsync(workspaceRoot);
|
|
68568
|
+
await saveGraph(workspaceRoot, rebuiltGraph);
|
|
68569
|
+
return rebuiltGraph;
|
|
68570
|
+
}
|
|
68571
|
+
}
|
|
68572
|
+
} catch {}
|
|
68573
|
+
}
|
|
68534
68574
|
updateGraphMetadata(graph);
|
|
68535
68575
|
await saveGraph(workspaceRoot, graph);
|
|
68536
68576
|
return graph;
|
|
@@ -68549,9 +68589,20 @@ function extractFilePath(args2) {
|
|
|
68549
68589
|
if (!args2 || typeof args2 !== "object")
|
|
68550
68590
|
return null;
|
|
68551
68591
|
const a = args2;
|
|
68552
|
-
|
|
68592
|
+
let filePath = a.file_path ?? a.path ?? a.filePath;
|
|
68553
68593
|
if (!filePath || typeof filePath !== "string")
|
|
68554
68594
|
return null;
|
|
68595
|
+
for (let i2 = 0;i2 < 3; i2++) {
|
|
68596
|
+
try {
|
|
68597
|
+
const decoded = decodeURIComponent(filePath);
|
|
68598
|
+
if (decoded === filePath)
|
|
68599
|
+
break;
|
|
68600
|
+
filePath = decoded;
|
|
68601
|
+
} catch {
|
|
68602
|
+
break;
|
|
68603
|
+
}
|
|
68604
|
+
}
|
|
68605
|
+
filePath = filePath.replace(/./g, ".").replace(///g, "/").replace(/․/g, ".");
|
|
68555
68606
|
return filePath;
|
|
68556
68607
|
}
|
|
68557
68608
|
function isSupportedSourceFile(filePath) {
|
|
@@ -68564,6 +68615,8 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
68564
68615
|
const _updateGraphForFiles = deps?.updateGraphForFiles ?? updateGraphForFiles;
|
|
68565
68616
|
let initStarted = false;
|
|
68566
68617
|
let initPromise = Promise.resolve();
|
|
68618
|
+
let consecutiveFailures = 0;
|
|
68619
|
+
const FAILURE_ADVISORY_THRESHOLD = 3;
|
|
68567
68620
|
async function doInit() {
|
|
68568
68621
|
await yieldToEventLoop();
|
|
68569
68622
|
try {
|
|
@@ -68592,37 +68645,48 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
68592
68645
|
if (!WRITE_TOOL_NAMES.includes(input.tool)) {
|
|
68593
68646
|
return;
|
|
68594
68647
|
}
|
|
68595
|
-
const
|
|
68596
|
-
if (!
|
|
68648
|
+
const filePath = extractFilePath(input.args);
|
|
68649
|
+
if (!filePath)
|
|
68597
68650
|
return;
|
|
68598
|
-
if (
|
|
68651
|
+
if (filePath.includes("\x00"))
|
|
68599
68652
|
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
68653
|
if (!isSupportedSourceFile(filePath))
|
|
68613
68654
|
return;
|
|
68614
|
-
const absoluteFilePath =
|
|
68615
|
-
|
|
68616
|
-
|
|
68655
|
+
const absoluteFilePath = path58.isAbsolute(filePath) ? filePath : path58.resolve(workspaceRoot, filePath);
|
|
68656
|
+
let realFilePath;
|
|
68657
|
+
try {
|
|
68658
|
+
realFilePath = realpathSync8(absoluteFilePath);
|
|
68659
|
+
} catch (error93) {
|
|
68660
|
+
if (!(error93 instanceof Error) || error93.code !== "ENOENT") {
|
|
68661
|
+
return;
|
|
68662
|
+
}
|
|
68663
|
+
realFilePath = absoluteFilePath;
|
|
68664
|
+
}
|
|
68665
|
+
let realWorkspace;
|
|
68666
|
+
try {
|
|
68667
|
+
realWorkspace = realpathSync8(workspaceRoot);
|
|
68668
|
+
} catch (error93) {
|
|
68669
|
+
if (!(error93 instanceof Error) || error93.code !== "ENOENT") {
|
|
68670
|
+
return;
|
|
68671
|
+
}
|
|
68672
|
+
realWorkspace = workspaceRoot;
|
|
68673
|
+
}
|
|
68674
|
+
const normalizedAbsolute = realFilePath.replace(/\\/g, "/");
|
|
68675
|
+
const normalizedWorkspace = realWorkspace.replace(/\\/g, "/");
|
|
68617
68676
|
if (!normalizedAbsolute.startsWith(`${normalizedWorkspace}/`) && normalizedAbsolute !== normalizedWorkspace) {
|
|
68618
68677
|
return;
|
|
68619
68678
|
}
|
|
68620
68679
|
try {
|
|
68621
68680
|
await _updateGraphForFiles(workspaceRoot, [absoluteFilePath]);
|
|
68622
|
-
|
|
68681
|
+
consecutiveFailures = 0;
|
|
68682
|
+
log(`[repo-graph] Incremental update for ${path58.basename(filePath)}`);
|
|
68623
68683
|
} catch (error93) {
|
|
68624
68684
|
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
68685
|
+
consecutiveFailures++;
|
|
68625
68686
|
error48(`[repo-graph] Incremental update failed: ${message}`);
|
|
68687
|
+
if (consecutiveFailures >= FAILURE_ADVISORY_THRESHOLD) {
|
|
68688
|
+
warn(`[repo-graph] ${consecutiveFailures} consecutive incremental update failures. ` + `The dependency graph may be stale. Consider reloading the workspace.`);
|
|
68689
|
+
}
|
|
68626
68690
|
}
|
|
68627
68691
|
}
|
|
68628
68692
|
};
|
|
@@ -68638,14 +68702,14 @@ init_manager2();
|
|
|
68638
68702
|
init_detector();
|
|
68639
68703
|
init_manager();
|
|
68640
68704
|
import * as fs46 from "node:fs";
|
|
68641
|
-
import * as
|
|
68705
|
+
import * as path68 from "node:path";
|
|
68642
68706
|
|
|
68643
68707
|
// src/services/decision-drift-analyzer.ts
|
|
68644
68708
|
init_utils2();
|
|
68645
68709
|
init_manager();
|
|
68646
68710
|
init_utils();
|
|
68647
68711
|
import * as fs38 from "node:fs";
|
|
68648
|
-
import * as
|
|
68712
|
+
import * as path59 from "node:path";
|
|
68649
68713
|
var DEFAULT_DRIFT_CONFIG = {
|
|
68650
68714
|
staleThresholdPhases: 1,
|
|
68651
68715
|
detectContradictions: true,
|
|
@@ -68799,7 +68863,7 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
68799
68863
|
currentPhase = legacyPhase;
|
|
68800
68864
|
}
|
|
68801
68865
|
}
|
|
68802
|
-
const contextPath =
|
|
68866
|
+
const contextPath = path59.join(directory, ".swarm", "context.md");
|
|
68803
68867
|
let contextContent = "";
|
|
68804
68868
|
try {
|
|
68805
68869
|
if (fs38.existsSync(contextPath)) {
|
|
@@ -68938,7 +69002,7 @@ init_utils();
|
|
|
68938
69002
|
init_constants();
|
|
68939
69003
|
init_schema();
|
|
68940
69004
|
import * as fs39 from "node:fs/promises";
|
|
68941
|
-
import * as
|
|
69005
|
+
import * as path60 from "node:path";
|
|
68942
69006
|
function safeGet(obj, key) {
|
|
68943
69007
|
if (!obj || !Object.hasOwn(obj, key))
|
|
68944
69008
|
return;
|
|
@@ -69170,9 +69234,9 @@ async function handleDebuggingSpiral(match, taskId, directory) {
|
|
|
69170
69234
|
let eventLogged = false;
|
|
69171
69235
|
let checkpointCreated = false;
|
|
69172
69236
|
try {
|
|
69173
|
-
const swarmDir =
|
|
69237
|
+
const swarmDir = path60.join(directory, ".swarm");
|
|
69174
69238
|
await fs39.mkdir(swarmDir, { recursive: true });
|
|
69175
|
-
const eventsPath =
|
|
69239
|
+
const eventsPath = path60.join(swarmDir, "events.jsonl");
|
|
69176
69240
|
await fs39.appendFile(eventsPath, `${formatDebuggingSpiralEvent(match, taskId)}
|
|
69177
69241
|
`);
|
|
69178
69242
|
eventLogged = true;
|
|
@@ -69307,7 +69371,7 @@ import * as fs43 from "node:fs";
|
|
|
69307
69371
|
|
|
69308
69372
|
// src/graph/graph-builder.ts
|
|
69309
69373
|
import * as fs41 from "node:fs";
|
|
69310
|
-
import * as
|
|
69374
|
+
import * as path63 from "node:path";
|
|
69311
69375
|
|
|
69312
69376
|
// node_modules/yocto-queue/index.js
|
|
69313
69377
|
class Node {
|
|
@@ -69398,26 +69462,26 @@ function pLimit(concurrency) {
|
|
|
69398
69462
|
activeCount--;
|
|
69399
69463
|
resumeNext();
|
|
69400
69464
|
};
|
|
69401
|
-
const run2 = async (function_,
|
|
69465
|
+
const run2 = async (function_, resolve20, arguments_2) => {
|
|
69402
69466
|
const result = (async () => function_(...arguments_2))();
|
|
69403
|
-
|
|
69467
|
+
resolve20(result);
|
|
69404
69468
|
try {
|
|
69405
69469
|
await result;
|
|
69406
69470
|
} catch {}
|
|
69407
69471
|
next();
|
|
69408
69472
|
};
|
|
69409
|
-
const enqueue = (function_,
|
|
69473
|
+
const enqueue = (function_, resolve20, reject, arguments_2) => {
|
|
69410
69474
|
const queueItem = { reject };
|
|
69411
69475
|
new Promise((internalResolve) => {
|
|
69412
69476
|
queueItem.run = internalResolve;
|
|
69413
69477
|
queue.enqueue(queueItem);
|
|
69414
|
-
}).then(run2.bind(undefined, function_,
|
|
69478
|
+
}).then(run2.bind(undefined, function_, resolve20, arguments_2));
|
|
69415
69479
|
if (activeCount < concurrency) {
|
|
69416
69480
|
resumeNext();
|
|
69417
69481
|
}
|
|
69418
69482
|
};
|
|
69419
|
-
const generator = (function_, ...arguments_2) => new Promise((
|
|
69420
|
-
enqueue(function_,
|
|
69483
|
+
const generator = (function_, ...arguments_2) => new Promise((resolve20, reject) => {
|
|
69484
|
+
enqueue(function_, resolve20, reject, arguments_2);
|
|
69421
69485
|
});
|
|
69422
69486
|
Object.defineProperties(generator, {
|
|
69423
69487
|
activeCount: {
|
|
@@ -69468,7 +69532,7 @@ function validateConcurrency(concurrency) {
|
|
|
69468
69532
|
// src/graph/import-extractor.ts
|
|
69469
69533
|
init_path_security();
|
|
69470
69534
|
import * as fs40 from "node:fs";
|
|
69471
|
-
import * as
|
|
69535
|
+
import * as path61 from "node:path";
|
|
69472
69536
|
var SOURCE_EXTENSIONS2 = [
|
|
69473
69537
|
".ts",
|
|
69474
69538
|
".tsx",
|
|
@@ -69513,28 +69577,28 @@ function getLanguageFromExtension(ext) {
|
|
|
69513
69577
|
return null;
|
|
69514
69578
|
}
|
|
69515
69579
|
function toRelForwardSlash(absPath, root) {
|
|
69516
|
-
return
|
|
69580
|
+
return path61.relative(root, absPath).replace(/\\/g, "/");
|
|
69517
69581
|
}
|
|
69518
69582
|
function tryResolveTSJS(rawModule, sourceFileAbs) {
|
|
69519
69583
|
if (!rawModule.startsWith(".") && !rawModule.startsWith("/")) {
|
|
69520
69584
|
return null;
|
|
69521
69585
|
}
|
|
69522
|
-
const sourceDir =
|
|
69523
|
-
const baseAbs =
|
|
69586
|
+
const sourceDir = path61.dirname(sourceFileAbs);
|
|
69587
|
+
const baseAbs = path61.resolve(sourceDir, rawModule);
|
|
69524
69588
|
const probe = (basePath) => {
|
|
69525
69589
|
for (const ext of RESOLVE_EXTENSION_CANDIDATES) {
|
|
69526
69590
|
const test = basePath + ext;
|
|
69527
69591
|
try {
|
|
69528
|
-
const
|
|
69529
|
-
if (
|
|
69592
|
+
const stat6 = fs40.statSync(test);
|
|
69593
|
+
if (stat6.isFile())
|
|
69530
69594
|
return test;
|
|
69531
69595
|
} catch {}
|
|
69532
69596
|
}
|
|
69533
69597
|
for (const indexFile of RESOLVE_INDEX_CANDIDATES) {
|
|
69534
|
-
const test =
|
|
69598
|
+
const test = path61.join(basePath, indexFile);
|
|
69535
69599
|
try {
|
|
69536
|
-
const
|
|
69537
|
-
if (
|
|
69600
|
+
const stat6 = fs40.statSync(test);
|
|
69601
|
+
if (stat6.isFile())
|
|
69538
69602
|
return test;
|
|
69539
69603
|
} catch {}
|
|
69540
69604
|
}
|
|
@@ -69561,13 +69625,13 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
69561
69625
|
}
|
|
69562
69626
|
const remainder = rawModule.slice(leadingDots).replace(/\./g, "/");
|
|
69563
69627
|
const upDirs = "../".repeat(Math.max(0, leadingDots - 1));
|
|
69564
|
-
const sourceDir =
|
|
69565
|
-
const baseAbs =
|
|
69628
|
+
const sourceDir = path61.dirname(sourceFileAbs);
|
|
69629
|
+
const baseAbs = path61.resolve(sourceDir, upDirs + remainder);
|
|
69566
69630
|
const accept = (test) => {
|
|
69567
69631
|
try {
|
|
69568
|
-
const
|
|
69569
|
-
if (
|
|
69570
|
-
const rel =
|
|
69632
|
+
const stat6 = fs40.statSync(test);
|
|
69633
|
+
if (stat6.isFile()) {
|
|
69634
|
+
const rel = path61.relative(workspaceRoot, test).replace(/\\/g, "/");
|
|
69571
69635
|
if (rel.startsWith(".."))
|
|
69572
69636
|
return null;
|
|
69573
69637
|
return test;
|
|
@@ -69581,7 +69645,7 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
69581
69645
|
return hit;
|
|
69582
69646
|
}
|
|
69583
69647
|
for (const indexFile of PY_INDEX_CANDIDATES) {
|
|
69584
|
-
const hit = accept(
|
|
69648
|
+
const hit = accept(path61.join(baseAbs, indexFile));
|
|
69585
69649
|
if (hit)
|
|
69586
69650
|
return hit;
|
|
69587
69651
|
}
|
|
@@ -69952,7 +70016,7 @@ function parseRustUses(content) {
|
|
|
69952
70016
|
}
|
|
69953
70017
|
function extractImports2(opts) {
|
|
69954
70018
|
const { absoluteFilePath, workspaceRoot } = opts;
|
|
69955
|
-
const ext =
|
|
70019
|
+
const ext = path61.extname(absoluteFilePath).toLowerCase();
|
|
69956
70020
|
const language = getLanguageFromExtension(ext);
|
|
69957
70021
|
if (!language)
|
|
69958
70022
|
return [];
|
|
@@ -70003,9 +70067,9 @@ function extractImports2(opts) {
|
|
|
70003
70067
|
}
|
|
70004
70068
|
|
|
70005
70069
|
// src/graph/symbol-extractor.ts
|
|
70006
|
-
import * as
|
|
70070
|
+
import * as path62 from "node:path";
|
|
70007
70071
|
function extractExportedSymbols(relativeFilePath, workspaceRoot) {
|
|
70008
|
-
const ext =
|
|
70072
|
+
const ext = path62.extname(relativeFilePath).toLowerCase();
|
|
70009
70073
|
const language = getLanguageFromExtension(ext);
|
|
70010
70074
|
if (!language)
|
|
70011
70075
|
return [];
|
|
@@ -70094,15 +70158,15 @@ function findSourceFiles(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
|
70094
70158
|
if (entry.isDirectory()) {
|
|
70095
70159
|
if (skipDirs.has(entry.name))
|
|
70096
70160
|
continue;
|
|
70097
|
-
stack.push(
|
|
70161
|
+
stack.push(path63.join(dir, entry.name));
|
|
70098
70162
|
continue;
|
|
70099
70163
|
}
|
|
70100
70164
|
if (!entry.isFile())
|
|
70101
70165
|
continue;
|
|
70102
|
-
const ext =
|
|
70166
|
+
const ext = path63.extname(entry.name).toLowerCase();
|
|
70103
70167
|
if (!SOURCE_EXT_SET.has(ext))
|
|
70104
70168
|
continue;
|
|
70105
|
-
out2.push(
|
|
70169
|
+
out2.push(path63.join(dir, entry.name));
|
|
70106
70170
|
}
|
|
70107
70171
|
}
|
|
70108
70172
|
return out2;
|
|
@@ -70130,7 +70194,7 @@ async function buildRepoGraph(workspaceRoot, options = {}) {
|
|
|
70130
70194
|
};
|
|
70131
70195
|
}
|
|
70132
70196
|
async function processFile(absoluteFilePath, workspaceRoot) {
|
|
70133
|
-
const ext =
|
|
70197
|
+
const ext = path63.extname(absoluteFilePath).toLowerCase();
|
|
70134
70198
|
const language = getLanguageFromExtension(ext);
|
|
70135
70199
|
if (!language)
|
|
70136
70200
|
return null;
|
|
@@ -70150,7 +70214,7 @@ async function processFile(absoluteFilePath, workspaceRoot) {
|
|
|
70150
70214
|
} catch {
|
|
70151
70215
|
return null;
|
|
70152
70216
|
}
|
|
70153
|
-
const relPath =
|
|
70217
|
+
const relPath = path63.relative(workspaceRoot, absoluteFilePath).replace(/\\/g, "/");
|
|
70154
70218
|
const imports = extractImports2({
|
|
70155
70219
|
absoluteFilePath,
|
|
70156
70220
|
workspaceRoot,
|
|
@@ -70392,10 +70456,10 @@ function formatSummary(opts) {
|
|
|
70392
70456
|
// src/graph/graph-store.ts
|
|
70393
70457
|
import * as crypto6 from "node:crypto";
|
|
70394
70458
|
import * as fs42 from "node:fs";
|
|
70395
|
-
import * as
|
|
70459
|
+
import * as path64 from "node:path";
|
|
70396
70460
|
var SWARM_DIR = ".swarm";
|
|
70397
70461
|
function getGraphPath2(workspaceRoot) {
|
|
70398
|
-
return
|
|
70462
|
+
return path64.join(workspaceRoot, SWARM_DIR, REPO_GRAPH_FILENAME2);
|
|
70399
70463
|
}
|
|
70400
70464
|
function loadGraph2(workspaceRoot) {
|
|
70401
70465
|
const file3 = getGraphPath2(workspaceRoot);
|
|
@@ -70417,10 +70481,10 @@ function loadGraph2(workspaceRoot) {
|
|
|
70417
70481
|
}
|
|
70418
70482
|
function saveGraph2(workspaceRoot, graph) {
|
|
70419
70483
|
const file3 = getGraphPath2(workspaceRoot);
|
|
70420
|
-
const dir =
|
|
70484
|
+
const dir = path64.dirname(file3);
|
|
70421
70485
|
try {
|
|
70422
|
-
const
|
|
70423
|
-
if (
|
|
70486
|
+
const stat6 = fs42.lstatSync(dir);
|
|
70487
|
+
if (stat6.isSymbolicLink()) {
|
|
70424
70488
|
throw new Error(`refusing to write graph: ${SWARM_DIR}/ is a symbolic link`);
|
|
70425
70489
|
}
|
|
70426
70490
|
} catch (err2) {
|
|
@@ -70456,15 +70520,15 @@ function isGraphFresh(graph, maxAgeMs = 5 * 60 * 1000) {
|
|
|
70456
70520
|
var cache = new Map;
|
|
70457
70521
|
function getCachedGraph2(directory) {
|
|
70458
70522
|
const file3 = getGraphPath2(directory);
|
|
70459
|
-
let
|
|
70523
|
+
let stat6;
|
|
70460
70524
|
try {
|
|
70461
|
-
|
|
70525
|
+
stat6 = fs43.statSync(file3);
|
|
70462
70526
|
} catch {
|
|
70463
70527
|
cache.delete(directory);
|
|
70464
70528
|
return null;
|
|
70465
70529
|
}
|
|
70466
70530
|
const cached3 = cache.get(directory);
|
|
70467
|
-
if (cached3 && cached3.mtimeMs ===
|
|
70531
|
+
if (cached3 && cached3.mtimeMs === stat6.mtimeMs && cached3.size === stat6.size) {
|
|
70468
70532
|
return cached3.graph;
|
|
70469
70533
|
}
|
|
70470
70534
|
const graph = loadGraph2(directory);
|
|
@@ -70472,7 +70536,7 @@ function getCachedGraph2(directory) {
|
|
|
70472
70536
|
cache.delete(directory);
|
|
70473
70537
|
return null;
|
|
70474
70538
|
}
|
|
70475
|
-
cache.set(directory, { graph, mtimeMs:
|
|
70539
|
+
cache.set(directory, { graph, mtimeMs: stat6.mtimeMs, size: stat6.size });
|
|
70476
70540
|
return graph;
|
|
70477
70541
|
}
|
|
70478
70542
|
function buildCoderLocalizationBlock(directory, targetFile) {
|
|
@@ -70523,7 +70587,7 @@ function buildReviewerBlastRadiusBlock(directory, changedFiles) {
|
|
|
70523
70587
|
// src/hooks/semantic-diff-injection.ts
|
|
70524
70588
|
import * as child_process5 from "node:child_process";
|
|
70525
70589
|
import * as fs44 from "node:fs";
|
|
70526
|
-
import * as
|
|
70590
|
+
import * as path66 from "node:path";
|
|
70527
70591
|
|
|
70528
70592
|
// src/diff/ast-diff.ts
|
|
70529
70593
|
init_tree_sitter();
|
|
@@ -71270,17 +71334,17 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
71270
71334
|
const fileConsumers = {};
|
|
71271
71335
|
if (graph) {
|
|
71272
71336
|
for (const f of filesToProcess) {
|
|
71273
|
-
const relativePath =
|
|
71337
|
+
const relativePath = path66.isAbsolute(f) ? path66.relative(directory, f) : f;
|
|
71274
71338
|
const normalized = normalizeGraphPath2(relativePath);
|
|
71275
71339
|
fileConsumers[normalized] = getImporters(graph, normalized).length;
|
|
71276
71340
|
fileConsumers[f] = fileConsumers[normalized];
|
|
71277
71341
|
}
|
|
71278
71342
|
}
|
|
71279
71343
|
for (const filePath of filesToProcess) {
|
|
71280
|
-
const normalizedPath =
|
|
71281
|
-
const resolvedPath =
|
|
71282
|
-
const relativeToDir =
|
|
71283
|
-
if (relativeToDir.startsWith("..") ||
|
|
71344
|
+
const normalizedPath = path66.normalize(filePath);
|
|
71345
|
+
const resolvedPath = path66.resolve(directory, normalizedPath);
|
|
71346
|
+
const relativeToDir = path66.relative(directory, resolvedPath);
|
|
71347
|
+
if (relativeToDir.startsWith("..") || path66.isAbsolute(relativeToDir)) {
|
|
71284
71348
|
continue;
|
|
71285
71349
|
}
|
|
71286
71350
|
try {
|
|
@@ -71307,7 +71371,7 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
71307
71371
|
stdio: "pipe",
|
|
71308
71372
|
maxBuffer: 5 * 1024 * 1024
|
|
71309
71373
|
}) : "";
|
|
71310
|
-
const newContent = fs44.readFileSync(
|
|
71374
|
+
const newContent = fs44.readFileSync(path66.join(directory, filePath), "utf-8");
|
|
71311
71375
|
const astResult = await computeASTDiff(filePath, oldContent, newContent);
|
|
71312
71376
|
if (astResult && (astResult.changes.length > 0 || astResult.error !== undefined)) {
|
|
71313
71377
|
astDiffs.push(astResult);
|
|
@@ -71649,7 +71713,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
71649
71713
|
await fs46.promises.writeFile(darkMatterPath, darkMatterReport, "utf-8");
|
|
71650
71714
|
warn(`[system-enhancer] Dark matter scan complete: ${darkMatter.length} co-change patterns found`);
|
|
71651
71715
|
try {
|
|
71652
|
-
const projectName =
|
|
71716
|
+
const projectName = path68.basename(path68.resolve(directory));
|
|
71653
71717
|
const knowledgeEntries = darkMatterToKnowledgeEntries2(darkMatter, projectName);
|
|
71654
71718
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
71655
71719
|
const existingEntries = await readKnowledge(knowledgePath);
|
|
@@ -71848,7 +71912,7 @@ ${lines.join(`
|
|
|
71848
71912
|
try {
|
|
71849
71913
|
const taskId_ccp = ccpSession?.currentTaskId;
|
|
71850
71914
|
if (taskId_ccp && !taskId_ccp.includes("..") && !taskId_ccp.includes("/") && !taskId_ccp.includes("\\") && !taskId_ccp.includes("\x00")) {
|
|
71851
|
-
const evidencePath =
|
|
71915
|
+
const evidencePath = path68.join(directory, ".swarm", "evidence", `${taskId_ccp}.json`);
|
|
71852
71916
|
if (fs46.existsSync(evidencePath)) {
|
|
71853
71917
|
const evidenceContent = fs46.readFileSync(evidencePath, "utf-8");
|
|
71854
71918
|
const evidenceData = JSON.parse(evidenceContent);
|
|
@@ -72996,13 +73060,13 @@ init_hive_promoter();
|
|
|
72996
73060
|
|
|
72997
73061
|
// src/hooks/incremental-verify.ts
|
|
72998
73062
|
import * as fs47 from "node:fs";
|
|
72999
|
-
import * as
|
|
73063
|
+
import * as path69 from "node:path";
|
|
73000
73064
|
|
|
73001
73065
|
// src/hooks/spawn-helper.ts
|
|
73002
73066
|
import * as child_process6 from "node:child_process";
|
|
73003
73067
|
var WIN32_CMD_BINARIES = new Set(["npm", "npx", "pnpm", "yarn"]);
|
|
73004
73068
|
function spawnAsync(command, cwd, timeoutMs) {
|
|
73005
|
-
return new Promise((
|
|
73069
|
+
return new Promise((resolve24) => {
|
|
73006
73070
|
try {
|
|
73007
73071
|
const [rawCmd, ...args2] = command;
|
|
73008
73072
|
const cmd = process.platform === "win32" && WIN32_CMD_BINARIES.has(rawCmd) && !rawCmd.includes(".") ? `${rawCmd}.cmd` : rawCmd;
|
|
@@ -73049,24 +73113,24 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
73049
73113
|
try {
|
|
73050
73114
|
proc.kill();
|
|
73051
73115
|
} catch {}
|
|
73052
|
-
|
|
73116
|
+
resolve24(null);
|
|
73053
73117
|
}, timeoutMs);
|
|
73054
73118
|
proc.on("close", (code) => {
|
|
73055
73119
|
if (done)
|
|
73056
73120
|
return;
|
|
73057
73121
|
done = true;
|
|
73058
73122
|
clearTimeout(timer);
|
|
73059
|
-
|
|
73123
|
+
resolve24({ exitCode: code ?? 1, stdout, stderr });
|
|
73060
73124
|
});
|
|
73061
73125
|
proc.on("error", () => {
|
|
73062
73126
|
if (done)
|
|
73063
73127
|
return;
|
|
73064
73128
|
done = true;
|
|
73065
73129
|
clearTimeout(timer);
|
|
73066
|
-
|
|
73130
|
+
resolve24(null);
|
|
73067
73131
|
});
|
|
73068
73132
|
} catch {
|
|
73069
|
-
|
|
73133
|
+
resolve24(null);
|
|
73070
73134
|
}
|
|
73071
73135
|
});
|
|
73072
73136
|
}
|
|
@@ -73074,18 +73138,18 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
73074
73138
|
// src/hooks/incremental-verify.ts
|
|
73075
73139
|
var emittedSkipAdvisories = new Set;
|
|
73076
73140
|
function detectPackageManager(projectDir) {
|
|
73077
|
-
if (fs47.existsSync(
|
|
73141
|
+
if (fs47.existsSync(path69.join(projectDir, "bun.lockb")))
|
|
73078
73142
|
return "bun";
|
|
73079
|
-
if (fs47.existsSync(
|
|
73143
|
+
if (fs47.existsSync(path69.join(projectDir, "pnpm-lock.yaml")))
|
|
73080
73144
|
return "pnpm";
|
|
73081
|
-
if (fs47.existsSync(
|
|
73145
|
+
if (fs47.existsSync(path69.join(projectDir, "yarn.lock")))
|
|
73082
73146
|
return "yarn";
|
|
73083
|
-
if (fs47.existsSync(
|
|
73147
|
+
if (fs47.existsSync(path69.join(projectDir, "package-lock.json")))
|
|
73084
73148
|
return "npm";
|
|
73085
73149
|
return "bun";
|
|
73086
73150
|
}
|
|
73087
73151
|
function detectTypecheckCommand(projectDir) {
|
|
73088
|
-
const pkgPath =
|
|
73152
|
+
const pkgPath = path69.join(projectDir, "package.json");
|
|
73089
73153
|
if (fs47.existsSync(pkgPath)) {
|
|
73090
73154
|
try {
|
|
73091
73155
|
const pkg = JSON.parse(fs47.readFileSync(pkgPath, "utf8"));
|
|
@@ -73102,8 +73166,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
73102
73166
|
...pkg.dependencies,
|
|
73103
73167
|
...pkg.devDependencies
|
|
73104
73168
|
};
|
|
73105
|
-
if (!deps?.typescript && !fs47.existsSync(
|
|
73106
|
-
const hasTSMarkers = deps?.typescript || fs47.existsSync(
|
|
73169
|
+
if (!deps?.typescript && !fs47.existsSync(path69.join(projectDir, "tsconfig.json"))) {}
|
|
73170
|
+
const hasTSMarkers = deps?.typescript || fs47.existsSync(path69.join(projectDir, "tsconfig.json"));
|
|
73107
73171
|
if (hasTSMarkers) {
|
|
73108
73172
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
73109
73173
|
}
|
|
@@ -73111,13 +73175,13 @@ function detectTypecheckCommand(projectDir) {
|
|
|
73111
73175
|
return null;
|
|
73112
73176
|
}
|
|
73113
73177
|
}
|
|
73114
|
-
if (fs47.existsSync(
|
|
73178
|
+
if (fs47.existsSync(path69.join(projectDir, "go.mod"))) {
|
|
73115
73179
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
73116
73180
|
}
|
|
73117
|
-
if (fs47.existsSync(
|
|
73181
|
+
if (fs47.existsSync(path69.join(projectDir, "Cargo.toml"))) {
|
|
73118
73182
|
return { command: ["cargo", "check"], language: "rust" };
|
|
73119
73183
|
}
|
|
73120
|
-
if (fs47.existsSync(
|
|
73184
|
+
if (fs47.existsSync(path69.join(projectDir, "pyproject.toml")) || fs47.existsSync(path69.join(projectDir, "requirements.txt")) || fs47.existsSync(path69.join(projectDir, "setup.py"))) {
|
|
73121
73185
|
return { command: null, language: "python" };
|
|
73122
73186
|
}
|
|
73123
73187
|
try {
|
|
@@ -73467,7 +73531,7 @@ init_scope_persistence();
|
|
|
73467
73531
|
init_state();
|
|
73468
73532
|
init_delegation_gate();
|
|
73469
73533
|
init_normalize_tool_name();
|
|
73470
|
-
import * as
|
|
73534
|
+
import * as path71 from "node:path";
|
|
73471
73535
|
var WRITE_TOOLS = new Set(WRITE_TOOL_NAMES);
|
|
73472
73536
|
function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
73473
73537
|
const enabled = config3.enabled ?? true;
|
|
@@ -73525,13 +73589,13 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
|
73525
73589
|
}
|
|
73526
73590
|
function isFileInScope(filePath, scopeEntries, directory) {
|
|
73527
73591
|
const dir = directory ?? process.cwd();
|
|
73528
|
-
const resolvedFile =
|
|
73592
|
+
const resolvedFile = path71.resolve(dir, filePath);
|
|
73529
73593
|
return scopeEntries.some((scope) => {
|
|
73530
|
-
const resolvedScope =
|
|
73594
|
+
const resolvedScope = path71.resolve(dir, scope);
|
|
73531
73595
|
if (resolvedFile === resolvedScope)
|
|
73532
73596
|
return true;
|
|
73533
|
-
const rel =
|
|
73534
|
-
return rel.length > 0 && !rel.startsWith("..") && !
|
|
73597
|
+
const rel = path71.relative(resolvedScope, resolvedFile);
|
|
73598
|
+
return rel.length > 0 && !rel.startsWith("..") && !path71.isAbsolute(rel);
|
|
73535
73599
|
});
|
|
73536
73600
|
}
|
|
73537
73601
|
|
|
@@ -73583,7 +73647,7 @@ function createSelfReviewHook(config3, injectAdvisory) {
|
|
|
73583
73647
|
|
|
73584
73648
|
// src/hooks/slop-detector.ts
|
|
73585
73649
|
import * as fs49 from "node:fs";
|
|
73586
|
-
import * as
|
|
73650
|
+
import * as path72 from "node:path";
|
|
73587
73651
|
var WRITE_EDIT_TOOLS = new Set([
|
|
73588
73652
|
"write",
|
|
73589
73653
|
"edit",
|
|
@@ -73633,7 +73697,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
73633
73697
|
break;
|
|
73634
73698
|
if (entry.isSymbolicLink())
|
|
73635
73699
|
continue;
|
|
73636
|
-
const full =
|
|
73700
|
+
const full = path72.join(dir, entry.name);
|
|
73637
73701
|
if (entry.isDirectory()) {
|
|
73638
73702
|
if (entry.name === "node_modules" || entry.name === ".git")
|
|
73639
73703
|
continue;
|
|
@@ -73648,7 +73712,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
73648
73712
|
return results;
|
|
73649
73713
|
}
|
|
73650
73714
|
function checkDeadExports(content, projectDir, startTime) {
|
|
73651
|
-
const hasPackageJson = fs49.existsSync(
|
|
73715
|
+
const hasPackageJson = fs49.existsSync(path72.join(projectDir, "package.json"));
|
|
73652
73716
|
if (!hasPackageJson)
|
|
73653
73717
|
return null;
|
|
73654
73718
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -73762,14 +73826,14 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
|
|
|
73762
73826
|
for (const utilDir of utilityDirs) {
|
|
73763
73827
|
if (Date.now() > deadline)
|
|
73764
73828
|
break;
|
|
73765
|
-
const utilPath =
|
|
73829
|
+
const utilPath = path72.join(projectDir, utilDir);
|
|
73766
73830
|
if (!fs49.existsSync(utilPath))
|
|
73767
73831
|
continue;
|
|
73768
73832
|
const files = walkFiles(utilPath, [".ts", ".tsx", ".js", ".jsx"], deadline);
|
|
73769
73833
|
for (const file3 of files) {
|
|
73770
73834
|
if (Date.now() > deadline)
|
|
73771
73835
|
break;
|
|
73772
|
-
if (targetFile &&
|
|
73836
|
+
if (targetFile && path72.resolve(file3) === path72.resolve(targetFile))
|
|
73773
73837
|
continue;
|
|
73774
73838
|
try {
|
|
73775
73839
|
const text = fs49.readFileSync(file3, "utf-8");
|
|
@@ -73907,14 +73971,14 @@ function createSteeringConsumedHook(directory) {
|
|
|
73907
73971
|
// src/hooks/trajectory-logger.ts
|
|
73908
73972
|
init_manager2();
|
|
73909
73973
|
import * as fs52 from "node:fs/promises";
|
|
73910
|
-
import * as
|
|
73974
|
+
import * as path74 from "node:path";
|
|
73911
73975
|
|
|
73912
73976
|
// src/prm/trajectory-store.ts
|
|
73913
73977
|
init_utils2();
|
|
73914
73978
|
import * as fs51 from "node:fs/promises";
|
|
73915
|
-
import * as
|
|
73979
|
+
import * as path73 from "node:path";
|
|
73916
73980
|
function getTrajectoryPath(sessionId, directory) {
|
|
73917
|
-
const relativePath =
|
|
73981
|
+
const relativePath = path73.join("trajectories", `${sessionId}.jsonl`);
|
|
73918
73982
|
return validateSwarmPath(directory, relativePath);
|
|
73919
73983
|
}
|
|
73920
73984
|
var _inMemoryTrajectoryCache = new Map;
|
|
@@ -73933,7 +73997,7 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
73933
73997
|
_inMemoryTrajectoryCache.set(sessionId, cached3);
|
|
73934
73998
|
}
|
|
73935
73999
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
73936
|
-
await fs51.mkdir(
|
|
74000
|
+
await fs51.mkdir(path73.dirname(trajectoryPath), { recursive: true });
|
|
73937
74001
|
const line = `${JSON.stringify(entry)}
|
|
73938
74002
|
`;
|
|
73939
74003
|
await fs51.appendFile(trajectoryPath, line, "utf-8");
|
|
@@ -73972,10 +74036,10 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
|
|
|
73972
74036
|
for (const entry of entries) {
|
|
73973
74037
|
if (!entry.isFile())
|
|
73974
74038
|
continue;
|
|
73975
|
-
const filePath =
|
|
74039
|
+
const filePath = path73.join(dirPath, entry.name);
|
|
73976
74040
|
try {
|
|
73977
|
-
const
|
|
73978
|
-
if (now -
|
|
74041
|
+
const stat7 = await fs51.stat(filePath);
|
|
74042
|
+
if (now - stat7.mtimeMs > cutoffMs) {
|
|
73979
74043
|
await fs51.unlink(filePath);
|
|
73980
74044
|
}
|
|
73981
74045
|
} catch {}
|
|
@@ -74164,10 +74228,10 @@ function createTrajectoryLoggerHook(config3, _directory) {
|
|
|
74164
74228
|
elapsed_ms
|
|
74165
74229
|
};
|
|
74166
74230
|
const sanitized = sanitizeTaskId2(taskId);
|
|
74167
|
-
const relativePath =
|
|
74231
|
+
const relativePath = path74.join("evidence", sanitized, "trajectory.jsonl");
|
|
74168
74232
|
const trajectoryPath = validateSwarmPath(_directory, relativePath);
|
|
74169
74233
|
try {
|
|
74170
|
-
await fs52.mkdir(
|
|
74234
|
+
await fs52.mkdir(path74.dirname(trajectoryPath), { recursive: true });
|
|
74171
74235
|
const line = `${JSON.stringify(entry)}
|
|
74172
74236
|
`;
|
|
74173
74237
|
await fs52.appendFile(trajectoryPath, line, "utf-8");
|
|
@@ -74718,16 +74782,16 @@ init_telemetry();
|
|
|
74718
74782
|
|
|
74719
74783
|
// src/prm/replay.ts
|
|
74720
74784
|
import { promises as fs53 } from "node:fs";
|
|
74721
|
-
import
|
|
74785
|
+
import path75 from "node:path";
|
|
74722
74786
|
function isPathSafe2(targetPath, basePath) {
|
|
74723
|
-
const resolvedTarget =
|
|
74724
|
-
const resolvedBase =
|
|
74725
|
-
const rel =
|
|
74726
|
-
return !rel.startsWith("..") && !
|
|
74787
|
+
const resolvedTarget = path75.resolve(targetPath);
|
|
74788
|
+
const resolvedBase = path75.resolve(basePath);
|
|
74789
|
+
const rel = path75.relative(resolvedBase, resolvedTarget);
|
|
74790
|
+
return !rel.startsWith("..") && !path75.isAbsolute(rel);
|
|
74727
74791
|
}
|
|
74728
74792
|
function isWithinReplaysDir(targetPath) {
|
|
74729
|
-
const resolved =
|
|
74730
|
-
const parts2 = resolved.split(
|
|
74793
|
+
const resolved = path75.resolve(targetPath);
|
|
74794
|
+
const parts2 = resolved.split(path75.sep);
|
|
74731
74795
|
for (let i2 = 0;i2 < parts2.length - 1; i2++) {
|
|
74732
74796
|
if (parts2[i2] === ".swarm" && parts2[i2 + 1] === "replays") {
|
|
74733
74797
|
return true;
|
|
@@ -74740,10 +74804,10 @@ function sanitizeFilename(input) {
|
|
|
74740
74804
|
}
|
|
74741
74805
|
async function startReplayRecording(sessionID, directory) {
|
|
74742
74806
|
try {
|
|
74743
|
-
const replayDir =
|
|
74807
|
+
const replayDir = path75.join(directory, ".swarm", "replays");
|
|
74744
74808
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
74745
74809
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
74746
|
-
const filepath =
|
|
74810
|
+
const filepath = path75.join(replayDir, filename);
|
|
74747
74811
|
if (!isPathSafe2(filepath, replayDir)) {
|
|
74748
74812
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
74749
74813
|
return null;
|
|
@@ -75117,7 +75181,7 @@ init_telemetry();
|
|
|
75117
75181
|
init_dist();
|
|
75118
75182
|
init_create_tool();
|
|
75119
75183
|
import * as fs54 from "node:fs";
|
|
75120
|
-
import * as
|
|
75184
|
+
import * as path76 from "node:path";
|
|
75121
75185
|
init_path_security();
|
|
75122
75186
|
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
75123
75187
|
function containsWindowsAttacks2(str) {
|
|
@@ -75134,14 +75198,14 @@ function containsWindowsAttacks2(str) {
|
|
|
75134
75198
|
}
|
|
75135
75199
|
function isPathInWorkspace2(filePath, workspace) {
|
|
75136
75200
|
try {
|
|
75137
|
-
const resolvedPath =
|
|
75201
|
+
const resolvedPath = path76.resolve(workspace, filePath);
|
|
75138
75202
|
if (!fs54.existsSync(resolvedPath)) {
|
|
75139
75203
|
return true;
|
|
75140
75204
|
}
|
|
75141
75205
|
const realWorkspace = fs54.realpathSync(workspace);
|
|
75142
75206
|
const realResolvedPath = fs54.realpathSync(resolvedPath);
|
|
75143
|
-
const relativePath =
|
|
75144
|
-
if (relativePath.startsWith("..") ||
|
|
75207
|
+
const relativePath = path76.relative(realWorkspace, realResolvedPath);
|
|
75208
|
+
if (relativePath.startsWith("..") || path76.isAbsolute(relativePath)) {
|
|
75145
75209
|
return false;
|
|
75146
75210
|
}
|
|
75147
75211
|
return true;
|
|
@@ -75150,7 +75214,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
75150
75214
|
}
|
|
75151
75215
|
}
|
|
75152
75216
|
function processFile2(file3, cwd, exportedOnly) {
|
|
75153
|
-
const ext =
|
|
75217
|
+
const ext = path76.extname(file3);
|
|
75154
75218
|
if (containsControlChars(file3)) {
|
|
75155
75219
|
return {
|
|
75156
75220
|
file: file3,
|
|
@@ -75183,7 +75247,7 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
75183
75247
|
errorType: "path-outside-workspace"
|
|
75184
75248
|
};
|
|
75185
75249
|
}
|
|
75186
|
-
const fullPath =
|
|
75250
|
+
const fullPath = path76.join(cwd, file3);
|
|
75187
75251
|
if (!fs54.existsSync(fullPath)) {
|
|
75188
75252
|
return {
|
|
75189
75253
|
file: file3,
|
|
@@ -75475,15 +75539,15 @@ init_task_id();
|
|
|
75475
75539
|
init_create_tool();
|
|
75476
75540
|
init_resolve_working_directory();
|
|
75477
75541
|
import * as fs55 from "node:fs";
|
|
75478
|
-
import * as
|
|
75542
|
+
import * as path77 from "node:path";
|
|
75479
75543
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
75480
75544
|
function isValidTaskId3(taskId) {
|
|
75481
75545
|
return isStrictTaskId(taskId);
|
|
75482
75546
|
}
|
|
75483
75547
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
75484
|
-
const normalizedWorkspace =
|
|
75485
|
-
const swarmPath =
|
|
75486
|
-
const normalizedPath =
|
|
75548
|
+
const normalizedWorkspace = path77.resolve(workspaceRoot);
|
|
75549
|
+
const swarmPath = path77.join(normalizedWorkspace, ".swarm", "evidence");
|
|
75550
|
+
const normalizedPath = path77.resolve(filePath);
|
|
75487
75551
|
return normalizedPath.startsWith(swarmPath);
|
|
75488
75552
|
}
|
|
75489
75553
|
function readEvidenceFile(evidencePath) {
|
|
@@ -75564,7 +75628,7 @@ var check_gate_status = createSwarmTool({
|
|
|
75564
75628
|
};
|
|
75565
75629
|
return JSON.stringify(errorResult, null, 2);
|
|
75566
75630
|
}
|
|
75567
|
-
const evidencePath =
|
|
75631
|
+
const evidencePath = path77.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
75568
75632
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
75569
75633
|
const errorResult = {
|
|
75570
75634
|
taskId: taskIdInput,
|
|
@@ -75661,7 +75725,7 @@ init_state();
|
|
|
75661
75725
|
init_create_tool();
|
|
75662
75726
|
init_resolve_working_directory();
|
|
75663
75727
|
import * as fs56 from "node:fs";
|
|
75664
|
-
import * as
|
|
75728
|
+
import * as path78 from "node:path";
|
|
75665
75729
|
function extractMatches(regex, text) {
|
|
75666
75730
|
return Array.from(text.matchAll(regex));
|
|
75667
75731
|
}
|
|
@@ -75813,10 +75877,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
75813
75877
|
let hasFileReadFailure = false;
|
|
75814
75878
|
for (const filePath of fileTargets) {
|
|
75815
75879
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
75816
|
-
const resolvedPath =
|
|
75817
|
-
const projectRoot =
|
|
75818
|
-
const relative16 =
|
|
75819
|
-
const withinProject = relative16 === "" || !relative16.startsWith("..") && !
|
|
75880
|
+
const resolvedPath = path78.resolve(directory, normalizedPath);
|
|
75881
|
+
const projectRoot = path78.resolve(directory);
|
|
75882
|
+
const relative16 = path78.relative(projectRoot, resolvedPath);
|
|
75883
|
+
const withinProject = relative16 === "" || !relative16.startsWith("..") && !path78.isAbsolute(relative16);
|
|
75820
75884
|
if (!withinProject) {
|
|
75821
75885
|
blockedTasks.push({
|
|
75822
75886
|
task_id: task.id,
|
|
@@ -75871,8 +75935,8 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
75871
75935
|
blockedTasks
|
|
75872
75936
|
};
|
|
75873
75937
|
try {
|
|
75874
|
-
const evidenceDir =
|
|
75875
|
-
const evidencePath =
|
|
75938
|
+
const evidenceDir = path78.join(directory, ".swarm", "evidence", `${phase}`);
|
|
75939
|
+
const evidencePath = path78.join(evidenceDir, "completion-verify.json");
|
|
75876
75940
|
fs56.mkdirSync(evidenceDir, { recursive: true });
|
|
75877
75941
|
const evidenceBundle = {
|
|
75878
75942
|
schema_version: "1.0.0",
|
|
@@ -75949,11 +76013,11 @@ var completion_verify = createSwarmTool({
|
|
|
75949
76013
|
// src/tools/complexity-hotspots.ts
|
|
75950
76014
|
init_zod();
|
|
75951
76015
|
import * as fs58 from "node:fs";
|
|
75952
|
-
import * as
|
|
76016
|
+
import * as path80 from "node:path";
|
|
75953
76017
|
|
|
75954
76018
|
// src/quality/metrics.ts
|
|
75955
76019
|
import * as fs57 from "node:fs";
|
|
75956
|
-
import * as
|
|
76020
|
+
import * as path79 from "node:path";
|
|
75957
76021
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
75958
76022
|
var MIN_DUPLICATION_LINES = 10;
|
|
75959
76023
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -75991,8 +76055,8 @@ function estimateCyclomaticComplexity(content) {
|
|
|
75991
76055
|
}
|
|
75992
76056
|
function getComplexityForFile(filePath) {
|
|
75993
76057
|
try {
|
|
75994
|
-
const
|
|
75995
|
-
if (
|
|
76058
|
+
const stat7 = fs57.statSync(filePath);
|
|
76059
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES4) {
|
|
75996
76060
|
return null;
|
|
75997
76061
|
}
|
|
75998
76062
|
const content = fs57.readFileSync(filePath, "utf-8");
|
|
@@ -76005,7 +76069,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
76005
76069
|
let totalComplexity = 0;
|
|
76006
76070
|
const analyzedFiles = [];
|
|
76007
76071
|
for (const file3 of files) {
|
|
76008
|
-
const fullPath =
|
|
76072
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76009
76073
|
if (!fs57.existsSync(fullPath)) {
|
|
76010
76074
|
continue;
|
|
76011
76075
|
}
|
|
@@ -76128,7 +76192,7 @@ function countGoExports(content) {
|
|
|
76128
76192
|
function getExportCountForFile(filePath) {
|
|
76129
76193
|
try {
|
|
76130
76194
|
const content = fs57.readFileSync(filePath, "utf-8");
|
|
76131
|
-
const ext =
|
|
76195
|
+
const ext = path79.extname(filePath).toLowerCase();
|
|
76132
76196
|
switch (ext) {
|
|
76133
76197
|
case ".ts":
|
|
76134
76198
|
case ".tsx":
|
|
@@ -76154,7 +76218,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
76154
76218
|
let totalExports = 0;
|
|
76155
76219
|
const analyzedFiles = [];
|
|
76156
76220
|
for (const file3 of files) {
|
|
76157
|
-
const fullPath =
|
|
76221
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76158
76222
|
if (!fs57.existsSync(fullPath)) {
|
|
76159
76223
|
continue;
|
|
76160
76224
|
}
|
|
@@ -76188,13 +76252,13 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
76188
76252
|
let duplicateLines = 0;
|
|
76189
76253
|
const analyzedFiles = [];
|
|
76190
76254
|
for (const file3 of files) {
|
|
76191
|
-
const fullPath =
|
|
76255
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76192
76256
|
if (!fs57.existsSync(fullPath)) {
|
|
76193
76257
|
continue;
|
|
76194
76258
|
}
|
|
76195
76259
|
try {
|
|
76196
|
-
const
|
|
76197
|
-
if (
|
|
76260
|
+
const stat7 = fs57.statSync(fullPath);
|
|
76261
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES4) {
|
|
76198
76262
|
continue;
|
|
76199
76263
|
}
|
|
76200
76264
|
const content = fs57.readFileSync(fullPath, "utf-8");
|
|
@@ -76221,8 +76285,8 @@ function countCodeLines(content) {
|
|
|
76221
76285
|
return lines.length;
|
|
76222
76286
|
}
|
|
76223
76287
|
function isTestFile(filePath) {
|
|
76224
|
-
const basename11 =
|
|
76225
|
-
const _ext =
|
|
76288
|
+
const basename11 = path79.basename(filePath);
|
|
76289
|
+
const _ext = path79.extname(filePath).toLowerCase();
|
|
76226
76290
|
const testPatterns = [
|
|
76227
76291
|
".test.",
|
|
76228
76292
|
".spec.",
|
|
@@ -76303,8 +76367,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
76303
76367
|
}
|
|
76304
76368
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
76305
76369
|
}
|
|
76306
|
-
function matchesGlobSegment(
|
|
76307
|
-
const normalizedPath =
|
|
76370
|
+
function matchesGlobSegment(path80, glob) {
|
|
76371
|
+
const normalizedPath = path80.replace(/\\/g, "/");
|
|
76308
76372
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
76309
76373
|
if (normalizedPath.includes("//")) {
|
|
76310
76374
|
return false;
|
|
@@ -76335,8 +76399,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
76335
76399
|
function hasGlobstar(glob) {
|
|
76336
76400
|
return glob.includes("**");
|
|
76337
76401
|
}
|
|
76338
|
-
function globMatches(
|
|
76339
|
-
const normalizedPath =
|
|
76402
|
+
function globMatches(path80, glob) {
|
|
76403
|
+
const normalizedPath = path80.replace(/\\/g, "/");
|
|
76340
76404
|
if (!glob || glob === "") {
|
|
76341
76405
|
if (normalizedPath.includes("//")) {
|
|
76342
76406
|
return false;
|
|
@@ -76372,7 +76436,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
76372
76436
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
76373
76437
|
let testLines = 0;
|
|
76374
76438
|
let codeLines = 0;
|
|
76375
|
-
const srcDir =
|
|
76439
|
+
const srcDir = path79.join(workingDir, "src");
|
|
76376
76440
|
if (fs57.existsSync(srcDir)) {
|
|
76377
76441
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
76378
76442
|
codeLines += lines;
|
|
@@ -76380,14 +76444,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
76380
76444
|
}
|
|
76381
76445
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
76382
76446
|
for (const dir of possibleSrcDirs) {
|
|
76383
|
-
const dirPath =
|
|
76447
|
+
const dirPath = path79.join(workingDir, dir);
|
|
76384
76448
|
if (fs57.existsSync(dirPath)) {
|
|
76385
76449
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
76386
76450
|
codeLines += lines;
|
|
76387
76451
|
});
|
|
76388
76452
|
}
|
|
76389
76453
|
}
|
|
76390
|
-
const testsDir =
|
|
76454
|
+
const testsDir = path79.join(workingDir, "tests");
|
|
76391
76455
|
if (fs57.existsSync(testsDir)) {
|
|
76392
76456
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
76393
76457
|
testLines += lines;
|
|
@@ -76395,7 +76459,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
76395
76459
|
}
|
|
76396
76460
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
76397
76461
|
for (const dir of possibleTestDirs) {
|
|
76398
|
-
const dirPath =
|
|
76462
|
+
const dirPath = path79.join(workingDir, dir);
|
|
76399
76463
|
if (fs57.existsSync(dirPath) && dirPath !== testsDir) {
|
|
76400
76464
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
76401
76465
|
testLines += lines;
|
|
@@ -76410,7 +76474,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
76410
76474
|
try {
|
|
76411
76475
|
const entries = fs57.readdirSync(dirPath, { withFileTypes: true });
|
|
76412
76476
|
for (const entry of entries) {
|
|
76413
|
-
const fullPath =
|
|
76477
|
+
const fullPath = path79.join(dirPath, entry.name);
|
|
76414
76478
|
if (entry.isDirectory()) {
|
|
76415
76479
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
76416
76480
|
continue;
|
|
@@ -76418,7 +76482,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
76418
76482
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
76419
76483
|
} else if (entry.isFile()) {
|
|
76420
76484
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
76421
|
-
const ext =
|
|
76485
|
+
const ext = path79.extname(entry.name).toLowerCase();
|
|
76422
76486
|
const validExts = [
|
|
76423
76487
|
".ts",
|
|
76424
76488
|
".tsx",
|
|
@@ -76654,8 +76718,8 @@ async function getGitChurn(days, directory) {
|
|
|
76654
76718
|
}
|
|
76655
76719
|
function getComplexityForFile2(filePath) {
|
|
76656
76720
|
try {
|
|
76657
|
-
const
|
|
76658
|
-
if (
|
|
76721
|
+
const stat7 = fs58.statSync(filePath);
|
|
76722
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES5) {
|
|
76659
76723
|
return null;
|
|
76660
76724
|
}
|
|
76661
76725
|
const content = fs58.readFileSync(filePath, "utf-8");
|
|
@@ -76669,7 +76733,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
76669
76733
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
76670
76734
|
const filteredChurn = new Map;
|
|
76671
76735
|
for (const [file3, count] of churnMap) {
|
|
76672
|
-
const ext =
|
|
76736
|
+
const ext = path80.extname(file3).toLowerCase();
|
|
76673
76737
|
if (extSet.has(ext)) {
|
|
76674
76738
|
filteredChurn.set(file3, count);
|
|
76675
76739
|
}
|
|
@@ -76680,7 +76744,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
76680
76744
|
for (const [file3, churnCount] of filteredChurn) {
|
|
76681
76745
|
let fullPath = file3;
|
|
76682
76746
|
if (!fs58.existsSync(fullPath)) {
|
|
76683
|
-
fullPath =
|
|
76747
|
+
fullPath = path80.join(cwd, file3);
|
|
76684
76748
|
}
|
|
76685
76749
|
const complexity = getComplexityForFile2(fullPath);
|
|
76686
76750
|
if (complexity !== null) {
|
|
@@ -76849,7 +76913,7 @@ ${body2}`);
|
|
|
76849
76913
|
// src/council/council-evidence-writer.ts
|
|
76850
76914
|
import {
|
|
76851
76915
|
appendFileSync as appendFileSync6,
|
|
76852
|
-
existsSync as
|
|
76916
|
+
existsSync as existsSync40,
|
|
76853
76917
|
mkdirSync as mkdirSync19,
|
|
76854
76918
|
readFileSync as readFileSync36,
|
|
76855
76919
|
writeFileSync as writeFileSync12
|
|
@@ -76892,7 +76956,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76892
76956
|
mkdirSync19(dir, { recursive: true });
|
|
76893
76957
|
const filePath = join69(dir, `${synthesis.taskId}.json`);
|
|
76894
76958
|
const existingRoot = Object.create(null);
|
|
76895
|
-
if (
|
|
76959
|
+
if (existsSync40(filePath)) {
|
|
76896
76960
|
try {
|
|
76897
76961
|
const parsed = JSON.parse(readFileSync36(filePath, "utf-8"));
|
|
76898
76962
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -76941,7 +77005,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76941
77005
|
|
|
76942
77006
|
// src/council/council-service.ts
|
|
76943
77007
|
import fs59 from "node:fs";
|
|
76944
|
-
import
|
|
77008
|
+
import path81 from "node:path";
|
|
76945
77009
|
|
|
76946
77010
|
// src/council/types.ts
|
|
76947
77011
|
var COUNCIL_DEFAULTS = {
|
|
@@ -77101,9 +77165,9 @@ function synthesizePhaseCouncilAdvisory(phaseNumber, phaseSummary, verdicts, rou
|
|
|
77101
77165
|
const unifiedFeedbackMd = buildPhaseCouncilFeedback(phaseNumber, phaseSummary, overallVerdict, rejectingMembers, requiredFixes, advisoryFindings, unresolvedConflicts, roundNumber, cfg.maxRounds);
|
|
77102
77166
|
const evidencePath = `.swarm/evidence/${phaseNumber}/phase-council.json`;
|
|
77103
77167
|
const baseDir = workingDir ?? process.cwd();
|
|
77104
|
-
const evidenceDir =
|
|
77168
|
+
const evidenceDir = path81.join(baseDir, ".swarm", "evidence", String(phaseNumber));
|
|
77105
77169
|
fs59.mkdirSync(evidenceDir, { recursive: true });
|
|
77106
|
-
const evidenceFile =
|
|
77170
|
+
const evidenceFile = path81.join(evidenceDir, "phase-council.json");
|
|
77107
77171
|
const evidenceBundle = {
|
|
77108
77172
|
entries: [
|
|
77109
77173
|
{
|
|
@@ -77206,7 +77270,7 @@ function buildPhaseCouncilFeedback(phaseNumber, phaseSummary, verdict, vetoedBy,
|
|
|
77206
77270
|
}
|
|
77207
77271
|
|
|
77208
77272
|
// src/council/criteria-store.ts
|
|
77209
|
-
import { existsSync as
|
|
77273
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync20, readFileSync as readFileSync37, writeFileSync as writeFileSync13 } from "node:fs";
|
|
77210
77274
|
import { join as join70 } from "node:path";
|
|
77211
77275
|
var COUNCIL_DIR = ".swarm/council";
|
|
77212
77276
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
@@ -77221,7 +77285,7 @@ function writeCriteria(workingDir, taskId, criteria) {
|
|
|
77221
77285
|
}
|
|
77222
77286
|
function readCriteria(workingDir, taskId) {
|
|
77223
77287
|
const filePath = join70(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
|
|
77224
|
-
if (!
|
|
77288
|
+
if (!existsSync41(filePath))
|
|
77225
77289
|
return null;
|
|
77226
77290
|
try {
|
|
77227
77291
|
const parsed = JSON.parse(readFileSync37(filePath, "utf-8"));
|
|
@@ -77373,7 +77437,7 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
77373
77437
|
init_zod();
|
|
77374
77438
|
init_loader();
|
|
77375
77439
|
import * as fs60 from "node:fs";
|
|
77376
|
-
import * as
|
|
77440
|
+
import * as path82 from "node:path";
|
|
77377
77441
|
|
|
77378
77442
|
// src/council/general-council-advisory.ts
|
|
77379
77443
|
var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
|
|
@@ -77801,10 +77865,10 @@ var convene_general_council = createSwarmTool({
|
|
|
77801
77865
|
const round1 = input.round1Responses;
|
|
77802
77866
|
const round2 = input.round2Responses ?? [];
|
|
77803
77867
|
const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
|
|
77804
|
-
const evidenceDir =
|
|
77868
|
+
const evidenceDir = path82.join(workingDir, ".swarm", "council", "general");
|
|
77805
77869
|
const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
|
|
77806
77870
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
77807
|
-
const evidencePath =
|
|
77871
|
+
const evidencePath = path82.join(evidenceDir, evidenceFile);
|
|
77808
77872
|
try {
|
|
77809
77873
|
await fs60.promises.mkdir(evidenceDir, { recursive: true });
|
|
77810
77874
|
await fs60.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
@@ -78039,7 +78103,7 @@ init_state();
|
|
|
78039
78103
|
init_task_id();
|
|
78040
78104
|
init_create_tool();
|
|
78041
78105
|
import * as fs61 from "node:fs";
|
|
78042
|
-
import * as
|
|
78106
|
+
import * as path83 from "node:path";
|
|
78043
78107
|
function validateTaskIdFormat2(taskId) {
|
|
78044
78108
|
return validateTaskIdFormat(taskId);
|
|
78045
78109
|
}
|
|
@@ -78113,8 +78177,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78113
78177
|
};
|
|
78114
78178
|
}
|
|
78115
78179
|
}
|
|
78116
|
-
normalizedDir =
|
|
78117
|
-
const pathParts = normalizedDir.split(
|
|
78180
|
+
normalizedDir = path83.normalize(args2.working_directory);
|
|
78181
|
+
const pathParts = normalizedDir.split(path83.sep);
|
|
78118
78182
|
if (pathParts.includes("..")) {
|
|
78119
78183
|
return {
|
|
78120
78184
|
success: false,
|
|
@@ -78124,10 +78188,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78124
78188
|
]
|
|
78125
78189
|
};
|
|
78126
78190
|
}
|
|
78127
|
-
const resolvedDir =
|
|
78191
|
+
const resolvedDir = path83.resolve(normalizedDir);
|
|
78128
78192
|
try {
|
|
78129
78193
|
const realPath = fs61.realpathSync(resolvedDir);
|
|
78130
|
-
const planPath2 =
|
|
78194
|
+
const planPath2 = path83.join(realPath, ".swarm", "plan.json");
|
|
78131
78195
|
if (!fs61.existsSync(planPath2)) {
|
|
78132
78196
|
return {
|
|
78133
78197
|
success: false,
|
|
@@ -78151,7 +78215,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78151
78215
|
console.warn("[declare-scope] fallbackDir is undefined, falling back to process.cwd()");
|
|
78152
78216
|
}
|
|
78153
78217
|
const directory = normalizedDir || fallbackDir;
|
|
78154
|
-
const planPath =
|
|
78218
|
+
const planPath = path83.resolve(directory, ".swarm", "plan.json");
|
|
78155
78219
|
if (!fs61.existsSync(planPath)) {
|
|
78156
78220
|
return {
|
|
78157
78221
|
success: false,
|
|
@@ -78191,8 +78255,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78191
78255
|
const normalizeErrors = [];
|
|
78192
78256
|
const dir = normalizedDir || fallbackDir || process.cwd();
|
|
78193
78257
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
78194
|
-
if (
|
|
78195
|
-
const relativePath =
|
|
78258
|
+
if (path83.isAbsolute(file3)) {
|
|
78259
|
+
const relativePath = path83.relative(dir, file3).replace(/\\/g, "/");
|
|
78196
78260
|
if (relativePath.startsWith("..")) {
|
|
78197
78261
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
78198
78262
|
return file3;
|
|
@@ -78253,7 +78317,7 @@ var declare_scope = createSwarmTool({
|
|
|
78253
78317
|
init_zod();
|
|
78254
78318
|
import * as child_process7 from "node:child_process";
|
|
78255
78319
|
import * as fs62 from "node:fs";
|
|
78256
|
-
import * as
|
|
78320
|
+
import * as path84 from "node:path";
|
|
78257
78321
|
init_create_tool();
|
|
78258
78322
|
var MAX_DIFF_LINES = 500;
|
|
78259
78323
|
var DIFF_TIMEOUT_MS = 30000;
|
|
@@ -78282,20 +78346,20 @@ function validateBase(base) {
|
|
|
78282
78346
|
function validatePaths(paths) {
|
|
78283
78347
|
if (!paths)
|
|
78284
78348
|
return null;
|
|
78285
|
-
for (const
|
|
78286
|
-
if (!
|
|
78349
|
+
for (const path85 of paths) {
|
|
78350
|
+
if (!path85 || path85.length === 0) {
|
|
78287
78351
|
return "empty path not allowed";
|
|
78288
78352
|
}
|
|
78289
|
-
if (
|
|
78353
|
+
if (path85.length > MAX_PATH_LENGTH) {
|
|
78290
78354
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
78291
78355
|
}
|
|
78292
|
-
if (SHELL_METACHARACTERS2.test(
|
|
78356
|
+
if (SHELL_METACHARACTERS2.test(path85)) {
|
|
78293
78357
|
return "path contains shell metacharacters";
|
|
78294
78358
|
}
|
|
78295
|
-
if (
|
|
78359
|
+
if (path85.startsWith("-")) {
|
|
78296
78360
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
78297
78361
|
}
|
|
78298
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
78362
|
+
if (CONTROL_CHAR_PATTERN2.test(path85)) {
|
|
78299
78363
|
return "path contains control characters";
|
|
78300
78364
|
}
|
|
78301
78365
|
}
|
|
@@ -78401,8 +78465,8 @@ var diff = createSwarmTool({
|
|
|
78401
78465
|
if (parts2.length >= 3) {
|
|
78402
78466
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
78403
78467
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
78404
|
-
const
|
|
78405
|
-
files.push({ path:
|
|
78468
|
+
const path85 = parts2[2];
|
|
78469
|
+
files.push({ path: path85, additions, deletions });
|
|
78406
78470
|
}
|
|
78407
78471
|
}
|
|
78408
78472
|
const contractChanges = [];
|
|
@@ -78442,7 +78506,7 @@ var diff = createSwarmTool({
|
|
|
78442
78506
|
} else if (base === "unstaged") {
|
|
78443
78507
|
const oldRef = `:${file3.path}`;
|
|
78444
78508
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
78445
|
-
newContent = fs62.readFileSync(
|
|
78509
|
+
newContent = fs62.readFileSync(path84.join(directory, file3.path), "utf-8");
|
|
78446
78510
|
} else {
|
|
78447
78511
|
const oldRef = `${base}:${file3.path}`;
|
|
78448
78512
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -78517,7 +78581,7 @@ var diff = createSwarmTool({
|
|
|
78517
78581
|
init_zod();
|
|
78518
78582
|
import * as child_process8 from "node:child_process";
|
|
78519
78583
|
import * as fs63 from "node:fs";
|
|
78520
|
-
import * as
|
|
78584
|
+
import * as path85 from "node:path";
|
|
78521
78585
|
init_create_tool();
|
|
78522
78586
|
var diff_summary = createSwarmTool({
|
|
78523
78587
|
description: "Generate a filtered semantic diff summary from AST analysis. Returns SemanticDiffSummary with optional filtering by classification or riskLevel.",
|
|
@@ -78565,7 +78629,7 @@ var diff_summary = createSwarmTool({
|
|
|
78565
78629
|
}
|
|
78566
78630
|
try {
|
|
78567
78631
|
let oldContent;
|
|
78568
|
-
const newContent = fs63.readFileSync(
|
|
78632
|
+
const newContent = fs63.readFileSync(path85.join(workingDir, filePath), "utf-8");
|
|
78569
78633
|
if (fileExistsInHead) {
|
|
78570
78634
|
oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
|
|
78571
78635
|
encoding: "utf-8",
|
|
@@ -78794,7 +78858,7 @@ init_zod();
|
|
|
78794
78858
|
init_create_tool();
|
|
78795
78859
|
init_path_security();
|
|
78796
78860
|
import * as fs64 from "node:fs";
|
|
78797
|
-
import * as
|
|
78861
|
+
import * as path86 from "node:path";
|
|
78798
78862
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
78799
78863
|
var MAX_EVIDENCE_FILES = 1000;
|
|
78800
78864
|
var EVIDENCE_DIR3 = ".swarm/evidence";
|
|
@@ -78821,9 +78885,9 @@ function validateRequiredTypes(input) {
|
|
|
78821
78885
|
return null;
|
|
78822
78886
|
}
|
|
78823
78887
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
78824
|
-
const normalizedCwd =
|
|
78825
|
-
const swarmPath =
|
|
78826
|
-
const normalizedPath =
|
|
78888
|
+
const normalizedCwd = path86.resolve(cwd);
|
|
78889
|
+
const swarmPath = path86.join(normalizedCwd, ".swarm");
|
|
78890
|
+
const normalizedPath = path86.resolve(filePath);
|
|
78827
78891
|
return normalizedPath.startsWith(swarmPath);
|
|
78828
78892
|
}
|
|
78829
78893
|
function parseCompletedTasks(planContent) {
|
|
@@ -78853,15 +78917,15 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
78853
78917
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
78854
78918
|
continue;
|
|
78855
78919
|
}
|
|
78856
|
-
const filePath =
|
|
78920
|
+
const filePath = path86.join(evidenceDir, filename);
|
|
78857
78921
|
try {
|
|
78858
|
-
const resolvedPath =
|
|
78859
|
-
const evidenceDirResolved =
|
|
78922
|
+
const resolvedPath = path86.resolve(filePath);
|
|
78923
|
+
const evidenceDirResolved = path86.resolve(evidenceDir);
|
|
78860
78924
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
78861
78925
|
continue;
|
|
78862
78926
|
}
|
|
78863
|
-
const
|
|
78864
|
-
if (!
|
|
78927
|
+
const stat7 = fs64.lstatSync(filePath);
|
|
78928
|
+
if (!stat7.isFile()) {
|
|
78865
78929
|
continue;
|
|
78866
78930
|
}
|
|
78867
78931
|
} catch {
|
|
@@ -78974,7 +79038,7 @@ var evidence_check = createSwarmTool({
|
|
|
78974
79038
|
return JSON.stringify(errorResult, null, 2);
|
|
78975
79039
|
}
|
|
78976
79040
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
78977
|
-
const planPath =
|
|
79041
|
+
const planPath = path86.join(cwd, PLAN_FILE);
|
|
78978
79042
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
78979
79043
|
const errorResult = {
|
|
78980
79044
|
error: "plan file path validation failed",
|
|
@@ -79006,7 +79070,7 @@ var evidence_check = createSwarmTool({
|
|
|
79006
79070
|
};
|
|
79007
79071
|
return JSON.stringify(result2, null, 2);
|
|
79008
79072
|
}
|
|
79009
|
-
const evidenceDir =
|
|
79073
|
+
const evidenceDir = path86.join(cwd, EVIDENCE_DIR3);
|
|
79010
79074
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
79011
79075
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
79012
79076
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -79024,7 +79088,7 @@ var evidence_check = createSwarmTool({
|
|
|
79024
79088
|
init_zod();
|
|
79025
79089
|
init_create_tool();
|
|
79026
79090
|
import * as fs65 from "node:fs";
|
|
79027
|
-
import * as
|
|
79091
|
+
import * as path87 from "node:path";
|
|
79028
79092
|
var EXT_MAP = {
|
|
79029
79093
|
python: ".py",
|
|
79030
79094
|
py: ".py",
|
|
@@ -79105,12 +79169,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
79105
79169
|
if (prefix) {
|
|
79106
79170
|
filename = `${prefix}_${filename}`;
|
|
79107
79171
|
}
|
|
79108
|
-
let filepath =
|
|
79109
|
-
const base =
|
|
79110
|
-
const ext =
|
|
79172
|
+
let filepath = path87.join(targetDir, filename);
|
|
79173
|
+
const base = path87.basename(filepath, path87.extname(filepath));
|
|
79174
|
+
const ext = path87.extname(filepath);
|
|
79111
79175
|
let counter = 1;
|
|
79112
79176
|
while (fs65.existsSync(filepath)) {
|
|
79113
|
-
filepath =
|
|
79177
|
+
filepath = path87.join(targetDir, `${base}_${counter}${ext}`);
|
|
79114
79178
|
counter++;
|
|
79115
79179
|
}
|
|
79116
79180
|
try {
|
|
@@ -79286,7 +79350,7 @@ init_create_tool();
|
|
|
79286
79350
|
var GITINGEST_TIMEOUT_MS = 1e4;
|
|
79287
79351
|
var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
|
|
79288
79352
|
var GITINGEST_MAX_RETRIES = 2;
|
|
79289
|
-
var delay = (ms) => new Promise((
|
|
79353
|
+
var delay = (ms) => new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
79290
79354
|
async function fetchGitingest(args2) {
|
|
79291
79355
|
for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
|
|
79292
79356
|
try {
|
|
@@ -79374,7 +79438,7 @@ init_zod();
|
|
|
79374
79438
|
init_create_tool();
|
|
79375
79439
|
init_path_security();
|
|
79376
79440
|
import * as fs66 from "node:fs";
|
|
79377
|
-
import * as
|
|
79441
|
+
import * as path88 from "node:path";
|
|
79378
79442
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
79379
79443
|
var MAX_SYMBOL_LENGTH = 256;
|
|
79380
79444
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -79422,7 +79486,7 @@ function validateSymbolInput(symbol3) {
|
|
|
79422
79486
|
return null;
|
|
79423
79487
|
}
|
|
79424
79488
|
function isBinaryFile2(filePath, buffer) {
|
|
79425
|
-
const ext =
|
|
79489
|
+
const ext = path88.extname(filePath).toLowerCase();
|
|
79426
79490
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
79427
79491
|
return false;
|
|
79428
79492
|
}
|
|
@@ -79446,15 +79510,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
79446
79510
|
const imports = [];
|
|
79447
79511
|
let _resolvedTarget;
|
|
79448
79512
|
try {
|
|
79449
|
-
_resolvedTarget =
|
|
79513
|
+
_resolvedTarget = path88.resolve(targetFile);
|
|
79450
79514
|
} catch {
|
|
79451
79515
|
_resolvedTarget = targetFile;
|
|
79452
79516
|
}
|
|
79453
|
-
const targetBasename =
|
|
79517
|
+
const targetBasename = path88.basename(targetFile, path88.extname(targetFile));
|
|
79454
79518
|
const targetWithExt = targetFile;
|
|
79455
79519
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
79456
|
-
const normalizedTargetWithExt =
|
|
79457
|
-
const normalizedTargetWithoutExt =
|
|
79520
|
+
const normalizedTargetWithExt = path88.normalize(targetWithExt).replace(/\\/g, "/");
|
|
79521
|
+
const normalizedTargetWithoutExt = path88.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
79458
79522
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
79459
79523
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
79460
79524
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -79477,9 +79541,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
79477
79541
|
}
|
|
79478
79542
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
79479
79543
|
let isMatch = false;
|
|
79480
|
-
const _targetDir =
|
|
79481
|
-
const targetExt =
|
|
79482
|
-
const targetBasenameNoExt =
|
|
79544
|
+
const _targetDir = path88.dirname(targetFile);
|
|
79545
|
+
const targetExt = path88.extname(targetFile);
|
|
79546
|
+
const targetBasenameNoExt = path88.basename(targetFile, targetExt);
|
|
79483
79547
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
79484
79548
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
79485
79549
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -79547,13 +79611,13 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
79547
79611
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
79548
79612
|
for (const entry of entries) {
|
|
79549
79613
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
79550
|
-
stats.skippedDirs.push(
|
|
79614
|
+
stats.skippedDirs.push(path88.join(dir, entry));
|
|
79551
79615
|
continue;
|
|
79552
79616
|
}
|
|
79553
|
-
const fullPath =
|
|
79554
|
-
let
|
|
79617
|
+
const fullPath = path88.join(dir, entry);
|
|
79618
|
+
let stat7;
|
|
79555
79619
|
try {
|
|
79556
|
-
|
|
79620
|
+
stat7 = fs66.statSync(fullPath);
|
|
79557
79621
|
} catch (e) {
|
|
79558
79622
|
stats.fileErrors.push({
|
|
79559
79623
|
path: fullPath,
|
|
@@ -79561,10 +79625,10 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
79561
79625
|
});
|
|
79562
79626
|
continue;
|
|
79563
79627
|
}
|
|
79564
|
-
if (
|
|
79628
|
+
if (stat7.isDirectory()) {
|
|
79565
79629
|
findSourceFiles2(fullPath, files, stats);
|
|
79566
|
-
} else if (
|
|
79567
|
-
const ext =
|
|
79630
|
+
} else if (stat7.isFile()) {
|
|
79631
|
+
const ext = path88.extname(fullPath).toLowerCase();
|
|
79568
79632
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
79569
79633
|
files.push(fullPath);
|
|
79570
79634
|
}
|
|
@@ -79621,7 +79685,7 @@ var imports = createSwarmTool({
|
|
|
79621
79685
|
return JSON.stringify(errorResult, null, 2);
|
|
79622
79686
|
}
|
|
79623
79687
|
try {
|
|
79624
|
-
const targetFile =
|
|
79688
|
+
const targetFile = path88.resolve(file3);
|
|
79625
79689
|
if (!fs66.existsSync(targetFile)) {
|
|
79626
79690
|
const errorResult = {
|
|
79627
79691
|
error: `target file not found: ${file3}`,
|
|
@@ -79643,7 +79707,7 @@ var imports = createSwarmTool({
|
|
|
79643
79707
|
};
|
|
79644
79708
|
return JSON.stringify(errorResult, null, 2);
|
|
79645
79709
|
}
|
|
79646
|
-
const baseDir =
|
|
79710
|
+
const baseDir = path88.dirname(targetFile);
|
|
79647
79711
|
const scanStats = {
|
|
79648
79712
|
skippedDirs: [],
|
|
79649
79713
|
skippedFiles: 0,
|
|
@@ -79658,8 +79722,8 @@ var imports = createSwarmTool({
|
|
|
79658
79722
|
if (consumers.length >= MAX_CONSUMERS)
|
|
79659
79723
|
break;
|
|
79660
79724
|
try {
|
|
79661
|
-
const
|
|
79662
|
-
if (
|
|
79725
|
+
const stat7 = fs66.statSync(filePath);
|
|
79726
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES7) {
|
|
79663
79727
|
skippedFileCount++;
|
|
79664
79728
|
continue;
|
|
79665
79729
|
}
|
|
@@ -79876,7 +79940,7 @@ init_zod();
|
|
|
79876
79940
|
init_config();
|
|
79877
79941
|
init_knowledge_store();
|
|
79878
79942
|
init_create_tool();
|
|
79879
|
-
import { existsSync as
|
|
79943
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
79880
79944
|
var DEFAULT_LIMIT = 10;
|
|
79881
79945
|
var MAX_LESSON_LENGTH = 200;
|
|
79882
79946
|
var VALID_CATEGORIES3 = [
|
|
@@ -79946,14 +80010,14 @@ function validateLimit(limit) {
|
|
|
79946
80010
|
}
|
|
79947
80011
|
async function readSwarmKnowledge(directory) {
|
|
79948
80012
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
79949
|
-
if (!
|
|
80013
|
+
if (!existsSync46(swarmPath)) {
|
|
79950
80014
|
return [];
|
|
79951
80015
|
}
|
|
79952
80016
|
return readKnowledge(swarmPath);
|
|
79953
80017
|
}
|
|
79954
80018
|
async function readHiveKnowledge() {
|
|
79955
80019
|
const hivePath = resolveHiveKnowledgePath();
|
|
79956
|
-
if (!
|
|
80020
|
+
if (!existsSync46(hivePath)) {
|
|
79957
80021
|
return [];
|
|
79958
80022
|
}
|
|
79959
80023
|
return readKnowledge(hivePath);
|
|
@@ -80189,7 +80253,7 @@ init_qa_gate_profile();
|
|
|
80189
80253
|
init_manager2();
|
|
80190
80254
|
init_curator();
|
|
80191
80255
|
import * as fs68 from "node:fs";
|
|
80192
|
-
import * as
|
|
80256
|
+
import * as path90 from "node:path";
|
|
80193
80257
|
init_knowledge_curator();
|
|
80194
80258
|
init_knowledge_reader();
|
|
80195
80259
|
init_knowledge_store();
|
|
@@ -80202,16 +80266,16 @@ init_plan_schema();
|
|
|
80202
80266
|
init_ledger();
|
|
80203
80267
|
init_manager();
|
|
80204
80268
|
import * as fs67 from "node:fs";
|
|
80205
|
-
import * as
|
|
80269
|
+
import * as path89 from "node:path";
|
|
80206
80270
|
async function writeCheckpoint(directory) {
|
|
80207
80271
|
try {
|
|
80208
80272
|
const plan = await loadPlan(directory);
|
|
80209
80273
|
if (!plan)
|
|
80210
80274
|
return;
|
|
80211
|
-
const swarmDir =
|
|
80275
|
+
const swarmDir = path89.join(directory, ".swarm");
|
|
80212
80276
|
fs67.mkdirSync(swarmDir, { recursive: true });
|
|
80213
|
-
const jsonPath =
|
|
80214
|
-
const mdPath =
|
|
80277
|
+
const jsonPath = path89.join(swarmDir, "SWARM_PLAN.json");
|
|
80278
|
+
const mdPath = path89.join(swarmDir, "SWARM_PLAN.md");
|
|
80215
80279
|
fs67.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
80216
80280
|
const md = derivePlanMarkdown(plan);
|
|
80217
80281
|
fs67.writeFileSync(mdPath, md, "utf8");
|
|
@@ -80446,7 +80510,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80446
80510
|
let driftCheckEnabled = true;
|
|
80447
80511
|
let driftHasSpecMd = false;
|
|
80448
80512
|
try {
|
|
80449
|
-
const specMdPath =
|
|
80513
|
+
const specMdPath = path90.join(dir, ".swarm", "spec.md");
|
|
80450
80514
|
driftHasSpecMd = fs68.existsSync(specMdPath);
|
|
80451
80515
|
const gatePlan = await loadPlan(dir);
|
|
80452
80516
|
if (gatePlan) {
|
|
@@ -80468,7 +80532,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80468
80532
|
} else {
|
|
80469
80533
|
let phaseType;
|
|
80470
80534
|
try {
|
|
80471
|
-
const planPath =
|
|
80535
|
+
const planPath = path90.join(dir, ".swarm", "plan.json");
|
|
80472
80536
|
if (fs68.existsSync(planPath)) {
|
|
80473
80537
|
const planRaw = fs68.readFileSync(planPath, "utf-8");
|
|
80474
80538
|
const plan = JSON.parse(planRaw);
|
|
@@ -80481,7 +80545,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80481
80545
|
warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
|
|
80482
80546
|
} else {
|
|
80483
80547
|
try {
|
|
80484
|
-
const driftEvidencePath =
|
|
80548
|
+
const driftEvidencePath = path90.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
80485
80549
|
let driftVerdictFound = false;
|
|
80486
80550
|
let driftVerdictApproved = false;
|
|
80487
80551
|
try {
|
|
@@ -80519,7 +80583,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80519
80583
|
let incompleteTaskCount = 0;
|
|
80520
80584
|
let planParseable = false;
|
|
80521
80585
|
try {
|
|
80522
|
-
const planPath =
|
|
80586
|
+
const planPath = path90.join(dir, ".swarm", "plan.json");
|
|
80523
80587
|
if (fs68.existsSync(planPath)) {
|
|
80524
80588
|
const planRaw = fs68.readFileSync(planPath, "utf-8");
|
|
80525
80589
|
const plan = JSON.parse(planRaw);
|
|
@@ -80586,7 +80650,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80586
80650
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
80587
80651
|
const effective = getEffectiveGates(profile, overrides);
|
|
80588
80652
|
if (effective.hallucination_guard === true) {
|
|
80589
|
-
const hgPath =
|
|
80653
|
+
const hgPath = path90.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
80590
80654
|
let hgVerdictFound = false;
|
|
80591
80655
|
let hgVerdictApproved = false;
|
|
80592
80656
|
try {
|
|
@@ -80658,7 +80722,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80658
80722
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
80659
80723
|
const effective = getEffectiveGates(profile, overrides);
|
|
80660
80724
|
if (effective.mutation_test === true) {
|
|
80661
|
-
const mgPath =
|
|
80725
|
+
const mgPath = path90.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
80662
80726
|
let mgVerdictFound = false;
|
|
80663
80727
|
let mgVerdict;
|
|
80664
80728
|
try {
|
|
@@ -80732,7 +80796,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80732
80796
|
const effective = getEffectiveGates(profile, overrides);
|
|
80733
80797
|
if (effective.council_mode === true) {
|
|
80734
80798
|
councilModeEnabled = true;
|
|
80735
|
-
const pcPath =
|
|
80799
|
+
const pcPath = path90.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
80736
80800
|
let pcVerdictFound = false;
|
|
80737
80801
|
let _pcVerdict;
|
|
80738
80802
|
let pcQuorumSize;
|
|
@@ -80934,7 +80998,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80934
80998
|
}
|
|
80935
80999
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
80936
81000
|
try {
|
|
80937
|
-
const projectName =
|
|
81001
|
+
const projectName = path90.basename(dir);
|
|
80938
81002
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
80939
81003
|
if (curationResult) {
|
|
80940
81004
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -81304,7 +81368,7 @@ init_utils();
|
|
|
81304
81368
|
init_bun_compat();
|
|
81305
81369
|
init_create_tool();
|
|
81306
81370
|
import * as fs69 from "node:fs";
|
|
81307
|
-
import * as
|
|
81371
|
+
import * as path91 from "node:path";
|
|
81308
81372
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
81309
81373
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
81310
81374
|
function isValidEcosystem(value) {
|
|
@@ -81332,16 +81396,16 @@ function validateArgs3(args2) {
|
|
|
81332
81396
|
function detectEcosystems(directory) {
|
|
81333
81397
|
const ecosystems = [];
|
|
81334
81398
|
const cwd = directory;
|
|
81335
|
-
if (fs69.existsSync(
|
|
81399
|
+
if (fs69.existsSync(path91.join(cwd, "package.json"))) {
|
|
81336
81400
|
ecosystems.push("npm");
|
|
81337
81401
|
}
|
|
81338
|
-
if (fs69.existsSync(
|
|
81402
|
+
if (fs69.existsSync(path91.join(cwd, "pyproject.toml")) || fs69.existsSync(path91.join(cwd, "requirements.txt"))) {
|
|
81339
81403
|
ecosystems.push("pip");
|
|
81340
81404
|
}
|
|
81341
|
-
if (fs69.existsSync(
|
|
81405
|
+
if (fs69.existsSync(path91.join(cwd, "Cargo.toml"))) {
|
|
81342
81406
|
ecosystems.push("cargo");
|
|
81343
81407
|
}
|
|
81344
|
-
if (fs69.existsSync(
|
|
81408
|
+
if (fs69.existsSync(path91.join(cwd, "go.mod"))) {
|
|
81345
81409
|
ecosystems.push("go");
|
|
81346
81410
|
}
|
|
81347
81411
|
try {
|
|
@@ -81350,13 +81414,13 @@ function detectEcosystems(directory) {
|
|
|
81350
81414
|
ecosystems.push("dotnet");
|
|
81351
81415
|
}
|
|
81352
81416
|
} catch {}
|
|
81353
|
-
if (fs69.existsSync(
|
|
81417
|
+
if (fs69.existsSync(path91.join(cwd, "Gemfile")) || fs69.existsSync(path91.join(cwd, "Gemfile.lock"))) {
|
|
81354
81418
|
ecosystems.push("ruby");
|
|
81355
81419
|
}
|
|
81356
|
-
if (fs69.existsSync(
|
|
81420
|
+
if (fs69.existsSync(path91.join(cwd, "pubspec.yaml"))) {
|
|
81357
81421
|
ecosystems.push("dart");
|
|
81358
81422
|
}
|
|
81359
|
-
if (fs69.existsSync(
|
|
81423
|
+
if (fs69.existsSync(path91.join(cwd, "composer.lock"))) {
|
|
81360
81424
|
ecosystems.push("composer");
|
|
81361
81425
|
}
|
|
81362
81426
|
return ecosystems;
|
|
@@ -81369,7 +81433,7 @@ async function runNpmAudit(directory) {
|
|
|
81369
81433
|
stderr: "pipe",
|
|
81370
81434
|
cwd: directory
|
|
81371
81435
|
});
|
|
81372
|
-
const timeoutPromise = new Promise((
|
|
81436
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81373
81437
|
const result = await Promise.race([
|
|
81374
81438
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
81375
81439
|
timeoutPromise
|
|
@@ -81489,7 +81553,7 @@ async function runPipAudit(directory) {
|
|
|
81489
81553
|
stderr: "pipe",
|
|
81490
81554
|
cwd: directory
|
|
81491
81555
|
});
|
|
81492
|
-
const timeoutPromise = new Promise((
|
|
81556
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81493
81557
|
const result = await Promise.race([
|
|
81494
81558
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
81495
81559
|
timeoutPromise
|
|
@@ -81617,7 +81681,7 @@ async function runCargoAudit(directory) {
|
|
|
81617
81681
|
stderr: "pipe",
|
|
81618
81682
|
cwd: directory
|
|
81619
81683
|
});
|
|
81620
|
-
const timeoutPromise = new Promise((
|
|
81684
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81621
81685
|
const result = await Promise.race([
|
|
81622
81686
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81623
81687
|
timeoutPromise
|
|
@@ -81741,7 +81805,7 @@ async function runGoAudit(directory) {
|
|
|
81741
81805
|
stderr: "pipe",
|
|
81742
81806
|
cwd: directory
|
|
81743
81807
|
});
|
|
81744
|
-
const timeoutPromise = new Promise((
|
|
81808
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81745
81809
|
const result = await Promise.race([
|
|
81746
81810
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81747
81811
|
timeoutPromise
|
|
@@ -81874,7 +81938,7 @@ async function runDotnetAudit(directory) {
|
|
|
81874
81938
|
stderr: "pipe",
|
|
81875
81939
|
cwd: directory
|
|
81876
81940
|
});
|
|
81877
|
-
const timeoutPromise = new Promise((
|
|
81941
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81878
81942
|
const result = await Promise.race([
|
|
81879
81943
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81880
81944
|
timeoutPromise
|
|
@@ -81990,7 +82054,7 @@ async function runBundleAudit(directory) {
|
|
|
81990
82054
|
stderr: "pipe",
|
|
81991
82055
|
cwd: directory
|
|
81992
82056
|
});
|
|
81993
|
-
const timeoutPromise = new Promise((
|
|
82057
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81994
82058
|
const result = await Promise.race([
|
|
81995
82059
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81996
82060
|
timeoutPromise
|
|
@@ -82135,7 +82199,7 @@ async function runDartAudit(directory) {
|
|
|
82135
82199
|
stderr: "pipe",
|
|
82136
82200
|
cwd: directory
|
|
82137
82201
|
});
|
|
82138
|
-
const timeoutPromise = new Promise((
|
|
82202
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
82139
82203
|
const result = await Promise.race([
|
|
82140
82204
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
82141
82205
|
timeoutPromise
|
|
@@ -82250,7 +82314,7 @@ async function runComposerAudit(directory) {
|
|
|
82250
82314
|
stderr: "pipe",
|
|
82251
82315
|
cwd: directory
|
|
82252
82316
|
});
|
|
82253
|
-
const timeoutPromise = new Promise((
|
|
82317
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
82254
82318
|
const result = await Promise.race([
|
|
82255
82319
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
82256
82320
|
timeoutPromise
|
|
@@ -82492,7 +82556,7 @@ var pkg_audit = createSwarmTool({
|
|
|
82492
82556
|
init_zod();
|
|
82493
82557
|
init_manager2();
|
|
82494
82558
|
import * as fs70 from "node:fs";
|
|
82495
|
-
import * as
|
|
82559
|
+
import * as path92 from "node:path";
|
|
82496
82560
|
init_utils();
|
|
82497
82561
|
init_create_tool();
|
|
82498
82562
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -82615,7 +82679,7 @@ function isScaffoldFile(filePath) {
|
|
|
82615
82679
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
82616
82680
|
return true;
|
|
82617
82681
|
}
|
|
82618
|
-
const filename =
|
|
82682
|
+
const filename = path92.basename(filePath);
|
|
82619
82683
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
82620
82684
|
return true;
|
|
82621
82685
|
}
|
|
@@ -82632,7 +82696,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
82632
82696
|
if (regex.test(normalizedPath)) {
|
|
82633
82697
|
return true;
|
|
82634
82698
|
}
|
|
82635
|
-
const filename =
|
|
82699
|
+
const filename = path92.basename(filePath);
|
|
82636
82700
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
82637
82701
|
if (filenameRegex.test(filename)) {
|
|
82638
82702
|
return true;
|
|
@@ -82641,7 +82705,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
82641
82705
|
return false;
|
|
82642
82706
|
}
|
|
82643
82707
|
function isParserSupported(filePath) {
|
|
82644
|
-
const ext =
|
|
82708
|
+
const ext = path92.extname(filePath).toLowerCase();
|
|
82645
82709
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
82646
82710
|
}
|
|
82647
82711
|
function isPlanFile(filePath) {
|
|
@@ -82888,9 +82952,9 @@ async function placeholderScan(input, directory) {
|
|
|
82888
82952
|
let filesScanned = 0;
|
|
82889
82953
|
const filesWithFindings = new Set;
|
|
82890
82954
|
for (const filePath of changed_files) {
|
|
82891
|
-
const fullPath =
|
|
82892
|
-
const resolvedDirectory =
|
|
82893
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
82955
|
+
const fullPath = path92.isAbsolute(filePath) ? filePath : path92.resolve(directory, filePath);
|
|
82956
|
+
const resolvedDirectory = path92.resolve(directory);
|
|
82957
|
+
if (!fullPath.startsWith(resolvedDirectory + path92.sep) && fullPath !== resolvedDirectory) {
|
|
82894
82958
|
continue;
|
|
82895
82959
|
}
|
|
82896
82960
|
if (!fs70.existsSync(fullPath)) {
|
|
@@ -82899,14 +82963,14 @@ async function placeholderScan(input, directory) {
|
|
|
82899
82963
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
82900
82964
|
continue;
|
|
82901
82965
|
}
|
|
82902
|
-
const relativeFilePath =
|
|
82966
|
+
const relativeFilePath = path92.relative(directory, fullPath).replace(/\\/g, "/");
|
|
82903
82967
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
82904
82968
|
continue;
|
|
82905
82969
|
}
|
|
82906
82970
|
let content;
|
|
82907
82971
|
try {
|
|
82908
|
-
const
|
|
82909
|
-
if (
|
|
82972
|
+
const stat7 = fs70.statSync(fullPath);
|
|
82973
|
+
if (stat7.size > MAX_FILE_SIZE) {
|
|
82910
82974
|
continue;
|
|
82911
82975
|
}
|
|
82912
82976
|
content = fs70.readFileSync(fullPath, "utf-8");
|
|
@@ -82971,7 +83035,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
82971
83035
|
});
|
|
82972
83036
|
// src/tools/pre-check-batch.ts
|
|
82973
83037
|
import * as fs73 from "node:fs";
|
|
82974
|
-
import * as
|
|
83038
|
+
import * as path95 from "node:path";
|
|
82975
83039
|
init_zod();
|
|
82976
83040
|
init_manager2();
|
|
82977
83041
|
init_utils();
|
|
@@ -83109,7 +83173,7 @@ init_zod();
|
|
|
83109
83173
|
init_manager2();
|
|
83110
83174
|
init_detector();
|
|
83111
83175
|
import * as fs72 from "node:fs";
|
|
83112
|
-
import * as
|
|
83176
|
+
import * as path94 from "node:path";
|
|
83113
83177
|
import { extname as extname18 } from "node:path";
|
|
83114
83178
|
|
|
83115
83179
|
// src/sast/rules/c.ts
|
|
@@ -83890,7 +83954,7 @@ function mapSemgrepSeverity(severity) {
|
|
|
83890
83954
|
}
|
|
83891
83955
|
}
|
|
83892
83956
|
async function executeWithTimeout(command, args2, options) {
|
|
83893
|
-
return new Promise((
|
|
83957
|
+
return new Promise((resolve33) => {
|
|
83894
83958
|
const child = child_process9.spawn(command, args2, {
|
|
83895
83959
|
shell: false,
|
|
83896
83960
|
cwd: options.cwd
|
|
@@ -83899,7 +83963,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83899
83963
|
let stderr = "";
|
|
83900
83964
|
const timeout = setTimeout(() => {
|
|
83901
83965
|
child.kill("SIGTERM");
|
|
83902
|
-
|
|
83966
|
+
resolve33({
|
|
83903
83967
|
stdout,
|
|
83904
83968
|
stderr: "Process timed out",
|
|
83905
83969
|
exitCode: 124
|
|
@@ -83913,7 +83977,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83913
83977
|
});
|
|
83914
83978
|
child.on("close", (code) => {
|
|
83915
83979
|
clearTimeout(timeout);
|
|
83916
|
-
|
|
83980
|
+
resolve33({
|
|
83917
83981
|
stdout,
|
|
83918
83982
|
stderr,
|
|
83919
83983
|
exitCode: code ?? 0
|
|
@@ -83921,7 +83985,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83921
83985
|
});
|
|
83922
83986
|
child.on("error", (err2) => {
|
|
83923
83987
|
clearTimeout(timeout);
|
|
83924
|
-
|
|
83988
|
+
resolve33({
|
|
83925
83989
|
stdout,
|
|
83926
83990
|
stderr: err2.message,
|
|
83927
83991
|
exitCode: 1
|
|
@@ -84003,24 +84067,24 @@ init_create_tool();
|
|
|
84003
84067
|
init_utils2();
|
|
84004
84068
|
import * as crypto8 from "node:crypto";
|
|
84005
84069
|
import * as fs71 from "node:fs";
|
|
84006
|
-
import * as
|
|
84070
|
+
import * as path93 from "node:path";
|
|
84007
84071
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
84008
84072
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
84009
84073
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
84010
84074
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
84011
84075
|
function normalizeFindingPath(directory, file3) {
|
|
84012
|
-
const resolved =
|
|
84013
|
-
const rel =
|
|
84076
|
+
const resolved = path93.isAbsolute(file3) ? file3 : path93.resolve(directory, file3);
|
|
84077
|
+
const rel = path93.relative(path93.resolve(directory), resolved);
|
|
84014
84078
|
return rel.replace(/\\/g, "/");
|
|
84015
84079
|
}
|
|
84016
84080
|
function baselineRelPath(phase) {
|
|
84017
|
-
return
|
|
84081
|
+
return path93.join("evidence", String(phase), "sast-baseline.json");
|
|
84018
84082
|
}
|
|
84019
84083
|
function tempRelPath(phase) {
|
|
84020
|
-
return
|
|
84084
|
+
return path93.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
84021
84085
|
}
|
|
84022
84086
|
function lockRelPath(phase) {
|
|
84023
|
-
return
|
|
84087
|
+
return path93.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
84024
84088
|
}
|
|
84025
84089
|
function getLine(lines, idx) {
|
|
84026
84090
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -84106,7 +84170,7 @@ async function acquireLock(lockPath) {
|
|
|
84106
84170
|
};
|
|
84107
84171
|
} catch {
|
|
84108
84172
|
if (attempt < LOCK_RETRY_DELAYS_MS.length) {
|
|
84109
|
-
await new Promise((
|
|
84173
|
+
await new Promise((resolve34) => setTimeout(resolve34, LOCK_RETRY_DELAYS_MS[attempt]));
|
|
84110
84174
|
}
|
|
84111
84175
|
}
|
|
84112
84176
|
}
|
|
@@ -84141,8 +84205,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
84141
84205
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
84142
84206
|
};
|
|
84143
84207
|
}
|
|
84144
|
-
fs71.mkdirSync(
|
|
84145
|
-
fs71.mkdirSync(
|
|
84208
|
+
fs71.mkdirSync(path93.dirname(baselinePath), { recursive: true });
|
|
84209
|
+
fs71.mkdirSync(path93.dirname(tempPath), { recursive: true });
|
|
84146
84210
|
const releaseLock = await acquireLock(lockPath);
|
|
84147
84211
|
try {
|
|
84148
84212
|
let existing = null;
|
|
@@ -84409,9 +84473,9 @@ async function sastScan(input, directory, config3) {
|
|
|
84409
84473
|
_filesSkipped++;
|
|
84410
84474
|
continue;
|
|
84411
84475
|
}
|
|
84412
|
-
const resolvedPath =
|
|
84413
|
-
const resolvedDirectory =
|
|
84414
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
84476
|
+
const resolvedPath = path94.isAbsolute(filePath) ? filePath : path94.resolve(directory, filePath);
|
|
84477
|
+
const resolvedDirectory = path94.resolve(directory);
|
|
84478
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path94.sep) && resolvedPath !== resolvedDirectory) {
|
|
84415
84479
|
_filesSkipped++;
|
|
84416
84480
|
continue;
|
|
84417
84481
|
}
|
|
@@ -84722,18 +84786,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
84722
84786
|
let resolved;
|
|
84723
84787
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
84724
84788
|
if (isWinAbs) {
|
|
84725
|
-
resolved =
|
|
84726
|
-
} else if (
|
|
84727
|
-
resolved =
|
|
84789
|
+
resolved = path95.win32.resolve(inputPath);
|
|
84790
|
+
} else if (path95.isAbsolute(inputPath)) {
|
|
84791
|
+
resolved = path95.resolve(inputPath);
|
|
84728
84792
|
} else {
|
|
84729
|
-
resolved =
|
|
84793
|
+
resolved = path95.resolve(baseDir, inputPath);
|
|
84730
84794
|
}
|
|
84731
|
-
const workspaceResolved =
|
|
84795
|
+
const workspaceResolved = path95.resolve(workspaceDir);
|
|
84732
84796
|
let relative20;
|
|
84733
84797
|
if (isWinAbs) {
|
|
84734
|
-
relative20 =
|
|
84798
|
+
relative20 = path95.win32.relative(workspaceResolved, resolved);
|
|
84735
84799
|
} else {
|
|
84736
|
-
relative20 =
|
|
84800
|
+
relative20 = path95.relative(workspaceResolved, resolved);
|
|
84737
84801
|
}
|
|
84738
84802
|
if (relative20.startsWith("..")) {
|
|
84739
84803
|
return "path traversal detected";
|
|
@@ -84798,7 +84862,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
84798
84862
|
if (typeof file3 !== "string") {
|
|
84799
84863
|
continue;
|
|
84800
84864
|
}
|
|
84801
|
-
const resolvedPath =
|
|
84865
|
+
const resolvedPath = path95.resolve(file3);
|
|
84802
84866
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
84803
84867
|
if (validationError) {
|
|
84804
84868
|
continue;
|
|
@@ -84955,7 +85019,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
84955
85019
|
skippedFiles++;
|
|
84956
85020
|
continue;
|
|
84957
85021
|
}
|
|
84958
|
-
const resolvedPath =
|
|
85022
|
+
const resolvedPath = path95.resolve(file3);
|
|
84959
85023
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
84960
85024
|
if (validationError) {
|
|
84961
85025
|
skippedFiles++;
|
|
@@ -84973,19 +85037,19 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
84973
85037
|
};
|
|
84974
85038
|
}
|
|
84975
85039
|
for (const file3 of validatedFiles) {
|
|
84976
|
-
const ext =
|
|
85040
|
+
const ext = path95.extname(file3).toLowerCase();
|
|
84977
85041
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
84978
85042
|
skippedFiles++;
|
|
84979
85043
|
continue;
|
|
84980
85044
|
}
|
|
84981
|
-
let
|
|
85045
|
+
let stat7;
|
|
84982
85046
|
try {
|
|
84983
|
-
|
|
85047
|
+
stat7 = fs73.statSync(file3);
|
|
84984
85048
|
} catch {
|
|
84985
85049
|
skippedFiles++;
|
|
84986
85050
|
continue;
|
|
84987
85051
|
}
|
|
84988
|
-
if (
|
|
85052
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES9) {
|
|
84989
85053
|
skippedFiles++;
|
|
84990
85054
|
continue;
|
|
84991
85055
|
}
|
|
@@ -85192,7 +85256,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
85192
85256
|
const preexistingFindings = [];
|
|
85193
85257
|
for (const finding of findings) {
|
|
85194
85258
|
const filePath = finding.location.file;
|
|
85195
|
-
const normalised =
|
|
85259
|
+
const normalised = path95.relative(directory, filePath).replace(/\\/g, "/");
|
|
85196
85260
|
const changedLines = changedLineRanges.get(normalised);
|
|
85197
85261
|
if (changedLines?.has(finding.location.line)) {
|
|
85198
85262
|
newFindings.push(finding);
|
|
@@ -85243,7 +85307,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
85243
85307
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
85244
85308
|
continue;
|
|
85245
85309
|
}
|
|
85246
|
-
changedFiles.push(
|
|
85310
|
+
changedFiles.push(path95.resolve(directory, file3));
|
|
85247
85311
|
}
|
|
85248
85312
|
if (changedFiles.length === 0) {
|
|
85249
85313
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -85444,7 +85508,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
85444
85508
|
};
|
|
85445
85509
|
return JSON.stringify(errorResult, null, 2);
|
|
85446
85510
|
}
|
|
85447
|
-
const resolvedDirectory =
|
|
85511
|
+
const resolvedDirectory = path95.resolve(typedArgs.directory);
|
|
85448
85512
|
const workspaceAnchor = resolvedDirectory;
|
|
85449
85513
|
const dirError = validateDirectory2(resolvedDirectory, workspaceAnchor);
|
|
85450
85514
|
if (dirError) {
|
|
@@ -85485,7 +85549,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
85485
85549
|
});
|
|
85486
85550
|
// src/tools/repo-map.ts
|
|
85487
85551
|
init_zod();
|
|
85488
|
-
import * as
|
|
85552
|
+
import * as path96 from "node:path";
|
|
85489
85553
|
init_path_security();
|
|
85490
85554
|
init_create_tool();
|
|
85491
85555
|
var VALID_ACTIONS = [
|
|
@@ -85510,7 +85574,7 @@ function validateFile(p) {
|
|
|
85510
85574
|
return "file contains control characters";
|
|
85511
85575
|
if (containsPathTraversal(p))
|
|
85512
85576
|
return "file contains path traversal";
|
|
85513
|
-
if (
|
|
85577
|
+
if (path96.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
85514
85578
|
return "file must be a workspace-relative path, not absolute";
|
|
85515
85579
|
}
|
|
85516
85580
|
return null;
|
|
@@ -85533,8 +85597,8 @@ function ok(action, payload) {
|
|
|
85533
85597
|
}
|
|
85534
85598
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
85535
85599
|
const normalized = input.replace(/\\/g, "/");
|
|
85536
|
-
if (
|
|
85537
|
-
const rel =
|
|
85600
|
+
if (path96.isAbsolute(normalized)) {
|
|
85601
|
+
const rel = path96.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
85538
85602
|
return normalizeGraphPath2(rel);
|
|
85539
85603
|
}
|
|
85540
85604
|
return normalizeGraphPath2(normalized);
|
|
@@ -85679,7 +85743,7 @@ var repo_map = createSwarmTool({
|
|
|
85679
85743
|
init_zod();
|
|
85680
85744
|
init_create_tool();
|
|
85681
85745
|
import * as fs74 from "node:fs";
|
|
85682
|
-
import * as
|
|
85746
|
+
import * as path97 from "node:path";
|
|
85683
85747
|
var SPEC_FILE = ".swarm/spec.md";
|
|
85684
85748
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
85685
85749
|
var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -85748,10 +85812,10 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85748
85812
|
return [];
|
|
85749
85813
|
}
|
|
85750
85814
|
for (const entry of entries) {
|
|
85751
|
-
const entryPath =
|
|
85815
|
+
const entryPath = path97.join(evidenceDir, entry);
|
|
85752
85816
|
try {
|
|
85753
|
-
const
|
|
85754
|
-
if (!
|
|
85817
|
+
const stat7 = fs74.statSync(entryPath);
|
|
85818
|
+
if (!stat7.isDirectory()) {
|
|
85755
85819
|
continue;
|
|
85756
85820
|
}
|
|
85757
85821
|
} catch {
|
|
@@ -85764,18 +85828,18 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85764
85828
|
if (entryPhase !== String(phase)) {
|
|
85765
85829
|
continue;
|
|
85766
85830
|
}
|
|
85767
|
-
const evidenceFilePath =
|
|
85831
|
+
const evidenceFilePath = path97.join(entryPath, "evidence.json");
|
|
85768
85832
|
try {
|
|
85769
|
-
const resolvedPath =
|
|
85770
|
-
const evidenceDirResolved =
|
|
85771
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
85833
|
+
const resolvedPath = path97.resolve(evidenceFilePath);
|
|
85834
|
+
const evidenceDirResolved = path97.resolve(evidenceDir);
|
|
85835
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path97.sep)) {
|
|
85772
85836
|
continue;
|
|
85773
85837
|
}
|
|
85774
|
-
const
|
|
85775
|
-
if (!
|
|
85838
|
+
const stat7 = fs74.lstatSync(evidenceFilePath);
|
|
85839
|
+
if (!stat7.isFile()) {
|
|
85776
85840
|
continue;
|
|
85777
85841
|
}
|
|
85778
|
-
if (
|
|
85842
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES9) {
|
|
85779
85843
|
continue;
|
|
85780
85844
|
}
|
|
85781
85845
|
} catch {
|
|
@@ -85802,7 +85866,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85802
85866
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
85803
85867
|
for (const file3 of diffEntry.files_changed) {
|
|
85804
85868
|
if (typeof file3 === "string") {
|
|
85805
|
-
touchedFiles.add(
|
|
85869
|
+
touchedFiles.add(path97.resolve(cwd, file3));
|
|
85806
85870
|
}
|
|
85807
85871
|
}
|
|
85808
85872
|
}
|
|
@@ -85815,8 +85879,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85815
85879
|
}
|
|
85816
85880
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
85817
85881
|
try {
|
|
85818
|
-
const resolvedPath =
|
|
85819
|
-
const cwdResolved =
|
|
85882
|
+
const resolvedPath = path97.resolve(filePath);
|
|
85883
|
+
const cwdResolved = path97.resolve(cwd);
|
|
85820
85884
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
85821
85885
|
return false;
|
|
85822
85886
|
}
|
|
@@ -85950,7 +86014,7 @@ var req_coverage = createSwarmTool({
|
|
|
85950
86014
|
}, null, 2);
|
|
85951
86015
|
}
|
|
85952
86016
|
const cwd = inputDirectory || directory;
|
|
85953
|
-
const specPath =
|
|
86017
|
+
const specPath = path97.join(cwd, SPEC_FILE);
|
|
85954
86018
|
let specContent;
|
|
85955
86019
|
try {
|
|
85956
86020
|
specContent = fs74.readFileSync(specPath, "utf-8");
|
|
@@ -85977,7 +86041,7 @@ var req_coverage = createSwarmTool({
|
|
|
85977
86041
|
message: "No FR requirements found in spec.md"
|
|
85978
86042
|
}, null, 2);
|
|
85979
86043
|
}
|
|
85980
|
-
const evidenceDir =
|
|
86044
|
+
const evidenceDir = path97.join(cwd, EVIDENCE_DIR4);
|
|
85981
86045
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
85982
86046
|
const analyzedRequirements = [];
|
|
85983
86047
|
let coveredCount = 0;
|
|
@@ -86003,7 +86067,7 @@ var req_coverage = createSwarmTool({
|
|
|
86003
86067
|
requirements: analyzedRequirements
|
|
86004
86068
|
};
|
|
86005
86069
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
86006
|
-
const reportPath =
|
|
86070
|
+
const reportPath = path97.join(evidenceDir, reportFilename);
|
|
86007
86071
|
try {
|
|
86008
86072
|
if (!fs74.existsSync(evidenceDir)) {
|
|
86009
86073
|
fs74.mkdirSync(evidenceDir, { recursive: true });
|
|
@@ -86091,7 +86155,7 @@ init_qa_gate_profile();
|
|
|
86091
86155
|
init_file_locks();
|
|
86092
86156
|
import * as crypto9 from "node:crypto";
|
|
86093
86157
|
import * as fs75 from "node:fs";
|
|
86094
|
-
import * as
|
|
86158
|
+
import * as path98 from "node:path";
|
|
86095
86159
|
init_ledger();
|
|
86096
86160
|
init_manager();
|
|
86097
86161
|
init_state();
|
|
@@ -86169,8 +86233,8 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86169
86233
|
};
|
|
86170
86234
|
}
|
|
86171
86235
|
if (args2.working_directory && fallbackDir) {
|
|
86172
|
-
const resolvedTarget =
|
|
86173
|
-
const resolvedRoot =
|
|
86236
|
+
const resolvedTarget = path98.resolve(args2.working_directory);
|
|
86237
|
+
const resolvedRoot = path98.resolve(fallbackDir);
|
|
86174
86238
|
let fallbackExists = false;
|
|
86175
86239
|
try {
|
|
86176
86240
|
fs75.accessSync(resolvedRoot, fs75.constants.F_OK);
|
|
@@ -86179,7 +86243,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86179
86243
|
fallbackExists = false;
|
|
86180
86244
|
}
|
|
86181
86245
|
if (fallbackExists) {
|
|
86182
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
86246
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path98.sep);
|
|
86183
86247
|
if (isSubdirectory) {
|
|
86184
86248
|
return {
|
|
86185
86249
|
success: false,
|
|
@@ -86195,10 +86259,10 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86195
86259
|
let specMtime;
|
|
86196
86260
|
let specHash;
|
|
86197
86261
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
86198
|
-
const specPath =
|
|
86262
|
+
const specPath = path98.join(targetWorkspace, ".swarm", "spec.md");
|
|
86199
86263
|
try {
|
|
86200
|
-
const
|
|
86201
|
-
specMtime =
|
|
86264
|
+
const stat7 = await fs75.promises.stat(specPath);
|
|
86265
|
+
specMtime = stat7.mtime.toISOString();
|
|
86202
86266
|
const content = await fs75.promises.readFile(specPath, "utf8");
|
|
86203
86267
|
specHash = crypto9.createHash("sha256").update(content).digest("hex");
|
|
86204
86268
|
} catch {
|
|
@@ -86211,7 +86275,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86211
86275
|
}
|
|
86212
86276
|
}
|
|
86213
86277
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
86214
|
-
const contextPath =
|
|
86278
|
+
const contextPath = path98.join(targetWorkspace, ".swarm", "context.md");
|
|
86215
86279
|
let contextContent = "";
|
|
86216
86280
|
try {
|
|
86217
86281
|
contextContent = await fs75.promises.readFile(contextPath, "utf8");
|
|
@@ -86361,7 +86425,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86361
86425
|
}
|
|
86362
86426
|
await writeCheckpoint(dir).catch(() => {});
|
|
86363
86427
|
try {
|
|
86364
|
-
const markerPath =
|
|
86428
|
+
const markerPath = path98.join(dir, ".swarm", ".plan-write-marker");
|
|
86365
86429
|
const marker = JSON.stringify({
|
|
86366
86430
|
source: "save_plan",
|
|
86367
86431
|
timestamp: new Date().toISOString(),
|
|
@@ -86384,7 +86448,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86384
86448
|
return {
|
|
86385
86449
|
success: true,
|
|
86386
86450
|
message: "Plan saved successfully",
|
|
86387
|
-
plan_path:
|
|
86451
|
+
plan_path: path98.join(dir, ".swarm", "plan.json"),
|
|
86388
86452
|
phases_count: plan.phases.length,
|
|
86389
86453
|
tasks_count: tasksCount,
|
|
86390
86454
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -86437,7 +86501,7 @@ var save_plan = createSwarmTool({
|
|
|
86437
86501
|
init_zod();
|
|
86438
86502
|
init_manager2();
|
|
86439
86503
|
import * as fs76 from "node:fs";
|
|
86440
|
-
import * as
|
|
86504
|
+
import * as path99 from "node:path";
|
|
86441
86505
|
|
|
86442
86506
|
// src/sbom/detectors/index.ts
|
|
86443
86507
|
init_utils();
|
|
@@ -87287,7 +87351,7 @@ function findManifestFiles(rootDir) {
|
|
|
87287
87351
|
try {
|
|
87288
87352
|
const entries = fs76.readdirSync(dir, { withFileTypes: true });
|
|
87289
87353
|
for (const entry of entries) {
|
|
87290
|
-
const fullPath =
|
|
87354
|
+
const fullPath = path99.join(dir, entry.name);
|
|
87291
87355
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
87292
87356
|
continue;
|
|
87293
87357
|
}
|
|
@@ -87296,7 +87360,7 @@ function findManifestFiles(rootDir) {
|
|
|
87296
87360
|
} else if (entry.isFile()) {
|
|
87297
87361
|
for (const pattern of patterns) {
|
|
87298
87362
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
87299
|
-
manifestFiles.push(
|
|
87363
|
+
manifestFiles.push(path99.relative(rootDir, fullPath));
|
|
87300
87364
|
break;
|
|
87301
87365
|
}
|
|
87302
87366
|
}
|
|
@@ -87314,11 +87378,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
87314
87378
|
try {
|
|
87315
87379
|
const entries = fs76.readdirSync(dir, { withFileTypes: true });
|
|
87316
87380
|
for (const entry of entries) {
|
|
87317
|
-
const fullPath =
|
|
87381
|
+
const fullPath = path99.join(dir, entry.name);
|
|
87318
87382
|
if (entry.isFile()) {
|
|
87319
87383
|
for (const pattern of patterns) {
|
|
87320
87384
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
87321
|
-
found.push(
|
|
87385
|
+
found.push(path99.relative(workingDir, fullPath));
|
|
87322
87386
|
break;
|
|
87323
87387
|
}
|
|
87324
87388
|
}
|
|
@@ -87331,11 +87395,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
87331
87395
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
87332
87396
|
const dirs = new Set;
|
|
87333
87397
|
for (const file3 of changedFiles) {
|
|
87334
|
-
let currentDir =
|
|
87398
|
+
let currentDir = path99.dirname(file3);
|
|
87335
87399
|
while (true) {
|
|
87336
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
87337
|
-
dirs.add(
|
|
87338
|
-
const parent =
|
|
87400
|
+
if (currentDir && currentDir !== "." && currentDir !== path99.sep) {
|
|
87401
|
+
dirs.add(path99.join(workingDir, currentDir));
|
|
87402
|
+
const parent = path99.dirname(currentDir);
|
|
87339
87403
|
if (parent === currentDir)
|
|
87340
87404
|
break;
|
|
87341
87405
|
currentDir = parent;
|
|
@@ -87419,7 +87483,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87419
87483
|
const changedFiles = obj.changed_files;
|
|
87420
87484
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
87421
87485
|
const workingDir = directory;
|
|
87422
|
-
const outputDir =
|
|
87486
|
+
const outputDir = path99.isAbsolute(relativeOutputDir) ? relativeOutputDir : path99.join(workingDir, relativeOutputDir);
|
|
87423
87487
|
let manifestFiles = [];
|
|
87424
87488
|
if (scope === "all") {
|
|
87425
87489
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -87442,7 +87506,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87442
87506
|
const processedFiles = [];
|
|
87443
87507
|
for (const manifestFile of manifestFiles) {
|
|
87444
87508
|
try {
|
|
87445
|
-
const fullPath =
|
|
87509
|
+
const fullPath = path99.isAbsolute(manifestFile) ? manifestFile : path99.join(workingDir, manifestFile);
|
|
87446
87510
|
if (!fs76.existsSync(fullPath)) {
|
|
87447
87511
|
continue;
|
|
87448
87512
|
}
|
|
@@ -87459,7 +87523,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87459
87523
|
const bom = generateCycloneDX(allComponents);
|
|
87460
87524
|
const bomJson = serializeCycloneDX(bom);
|
|
87461
87525
|
const filename = generateSbomFilename();
|
|
87462
|
-
const outputPath =
|
|
87526
|
+
const outputPath = path99.join(outputDir, filename);
|
|
87463
87527
|
fs76.writeFileSync(outputPath, bomJson, "utf-8");
|
|
87464
87528
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
87465
87529
|
try {
|
|
@@ -87503,7 +87567,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87503
87567
|
init_zod();
|
|
87504
87568
|
init_create_tool();
|
|
87505
87569
|
import * as fs77 from "node:fs";
|
|
87506
|
-
import * as
|
|
87570
|
+
import * as path100 from "node:path";
|
|
87507
87571
|
var SPEC_CANDIDATES = [
|
|
87508
87572
|
"openapi.json",
|
|
87509
87573
|
"openapi.yaml",
|
|
@@ -87535,12 +87599,12 @@ function normalizePath3(p) {
|
|
|
87535
87599
|
}
|
|
87536
87600
|
function discoverSpecFile(cwd, specFileArg) {
|
|
87537
87601
|
if (specFileArg) {
|
|
87538
|
-
const resolvedPath =
|
|
87539
|
-
const normalizedCwd = cwd.endsWith(
|
|
87602
|
+
const resolvedPath = path100.resolve(cwd, specFileArg);
|
|
87603
|
+
const normalizedCwd = cwd.endsWith(path100.sep) ? cwd : cwd + path100.sep;
|
|
87540
87604
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
87541
87605
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
87542
87606
|
}
|
|
87543
|
-
const ext =
|
|
87607
|
+
const ext = path100.extname(resolvedPath).toLowerCase();
|
|
87544
87608
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
87545
87609
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
87546
87610
|
}
|
|
@@ -87554,7 +87618,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
87554
87618
|
return resolvedPath;
|
|
87555
87619
|
}
|
|
87556
87620
|
for (const candidate of SPEC_CANDIDATES) {
|
|
87557
|
-
const candidatePath =
|
|
87621
|
+
const candidatePath = path100.resolve(cwd, candidate);
|
|
87558
87622
|
if (fs77.existsSync(candidatePath)) {
|
|
87559
87623
|
const stats = fs77.statSync(candidatePath);
|
|
87560
87624
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -87566,7 +87630,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
87566
87630
|
}
|
|
87567
87631
|
function parseSpec(specFile) {
|
|
87568
87632
|
const content = fs77.readFileSync(specFile, "utf-8");
|
|
87569
|
-
const ext =
|
|
87633
|
+
const ext = path100.extname(specFile).toLowerCase();
|
|
87570
87634
|
if (ext === ".json") {
|
|
87571
87635
|
return parseJsonSpec(content);
|
|
87572
87636
|
}
|
|
@@ -87642,7 +87706,7 @@ function extractRoutes(cwd) {
|
|
|
87642
87706
|
return;
|
|
87643
87707
|
}
|
|
87644
87708
|
for (const entry of entries) {
|
|
87645
|
-
const fullPath =
|
|
87709
|
+
const fullPath = path100.join(dir, entry.name);
|
|
87646
87710
|
if (entry.isSymbolicLink()) {
|
|
87647
87711
|
continue;
|
|
87648
87712
|
}
|
|
@@ -87652,7 +87716,7 @@ function extractRoutes(cwd) {
|
|
|
87652
87716
|
}
|
|
87653
87717
|
walkDir(fullPath);
|
|
87654
87718
|
} else if (entry.isFile()) {
|
|
87655
|
-
const ext =
|
|
87719
|
+
const ext = path100.extname(entry.name).toLowerCase();
|
|
87656
87720
|
const baseName = entry.name.toLowerCase();
|
|
87657
87721
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
87658
87722
|
continue;
|
|
@@ -87820,7 +87884,7 @@ init_bun_compat();
|
|
|
87820
87884
|
init_path_security();
|
|
87821
87885
|
init_create_tool();
|
|
87822
87886
|
import * as fs78 from "node:fs";
|
|
87823
|
-
import * as
|
|
87887
|
+
import * as path101 from "node:path";
|
|
87824
87888
|
var DEFAULT_MAX_RESULTS = 100;
|
|
87825
87889
|
var DEFAULT_MAX_LINES = 200;
|
|
87826
87890
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -87856,11 +87920,11 @@ function containsWindowsAttacks3(str) {
|
|
|
87856
87920
|
}
|
|
87857
87921
|
function isPathInWorkspace3(filePath, workspace) {
|
|
87858
87922
|
try {
|
|
87859
|
-
const resolvedPath =
|
|
87923
|
+
const resolvedPath = path101.resolve(workspace, filePath);
|
|
87860
87924
|
const realWorkspace = fs78.realpathSync(workspace);
|
|
87861
87925
|
const realResolvedPath = fs78.realpathSync(resolvedPath);
|
|
87862
|
-
const relativePath =
|
|
87863
|
-
if (relativePath.startsWith("..") ||
|
|
87926
|
+
const relativePath = path101.relative(realWorkspace, realResolvedPath);
|
|
87927
|
+
if (relativePath.startsWith("..") || path101.isAbsolute(relativePath)) {
|
|
87864
87928
|
return false;
|
|
87865
87929
|
}
|
|
87866
87930
|
return true;
|
|
@@ -87873,11 +87937,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
87873
87937
|
}
|
|
87874
87938
|
function findRgInEnvPath() {
|
|
87875
87939
|
const searchPath = process.env.PATH ?? "";
|
|
87876
|
-
for (const dir of searchPath.split(
|
|
87940
|
+
for (const dir of searchPath.split(path101.delimiter)) {
|
|
87877
87941
|
if (!dir)
|
|
87878
87942
|
continue;
|
|
87879
87943
|
const isWindows = process.platform === "win32";
|
|
87880
|
-
const candidate =
|
|
87944
|
+
const candidate = path101.join(dir, isWindows ? "rg.exe" : "rg");
|
|
87881
87945
|
if (fs78.existsSync(candidate))
|
|
87882
87946
|
return candidate;
|
|
87883
87947
|
}
|
|
@@ -87932,7 +87996,7 @@ async function ripgrepSearch(opts) {
|
|
|
87932
87996
|
stderr: "pipe",
|
|
87933
87997
|
cwd: opts.workspace
|
|
87934
87998
|
});
|
|
87935
|
-
const timeout = new Promise((
|
|
87999
|
+
const timeout = new Promise((resolve40) => setTimeout(() => resolve40("timeout"), REGEX_TIMEOUT_MS));
|
|
87936
88000
|
const exitPromise = proc.exited;
|
|
87937
88001
|
const result = await Promise.race([exitPromise, timeout]);
|
|
87938
88002
|
if (result === "timeout") {
|
|
@@ -88007,8 +88071,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
88007
88071
|
try {
|
|
88008
88072
|
const entries = fs78.readdirSync(dir, { withFileTypes: true });
|
|
88009
88073
|
for (const entry of entries) {
|
|
88010
|
-
const fullPath =
|
|
88011
|
-
const relativePath =
|
|
88074
|
+
const fullPath = path101.join(dir, entry.name);
|
|
88075
|
+
const relativePath = path101.relative(workspace, fullPath);
|
|
88012
88076
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
88013
88077
|
continue;
|
|
88014
88078
|
}
|
|
@@ -88049,7 +88113,7 @@ async function fallbackSearch(opts) {
|
|
|
88049
88113
|
const matches = [];
|
|
88050
88114
|
let total = 0;
|
|
88051
88115
|
for (const file3 of files) {
|
|
88052
|
-
const fullPath =
|
|
88116
|
+
const fullPath = path101.join(opts.workspace, file3);
|
|
88053
88117
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
88054
88118
|
continue;
|
|
88055
88119
|
}
|
|
@@ -88430,7 +88494,7 @@ init_zod();
|
|
|
88430
88494
|
init_path_security();
|
|
88431
88495
|
init_create_tool();
|
|
88432
88496
|
import * as fs79 from "node:fs";
|
|
88433
|
-
import * as
|
|
88497
|
+
import * as path102 from "node:path";
|
|
88434
88498
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
88435
88499
|
function containsWindowsAttacks4(str) {
|
|
88436
88500
|
if (/:[^\\/]/.test(str))
|
|
@@ -88444,14 +88508,14 @@ function containsWindowsAttacks4(str) {
|
|
|
88444
88508
|
}
|
|
88445
88509
|
function isPathInWorkspace4(filePath, workspace) {
|
|
88446
88510
|
try {
|
|
88447
|
-
const resolvedPath =
|
|
88511
|
+
const resolvedPath = path102.resolve(workspace, filePath);
|
|
88448
88512
|
if (!fs79.existsSync(resolvedPath)) {
|
|
88449
88513
|
return true;
|
|
88450
88514
|
}
|
|
88451
88515
|
const realWorkspace = fs79.realpathSync(workspace);
|
|
88452
88516
|
const realResolvedPath = fs79.realpathSync(resolvedPath);
|
|
88453
|
-
const relativePath =
|
|
88454
|
-
if (relativePath.startsWith("..") ||
|
|
88517
|
+
const relativePath = path102.relative(realWorkspace, realResolvedPath);
|
|
88518
|
+
if (relativePath.startsWith("..") || path102.isAbsolute(relativePath)) {
|
|
88455
88519
|
return false;
|
|
88456
88520
|
}
|
|
88457
88521
|
return true;
|
|
@@ -88659,7 +88723,7 @@ var suggestPatch = createSwarmTool({
|
|
|
88659
88723
|
});
|
|
88660
88724
|
continue;
|
|
88661
88725
|
}
|
|
88662
|
-
const fullPath =
|
|
88726
|
+
const fullPath = path102.resolve(directory, change.file);
|
|
88663
88727
|
if (!fs79.existsSync(fullPath)) {
|
|
88664
88728
|
errors5.push({
|
|
88665
88729
|
success: false,
|
|
@@ -88922,7 +88986,7 @@ var generate_mutants = createSwarmTool({
|
|
|
88922
88986
|
init_spec_schema();
|
|
88923
88987
|
init_create_tool();
|
|
88924
88988
|
import * as fs80 from "node:fs";
|
|
88925
|
-
import * as
|
|
88989
|
+
import * as path103 from "node:path";
|
|
88926
88990
|
var SPEC_FILE_NAME = "spec.md";
|
|
88927
88991
|
var SWARM_DIR2 = ".swarm";
|
|
88928
88992
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -88975,7 +89039,7 @@ var lint_spec = createSwarmTool({
|
|
|
88975
89039
|
async execute(_args, directory) {
|
|
88976
89040
|
const errors5 = [];
|
|
88977
89041
|
const warnings = [];
|
|
88978
|
-
const specPath =
|
|
89042
|
+
const specPath = path103.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
88979
89043
|
if (!fs80.existsSync(specPath)) {
|
|
88980
89044
|
const result2 = {
|
|
88981
89045
|
valid: false,
|
|
@@ -89046,12 +89110,12 @@ var lint_spec = createSwarmTool({
|
|
|
89046
89110
|
// src/tools/mutation-test.ts
|
|
89047
89111
|
init_zod();
|
|
89048
89112
|
import * as fs81 from "node:fs";
|
|
89049
|
-
import * as
|
|
89113
|
+
import * as path105 from "node:path";
|
|
89050
89114
|
|
|
89051
89115
|
// src/mutation/engine.ts
|
|
89052
89116
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
89053
89117
|
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync20 } from "node:fs";
|
|
89054
|
-
import * as
|
|
89118
|
+
import * as path104 from "node:path";
|
|
89055
89119
|
|
|
89056
89120
|
// src/mutation/equivalence.ts
|
|
89057
89121
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -89186,7 +89250,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
89186
89250
|
let patchFile;
|
|
89187
89251
|
try {
|
|
89188
89252
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
89189
|
-
patchFile =
|
|
89253
|
+
patchFile = path104.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
89190
89254
|
try {
|
|
89191
89255
|
writeFileSync20(patchFile, patch.patch);
|
|
89192
89256
|
} catch (writeErr) {
|
|
@@ -89580,7 +89644,7 @@ var mutation_test = createSwarmTool({
|
|
|
89580
89644
|
];
|
|
89581
89645
|
for (const filePath of uniquePaths) {
|
|
89582
89646
|
try {
|
|
89583
|
-
const resolvedPath =
|
|
89647
|
+
const resolvedPath = path105.resolve(cwd, filePath);
|
|
89584
89648
|
sourceFiles.set(filePath, fs81.readFileSync(resolvedPath, "utf-8"));
|
|
89585
89649
|
} catch {}
|
|
89586
89650
|
}
|
|
@@ -89600,7 +89664,7 @@ init_zod();
|
|
|
89600
89664
|
init_manager2();
|
|
89601
89665
|
init_detector();
|
|
89602
89666
|
import * as fs82 from "node:fs";
|
|
89603
|
-
import * as
|
|
89667
|
+
import * as path106 from "node:path";
|
|
89604
89668
|
init_create_tool();
|
|
89605
89669
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
89606
89670
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -89666,7 +89730,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89666
89730
|
if (languages?.length) {
|
|
89667
89731
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
89668
89732
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
89669
|
-
const ext =
|
|
89733
|
+
const ext = path106.extname(file3.path).toLowerCase();
|
|
89670
89734
|
const langDef = getLanguageForExtension(ext);
|
|
89671
89735
|
const fileProfile = getProfileForFile(file3.path);
|
|
89672
89736
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -89679,7 +89743,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89679
89743
|
let skippedCount = 0;
|
|
89680
89744
|
for (const fileInfo of filesToCheck) {
|
|
89681
89745
|
const { path: filePath } = fileInfo;
|
|
89682
|
-
const fullPath =
|
|
89746
|
+
const fullPath = path106.isAbsolute(filePath) ? filePath : path106.join(directory, filePath);
|
|
89683
89747
|
const result = {
|
|
89684
89748
|
path: filePath,
|
|
89685
89749
|
language: "",
|
|
@@ -89728,7 +89792,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89728
89792
|
results.push(result);
|
|
89729
89793
|
continue;
|
|
89730
89794
|
}
|
|
89731
|
-
const ext =
|
|
89795
|
+
const ext = path106.extname(filePath).toLowerCase();
|
|
89732
89796
|
const langDef = getLanguageForExtension(ext);
|
|
89733
89797
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
89734
89798
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -89821,7 +89885,7 @@ init_utils();
|
|
|
89821
89885
|
init_create_tool();
|
|
89822
89886
|
init_path_security();
|
|
89823
89887
|
import * as fs83 from "node:fs";
|
|
89824
|
-
import * as
|
|
89888
|
+
import * as path107 from "node:path";
|
|
89825
89889
|
var MAX_TEXT_LENGTH = 200;
|
|
89826
89890
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
89827
89891
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -89887,9 +89951,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
89887
89951
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
89888
89952
|
}
|
|
89889
89953
|
try {
|
|
89890
|
-
const resolvedPath =
|
|
89891
|
-
const normalizedCwd =
|
|
89892
|
-
const normalizedResolved =
|
|
89954
|
+
const resolvedPath = path107.resolve(paths);
|
|
89955
|
+
const normalizedCwd = path107.resolve(cwd);
|
|
89956
|
+
const normalizedResolved = path107.resolve(resolvedPath);
|
|
89893
89957
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
89894
89958
|
return {
|
|
89895
89959
|
error: "paths must be within the current working directory",
|
|
@@ -89905,7 +89969,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
89905
89969
|
}
|
|
89906
89970
|
}
|
|
89907
89971
|
function isSupportedExtension(filePath) {
|
|
89908
|
-
const ext =
|
|
89972
|
+
const ext = path107.extname(filePath).toLowerCase();
|
|
89909
89973
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
89910
89974
|
}
|
|
89911
89975
|
function findSourceFiles3(dir, files = []) {
|
|
@@ -89920,16 +89984,16 @@ function findSourceFiles3(dir, files = []) {
|
|
|
89920
89984
|
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
89921
89985
|
continue;
|
|
89922
89986
|
}
|
|
89923
|
-
const fullPath =
|
|
89924
|
-
let
|
|
89987
|
+
const fullPath = path107.join(dir, entry);
|
|
89988
|
+
let stat7;
|
|
89925
89989
|
try {
|
|
89926
|
-
|
|
89990
|
+
stat7 = fs83.statSync(fullPath);
|
|
89927
89991
|
} catch {
|
|
89928
89992
|
continue;
|
|
89929
89993
|
}
|
|
89930
|
-
if (
|
|
89994
|
+
if (stat7.isDirectory()) {
|
|
89931
89995
|
findSourceFiles3(fullPath, files);
|
|
89932
|
-
} else if (
|
|
89996
|
+
} else if (stat7.isFile()) {
|
|
89933
89997
|
if (isSupportedExtension(fullPath)) {
|
|
89934
89998
|
files.push(fullPath);
|
|
89935
89999
|
}
|
|
@@ -90026,13 +90090,13 @@ var todo_extract = createSwarmTool({
|
|
|
90026
90090
|
return JSON.stringify(errorResult, null, 2);
|
|
90027
90091
|
}
|
|
90028
90092
|
const filesToScan = [];
|
|
90029
|
-
const
|
|
90030
|
-
if (
|
|
90093
|
+
const stat7 = fs83.statSync(scanPath);
|
|
90094
|
+
if (stat7.isFile()) {
|
|
90031
90095
|
if (isSupportedExtension(scanPath)) {
|
|
90032
90096
|
filesToScan.push(scanPath);
|
|
90033
90097
|
} else {
|
|
90034
90098
|
const errorResult = {
|
|
90035
|
-
error: `unsupported file extension: ${
|
|
90099
|
+
error: `unsupported file extension: ${path107.extname(scanPath)}`,
|
|
90036
90100
|
total: 0,
|
|
90037
90101
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
90038
90102
|
entries: []
|
|
@@ -90081,17 +90145,17 @@ init_schema();
|
|
|
90081
90145
|
init_qa_gate_profile();
|
|
90082
90146
|
init_gate_evidence();
|
|
90083
90147
|
import * as fs86 from "node:fs";
|
|
90084
|
-
import * as
|
|
90148
|
+
import * as path110 from "node:path";
|
|
90085
90149
|
|
|
90086
90150
|
// src/hooks/diff-scope.ts
|
|
90087
90151
|
init_bun_compat();
|
|
90088
90152
|
import * as fs85 from "node:fs";
|
|
90089
|
-
import * as
|
|
90153
|
+
import * as path109 from "node:path";
|
|
90090
90154
|
|
|
90091
90155
|
// src/utils/gitignore-warning.ts
|
|
90092
90156
|
init_bun_compat();
|
|
90093
90157
|
import * as fs84 from "node:fs";
|
|
90094
|
-
import * as
|
|
90158
|
+
import * as path108 from "node:path";
|
|
90095
90159
|
var _internals = { bunSpawn };
|
|
90096
90160
|
var _swarmGitExcludedChecked = false;
|
|
90097
90161
|
function fileCoversSwarm(content) {
|
|
@@ -90165,10 +90229,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
90165
90229
|
const excludeRelPath = excludePathRaw.trim();
|
|
90166
90230
|
if (!excludeRelPath)
|
|
90167
90231
|
return;
|
|
90168
|
-
const excludePath =
|
|
90232
|
+
const excludePath = path108.isAbsolute(excludeRelPath) ? excludeRelPath : path108.join(directory, excludeRelPath);
|
|
90169
90233
|
if (checkIgnoreExitCode !== 0) {
|
|
90170
90234
|
try {
|
|
90171
|
-
fs84.mkdirSync(
|
|
90235
|
+
fs84.mkdirSync(path108.dirname(excludePath), { recursive: true });
|
|
90172
90236
|
let existing = "";
|
|
90173
90237
|
try {
|
|
90174
90238
|
existing = fs84.readFileSync(excludePath, "utf8");
|
|
@@ -90212,7 +90276,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
90212
90276
|
var _internals2 = { bunSpawn };
|
|
90213
90277
|
function getDeclaredScope(taskId, directory) {
|
|
90214
90278
|
try {
|
|
90215
|
-
const planPath =
|
|
90279
|
+
const planPath = path109.join(directory, ".swarm", "plan.json");
|
|
90216
90280
|
if (!fs85.existsSync(planPath))
|
|
90217
90281
|
return null;
|
|
90218
90282
|
const raw = fs85.readFileSync(planPath, "utf-8");
|
|
@@ -90349,7 +90413,7 @@ var TIER_3_PATTERNS = [
|
|
|
90349
90413
|
];
|
|
90350
90414
|
function matchesTier3Pattern(files) {
|
|
90351
90415
|
for (const file3 of files) {
|
|
90352
|
-
const fileName =
|
|
90416
|
+
const fileName = path110.basename(file3);
|
|
90353
90417
|
for (const pattern of TIER_3_PATTERNS) {
|
|
90354
90418
|
if (pattern.test(fileName)) {
|
|
90355
90419
|
return true;
|
|
@@ -90363,7 +90427,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
90363
90427
|
if (hasActiveTurboMode()) {
|
|
90364
90428
|
const resolvedDir2 = workingDirectory;
|
|
90365
90429
|
try {
|
|
90366
|
-
const planPath =
|
|
90430
|
+
const planPath = path110.join(resolvedDir2, ".swarm", "plan.json");
|
|
90367
90431
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90368
90432
|
const plan = JSON.parse(planRaw);
|
|
90369
90433
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -90433,7 +90497,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
90433
90497
|
}
|
|
90434
90498
|
try {
|
|
90435
90499
|
const resolvedDir2 = workingDirectory;
|
|
90436
|
-
const planPath =
|
|
90500
|
+
const planPath = path110.join(resolvedDir2, ".swarm", "plan.json");
|
|
90437
90501
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90438
90502
|
const plan = JSON.parse(planRaw);
|
|
90439
90503
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -90623,8 +90687,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90623
90687
|
};
|
|
90624
90688
|
}
|
|
90625
90689
|
}
|
|
90626
|
-
normalizedDir =
|
|
90627
|
-
const pathParts = normalizedDir.split(
|
|
90690
|
+
normalizedDir = path110.normalize(args2.working_directory);
|
|
90691
|
+
const pathParts = normalizedDir.split(path110.sep);
|
|
90628
90692
|
if (pathParts.includes("..")) {
|
|
90629
90693
|
return {
|
|
90630
90694
|
success: false,
|
|
@@ -90634,10 +90698,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90634
90698
|
]
|
|
90635
90699
|
};
|
|
90636
90700
|
}
|
|
90637
|
-
const resolvedDir =
|
|
90701
|
+
const resolvedDir = path110.resolve(normalizedDir);
|
|
90638
90702
|
try {
|
|
90639
90703
|
const realPath = fs86.realpathSync(resolvedDir);
|
|
90640
|
-
const planPath =
|
|
90704
|
+
const planPath = path110.join(realPath, ".swarm", "plan.json");
|
|
90641
90705
|
if (!fs86.existsSync(planPath)) {
|
|
90642
90706
|
return {
|
|
90643
90707
|
success: false,
|
|
@@ -90669,8 +90733,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90669
90733
|
}
|
|
90670
90734
|
if (args2.status === "in_progress") {
|
|
90671
90735
|
try {
|
|
90672
|
-
const evidencePath =
|
|
90673
|
-
fs86.mkdirSync(
|
|
90736
|
+
const evidencePath = path110.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
90737
|
+
fs86.mkdirSync(path110.dirname(evidencePath), { recursive: true });
|
|
90674
90738
|
const fd = fs86.openSync(evidencePath, "wx");
|
|
90675
90739
|
let writeOk = false;
|
|
90676
90740
|
try {
|
|
@@ -90694,7 +90758,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90694
90758
|
recoverTaskStateFromDelegations(args2.task_id);
|
|
90695
90759
|
let phaseRequiresReviewer = true;
|
|
90696
90760
|
try {
|
|
90697
|
-
const planPath =
|
|
90761
|
+
const planPath = path110.join(directory, ".swarm", "plan.json");
|
|
90698
90762
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90699
90763
|
const plan = JSON.parse(planRaw);
|
|
90700
90764
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -91006,7 +91070,7 @@ init_ledger();
|
|
|
91006
91070
|
init_manager();
|
|
91007
91071
|
init_create_tool();
|
|
91008
91072
|
import fs87 from "node:fs";
|
|
91009
|
-
import
|
|
91073
|
+
import path111 from "node:path";
|
|
91010
91074
|
function derivePlanId5(plan) {
|
|
91011
91075
|
return `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
91012
91076
|
}
|
|
@@ -91057,7 +91121,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
91057
91121
|
entries: [evidenceEntry]
|
|
91058
91122
|
};
|
|
91059
91123
|
const filename = "drift-verifier.json";
|
|
91060
|
-
const relativePath =
|
|
91124
|
+
const relativePath = path111.join("evidence", String(phase), filename);
|
|
91061
91125
|
let validatedPath;
|
|
91062
91126
|
try {
|
|
91063
91127
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91068,10 +91132,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
91068
91132
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91069
91133
|
}, null, 2);
|
|
91070
91134
|
}
|
|
91071
|
-
const evidenceDir =
|
|
91135
|
+
const evidenceDir = path111.dirname(validatedPath);
|
|
91072
91136
|
try {
|
|
91073
91137
|
await fs87.promises.mkdir(evidenceDir, { recursive: true });
|
|
91074
|
-
const tempPath =
|
|
91138
|
+
const tempPath = path111.join(evidenceDir, `.${filename}.tmp`);
|
|
91075
91139
|
await fs87.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91076
91140
|
await fs87.promises.rename(tempPath, validatedPath);
|
|
91077
91141
|
let snapshotInfo;
|
|
@@ -91168,7 +91232,7 @@ init_zod();
|
|
|
91168
91232
|
init_utils2();
|
|
91169
91233
|
init_create_tool();
|
|
91170
91234
|
import fs88 from "node:fs";
|
|
91171
|
-
import
|
|
91235
|
+
import path112 from "node:path";
|
|
91172
91236
|
function normalizeVerdict2(verdict) {
|
|
91173
91237
|
switch (verdict) {
|
|
91174
91238
|
case "APPROVED":
|
|
@@ -91216,7 +91280,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
91216
91280
|
entries: [evidenceEntry]
|
|
91217
91281
|
};
|
|
91218
91282
|
const filename = "hallucination-guard.json";
|
|
91219
|
-
const relativePath =
|
|
91283
|
+
const relativePath = path112.join("evidence", String(phase), filename);
|
|
91220
91284
|
let validatedPath;
|
|
91221
91285
|
try {
|
|
91222
91286
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91227,10 +91291,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
91227
91291
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91228
91292
|
}, null, 2);
|
|
91229
91293
|
}
|
|
91230
|
-
const evidenceDir =
|
|
91294
|
+
const evidenceDir = path112.dirname(validatedPath);
|
|
91231
91295
|
try {
|
|
91232
91296
|
await fs88.promises.mkdir(evidenceDir, { recursive: true });
|
|
91233
|
-
const tempPath =
|
|
91297
|
+
const tempPath = path112.join(evidenceDir, `.${filename}.tmp`);
|
|
91234
91298
|
await fs88.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91235
91299
|
await fs88.promises.rename(tempPath, validatedPath);
|
|
91236
91300
|
return JSON.stringify({
|
|
@@ -91279,7 +91343,7 @@ init_zod();
|
|
|
91279
91343
|
init_utils2();
|
|
91280
91344
|
init_create_tool();
|
|
91281
91345
|
import fs89 from "node:fs";
|
|
91282
|
-
import
|
|
91346
|
+
import path113 from "node:path";
|
|
91283
91347
|
function normalizeVerdict3(verdict) {
|
|
91284
91348
|
switch (verdict) {
|
|
91285
91349
|
case "PASS":
|
|
@@ -91353,7 +91417,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
91353
91417
|
entries: [evidenceEntry]
|
|
91354
91418
|
};
|
|
91355
91419
|
const filename = "mutation-gate.json";
|
|
91356
|
-
const relativePath =
|
|
91420
|
+
const relativePath = path113.join("evidence", String(phase), filename);
|
|
91357
91421
|
let validatedPath;
|
|
91358
91422
|
try {
|
|
91359
91423
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91364,10 +91428,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
91364
91428
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91365
91429
|
}, null, 2);
|
|
91366
91430
|
}
|
|
91367
|
-
const evidenceDir =
|
|
91431
|
+
const evidenceDir = path113.dirname(validatedPath);
|
|
91368
91432
|
try {
|
|
91369
91433
|
await fs89.promises.mkdir(evidenceDir, { recursive: true });
|
|
91370
|
-
const tempPath =
|
|
91434
|
+
const tempPath = path113.join(evidenceDir, `.${filename}.tmp`);
|
|
91371
91435
|
await fs89.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91372
91436
|
await fs89.promises.rename(tempPath, validatedPath);
|
|
91373
91437
|
return JSON.stringify({
|
|
@@ -91661,7 +91725,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
91661
91725
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
91662
91726
|
preflightTriggerManager = new PTM(automationConfig);
|
|
91663
91727
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
91664
|
-
const swarmDir =
|
|
91728
|
+
const swarmDir = path114.resolve(ctx.directory, ".swarm");
|
|
91665
91729
|
statusArtifact = new ASA(swarmDir);
|
|
91666
91730
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
91667
91731
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|