opencode-swarm 7.4.2 → 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 +909 -842
- package/dist/state.d.ts +2 -1
- 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",
|
|
@@ -23146,7 +23146,8 @@ function extractIncompleteTasksFromPlan(plan, maxChars = 500) {
|
|
|
23146
23146
|
return null;
|
|
23147
23147
|
const lines = incomplete.map((t) => {
|
|
23148
23148
|
const deps = t.depends.length > 0 ? ` (depends: ${t.depends.join(", ")})` : "";
|
|
23149
|
-
|
|
23149
|
+
const marker = t.status === "in_progress" ? " ← CURRENT" : "";
|
|
23150
|
+
return `- [ ] ${t.id}: ${t.description} [${t.size.toUpperCase()}]${deps}${marker}`;
|
|
23150
23151
|
});
|
|
23151
23152
|
const text = lines.join(`
|
|
23152
23153
|
`);
|
|
@@ -62655,8 +62656,8 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62655
62656
|
var moduleRtn;
|
|
62656
62657
|
var Module = moduleArg;
|
|
62657
62658
|
var readyPromiseResolve, readyPromiseReject;
|
|
62658
|
-
var readyPromise = new Promise((
|
|
62659
|
-
readyPromiseResolve =
|
|
62659
|
+
var readyPromise = new Promise((resolve22, reject) => {
|
|
62660
|
+
readyPromiseResolve = resolve22;
|
|
62660
62661
|
readyPromiseReject = reject;
|
|
62661
62662
|
});
|
|
62662
62663
|
var ENVIRONMENT_IS_WEB = typeof window == "object";
|
|
@@ -62678,11 +62679,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62678
62679
|
throw toThrow;
|
|
62679
62680
|
}, "quit_");
|
|
62680
62681
|
var scriptDirectory = "";
|
|
62681
|
-
function locateFile(
|
|
62682
|
+
function locateFile(path65) {
|
|
62682
62683
|
if (Module["locateFile"]) {
|
|
62683
|
-
return Module["locateFile"](
|
|
62684
|
+
return Module["locateFile"](path65, scriptDirectory);
|
|
62684
62685
|
}
|
|
62685
|
-
return scriptDirectory +
|
|
62686
|
+
return scriptDirectory + path65;
|
|
62686
62687
|
}
|
|
62687
62688
|
__name(locateFile, "locateFile");
|
|
62688
62689
|
var readAsync, readBinary;
|
|
@@ -62736,13 +62737,13 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62736
62737
|
}
|
|
62737
62738
|
readAsync = /* @__PURE__ */ __name(async (url3) => {
|
|
62738
62739
|
if (isFileURI(url3)) {
|
|
62739
|
-
return new Promise((
|
|
62740
|
+
return new Promise((resolve22, reject) => {
|
|
62740
62741
|
var xhr = new XMLHttpRequest;
|
|
62741
62742
|
xhr.open("GET", url3, true);
|
|
62742
62743
|
xhr.responseType = "arraybuffer";
|
|
62743
62744
|
xhr.onload = () => {
|
|
62744
62745
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
62745
|
-
|
|
62746
|
+
resolve22(xhr.response);
|
|
62746
62747
|
return;
|
|
62747
62748
|
}
|
|
62748
62749
|
reject(xhr.status);
|
|
@@ -62962,10 +62963,10 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
62962
62963
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
62963
62964
|
var info2 = getWasmImports();
|
|
62964
62965
|
if (Module["instantiateWasm"]) {
|
|
62965
|
-
return new Promise((
|
|
62966
|
+
return new Promise((resolve22, reject) => {
|
|
62966
62967
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
62967
62968
|
receiveInstance(mod, inst);
|
|
62968
|
-
|
|
62969
|
+
resolve22(mod.exports);
|
|
62969
62970
|
});
|
|
62970
62971
|
});
|
|
62971
62972
|
}
|
|
@@ -64431,13 +64432,13 @@ __export(exports_runtime, {
|
|
|
64431
64432
|
getInitializedLanguages: () => getInitializedLanguages,
|
|
64432
64433
|
clearParserCache: () => clearParserCache
|
|
64433
64434
|
});
|
|
64434
|
-
import * as
|
|
64435
|
+
import * as path65 from "node:path";
|
|
64435
64436
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
64436
64437
|
async function initTreeSitter() {
|
|
64437
64438
|
if (treeSitterInitialized) {
|
|
64438
64439
|
return;
|
|
64439
64440
|
}
|
|
64440
|
-
const thisDir =
|
|
64441
|
+
const thisDir = path65.dirname(fileURLToPath2(import.meta.url));
|
|
64441
64442
|
const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
|
|
64442
64443
|
if (isSource) {
|
|
64443
64444
|
await Parser.init();
|
|
@@ -64445,7 +64446,7 @@ async function initTreeSitter() {
|
|
|
64445
64446
|
const grammarsDir = getGrammarsDirAbsolute();
|
|
64446
64447
|
await Parser.init({
|
|
64447
64448
|
locateFile(scriptName) {
|
|
64448
|
-
return
|
|
64449
|
+
return path65.join(grammarsDir, scriptName);
|
|
64449
64450
|
}
|
|
64450
64451
|
});
|
|
64451
64452
|
}
|
|
@@ -64466,11 +64467,11 @@ function getWasmFileName(languageId) {
|
|
|
64466
64467
|
return `tree-sitter-${sanitized}.wasm`;
|
|
64467
64468
|
}
|
|
64468
64469
|
function getGrammarsDirAbsolute() {
|
|
64469
|
-
const thisDir =
|
|
64470
|
+
const thisDir = path65.dirname(fileURLToPath2(import.meta.url));
|
|
64470
64471
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
64471
64472
|
const isSource = normalized.endsWith("/src/lang");
|
|
64472
64473
|
const isCliBundle = normalized.endsWith("/cli");
|
|
64473
|
-
return isSource ?
|
|
64474
|
+
return isSource ? path65.join(thisDir, "grammars") : isCliBundle ? path65.join(thisDir, "..", "lang", "grammars") : path65.join(thisDir, "lang", "grammars");
|
|
64474
64475
|
}
|
|
64475
64476
|
async function loadGrammar(languageId) {
|
|
64476
64477
|
if (typeof languageId !== "string" || languageId.length > 100) {
|
|
@@ -64486,9 +64487,9 @@ async function loadGrammar(languageId) {
|
|
|
64486
64487
|
await initTreeSitter();
|
|
64487
64488
|
const parser = new Parser;
|
|
64488
64489
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
64489
|
-
const wasmPath =
|
|
64490
|
-
const { existsSync:
|
|
64491
|
-
if (!
|
|
64490
|
+
const wasmPath = path65.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
64491
|
+
const { existsSync: existsSync33 } = await import("node:fs");
|
|
64492
|
+
if (!existsSync33(wasmPath)) {
|
|
64492
64493
|
throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
|
|
64493
64494
|
Make sure to run 'bun run build' to copy grammar files to dist/lang/grammars/`);
|
|
64494
64495
|
}
|
|
@@ -64521,7 +64522,7 @@ async function isGrammarAvailable(languageId) {
|
|
|
64521
64522
|
}
|
|
64522
64523
|
try {
|
|
64523
64524
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
64524
|
-
const wasmPath =
|
|
64525
|
+
const wasmPath = path65.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
64525
64526
|
const { statSync: statSync19 } = await import("node:fs");
|
|
64526
64527
|
statSync19(wasmPath);
|
|
64527
64528
|
return true;
|
|
@@ -64580,13 +64581,13 @@ __export(exports_doc_scan, {
|
|
|
64580
64581
|
import * as crypto7 from "node:crypto";
|
|
64581
64582
|
import * as fs45 from "node:fs";
|
|
64582
64583
|
import { mkdir as mkdir10, readFile as readFile10, writeFile as writeFile9 } from "node:fs/promises";
|
|
64583
|
-
import * as
|
|
64584
|
+
import * as path67 from "node:path";
|
|
64584
64585
|
function normalizeSeparators(filePath) {
|
|
64585
64586
|
return filePath.replace(/\\/g, "/");
|
|
64586
64587
|
}
|
|
64587
64588
|
function matchesDocPattern(filePath, patterns) {
|
|
64588
64589
|
const normalizedPath = normalizeSeparators(filePath);
|
|
64589
|
-
const basename9 =
|
|
64590
|
+
const basename9 = path67.basename(filePath);
|
|
64590
64591
|
for (const pattern of patterns) {
|
|
64591
64592
|
if (!pattern.includes("/") && !pattern.includes("\\")) {
|
|
64592
64593
|
if (basename9 === pattern) {
|
|
@@ -64642,7 +64643,7 @@ function stripMarkdown(text) {
|
|
|
64642
64643
|
return text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s*[-*•]\s+/gm, "").replace(/^\s*\d+\.\s+/gm, "").trim();
|
|
64643
64644
|
}
|
|
64644
64645
|
async function scanDocIndex(directory) {
|
|
64645
|
-
const manifestPath =
|
|
64646
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64646
64647
|
const defaultPatterns = DocsConfigSchema.parse({}).doc_patterns;
|
|
64647
64648
|
const extraPatterns = [
|
|
64648
64649
|
"ARCHITECTURE.md",
|
|
@@ -64659,9 +64660,9 @@ async function scanDocIndex(directory) {
|
|
|
64659
64660
|
let cacheValid = true;
|
|
64660
64661
|
for (const file3 of existingManifest.files) {
|
|
64661
64662
|
try {
|
|
64662
|
-
const fullPath =
|
|
64663
|
-
const
|
|
64664
|
-
if (
|
|
64663
|
+
const fullPath = path67.join(directory, file3.path);
|
|
64664
|
+
const stat6 = fs45.statSync(fullPath);
|
|
64665
|
+
if (stat6.mtimeMs > file3.mtime) {
|
|
64665
64666
|
cacheValid = false;
|
|
64666
64667
|
break;
|
|
64667
64668
|
}
|
|
@@ -64689,14 +64690,14 @@ async function scanDocIndex(directory) {
|
|
|
64689
64690
|
}
|
|
64690
64691
|
const entries = rawEntries.filter((e) => typeof e === "string");
|
|
64691
64692
|
for (const entry of entries) {
|
|
64692
|
-
const fullPath =
|
|
64693
|
-
let
|
|
64693
|
+
const fullPath = path67.join(directory, entry);
|
|
64694
|
+
let stat6;
|
|
64694
64695
|
try {
|
|
64695
|
-
|
|
64696
|
+
stat6 = fs45.statSync(fullPath);
|
|
64696
64697
|
} catch {
|
|
64697
64698
|
continue;
|
|
64698
64699
|
}
|
|
64699
|
-
if (!
|
|
64700
|
+
if (!stat6.isFile())
|
|
64700
64701
|
continue;
|
|
64701
64702
|
const pathParts = normalizeSeparators(entry).split("/");
|
|
64702
64703
|
let skipThisFile = false;
|
|
@@ -64725,7 +64726,7 @@ async function scanDocIndex(directory) {
|
|
|
64725
64726
|
} catch {
|
|
64726
64727
|
continue;
|
|
64727
64728
|
}
|
|
64728
|
-
const { title, summary } = extractTitleAndSummary(content,
|
|
64729
|
+
const { title, summary } = extractTitleAndSummary(content, path67.basename(entry));
|
|
64729
64730
|
const lineCount = content.split(`
|
|
64730
64731
|
`).length;
|
|
64731
64732
|
discoveredFiles.push({
|
|
@@ -64733,7 +64734,7 @@ async function scanDocIndex(directory) {
|
|
|
64733
64734
|
title,
|
|
64734
64735
|
summary,
|
|
64735
64736
|
lines: lineCount,
|
|
64736
|
-
mtime:
|
|
64737
|
+
mtime: stat6.mtimeMs
|
|
64737
64738
|
});
|
|
64738
64739
|
}
|
|
64739
64740
|
discoveredFiles.sort((a, b) => a.path.toLowerCase().localeCompare(b.path.toLowerCase()));
|
|
@@ -64751,7 +64752,7 @@ async function scanDocIndex(directory) {
|
|
|
64751
64752
|
files: discoveredFiles
|
|
64752
64753
|
};
|
|
64753
64754
|
try {
|
|
64754
|
-
await mkdir10(
|
|
64755
|
+
await mkdir10(path67.dirname(manifestPath), { recursive: true });
|
|
64755
64756
|
await writeFile9(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
64756
64757
|
} catch {}
|
|
64757
64758
|
return { manifest, cached: false };
|
|
@@ -64790,7 +64791,7 @@ function extractConstraintsFromContent(content) {
|
|
|
64790
64791
|
return constraints;
|
|
64791
64792
|
}
|
|
64792
64793
|
async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
64793
|
-
const manifestPath =
|
|
64794
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64794
64795
|
let manifest;
|
|
64795
64796
|
try {
|
|
64796
64797
|
const content = await readFile10(manifestPath, "utf-8");
|
|
@@ -64816,7 +64817,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64816
64817
|
}
|
|
64817
64818
|
let fullContent;
|
|
64818
64819
|
try {
|
|
64819
|
-
fullContent = await readFile10(
|
|
64820
|
+
fullContent = await readFile10(path67.join(directory, docFile.path), "utf-8");
|
|
64820
64821
|
} catch {
|
|
64821
64822
|
skippedCount++;
|
|
64822
64823
|
continue;
|
|
@@ -64839,7 +64840,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64839
64840
|
tier: "swarm",
|
|
64840
64841
|
lesson: constraint,
|
|
64841
64842
|
category: "architecture",
|
|
64842
|
-
tags: ["doc-scan",
|
|
64843
|
+
tags: ["doc-scan", path67.basename(docFile.path)],
|
|
64843
64844
|
scope: "global",
|
|
64844
64845
|
confidence: 0.5,
|
|
64845
64846
|
status: "candidate",
|
|
@@ -64912,7 +64913,7 @@ var init_doc_scan = __esm(() => {
|
|
|
64912
64913
|
}
|
|
64913
64914
|
} catch {}
|
|
64914
64915
|
if (force) {
|
|
64915
|
-
const manifestPath =
|
|
64916
|
+
const manifestPath = path67.join(directory, ".swarm", "doc-manifest.json");
|
|
64916
64917
|
try {
|
|
64917
64918
|
fs45.unlinkSync(manifestPath);
|
|
64918
64919
|
} catch {}
|
|
@@ -65103,9 +65104,9 @@ __export(exports_curator_drift, {
|
|
|
65103
65104
|
buildDriftInjectionText: () => buildDriftInjectionText
|
|
65104
65105
|
});
|
|
65105
65106
|
import * as fs48 from "node:fs";
|
|
65106
|
-
import * as
|
|
65107
|
+
import * as path70 from "node:path";
|
|
65107
65108
|
async function readPriorDriftReports(directory) {
|
|
65108
|
-
const swarmDir =
|
|
65109
|
+
const swarmDir = path70.join(directory, ".swarm");
|
|
65109
65110
|
const entries = await fs48.promises.readdir(swarmDir).catch(() => null);
|
|
65110
65111
|
if (entries === null)
|
|
65111
65112
|
return [];
|
|
@@ -65132,7 +65133,7 @@ async function readPriorDriftReports(directory) {
|
|
|
65132
65133
|
async function writeDriftReport(directory, report) {
|
|
65133
65134
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
65134
65135
|
const filePath = validateSwarmPath(directory, filename);
|
|
65135
|
-
const swarmDir =
|
|
65136
|
+
const swarmDir = path70.dirname(filePath);
|
|
65136
65137
|
await fs48.promises.mkdir(swarmDir, { recursive: true });
|
|
65137
65138
|
try {
|
|
65138
65139
|
await fs48.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
@@ -65266,7 +65267,7 @@ var init_curator_drift = __esm(() => {
|
|
|
65266
65267
|
// src/index.ts
|
|
65267
65268
|
init_package();
|
|
65268
65269
|
init_agents2();
|
|
65269
|
-
import * as
|
|
65270
|
+
import * as path114 from "node:path";
|
|
65270
65271
|
|
|
65271
65272
|
// src/background/index.ts
|
|
65272
65273
|
init_event_bus();
|
|
@@ -65939,6 +65940,7 @@ function createCcCommandInterceptHook(config3 = {}) {
|
|
|
65939
65940
|
}
|
|
65940
65941
|
// src/hooks/compaction-customizer.ts
|
|
65941
65942
|
init_manager();
|
|
65943
|
+
init_state();
|
|
65942
65944
|
init_utils2();
|
|
65943
65945
|
import * as fs33 from "node:fs";
|
|
65944
65946
|
import { join as join45 } from "node:path";
|
|
@@ -65995,6 +65997,7 @@ function createCompactionCustomizerHook(config3, directory) {
|
|
|
65995
65997
|
}
|
|
65996
65998
|
} catch {}
|
|
65997
65999
|
output.context.push("[KNOWLEDGE TOOLS] You have persistent knowledge tools: knowledge_recall (search for relevant past decisions), knowledge_add (store a new lesson), knowledge_remove (delete outdated entries). Use knowledge_recall when past context would help.");
|
|
66000
|
+
await buildRehydrationCache(directory);
|
|
65998
66001
|
})
|
|
65999
66002
|
};
|
|
66000
66003
|
}
|
|
@@ -67397,16 +67400,16 @@ ${originalText}`;
|
|
|
67397
67400
|
}
|
|
67398
67401
|
// src/hooks/repo-graph-builder.ts
|
|
67399
67402
|
init_constants();
|
|
67400
|
-
import
|
|
67403
|
+
import { realpathSync as realpathSync8 } from "node:fs";
|
|
67404
|
+
import * as path58 from "node:path";
|
|
67401
67405
|
|
|
67402
|
-
// src/tools/repo-graph.ts
|
|
67403
|
-
init_utils2();
|
|
67406
|
+
// src/tools/repo-graph/builder.ts
|
|
67404
67407
|
init_path_security();
|
|
67405
67408
|
import * as fsSync3 from "node:fs";
|
|
67406
|
-
import {
|
|
67409
|
+
import { existsSync as existsSync29, realpathSync as realpathSync6 } from "node:fs";
|
|
67407
67410
|
import * as fsPromises5 from "node:fs/promises";
|
|
67408
67411
|
import * as os7 from "node:os";
|
|
67409
|
-
import * as
|
|
67412
|
+
import * as path54 from "node:path";
|
|
67410
67413
|
|
|
67411
67414
|
// src/utils/timeout.ts
|
|
67412
67415
|
async function withTimeout(promise3, ms, timeoutError) {
|
|
@@ -67766,17 +67769,38 @@ var symbols = createSwarmTool({
|
|
|
67766
67769
|
}
|
|
67767
67770
|
});
|
|
67768
67771
|
|
|
67769
|
-
// src/tools/repo-graph.ts
|
|
67770
|
-
|
|
67771
|
-
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";
|
|
67772
67776
|
function normalizeGraphPath(filePath) {
|
|
67773
67777
|
return path53.normalize(filePath).replace(/\\/g, "/");
|
|
67774
67778
|
}
|
|
67775
|
-
|
|
67776
|
-
|
|
67777
|
-
|
|
67778
|
-
|
|
67779
|
-
|
|
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();
|
|
67780
67804
|
function validateWorkspace(workspace) {
|
|
67781
67805
|
if (!workspace || typeof workspace !== "string" || workspace.trim() === "") {
|
|
67782
67806
|
throw new Error("Invalid workspace: must be a non-empty string");
|
|
@@ -67864,309 +67888,8 @@ function validateGraphEdge(edge) {
|
|
|
67864
67888
|
throw new Error("Invalid edge: control characters detected");
|
|
67865
67889
|
}
|
|
67866
67890
|
}
|
|
67867
|
-
|
|
67868
|
-
|
|
67869
|
-
return null;
|
|
67870
|
-
}
|
|
67871
|
-
if (specifier.startsWith("/") || specifier.startsWith("\\")) {
|
|
67872
|
-
return null;
|
|
67873
|
-
}
|
|
67874
|
-
if (/^[A-Za-z]:[/\\]/.test(specifier)) {
|
|
67875
|
-
return null;
|
|
67876
|
-
}
|
|
67877
|
-
if (specifier.startsWith("http://") || specifier.startsWith("https://")) {
|
|
67878
|
-
return null;
|
|
67879
|
-
}
|
|
67880
|
-
try {
|
|
67881
|
-
if (specifier.startsWith(".")) {
|
|
67882
|
-
const sourceDir = path53.dirname(sourceFile);
|
|
67883
|
-
let resolved = path53.resolve(sourceDir, specifier);
|
|
67884
|
-
let realResolved;
|
|
67885
|
-
try {
|
|
67886
|
-
realResolved = realpathSync6(resolved);
|
|
67887
|
-
} catch {
|
|
67888
|
-
realResolved = resolved;
|
|
67889
|
-
}
|
|
67890
|
-
let realRoot;
|
|
67891
|
-
try {
|
|
67892
|
-
realRoot = realpathSync6(workspaceRoot);
|
|
67893
|
-
} catch {
|
|
67894
|
-
realRoot = path53.normalize(workspaceRoot);
|
|
67895
|
-
}
|
|
67896
|
-
if (!existsSync29(resolved)) {
|
|
67897
|
-
const EXTENSIONS = [
|
|
67898
|
-
".ts",
|
|
67899
|
-
".tsx",
|
|
67900
|
-
".js",
|
|
67901
|
-
".jsx",
|
|
67902
|
-
".mjs",
|
|
67903
|
-
".cjs",
|
|
67904
|
-
".py",
|
|
67905
|
-
".json"
|
|
67906
|
-
];
|
|
67907
|
-
let found = null;
|
|
67908
|
-
for (const ext of EXTENSIONS) {
|
|
67909
|
-
const candidate = resolved + ext;
|
|
67910
|
-
if (existsSync29(candidate)) {
|
|
67911
|
-
found = candidate;
|
|
67912
|
-
break;
|
|
67913
|
-
}
|
|
67914
|
-
}
|
|
67915
|
-
if (found) {
|
|
67916
|
-
try {
|
|
67917
|
-
realResolved = realpathSync6(found);
|
|
67918
|
-
} catch {
|
|
67919
|
-
realResolved = found;
|
|
67920
|
-
}
|
|
67921
|
-
resolved = found;
|
|
67922
|
-
} else {
|
|
67923
|
-
return null;
|
|
67924
|
-
}
|
|
67925
|
-
}
|
|
67926
|
-
const normalizedResolved = path53.normalize(realResolved);
|
|
67927
|
-
const normalizedRoot = path53.normalize(realRoot);
|
|
67928
|
-
if (!normalizedResolved.startsWith(normalizedRoot + path53.sep) && normalizedResolved !== normalizedRoot) {
|
|
67929
|
-
return null;
|
|
67930
|
-
}
|
|
67931
|
-
return resolved;
|
|
67932
|
-
}
|
|
67933
|
-
return null;
|
|
67934
|
-
} catch {
|
|
67935
|
-
return null;
|
|
67936
|
-
}
|
|
67937
|
-
}
|
|
67938
|
-
function createEmptyGraph(workspaceRoot) {
|
|
67939
|
-
return {
|
|
67940
|
-
schema_version: GRAPH_SCHEMA_VERSION,
|
|
67941
|
-
workspaceRoot: path53.normalize(workspaceRoot),
|
|
67942
|
-
nodes: {},
|
|
67943
|
-
edges: [],
|
|
67944
|
-
metadata: {
|
|
67945
|
-
generatedAt: new Date().toISOString(),
|
|
67946
|
-
generator: "repo-graph",
|
|
67947
|
-
nodeCount: 0,
|
|
67948
|
-
edgeCount: 0
|
|
67949
|
-
}
|
|
67950
|
-
};
|
|
67951
|
-
}
|
|
67952
|
-
function updateGraphMetadata(graph) {
|
|
67953
|
-
graph.metadata = {
|
|
67954
|
-
generatedAt: new Date().toISOString(),
|
|
67955
|
-
generator: "repo-graph",
|
|
67956
|
-
nodeCount: Object.keys(graph.nodes).length,
|
|
67957
|
-
edgeCount: graph.edges.length
|
|
67958
|
-
};
|
|
67959
|
-
}
|
|
67960
|
-
function upsertNode(graph, node) {
|
|
67961
|
-
validateGraphNode(node);
|
|
67962
|
-
const key = normalizeGraphPath(node.filePath);
|
|
67963
|
-
graph.nodes[key] = node;
|
|
67964
|
-
updateGraphMetadata(graph);
|
|
67965
|
-
}
|
|
67966
|
-
function addEdge(graph, edge) {
|
|
67967
|
-
validateGraphEdge(edge);
|
|
67968
|
-
const exists = graph.edges.some((e) => e.source === edge.source && e.target === edge.target && e.importSpecifier === edge.importSpecifier);
|
|
67969
|
-
if (!exists) {
|
|
67970
|
-
graph.edges.push(edge);
|
|
67971
|
-
updateGraphMetadata(graph);
|
|
67972
|
-
}
|
|
67973
|
-
}
|
|
67974
|
-
function getCachedGraph(workspace) {
|
|
67975
|
-
return graphCache.get(path53.normalize(workspace));
|
|
67976
|
-
}
|
|
67977
|
-
function setCachedGraph(workspace, graph, mtime) {
|
|
67978
|
-
const normalized = path53.normalize(workspace);
|
|
67979
|
-
graphCache.set(normalized, graph);
|
|
67980
|
-
dirtyFlags.set(normalized, false);
|
|
67981
|
-
if (mtime !== undefined) {
|
|
67982
|
-
mtimeCache.set(normalized, mtime);
|
|
67983
|
-
}
|
|
67984
|
-
}
|
|
67985
|
-
function isDirty(workspace) {
|
|
67986
|
-
return dirtyFlags.get(path53.normalize(workspace)) ?? false;
|
|
67987
|
-
}
|
|
67988
|
-
function clearCache(workspace) {
|
|
67989
|
-
const normalized = path53.normalize(workspace);
|
|
67990
|
-
graphCache.delete(normalized);
|
|
67991
|
-
dirtyFlags.delete(normalized);
|
|
67992
|
-
mtimeCache.delete(normalized);
|
|
67993
|
-
}
|
|
67994
|
-
function getGraphPath(workspace) {
|
|
67995
|
-
validateWorkspace(workspace);
|
|
67996
|
-
const basePath = validateSwarmPath(workspace, REPO_GRAPH_FILENAME);
|
|
67997
|
-
validateSymlinkBoundary(basePath, workspace);
|
|
67998
|
-
return basePath;
|
|
67999
|
-
}
|
|
68000
|
-
async function loadGraph(workspace) {
|
|
68001
|
-
validateWorkspace(workspace);
|
|
68002
|
-
const normalized = path53.normalize(workspace);
|
|
68003
|
-
const cached3 = getCachedGraph(normalized);
|
|
68004
|
-
if (cached3 && !isDirty(normalized)) {
|
|
68005
|
-
try {
|
|
68006
|
-
const graphPath = getGraphPath(workspace);
|
|
68007
|
-
if (existsSync29(graphPath)) {
|
|
68008
|
-
const stats = await fsPromises5.stat(graphPath);
|
|
68009
|
-
const cachedMtime = mtimeCache.get(normalized);
|
|
68010
|
-
if (cachedMtime !== undefined && stats.mtimeMs !== cachedMtime) {
|
|
68011
|
-
clearCache(normalized);
|
|
68012
|
-
} else {
|
|
68013
|
-
return cached3;
|
|
68014
|
-
}
|
|
68015
|
-
} else {
|
|
68016
|
-
clearCache(normalized);
|
|
68017
|
-
}
|
|
68018
|
-
} catch {
|
|
68019
|
-
clearCache(normalized);
|
|
68020
|
-
}
|
|
68021
|
-
}
|
|
68022
|
-
try {
|
|
68023
|
-
const graphPath = getGraphPath(workspace);
|
|
68024
|
-
if (!existsSync29(graphPath)) {
|
|
68025
|
-
return null;
|
|
68026
|
-
}
|
|
68027
|
-
const stats = await fsPromises5.stat(graphPath);
|
|
68028
|
-
const content = await fsPromises5.readFile(graphPath, "utf-8");
|
|
68029
|
-
if (content.includes("\x00") || content.includes("�")) {
|
|
68030
|
-
throw Object.assign(new Error("repo-graph.json contains null bytes or invalid encoding"), { code: "CORRUPTION" });
|
|
68031
|
-
}
|
|
68032
|
-
let parsed;
|
|
68033
|
-
try {
|
|
68034
|
-
parsed = JSON.parse(content);
|
|
68035
|
-
} catch {
|
|
68036
|
-
throw Object.assign(new Error("repo-graph.json contains invalid JSON"), {
|
|
68037
|
-
code: "CORRUPTION"
|
|
68038
|
-
});
|
|
68039
|
-
}
|
|
68040
|
-
if (!parsed.schema_version) {
|
|
68041
|
-
throw Object.assign(new Error("repo-graph.json missing schema_version"), {
|
|
68042
|
-
code: "CORRUPTION"
|
|
68043
|
-
});
|
|
68044
|
-
}
|
|
68045
|
-
if (!parsed.nodes || typeof parsed.nodes !== "object") {
|
|
68046
|
-
throw Object.assign(new Error("repo-graph.json missing or invalid nodes"), { code: "CORRUPTION" });
|
|
68047
|
-
}
|
|
68048
|
-
if (!Array.isArray(parsed.edges)) {
|
|
68049
|
-
throw Object.assign(new Error("repo-graph.json missing or invalid edges"), { code: "CORRUPTION" });
|
|
68050
|
-
}
|
|
68051
|
-
for (const [key, node] of Object.entries(parsed.nodes)) {
|
|
68052
|
-
if (!key || typeof key !== "string") {
|
|
68053
|
-
throw Object.assign(new Error("repo-graph.json contains invalid node key"), { code: "CORRUPTION" });
|
|
68054
|
-
}
|
|
68055
|
-
try {
|
|
68056
|
-
validateGraphNode(node);
|
|
68057
|
-
} catch (err2) {
|
|
68058
|
-
const msg = err2 instanceof Error ? err2.message : "Invalid node structure";
|
|
68059
|
-
throw Object.assign(new Error(`repo-graph.json node validation failed: ${msg}`), { code: "CORRUPTION" });
|
|
68060
|
-
}
|
|
68061
|
-
}
|
|
68062
|
-
for (const edge of parsed.edges) {
|
|
68063
|
-
try {
|
|
68064
|
-
validateGraphEdge(edge);
|
|
68065
|
-
} catch (err2) {
|
|
68066
|
-
const msg = err2 instanceof Error ? err2.message : "Invalid edge structure";
|
|
68067
|
-
throw Object.assign(new Error(`repo-graph.json edge validation failed: ${msg}`), { code: "CORRUPTION" });
|
|
68068
|
-
}
|
|
68069
|
-
}
|
|
68070
|
-
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") {
|
|
68071
|
-
throw Object.assign(new Error("repo-graph.json missing or invalid metadata"), { code: "CORRUPTION" });
|
|
68072
|
-
}
|
|
68073
|
-
setCachedGraph(normalized, parsed, stats.mtimeMs);
|
|
68074
|
-
return parsed;
|
|
68075
|
-
} catch (error93) {
|
|
68076
|
-
if (error93 instanceof Error && "code" in error93 && error93.code === "CORRUPTION") {
|
|
68077
|
-
throw error93;
|
|
68078
|
-
}
|
|
68079
|
-
if (error93 instanceof Error && "code" in error93 && error93.code === "ENOENT") {
|
|
68080
|
-
return null;
|
|
68081
|
-
}
|
|
68082
|
-
throw error93;
|
|
68083
|
-
}
|
|
68084
|
-
}
|
|
68085
|
-
async function saveGraph(workspace, graph, options) {
|
|
68086
|
-
validateWorkspace(workspace);
|
|
68087
|
-
if (!graph.schema_version) {
|
|
68088
|
-
throw new Error("Graph must have schema_version");
|
|
68089
|
-
}
|
|
68090
|
-
if (!graph.nodes || typeof graph.nodes !== "object") {
|
|
68091
|
-
throw new Error("Graph must have nodes object");
|
|
68092
|
-
}
|
|
68093
|
-
if (!Array.isArray(graph.edges)) {
|
|
68094
|
-
throw new Error("Graph must have edges array");
|
|
68095
|
-
}
|
|
68096
|
-
const normalizedWorkspace = path53.normalize(workspace);
|
|
68097
|
-
let realWorkspace;
|
|
68098
|
-
try {
|
|
68099
|
-
realWorkspace = realpathSync6(workspace);
|
|
68100
|
-
} catch {
|
|
68101
|
-
realWorkspace = normalizedWorkspace;
|
|
68102
|
-
}
|
|
68103
|
-
const normalizedGraphRoot = path53.normalize(graph.workspaceRoot);
|
|
68104
|
-
let realGraphRoot;
|
|
68105
|
-
try {
|
|
68106
|
-
realGraphRoot = realpathSync6(graph.workspaceRoot);
|
|
68107
|
-
} catch {
|
|
68108
|
-
realGraphRoot = normalizedGraphRoot;
|
|
68109
|
-
}
|
|
68110
|
-
if (path53.normalize(realWorkspace) !== path53.normalize(realGraphRoot)) {
|
|
68111
|
-
throw new Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);
|
|
68112
|
-
}
|
|
68113
|
-
const normalized = normalizedWorkspace;
|
|
68114
|
-
const graphPath = getGraphPath(workspace);
|
|
68115
|
-
updateGraphMetadata(graph);
|
|
68116
|
-
const tempPath = `${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
68117
|
-
await fsPromises5.mkdir(path53.dirname(tempPath), { recursive: true });
|
|
68118
|
-
let lastError = null;
|
|
68119
|
-
try {
|
|
68120
|
-
if (options?.createAtomic) {
|
|
68121
|
-
try {
|
|
68122
|
-
const handle2 = await fsPromises5.open(tempPath, "wx", 420);
|
|
68123
|
-
await handle2.writeFile(JSON.stringify(graph, null, 2), "utf-8");
|
|
68124
|
-
await handle2.close();
|
|
68125
|
-
} catch (error93) {
|
|
68126
|
-
if (error93 instanceof Error && "code" in error93 && error93.code === "EEXIST") {
|
|
68127
|
-
throw new Error("file already exists");
|
|
68128
|
-
}
|
|
68129
|
-
throw error93;
|
|
68130
|
-
}
|
|
68131
|
-
} else {
|
|
68132
|
-
await fsPromises5.writeFile(tempPath, JSON.stringify(graph, null, 2), "utf-8");
|
|
68133
|
-
}
|
|
68134
|
-
if (options?.createAtomic) {
|
|
68135
|
-
try {
|
|
68136
|
-
await fsPromises5.copyFile(tempPath, graphPath, constants4.COPYFILE_EXCL);
|
|
68137
|
-
} catch (error93) {
|
|
68138
|
-
lastError = error93 instanceof Error ? error93 : new Error(String(error93));
|
|
68139
|
-
throw lastError;
|
|
68140
|
-
}
|
|
68141
|
-
} else {
|
|
68142
|
-
let retries = 0;
|
|
68143
|
-
while (retries < WINDOWS_RENAME_MAX_RETRIES2) {
|
|
68144
|
-
try {
|
|
68145
|
-
await fsPromises5.rename(tempPath, graphPath);
|
|
68146
|
-
break;
|
|
68147
|
-
} catch (error93) {
|
|
68148
|
-
lastError = error93 instanceof Error ? error93 : new Error(String(error93));
|
|
68149
|
-
if (lastError instanceof Error && "code" in lastError && lastError.code === "EEXIST" && retries < WINDOWS_RENAME_MAX_RETRIES2 - 1) {
|
|
68150
|
-
retries++;
|
|
68151
|
-
await new Promise((resolve18) => setTimeout(resolve18, WINDOWS_RENAME_RETRY_DELAY_MS2));
|
|
68152
|
-
continue;
|
|
68153
|
-
}
|
|
68154
|
-
throw lastError;
|
|
68155
|
-
}
|
|
68156
|
-
}
|
|
68157
|
-
}
|
|
68158
|
-
} finally {
|
|
68159
|
-
try {
|
|
68160
|
-
await fsPromises5.unlink(tempPath);
|
|
68161
|
-
} catch (error93) {
|
|
68162
|
-
if (error93 instanceof Error && "code" in error93 && error93.code !== "ENOENT") {
|
|
68163
|
-
error48(`Failed to clean up temp file ${tempPath}:`, error93);
|
|
68164
|
-
}
|
|
68165
|
-
}
|
|
68166
|
-
}
|
|
68167
|
-
const stats = await fsPromises5.stat(graphPath);
|
|
68168
|
-
setCachedGraph(normalized, graph, stats.mtimeMs);
|
|
68169
|
-
}
|
|
67891
|
+
|
|
67892
|
+
// src/tools/repo-graph/builder.ts
|
|
68170
67893
|
var SKIP_DIRECTORIES2 = new Set([
|
|
68171
67894
|
"node_modules",
|
|
68172
67895
|
".git",
|
|
@@ -68193,17 +67916,111 @@ var SUPPORTED_EXTENSIONS = [
|
|
|
68193
67916
|
var DEFAULT_WALK_FILE_CAP = 1e4;
|
|
68194
67917
|
var DEFAULT_WALK_BUDGET_MS = 5000;
|
|
68195
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
|
+
}
|
|
68196
68013
|
function isRefusedWorkspaceRoot(target) {
|
|
68197
68014
|
let resolved;
|
|
68198
68015
|
try {
|
|
68199
68016
|
resolved = realpathSync6(target);
|
|
68200
68017
|
} catch {
|
|
68201
|
-
resolved =
|
|
68018
|
+
resolved = path54.resolve(target);
|
|
68202
68019
|
}
|
|
68203
68020
|
const refused = new Set;
|
|
68204
68021
|
const add = (p) => {
|
|
68205
68022
|
if (typeof p === "string" && p.length > 0) {
|
|
68206
|
-
refused.add(
|
|
68023
|
+
refused.add(path54.resolve(p));
|
|
68207
68024
|
}
|
|
68208
68025
|
};
|
|
68209
68026
|
add(os7.homedir());
|
|
@@ -68218,15 +68035,6 @@ function isRefusedWorkspaceRoot(target) {
|
|
|
68218
68035
|
}
|
|
68219
68036
|
return refused.has(resolved);
|
|
68220
68037
|
}
|
|
68221
|
-
var EXTENSION_TO_LANGUAGE = {
|
|
68222
|
-
".ts": "typescript",
|
|
68223
|
-
".tsx": "typescript",
|
|
68224
|
-
".js": "javascript",
|
|
68225
|
-
".jsx": "javascript",
|
|
68226
|
-
".mjs": "javascript",
|
|
68227
|
-
".cjs": "javascript",
|
|
68228
|
-
".py": "python"
|
|
68229
|
-
};
|
|
68230
68038
|
function parseFileImports(content) {
|
|
68231
68039
|
const imports = [];
|
|
68232
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;
|
|
@@ -68322,7 +68130,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68322
68130
|
ctx.stats.skippedDirs++;
|
|
68323
68131
|
continue;
|
|
68324
68132
|
}
|
|
68325
|
-
const fullPath =
|
|
68133
|
+
const fullPath = path54.join(current, entry.name);
|
|
68326
68134
|
if (entry.isSymbolicLink() && !ctx.followSymlinks) {
|
|
68327
68135
|
ctx.stats.skippedDirs++;
|
|
68328
68136
|
continue;
|
|
@@ -68330,7 +68138,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68330
68138
|
if (entry.isDirectory()) {
|
|
68331
68139
|
queue.push(fullPath);
|
|
68332
68140
|
} else if (entry.isFile()) {
|
|
68333
|
-
const ext =
|
|
68141
|
+
const ext = path54.extname(fullPath).toLowerCase();
|
|
68334
68142
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
68335
68143
|
files.push(fullPath);
|
|
68336
68144
|
}
|
|
@@ -68347,11 +68155,11 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
68347
68155
|
return files;
|
|
68348
68156
|
}
|
|
68349
68157
|
function toModuleName(filePath, workspaceRoot) {
|
|
68350
|
-
const relative9 =
|
|
68351
|
-
return relative9.split(
|
|
68158
|
+
const relative9 = path54.relative(workspaceRoot, filePath);
|
|
68159
|
+
return relative9.split(path54.sep).join("/");
|
|
68352
68160
|
}
|
|
68353
68161
|
function getLanguage(filePath) {
|
|
68354
|
-
const ext =
|
|
68162
|
+
const ext = path54.extname(filePath).toLowerCase();
|
|
68355
68163
|
return EXTENSION_TO_LANGUAGE[ext] ?? "unknown";
|
|
68356
68164
|
}
|
|
68357
68165
|
function isBinaryContent(content) {
|
|
@@ -68360,13 +68168,67 @@ function isBinaryContent(content) {
|
|
|
68360
68168
|
}
|
|
68361
68169
|
return false;
|
|
68362
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
|
+
}
|
|
68363
68225
|
async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
68364
68226
|
validateWorkspace(workspaceRoot);
|
|
68365
68227
|
const maxFileSize = options?.maxFileSizeBytes ?? 1024 * 1024;
|
|
68366
68228
|
const maxFiles = options?.maxFiles ?? DEFAULT_WALK_FILE_CAP;
|
|
68367
68229
|
const walkBudgetMs = options?.walkBudgetMs ?? DEFAULT_WALK_BUDGET_MS;
|
|
68368
68230
|
const followSymlinks = options?.followSymlinks ?? false;
|
|
68369
|
-
const absoluteRoot =
|
|
68231
|
+
const absoluteRoot = path54.resolve(workspaceRoot);
|
|
68370
68232
|
if (!existsSync29(absoluteRoot)) {
|
|
68371
68233
|
throw new Error(`Workspace directory does not exist: ${workspaceRoot}`);
|
|
68372
68234
|
}
|
|
@@ -68421,60 +68283,225 @@ async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
|
68421
68283
|
}
|
|
68422
68284
|
return graph;
|
|
68423
68285
|
}
|
|
68424
|
-
|
|
68425
|
-
|
|
68426
|
-
|
|
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
|
+
}
|
|
68427
68355
|
try {
|
|
68428
|
-
|
|
68429
|
-
if (
|
|
68430
|
-
return
|
|
68356
|
+
const graphPath = getGraphPath(workspace);
|
|
68357
|
+
if (!existsSync30(graphPath)) {
|
|
68358
|
+
return null;
|
|
68431
68359
|
}
|
|
68432
|
-
|
|
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);
|
|
68433
68433
|
} catch {
|
|
68434
|
-
|
|
68434
|
+
realWorkspace = normalizedWorkspace;
|
|
68435
68435
|
}
|
|
68436
|
-
|
|
68437
|
-
|
|
68436
|
+
const normalizedGraphRoot = path56.normalize(graph.workspaceRoot);
|
|
68437
|
+
let realGraphRoot;
|
|
68438
|
+
try {
|
|
68439
|
+
realGraphRoot = realpathSync7(graph.workspaceRoot);
|
|
68440
|
+
} catch {
|
|
68441
|
+
realGraphRoot = normalizedGraphRoot;
|
|
68438
68442
|
}
|
|
68439
|
-
|
|
68440
|
-
|
|
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;
|
|
68441
68452
|
try {
|
|
68442
|
-
if (
|
|
68443
|
-
|
|
68444
|
-
|
|
68445
|
-
|
|
68446
|
-
|
|
68447
|
-
|
|
68448
|
-
|
|
68449
|
-
|
|
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");
|
|
68450
68466
|
}
|
|
68451
|
-
|
|
68452
|
-
|
|
68453
|
-
|
|
68454
|
-
|
|
68455
|
-
|
|
68456
|
-
|
|
68457
|
-
|
|
68458
|
-
|
|
68459
|
-
|
|
68460
|
-
|
|
68461
|
-
|
|
68462
|
-
|
|
68463
|
-
|
|
68464
|
-
|
|
68465
|
-
|
|
68466
|
-
|
|
68467
|
-
|
|
68468
|
-
|
|
68469
|
-
|
|
68470
|
-
|
|
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);
|
|
68471
68497
|
}
|
|
68472
68498
|
}
|
|
68473
|
-
return { node, edges };
|
|
68474
|
-
} catch {
|
|
68475
|
-
return { node: null, edges: [] };
|
|
68476
68499
|
}
|
|
68500
|
+
const stats = await fsPromises6.stat(graphPath);
|
|
68501
|
+
setCachedGraph(normalized, graph, stats.mtimeMs);
|
|
68477
68502
|
}
|
|
68503
|
+
|
|
68504
|
+
// src/tools/repo-graph/incremental.ts
|
|
68478
68505
|
async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
68479
68506
|
if (options?.forceRebuild) {
|
|
68480
68507
|
const graph2 = await buildWorkspaceGraphAsync(workspaceRoot);
|
|
@@ -68488,12 +68515,12 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
68488
68515
|
return graph2;
|
|
68489
68516
|
}
|
|
68490
68517
|
const graph = existingGraph;
|
|
68491
|
-
const absoluteRoot =
|
|
68518
|
+
const absoluteRoot = path57.resolve(workspaceRoot);
|
|
68492
68519
|
const maxFileSize = 1024 * 1024;
|
|
68493
68520
|
const updatedPaths = new Set;
|
|
68494
68521
|
for (const rawFilePath of filePaths) {
|
|
68495
68522
|
const normalizedPath = normalizeGraphPath(rawFilePath);
|
|
68496
|
-
const fileExists =
|
|
68523
|
+
const fileExists = existsSync31(rawFilePath);
|
|
68497
68524
|
if (fileExists) {
|
|
68498
68525
|
graph.edges = graph.edges.filter((e) => normalizeGraphPath(e.source) !== normalizedPath);
|
|
68499
68526
|
const result = scanFile(rawFilePath, absoluteRoot, maxFileSize);
|
|
@@ -68528,6 +68555,22 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
68528
68555
|
await saveGraph(workspaceRoot, rebuiltGraph);
|
|
68529
68556
|
return rebuiltGraph;
|
|
68530
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
|
+
}
|
|
68531
68574
|
updateGraphMetadata(graph);
|
|
68532
68575
|
await saveGraph(workspaceRoot, graph);
|
|
68533
68576
|
return graph;
|
|
@@ -68546,9 +68589,20 @@ function extractFilePath(args2) {
|
|
|
68546
68589
|
if (!args2 || typeof args2 !== "object")
|
|
68547
68590
|
return null;
|
|
68548
68591
|
const a = args2;
|
|
68549
|
-
|
|
68592
|
+
let filePath = a.file_path ?? a.path ?? a.filePath;
|
|
68550
68593
|
if (!filePath || typeof filePath !== "string")
|
|
68551
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, ".");
|
|
68552
68606
|
return filePath;
|
|
68553
68607
|
}
|
|
68554
68608
|
function isSupportedSourceFile(filePath) {
|
|
@@ -68561,6 +68615,8 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
68561
68615
|
const _updateGraphForFiles = deps?.updateGraphForFiles ?? updateGraphForFiles;
|
|
68562
68616
|
let initStarted = false;
|
|
68563
68617
|
let initPromise = Promise.resolve();
|
|
68618
|
+
let consecutiveFailures = 0;
|
|
68619
|
+
const FAILURE_ADVISORY_THRESHOLD = 3;
|
|
68564
68620
|
async function doInit() {
|
|
68565
68621
|
await yieldToEventLoop();
|
|
68566
68622
|
try {
|
|
@@ -68589,37 +68645,48 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
68589
68645
|
if (!WRITE_TOOL_NAMES.includes(input.tool)) {
|
|
68590
68646
|
return;
|
|
68591
68647
|
}
|
|
68592
|
-
const
|
|
68593
|
-
if (!
|
|
68648
|
+
const filePath = extractFilePath(input.args);
|
|
68649
|
+
if (!filePath)
|
|
68594
68650
|
return;
|
|
68595
|
-
if (
|
|
68651
|
+
if (filePath.includes("\x00"))
|
|
68596
68652
|
return;
|
|
68597
|
-
let filePath = rawFilePath;
|
|
68598
|
-
for (let i2 = 0;i2 < 3; i2++) {
|
|
68599
|
-
try {
|
|
68600
|
-
const decoded = decodeURIComponent(filePath);
|
|
68601
|
-
if (decoded === filePath)
|
|
68602
|
-
break;
|
|
68603
|
-
filePath = decoded;
|
|
68604
|
-
} catch {
|
|
68605
|
-
break;
|
|
68606
|
-
}
|
|
68607
|
-
}
|
|
68608
|
-
filePath = filePath.replace(/./g, ".").replace(///g, "/").replace(/․/g, ".");
|
|
68609
68653
|
if (!isSupportedSourceFile(filePath))
|
|
68610
68654
|
return;
|
|
68611
|
-
const absoluteFilePath =
|
|
68612
|
-
|
|
68613
|
-
|
|
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, "/");
|
|
68614
68676
|
if (!normalizedAbsolute.startsWith(`${normalizedWorkspace}/`) && normalizedAbsolute !== normalizedWorkspace) {
|
|
68615
68677
|
return;
|
|
68616
68678
|
}
|
|
68617
68679
|
try {
|
|
68618
68680
|
await _updateGraphForFiles(workspaceRoot, [absoluteFilePath]);
|
|
68619
|
-
|
|
68681
|
+
consecutiveFailures = 0;
|
|
68682
|
+
log(`[repo-graph] Incremental update for ${path58.basename(filePath)}`);
|
|
68620
68683
|
} catch (error93) {
|
|
68621
68684
|
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
68685
|
+
consecutiveFailures++;
|
|
68622
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
|
+
}
|
|
68623
68690
|
}
|
|
68624
68691
|
}
|
|
68625
68692
|
};
|
|
@@ -68635,14 +68702,14 @@ init_manager2();
|
|
|
68635
68702
|
init_detector();
|
|
68636
68703
|
init_manager();
|
|
68637
68704
|
import * as fs46 from "node:fs";
|
|
68638
|
-
import * as
|
|
68705
|
+
import * as path68 from "node:path";
|
|
68639
68706
|
|
|
68640
68707
|
// src/services/decision-drift-analyzer.ts
|
|
68641
68708
|
init_utils2();
|
|
68642
68709
|
init_manager();
|
|
68643
68710
|
init_utils();
|
|
68644
68711
|
import * as fs38 from "node:fs";
|
|
68645
|
-
import * as
|
|
68712
|
+
import * as path59 from "node:path";
|
|
68646
68713
|
var DEFAULT_DRIFT_CONFIG = {
|
|
68647
68714
|
staleThresholdPhases: 1,
|
|
68648
68715
|
detectContradictions: true,
|
|
@@ -68796,7 +68863,7 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
68796
68863
|
currentPhase = legacyPhase;
|
|
68797
68864
|
}
|
|
68798
68865
|
}
|
|
68799
|
-
const contextPath =
|
|
68866
|
+
const contextPath = path59.join(directory, ".swarm", "context.md");
|
|
68800
68867
|
let contextContent = "";
|
|
68801
68868
|
try {
|
|
68802
68869
|
if (fs38.existsSync(contextPath)) {
|
|
@@ -68935,7 +69002,7 @@ init_utils();
|
|
|
68935
69002
|
init_constants();
|
|
68936
69003
|
init_schema();
|
|
68937
69004
|
import * as fs39 from "node:fs/promises";
|
|
68938
|
-
import * as
|
|
69005
|
+
import * as path60 from "node:path";
|
|
68939
69006
|
function safeGet(obj, key) {
|
|
68940
69007
|
if (!obj || !Object.hasOwn(obj, key))
|
|
68941
69008
|
return;
|
|
@@ -69167,9 +69234,9 @@ async function handleDebuggingSpiral(match, taskId, directory) {
|
|
|
69167
69234
|
let eventLogged = false;
|
|
69168
69235
|
let checkpointCreated = false;
|
|
69169
69236
|
try {
|
|
69170
|
-
const swarmDir =
|
|
69237
|
+
const swarmDir = path60.join(directory, ".swarm");
|
|
69171
69238
|
await fs39.mkdir(swarmDir, { recursive: true });
|
|
69172
|
-
const eventsPath =
|
|
69239
|
+
const eventsPath = path60.join(swarmDir, "events.jsonl");
|
|
69173
69240
|
await fs39.appendFile(eventsPath, `${formatDebuggingSpiralEvent(match, taskId)}
|
|
69174
69241
|
`);
|
|
69175
69242
|
eventLogged = true;
|
|
@@ -69304,7 +69371,7 @@ import * as fs43 from "node:fs";
|
|
|
69304
69371
|
|
|
69305
69372
|
// src/graph/graph-builder.ts
|
|
69306
69373
|
import * as fs41 from "node:fs";
|
|
69307
|
-
import * as
|
|
69374
|
+
import * as path63 from "node:path";
|
|
69308
69375
|
|
|
69309
69376
|
// node_modules/yocto-queue/index.js
|
|
69310
69377
|
class Node {
|
|
@@ -69395,26 +69462,26 @@ function pLimit(concurrency) {
|
|
|
69395
69462
|
activeCount--;
|
|
69396
69463
|
resumeNext();
|
|
69397
69464
|
};
|
|
69398
|
-
const run2 = async (function_,
|
|
69465
|
+
const run2 = async (function_, resolve20, arguments_2) => {
|
|
69399
69466
|
const result = (async () => function_(...arguments_2))();
|
|
69400
|
-
|
|
69467
|
+
resolve20(result);
|
|
69401
69468
|
try {
|
|
69402
69469
|
await result;
|
|
69403
69470
|
} catch {}
|
|
69404
69471
|
next();
|
|
69405
69472
|
};
|
|
69406
|
-
const enqueue = (function_,
|
|
69473
|
+
const enqueue = (function_, resolve20, reject, arguments_2) => {
|
|
69407
69474
|
const queueItem = { reject };
|
|
69408
69475
|
new Promise((internalResolve) => {
|
|
69409
69476
|
queueItem.run = internalResolve;
|
|
69410
69477
|
queue.enqueue(queueItem);
|
|
69411
|
-
}).then(run2.bind(undefined, function_,
|
|
69478
|
+
}).then(run2.bind(undefined, function_, resolve20, arguments_2));
|
|
69412
69479
|
if (activeCount < concurrency) {
|
|
69413
69480
|
resumeNext();
|
|
69414
69481
|
}
|
|
69415
69482
|
};
|
|
69416
|
-
const generator = (function_, ...arguments_2) => new Promise((
|
|
69417
|
-
enqueue(function_,
|
|
69483
|
+
const generator = (function_, ...arguments_2) => new Promise((resolve20, reject) => {
|
|
69484
|
+
enqueue(function_, resolve20, reject, arguments_2);
|
|
69418
69485
|
});
|
|
69419
69486
|
Object.defineProperties(generator, {
|
|
69420
69487
|
activeCount: {
|
|
@@ -69465,7 +69532,7 @@ function validateConcurrency(concurrency) {
|
|
|
69465
69532
|
// src/graph/import-extractor.ts
|
|
69466
69533
|
init_path_security();
|
|
69467
69534
|
import * as fs40 from "node:fs";
|
|
69468
|
-
import * as
|
|
69535
|
+
import * as path61 from "node:path";
|
|
69469
69536
|
var SOURCE_EXTENSIONS2 = [
|
|
69470
69537
|
".ts",
|
|
69471
69538
|
".tsx",
|
|
@@ -69510,28 +69577,28 @@ function getLanguageFromExtension(ext) {
|
|
|
69510
69577
|
return null;
|
|
69511
69578
|
}
|
|
69512
69579
|
function toRelForwardSlash(absPath, root) {
|
|
69513
|
-
return
|
|
69580
|
+
return path61.relative(root, absPath).replace(/\\/g, "/");
|
|
69514
69581
|
}
|
|
69515
69582
|
function tryResolveTSJS(rawModule, sourceFileAbs) {
|
|
69516
69583
|
if (!rawModule.startsWith(".") && !rawModule.startsWith("/")) {
|
|
69517
69584
|
return null;
|
|
69518
69585
|
}
|
|
69519
|
-
const sourceDir =
|
|
69520
|
-
const baseAbs =
|
|
69586
|
+
const sourceDir = path61.dirname(sourceFileAbs);
|
|
69587
|
+
const baseAbs = path61.resolve(sourceDir, rawModule);
|
|
69521
69588
|
const probe = (basePath) => {
|
|
69522
69589
|
for (const ext of RESOLVE_EXTENSION_CANDIDATES) {
|
|
69523
69590
|
const test = basePath + ext;
|
|
69524
69591
|
try {
|
|
69525
|
-
const
|
|
69526
|
-
if (
|
|
69592
|
+
const stat6 = fs40.statSync(test);
|
|
69593
|
+
if (stat6.isFile())
|
|
69527
69594
|
return test;
|
|
69528
69595
|
} catch {}
|
|
69529
69596
|
}
|
|
69530
69597
|
for (const indexFile of RESOLVE_INDEX_CANDIDATES) {
|
|
69531
|
-
const test =
|
|
69598
|
+
const test = path61.join(basePath, indexFile);
|
|
69532
69599
|
try {
|
|
69533
|
-
const
|
|
69534
|
-
if (
|
|
69600
|
+
const stat6 = fs40.statSync(test);
|
|
69601
|
+
if (stat6.isFile())
|
|
69535
69602
|
return test;
|
|
69536
69603
|
} catch {}
|
|
69537
69604
|
}
|
|
@@ -69558,13 +69625,13 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
69558
69625
|
}
|
|
69559
69626
|
const remainder = rawModule.slice(leadingDots).replace(/\./g, "/");
|
|
69560
69627
|
const upDirs = "../".repeat(Math.max(0, leadingDots - 1));
|
|
69561
|
-
const sourceDir =
|
|
69562
|
-
const baseAbs =
|
|
69628
|
+
const sourceDir = path61.dirname(sourceFileAbs);
|
|
69629
|
+
const baseAbs = path61.resolve(sourceDir, upDirs + remainder);
|
|
69563
69630
|
const accept = (test) => {
|
|
69564
69631
|
try {
|
|
69565
|
-
const
|
|
69566
|
-
if (
|
|
69567
|
-
const rel =
|
|
69632
|
+
const stat6 = fs40.statSync(test);
|
|
69633
|
+
if (stat6.isFile()) {
|
|
69634
|
+
const rel = path61.relative(workspaceRoot, test).replace(/\\/g, "/");
|
|
69568
69635
|
if (rel.startsWith(".."))
|
|
69569
69636
|
return null;
|
|
69570
69637
|
return test;
|
|
@@ -69578,7 +69645,7 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
69578
69645
|
return hit;
|
|
69579
69646
|
}
|
|
69580
69647
|
for (const indexFile of PY_INDEX_CANDIDATES) {
|
|
69581
|
-
const hit = accept(
|
|
69648
|
+
const hit = accept(path61.join(baseAbs, indexFile));
|
|
69582
69649
|
if (hit)
|
|
69583
69650
|
return hit;
|
|
69584
69651
|
}
|
|
@@ -69949,7 +70016,7 @@ function parseRustUses(content) {
|
|
|
69949
70016
|
}
|
|
69950
70017
|
function extractImports2(opts) {
|
|
69951
70018
|
const { absoluteFilePath, workspaceRoot } = opts;
|
|
69952
|
-
const ext =
|
|
70019
|
+
const ext = path61.extname(absoluteFilePath).toLowerCase();
|
|
69953
70020
|
const language = getLanguageFromExtension(ext);
|
|
69954
70021
|
if (!language)
|
|
69955
70022
|
return [];
|
|
@@ -70000,9 +70067,9 @@ function extractImports2(opts) {
|
|
|
70000
70067
|
}
|
|
70001
70068
|
|
|
70002
70069
|
// src/graph/symbol-extractor.ts
|
|
70003
|
-
import * as
|
|
70070
|
+
import * as path62 from "node:path";
|
|
70004
70071
|
function extractExportedSymbols(relativeFilePath, workspaceRoot) {
|
|
70005
|
-
const ext =
|
|
70072
|
+
const ext = path62.extname(relativeFilePath).toLowerCase();
|
|
70006
70073
|
const language = getLanguageFromExtension(ext);
|
|
70007
70074
|
if (!language)
|
|
70008
70075
|
return [];
|
|
@@ -70091,15 +70158,15 @@ function findSourceFiles(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
|
70091
70158
|
if (entry.isDirectory()) {
|
|
70092
70159
|
if (skipDirs.has(entry.name))
|
|
70093
70160
|
continue;
|
|
70094
|
-
stack.push(
|
|
70161
|
+
stack.push(path63.join(dir, entry.name));
|
|
70095
70162
|
continue;
|
|
70096
70163
|
}
|
|
70097
70164
|
if (!entry.isFile())
|
|
70098
70165
|
continue;
|
|
70099
|
-
const ext =
|
|
70166
|
+
const ext = path63.extname(entry.name).toLowerCase();
|
|
70100
70167
|
if (!SOURCE_EXT_SET.has(ext))
|
|
70101
70168
|
continue;
|
|
70102
|
-
out2.push(
|
|
70169
|
+
out2.push(path63.join(dir, entry.name));
|
|
70103
70170
|
}
|
|
70104
70171
|
}
|
|
70105
70172
|
return out2;
|
|
@@ -70127,7 +70194,7 @@ async function buildRepoGraph(workspaceRoot, options = {}) {
|
|
|
70127
70194
|
};
|
|
70128
70195
|
}
|
|
70129
70196
|
async function processFile(absoluteFilePath, workspaceRoot) {
|
|
70130
|
-
const ext =
|
|
70197
|
+
const ext = path63.extname(absoluteFilePath).toLowerCase();
|
|
70131
70198
|
const language = getLanguageFromExtension(ext);
|
|
70132
70199
|
if (!language)
|
|
70133
70200
|
return null;
|
|
@@ -70147,7 +70214,7 @@ async function processFile(absoluteFilePath, workspaceRoot) {
|
|
|
70147
70214
|
} catch {
|
|
70148
70215
|
return null;
|
|
70149
70216
|
}
|
|
70150
|
-
const relPath =
|
|
70217
|
+
const relPath = path63.relative(workspaceRoot, absoluteFilePath).replace(/\\/g, "/");
|
|
70151
70218
|
const imports = extractImports2({
|
|
70152
70219
|
absoluteFilePath,
|
|
70153
70220
|
workspaceRoot,
|
|
@@ -70389,10 +70456,10 @@ function formatSummary(opts) {
|
|
|
70389
70456
|
// src/graph/graph-store.ts
|
|
70390
70457
|
import * as crypto6 from "node:crypto";
|
|
70391
70458
|
import * as fs42 from "node:fs";
|
|
70392
|
-
import * as
|
|
70459
|
+
import * as path64 from "node:path";
|
|
70393
70460
|
var SWARM_DIR = ".swarm";
|
|
70394
70461
|
function getGraphPath2(workspaceRoot) {
|
|
70395
|
-
return
|
|
70462
|
+
return path64.join(workspaceRoot, SWARM_DIR, REPO_GRAPH_FILENAME2);
|
|
70396
70463
|
}
|
|
70397
70464
|
function loadGraph2(workspaceRoot) {
|
|
70398
70465
|
const file3 = getGraphPath2(workspaceRoot);
|
|
@@ -70414,10 +70481,10 @@ function loadGraph2(workspaceRoot) {
|
|
|
70414
70481
|
}
|
|
70415
70482
|
function saveGraph2(workspaceRoot, graph) {
|
|
70416
70483
|
const file3 = getGraphPath2(workspaceRoot);
|
|
70417
|
-
const dir =
|
|
70484
|
+
const dir = path64.dirname(file3);
|
|
70418
70485
|
try {
|
|
70419
|
-
const
|
|
70420
|
-
if (
|
|
70486
|
+
const stat6 = fs42.lstatSync(dir);
|
|
70487
|
+
if (stat6.isSymbolicLink()) {
|
|
70421
70488
|
throw new Error(`refusing to write graph: ${SWARM_DIR}/ is a symbolic link`);
|
|
70422
70489
|
}
|
|
70423
70490
|
} catch (err2) {
|
|
@@ -70453,15 +70520,15 @@ function isGraphFresh(graph, maxAgeMs = 5 * 60 * 1000) {
|
|
|
70453
70520
|
var cache = new Map;
|
|
70454
70521
|
function getCachedGraph2(directory) {
|
|
70455
70522
|
const file3 = getGraphPath2(directory);
|
|
70456
|
-
let
|
|
70523
|
+
let stat6;
|
|
70457
70524
|
try {
|
|
70458
|
-
|
|
70525
|
+
stat6 = fs43.statSync(file3);
|
|
70459
70526
|
} catch {
|
|
70460
70527
|
cache.delete(directory);
|
|
70461
70528
|
return null;
|
|
70462
70529
|
}
|
|
70463
70530
|
const cached3 = cache.get(directory);
|
|
70464
|
-
if (cached3 && cached3.mtimeMs ===
|
|
70531
|
+
if (cached3 && cached3.mtimeMs === stat6.mtimeMs && cached3.size === stat6.size) {
|
|
70465
70532
|
return cached3.graph;
|
|
70466
70533
|
}
|
|
70467
70534
|
const graph = loadGraph2(directory);
|
|
@@ -70469,7 +70536,7 @@ function getCachedGraph2(directory) {
|
|
|
70469
70536
|
cache.delete(directory);
|
|
70470
70537
|
return null;
|
|
70471
70538
|
}
|
|
70472
|
-
cache.set(directory, { graph, mtimeMs:
|
|
70539
|
+
cache.set(directory, { graph, mtimeMs: stat6.mtimeMs, size: stat6.size });
|
|
70473
70540
|
return graph;
|
|
70474
70541
|
}
|
|
70475
70542
|
function buildCoderLocalizationBlock(directory, targetFile) {
|
|
@@ -70520,7 +70587,7 @@ function buildReviewerBlastRadiusBlock(directory, changedFiles) {
|
|
|
70520
70587
|
// src/hooks/semantic-diff-injection.ts
|
|
70521
70588
|
import * as child_process5 from "node:child_process";
|
|
70522
70589
|
import * as fs44 from "node:fs";
|
|
70523
|
-
import * as
|
|
70590
|
+
import * as path66 from "node:path";
|
|
70524
70591
|
|
|
70525
70592
|
// src/diff/ast-diff.ts
|
|
70526
70593
|
init_tree_sitter();
|
|
@@ -71267,17 +71334,17 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
71267
71334
|
const fileConsumers = {};
|
|
71268
71335
|
if (graph) {
|
|
71269
71336
|
for (const f of filesToProcess) {
|
|
71270
|
-
const relativePath =
|
|
71337
|
+
const relativePath = path66.isAbsolute(f) ? path66.relative(directory, f) : f;
|
|
71271
71338
|
const normalized = normalizeGraphPath2(relativePath);
|
|
71272
71339
|
fileConsumers[normalized] = getImporters(graph, normalized).length;
|
|
71273
71340
|
fileConsumers[f] = fileConsumers[normalized];
|
|
71274
71341
|
}
|
|
71275
71342
|
}
|
|
71276
71343
|
for (const filePath of filesToProcess) {
|
|
71277
|
-
const normalizedPath =
|
|
71278
|
-
const resolvedPath =
|
|
71279
|
-
const relativeToDir =
|
|
71280
|
-
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)) {
|
|
71281
71348
|
continue;
|
|
71282
71349
|
}
|
|
71283
71350
|
try {
|
|
@@ -71304,7 +71371,7 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
71304
71371
|
stdio: "pipe",
|
|
71305
71372
|
maxBuffer: 5 * 1024 * 1024
|
|
71306
71373
|
}) : "";
|
|
71307
|
-
const newContent = fs44.readFileSync(
|
|
71374
|
+
const newContent = fs44.readFileSync(path66.join(directory, filePath), "utf-8");
|
|
71308
71375
|
const astResult = await computeASTDiff(filePath, oldContent, newContent);
|
|
71309
71376
|
if (astResult && (astResult.changes.length > 0 || astResult.error !== undefined)) {
|
|
71310
71377
|
astDiffs.push(astResult);
|
|
@@ -71646,7 +71713,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
71646
71713
|
await fs46.promises.writeFile(darkMatterPath, darkMatterReport, "utf-8");
|
|
71647
71714
|
warn(`[system-enhancer] Dark matter scan complete: ${darkMatter.length} co-change patterns found`);
|
|
71648
71715
|
try {
|
|
71649
|
-
const projectName =
|
|
71716
|
+
const projectName = path68.basename(path68.resolve(directory));
|
|
71650
71717
|
const knowledgeEntries = darkMatterToKnowledgeEntries2(darkMatter, projectName);
|
|
71651
71718
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
71652
71719
|
const existingEntries = await readKnowledge(knowledgePath);
|
|
@@ -71845,7 +71912,7 @@ ${lines.join(`
|
|
|
71845
71912
|
try {
|
|
71846
71913
|
const taskId_ccp = ccpSession?.currentTaskId;
|
|
71847
71914
|
if (taskId_ccp && !taskId_ccp.includes("..") && !taskId_ccp.includes("/") && !taskId_ccp.includes("\\") && !taskId_ccp.includes("\x00")) {
|
|
71848
|
-
const evidencePath =
|
|
71915
|
+
const evidencePath = path68.join(directory, ".swarm", "evidence", `${taskId_ccp}.json`);
|
|
71849
71916
|
if (fs46.existsSync(evidencePath)) {
|
|
71850
71917
|
const evidenceContent = fs46.readFileSync(evidencePath, "utf-8");
|
|
71851
71918
|
const evidenceData = JSON.parse(evidenceContent);
|
|
@@ -72993,13 +73060,13 @@ init_hive_promoter();
|
|
|
72993
73060
|
|
|
72994
73061
|
// src/hooks/incremental-verify.ts
|
|
72995
73062
|
import * as fs47 from "node:fs";
|
|
72996
|
-
import * as
|
|
73063
|
+
import * as path69 from "node:path";
|
|
72997
73064
|
|
|
72998
73065
|
// src/hooks/spawn-helper.ts
|
|
72999
73066
|
import * as child_process6 from "node:child_process";
|
|
73000
73067
|
var WIN32_CMD_BINARIES = new Set(["npm", "npx", "pnpm", "yarn"]);
|
|
73001
73068
|
function spawnAsync(command, cwd, timeoutMs) {
|
|
73002
|
-
return new Promise((
|
|
73069
|
+
return new Promise((resolve24) => {
|
|
73003
73070
|
try {
|
|
73004
73071
|
const [rawCmd, ...args2] = command;
|
|
73005
73072
|
const cmd = process.platform === "win32" && WIN32_CMD_BINARIES.has(rawCmd) && !rawCmd.includes(".") ? `${rawCmd}.cmd` : rawCmd;
|
|
@@ -73046,24 +73113,24 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
73046
73113
|
try {
|
|
73047
73114
|
proc.kill();
|
|
73048
73115
|
} catch {}
|
|
73049
|
-
|
|
73116
|
+
resolve24(null);
|
|
73050
73117
|
}, timeoutMs);
|
|
73051
73118
|
proc.on("close", (code) => {
|
|
73052
73119
|
if (done)
|
|
73053
73120
|
return;
|
|
73054
73121
|
done = true;
|
|
73055
73122
|
clearTimeout(timer);
|
|
73056
|
-
|
|
73123
|
+
resolve24({ exitCode: code ?? 1, stdout, stderr });
|
|
73057
73124
|
});
|
|
73058
73125
|
proc.on("error", () => {
|
|
73059
73126
|
if (done)
|
|
73060
73127
|
return;
|
|
73061
73128
|
done = true;
|
|
73062
73129
|
clearTimeout(timer);
|
|
73063
|
-
|
|
73130
|
+
resolve24(null);
|
|
73064
73131
|
});
|
|
73065
73132
|
} catch {
|
|
73066
|
-
|
|
73133
|
+
resolve24(null);
|
|
73067
73134
|
}
|
|
73068
73135
|
});
|
|
73069
73136
|
}
|
|
@@ -73071,18 +73138,18 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
73071
73138
|
// src/hooks/incremental-verify.ts
|
|
73072
73139
|
var emittedSkipAdvisories = new Set;
|
|
73073
73140
|
function detectPackageManager(projectDir) {
|
|
73074
|
-
if (fs47.existsSync(
|
|
73141
|
+
if (fs47.existsSync(path69.join(projectDir, "bun.lockb")))
|
|
73075
73142
|
return "bun";
|
|
73076
|
-
if (fs47.existsSync(
|
|
73143
|
+
if (fs47.existsSync(path69.join(projectDir, "pnpm-lock.yaml")))
|
|
73077
73144
|
return "pnpm";
|
|
73078
|
-
if (fs47.existsSync(
|
|
73145
|
+
if (fs47.existsSync(path69.join(projectDir, "yarn.lock")))
|
|
73079
73146
|
return "yarn";
|
|
73080
|
-
if (fs47.existsSync(
|
|
73147
|
+
if (fs47.existsSync(path69.join(projectDir, "package-lock.json")))
|
|
73081
73148
|
return "npm";
|
|
73082
73149
|
return "bun";
|
|
73083
73150
|
}
|
|
73084
73151
|
function detectTypecheckCommand(projectDir) {
|
|
73085
|
-
const pkgPath =
|
|
73152
|
+
const pkgPath = path69.join(projectDir, "package.json");
|
|
73086
73153
|
if (fs47.existsSync(pkgPath)) {
|
|
73087
73154
|
try {
|
|
73088
73155
|
const pkg = JSON.parse(fs47.readFileSync(pkgPath, "utf8"));
|
|
@@ -73099,8 +73166,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
73099
73166
|
...pkg.dependencies,
|
|
73100
73167
|
...pkg.devDependencies
|
|
73101
73168
|
};
|
|
73102
|
-
if (!deps?.typescript && !fs47.existsSync(
|
|
73103
|
-
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"));
|
|
73104
73171
|
if (hasTSMarkers) {
|
|
73105
73172
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
73106
73173
|
}
|
|
@@ -73108,13 +73175,13 @@ function detectTypecheckCommand(projectDir) {
|
|
|
73108
73175
|
return null;
|
|
73109
73176
|
}
|
|
73110
73177
|
}
|
|
73111
|
-
if (fs47.existsSync(
|
|
73178
|
+
if (fs47.existsSync(path69.join(projectDir, "go.mod"))) {
|
|
73112
73179
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
73113
73180
|
}
|
|
73114
|
-
if (fs47.existsSync(
|
|
73181
|
+
if (fs47.existsSync(path69.join(projectDir, "Cargo.toml"))) {
|
|
73115
73182
|
return { command: ["cargo", "check"], language: "rust" };
|
|
73116
73183
|
}
|
|
73117
|
-
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"))) {
|
|
73118
73185
|
return { command: null, language: "python" };
|
|
73119
73186
|
}
|
|
73120
73187
|
try {
|
|
@@ -73464,7 +73531,7 @@ init_scope_persistence();
|
|
|
73464
73531
|
init_state();
|
|
73465
73532
|
init_delegation_gate();
|
|
73466
73533
|
init_normalize_tool_name();
|
|
73467
|
-
import * as
|
|
73534
|
+
import * as path71 from "node:path";
|
|
73468
73535
|
var WRITE_TOOLS = new Set(WRITE_TOOL_NAMES);
|
|
73469
73536
|
function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
73470
73537
|
const enabled = config3.enabled ?? true;
|
|
@@ -73522,13 +73589,13 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
|
73522
73589
|
}
|
|
73523
73590
|
function isFileInScope(filePath, scopeEntries, directory) {
|
|
73524
73591
|
const dir = directory ?? process.cwd();
|
|
73525
|
-
const resolvedFile =
|
|
73592
|
+
const resolvedFile = path71.resolve(dir, filePath);
|
|
73526
73593
|
return scopeEntries.some((scope) => {
|
|
73527
|
-
const resolvedScope =
|
|
73594
|
+
const resolvedScope = path71.resolve(dir, scope);
|
|
73528
73595
|
if (resolvedFile === resolvedScope)
|
|
73529
73596
|
return true;
|
|
73530
|
-
const rel =
|
|
73531
|
-
return rel.length > 0 && !rel.startsWith("..") && !
|
|
73597
|
+
const rel = path71.relative(resolvedScope, resolvedFile);
|
|
73598
|
+
return rel.length > 0 && !rel.startsWith("..") && !path71.isAbsolute(rel);
|
|
73532
73599
|
});
|
|
73533
73600
|
}
|
|
73534
73601
|
|
|
@@ -73580,7 +73647,7 @@ function createSelfReviewHook(config3, injectAdvisory) {
|
|
|
73580
73647
|
|
|
73581
73648
|
// src/hooks/slop-detector.ts
|
|
73582
73649
|
import * as fs49 from "node:fs";
|
|
73583
|
-
import * as
|
|
73650
|
+
import * as path72 from "node:path";
|
|
73584
73651
|
var WRITE_EDIT_TOOLS = new Set([
|
|
73585
73652
|
"write",
|
|
73586
73653
|
"edit",
|
|
@@ -73630,7 +73697,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
73630
73697
|
break;
|
|
73631
73698
|
if (entry.isSymbolicLink())
|
|
73632
73699
|
continue;
|
|
73633
|
-
const full =
|
|
73700
|
+
const full = path72.join(dir, entry.name);
|
|
73634
73701
|
if (entry.isDirectory()) {
|
|
73635
73702
|
if (entry.name === "node_modules" || entry.name === ".git")
|
|
73636
73703
|
continue;
|
|
@@ -73645,7 +73712,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
73645
73712
|
return results;
|
|
73646
73713
|
}
|
|
73647
73714
|
function checkDeadExports(content, projectDir, startTime) {
|
|
73648
|
-
const hasPackageJson = fs49.existsSync(
|
|
73715
|
+
const hasPackageJson = fs49.existsSync(path72.join(projectDir, "package.json"));
|
|
73649
73716
|
if (!hasPackageJson)
|
|
73650
73717
|
return null;
|
|
73651
73718
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -73759,14 +73826,14 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
|
|
|
73759
73826
|
for (const utilDir of utilityDirs) {
|
|
73760
73827
|
if (Date.now() > deadline)
|
|
73761
73828
|
break;
|
|
73762
|
-
const utilPath =
|
|
73829
|
+
const utilPath = path72.join(projectDir, utilDir);
|
|
73763
73830
|
if (!fs49.existsSync(utilPath))
|
|
73764
73831
|
continue;
|
|
73765
73832
|
const files = walkFiles(utilPath, [".ts", ".tsx", ".js", ".jsx"], deadline);
|
|
73766
73833
|
for (const file3 of files) {
|
|
73767
73834
|
if (Date.now() > deadline)
|
|
73768
73835
|
break;
|
|
73769
|
-
if (targetFile &&
|
|
73836
|
+
if (targetFile && path72.resolve(file3) === path72.resolve(targetFile))
|
|
73770
73837
|
continue;
|
|
73771
73838
|
try {
|
|
73772
73839
|
const text = fs49.readFileSync(file3, "utf-8");
|
|
@@ -73904,14 +73971,14 @@ function createSteeringConsumedHook(directory) {
|
|
|
73904
73971
|
// src/hooks/trajectory-logger.ts
|
|
73905
73972
|
init_manager2();
|
|
73906
73973
|
import * as fs52 from "node:fs/promises";
|
|
73907
|
-
import * as
|
|
73974
|
+
import * as path74 from "node:path";
|
|
73908
73975
|
|
|
73909
73976
|
// src/prm/trajectory-store.ts
|
|
73910
73977
|
init_utils2();
|
|
73911
73978
|
import * as fs51 from "node:fs/promises";
|
|
73912
|
-
import * as
|
|
73979
|
+
import * as path73 from "node:path";
|
|
73913
73980
|
function getTrajectoryPath(sessionId, directory) {
|
|
73914
|
-
const relativePath =
|
|
73981
|
+
const relativePath = path73.join("trajectories", `${sessionId}.jsonl`);
|
|
73915
73982
|
return validateSwarmPath(directory, relativePath);
|
|
73916
73983
|
}
|
|
73917
73984
|
var _inMemoryTrajectoryCache = new Map;
|
|
@@ -73930,7 +73997,7 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
73930
73997
|
_inMemoryTrajectoryCache.set(sessionId, cached3);
|
|
73931
73998
|
}
|
|
73932
73999
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
73933
|
-
await fs51.mkdir(
|
|
74000
|
+
await fs51.mkdir(path73.dirname(trajectoryPath), { recursive: true });
|
|
73934
74001
|
const line = `${JSON.stringify(entry)}
|
|
73935
74002
|
`;
|
|
73936
74003
|
await fs51.appendFile(trajectoryPath, line, "utf-8");
|
|
@@ -73969,10 +74036,10 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
|
|
|
73969
74036
|
for (const entry of entries) {
|
|
73970
74037
|
if (!entry.isFile())
|
|
73971
74038
|
continue;
|
|
73972
|
-
const filePath =
|
|
74039
|
+
const filePath = path73.join(dirPath, entry.name);
|
|
73973
74040
|
try {
|
|
73974
|
-
const
|
|
73975
|
-
if (now -
|
|
74041
|
+
const stat7 = await fs51.stat(filePath);
|
|
74042
|
+
if (now - stat7.mtimeMs > cutoffMs) {
|
|
73976
74043
|
await fs51.unlink(filePath);
|
|
73977
74044
|
}
|
|
73978
74045
|
} catch {}
|
|
@@ -74161,10 +74228,10 @@ function createTrajectoryLoggerHook(config3, _directory) {
|
|
|
74161
74228
|
elapsed_ms
|
|
74162
74229
|
};
|
|
74163
74230
|
const sanitized = sanitizeTaskId2(taskId);
|
|
74164
|
-
const relativePath =
|
|
74231
|
+
const relativePath = path74.join("evidence", sanitized, "trajectory.jsonl");
|
|
74165
74232
|
const trajectoryPath = validateSwarmPath(_directory, relativePath);
|
|
74166
74233
|
try {
|
|
74167
|
-
await fs52.mkdir(
|
|
74234
|
+
await fs52.mkdir(path74.dirname(trajectoryPath), { recursive: true });
|
|
74168
74235
|
const line = `${JSON.stringify(entry)}
|
|
74169
74236
|
`;
|
|
74170
74237
|
await fs52.appendFile(trajectoryPath, line, "utf-8");
|
|
@@ -74715,16 +74782,16 @@ init_telemetry();
|
|
|
74715
74782
|
|
|
74716
74783
|
// src/prm/replay.ts
|
|
74717
74784
|
import { promises as fs53 } from "node:fs";
|
|
74718
|
-
import
|
|
74785
|
+
import path75 from "node:path";
|
|
74719
74786
|
function isPathSafe2(targetPath, basePath) {
|
|
74720
|
-
const resolvedTarget =
|
|
74721
|
-
const resolvedBase =
|
|
74722
|
-
const rel =
|
|
74723
|
-
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);
|
|
74724
74791
|
}
|
|
74725
74792
|
function isWithinReplaysDir(targetPath) {
|
|
74726
|
-
const resolved =
|
|
74727
|
-
const parts2 = resolved.split(
|
|
74793
|
+
const resolved = path75.resolve(targetPath);
|
|
74794
|
+
const parts2 = resolved.split(path75.sep);
|
|
74728
74795
|
for (let i2 = 0;i2 < parts2.length - 1; i2++) {
|
|
74729
74796
|
if (parts2[i2] === ".swarm" && parts2[i2 + 1] === "replays") {
|
|
74730
74797
|
return true;
|
|
@@ -74737,10 +74804,10 @@ function sanitizeFilename(input) {
|
|
|
74737
74804
|
}
|
|
74738
74805
|
async function startReplayRecording(sessionID, directory) {
|
|
74739
74806
|
try {
|
|
74740
|
-
const replayDir =
|
|
74807
|
+
const replayDir = path75.join(directory, ".swarm", "replays");
|
|
74741
74808
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
74742
74809
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
74743
|
-
const filepath =
|
|
74810
|
+
const filepath = path75.join(replayDir, filename);
|
|
74744
74811
|
if (!isPathSafe2(filepath, replayDir)) {
|
|
74745
74812
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
74746
74813
|
return null;
|
|
@@ -75114,7 +75181,7 @@ init_telemetry();
|
|
|
75114
75181
|
init_dist();
|
|
75115
75182
|
init_create_tool();
|
|
75116
75183
|
import * as fs54 from "node:fs";
|
|
75117
|
-
import * as
|
|
75184
|
+
import * as path76 from "node:path";
|
|
75118
75185
|
init_path_security();
|
|
75119
75186
|
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
75120
75187
|
function containsWindowsAttacks2(str) {
|
|
@@ -75131,14 +75198,14 @@ function containsWindowsAttacks2(str) {
|
|
|
75131
75198
|
}
|
|
75132
75199
|
function isPathInWorkspace2(filePath, workspace) {
|
|
75133
75200
|
try {
|
|
75134
|
-
const resolvedPath =
|
|
75201
|
+
const resolvedPath = path76.resolve(workspace, filePath);
|
|
75135
75202
|
if (!fs54.existsSync(resolvedPath)) {
|
|
75136
75203
|
return true;
|
|
75137
75204
|
}
|
|
75138
75205
|
const realWorkspace = fs54.realpathSync(workspace);
|
|
75139
75206
|
const realResolvedPath = fs54.realpathSync(resolvedPath);
|
|
75140
|
-
const relativePath =
|
|
75141
|
-
if (relativePath.startsWith("..") ||
|
|
75207
|
+
const relativePath = path76.relative(realWorkspace, realResolvedPath);
|
|
75208
|
+
if (relativePath.startsWith("..") || path76.isAbsolute(relativePath)) {
|
|
75142
75209
|
return false;
|
|
75143
75210
|
}
|
|
75144
75211
|
return true;
|
|
@@ -75147,7 +75214,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
75147
75214
|
}
|
|
75148
75215
|
}
|
|
75149
75216
|
function processFile2(file3, cwd, exportedOnly) {
|
|
75150
|
-
const ext =
|
|
75217
|
+
const ext = path76.extname(file3);
|
|
75151
75218
|
if (containsControlChars(file3)) {
|
|
75152
75219
|
return {
|
|
75153
75220
|
file: file3,
|
|
@@ -75180,7 +75247,7 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
75180
75247
|
errorType: "path-outside-workspace"
|
|
75181
75248
|
};
|
|
75182
75249
|
}
|
|
75183
|
-
const fullPath =
|
|
75250
|
+
const fullPath = path76.join(cwd, file3);
|
|
75184
75251
|
if (!fs54.existsSync(fullPath)) {
|
|
75185
75252
|
return {
|
|
75186
75253
|
file: file3,
|
|
@@ -75472,15 +75539,15 @@ init_task_id();
|
|
|
75472
75539
|
init_create_tool();
|
|
75473
75540
|
init_resolve_working_directory();
|
|
75474
75541
|
import * as fs55 from "node:fs";
|
|
75475
|
-
import * as
|
|
75542
|
+
import * as path77 from "node:path";
|
|
75476
75543
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
75477
75544
|
function isValidTaskId3(taskId) {
|
|
75478
75545
|
return isStrictTaskId(taskId);
|
|
75479
75546
|
}
|
|
75480
75547
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
75481
|
-
const normalizedWorkspace =
|
|
75482
|
-
const swarmPath =
|
|
75483
|
-
const normalizedPath =
|
|
75548
|
+
const normalizedWorkspace = path77.resolve(workspaceRoot);
|
|
75549
|
+
const swarmPath = path77.join(normalizedWorkspace, ".swarm", "evidence");
|
|
75550
|
+
const normalizedPath = path77.resolve(filePath);
|
|
75484
75551
|
return normalizedPath.startsWith(swarmPath);
|
|
75485
75552
|
}
|
|
75486
75553
|
function readEvidenceFile(evidencePath) {
|
|
@@ -75561,7 +75628,7 @@ var check_gate_status = createSwarmTool({
|
|
|
75561
75628
|
};
|
|
75562
75629
|
return JSON.stringify(errorResult, null, 2);
|
|
75563
75630
|
}
|
|
75564
|
-
const evidencePath =
|
|
75631
|
+
const evidencePath = path77.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
75565
75632
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
75566
75633
|
const errorResult = {
|
|
75567
75634
|
taskId: taskIdInput,
|
|
@@ -75658,7 +75725,7 @@ init_state();
|
|
|
75658
75725
|
init_create_tool();
|
|
75659
75726
|
init_resolve_working_directory();
|
|
75660
75727
|
import * as fs56 from "node:fs";
|
|
75661
|
-
import * as
|
|
75728
|
+
import * as path78 from "node:path";
|
|
75662
75729
|
function extractMatches(regex, text) {
|
|
75663
75730
|
return Array.from(text.matchAll(regex));
|
|
75664
75731
|
}
|
|
@@ -75810,10 +75877,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
75810
75877
|
let hasFileReadFailure = false;
|
|
75811
75878
|
for (const filePath of fileTargets) {
|
|
75812
75879
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
75813
|
-
const resolvedPath =
|
|
75814
|
-
const projectRoot =
|
|
75815
|
-
const relative16 =
|
|
75816
|
-
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);
|
|
75817
75884
|
if (!withinProject) {
|
|
75818
75885
|
blockedTasks.push({
|
|
75819
75886
|
task_id: task.id,
|
|
@@ -75868,8 +75935,8 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
75868
75935
|
blockedTasks
|
|
75869
75936
|
};
|
|
75870
75937
|
try {
|
|
75871
|
-
const evidenceDir =
|
|
75872
|
-
const evidencePath =
|
|
75938
|
+
const evidenceDir = path78.join(directory, ".swarm", "evidence", `${phase}`);
|
|
75939
|
+
const evidencePath = path78.join(evidenceDir, "completion-verify.json");
|
|
75873
75940
|
fs56.mkdirSync(evidenceDir, { recursive: true });
|
|
75874
75941
|
const evidenceBundle = {
|
|
75875
75942
|
schema_version: "1.0.0",
|
|
@@ -75946,11 +76013,11 @@ var completion_verify = createSwarmTool({
|
|
|
75946
76013
|
// src/tools/complexity-hotspots.ts
|
|
75947
76014
|
init_zod();
|
|
75948
76015
|
import * as fs58 from "node:fs";
|
|
75949
|
-
import * as
|
|
76016
|
+
import * as path80 from "node:path";
|
|
75950
76017
|
|
|
75951
76018
|
// src/quality/metrics.ts
|
|
75952
76019
|
import * as fs57 from "node:fs";
|
|
75953
|
-
import * as
|
|
76020
|
+
import * as path79 from "node:path";
|
|
75954
76021
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
75955
76022
|
var MIN_DUPLICATION_LINES = 10;
|
|
75956
76023
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -75988,8 +76055,8 @@ function estimateCyclomaticComplexity(content) {
|
|
|
75988
76055
|
}
|
|
75989
76056
|
function getComplexityForFile(filePath) {
|
|
75990
76057
|
try {
|
|
75991
|
-
const
|
|
75992
|
-
if (
|
|
76058
|
+
const stat7 = fs57.statSync(filePath);
|
|
76059
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES4) {
|
|
75993
76060
|
return null;
|
|
75994
76061
|
}
|
|
75995
76062
|
const content = fs57.readFileSync(filePath, "utf-8");
|
|
@@ -76002,7 +76069,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
76002
76069
|
let totalComplexity = 0;
|
|
76003
76070
|
const analyzedFiles = [];
|
|
76004
76071
|
for (const file3 of files) {
|
|
76005
|
-
const fullPath =
|
|
76072
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76006
76073
|
if (!fs57.existsSync(fullPath)) {
|
|
76007
76074
|
continue;
|
|
76008
76075
|
}
|
|
@@ -76125,7 +76192,7 @@ function countGoExports(content) {
|
|
|
76125
76192
|
function getExportCountForFile(filePath) {
|
|
76126
76193
|
try {
|
|
76127
76194
|
const content = fs57.readFileSync(filePath, "utf-8");
|
|
76128
|
-
const ext =
|
|
76195
|
+
const ext = path79.extname(filePath).toLowerCase();
|
|
76129
76196
|
switch (ext) {
|
|
76130
76197
|
case ".ts":
|
|
76131
76198
|
case ".tsx":
|
|
@@ -76151,7 +76218,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
76151
76218
|
let totalExports = 0;
|
|
76152
76219
|
const analyzedFiles = [];
|
|
76153
76220
|
for (const file3 of files) {
|
|
76154
|
-
const fullPath =
|
|
76221
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76155
76222
|
if (!fs57.existsSync(fullPath)) {
|
|
76156
76223
|
continue;
|
|
76157
76224
|
}
|
|
@@ -76185,13 +76252,13 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
76185
76252
|
let duplicateLines = 0;
|
|
76186
76253
|
const analyzedFiles = [];
|
|
76187
76254
|
for (const file3 of files) {
|
|
76188
|
-
const fullPath =
|
|
76255
|
+
const fullPath = path79.isAbsolute(file3) ? file3 : path79.join(workingDir, file3);
|
|
76189
76256
|
if (!fs57.existsSync(fullPath)) {
|
|
76190
76257
|
continue;
|
|
76191
76258
|
}
|
|
76192
76259
|
try {
|
|
76193
|
-
const
|
|
76194
|
-
if (
|
|
76260
|
+
const stat7 = fs57.statSync(fullPath);
|
|
76261
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES4) {
|
|
76195
76262
|
continue;
|
|
76196
76263
|
}
|
|
76197
76264
|
const content = fs57.readFileSync(fullPath, "utf-8");
|
|
@@ -76218,8 +76285,8 @@ function countCodeLines(content) {
|
|
|
76218
76285
|
return lines.length;
|
|
76219
76286
|
}
|
|
76220
76287
|
function isTestFile(filePath) {
|
|
76221
|
-
const basename11 =
|
|
76222
|
-
const _ext =
|
|
76288
|
+
const basename11 = path79.basename(filePath);
|
|
76289
|
+
const _ext = path79.extname(filePath).toLowerCase();
|
|
76223
76290
|
const testPatterns = [
|
|
76224
76291
|
".test.",
|
|
76225
76292
|
".spec.",
|
|
@@ -76300,8 +76367,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
76300
76367
|
}
|
|
76301
76368
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
76302
76369
|
}
|
|
76303
|
-
function matchesGlobSegment(
|
|
76304
|
-
const normalizedPath =
|
|
76370
|
+
function matchesGlobSegment(path80, glob) {
|
|
76371
|
+
const normalizedPath = path80.replace(/\\/g, "/");
|
|
76305
76372
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
76306
76373
|
if (normalizedPath.includes("//")) {
|
|
76307
76374
|
return false;
|
|
@@ -76332,8 +76399,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
76332
76399
|
function hasGlobstar(glob) {
|
|
76333
76400
|
return glob.includes("**");
|
|
76334
76401
|
}
|
|
76335
|
-
function globMatches(
|
|
76336
|
-
const normalizedPath =
|
|
76402
|
+
function globMatches(path80, glob) {
|
|
76403
|
+
const normalizedPath = path80.replace(/\\/g, "/");
|
|
76337
76404
|
if (!glob || glob === "") {
|
|
76338
76405
|
if (normalizedPath.includes("//")) {
|
|
76339
76406
|
return false;
|
|
@@ -76369,7 +76436,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
76369
76436
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
76370
76437
|
let testLines = 0;
|
|
76371
76438
|
let codeLines = 0;
|
|
76372
|
-
const srcDir =
|
|
76439
|
+
const srcDir = path79.join(workingDir, "src");
|
|
76373
76440
|
if (fs57.existsSync(srcDir)) {
|
|
76374
76441
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
76375
76442
|
codeLines += lines;
|
|
@@ -76377,14 +76444,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
76377
76444
|
}
|
|
76378
76445
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
76379
76446
|
for (const dir of possibleSrcDirs) {
|
|
76380
|
-
const dirPath =
|
|
76447
|
+
const dirPath = path79.join(workingDir, dir);
|
|
76381
76448
|
if (fs57.existsSync(dirPath)) {
|
|
76382
76449
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
76383
76450
|
codeLines += lines;
|
|
76384
76451
|
});
|
|
76385
76452
|
}
|
|
76386
76453
|
}
|
|
76387
|
-
const testsDir =
|
|
76454
|
+
const testsDir = path79.join(workingDir, "tests");
|
|
76388
76455
|
if (fs57.existsSync(testsDir)) {
|
|
76389
76456
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
76390
76457
|
testLines += lines;
|
|
@@ -76392,7 +76459,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
76392
76459
|
}
|
|
76393
76460
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
76394
76461
|
for (const dir of possibleTestDirs) {
|
|
76395
|
-
const dirPath =
|
|
76462
|
+
const dirPath = path79.join(workingDir, dir);
|
|
76396
76463
|
if (fs57.existsSync(dirPath) && dirPath !== testsDir) {
|
|
76397
76464
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
76398
76465
|
testLines += lines;
|
|
@@ -76407,7 +76474,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
76407
76474
|
try {
|
|
76408
76475
|
const entries = fs57.readdirSync(dirPath, { withFileTypes: true });
|
|
76409
76476
|
for (const entry of entries) {
|
|
76410
|
-
const fullPath =
|
|
76477
|
+
const fullPath = path79.join(dirPath, entry.name);
|
|
76411
76478
|
if (entry.isDirectory()) {
|
|
76412
76479
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
76413
76480
|
continue;
|
|
@@ -76415,7 +76482,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
76415
76482
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
76416
76483
|
} else if (entry.isFile()) {
|
|
76417
76484
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
76418
|
-
const ext =
|
|
76485
|
+
const ext = path79.extname(entry.name).toLowerCase();
|
|
76419
76486
|
const validExts = [
|
|
76420
76487
|
".ts",
|
|
76421
76488
|
".tsx",
|
|
@@ -76651,8 +76718,8 @@ async function getGitChurn(days, directory) {
|
|
|
76651
76718
|
}
|
|
76652
76719
|
function getComplexityForFile2(filePath) {
|
|
76653
76720
|
try {
|
|
76654
|
-
const
|
|
76655
|
-
if (
|
|
76721
|
+
const stat7 = fs58.statSync(filePath);
|
|
76722
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES5) {
|
|
76656
76723
|
return null;
|
|
76657
76724
|
}
|
|
76658
76725
|
const content = fs58.readFileSync(filePath, "utf-8");
|
|
@@ -76666,7 +76733,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
76666
76733
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
76667
76734
|
const filteredChurn = new Map;
|
|
76668
76735
|
for (const [file3, count] of churnMap) {
|
|
76669
|
-
const ext =
|
|
76736
|
+
const ext = path80.extname(file3).toLowerCase();
|
|
76670
76737
|
if (extSet.has(ext)) {
|
|
76671
76738
|
filteredChurn.set(file3, count);
|
|
76672
76739
|
}
|
|
@@ -76677,7 +76744,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
76677
76744
|
for (const [file3, churnCount] of filteredChurn) {
|
|
76678
76745
|
let fullPath = file3;
|
|
76679
76746
|
if (!fs58.existsSync(fullPath)) {
|
|
76680
|
-
fullPath =
|
|
76747
|
+
fullPath = path80.join(cwd, file3);
|
|
76681
76748
|
}
|
|
76682
76749
|
const complexity = getComplexityForFile2(fullPath);
|
|
76683
76750
|
if (complexity !== null) {
|
|
@@ -76846,7 +76913,7 @@ ${body2}`);
|
|
|
76846
76913
|
// src/council/council-evidence-writer.ts
|
|
76847
76914
|
import {
|
|
76848
76915
|
appendFileSync as appendFileSync6,
|
|
76849
|
-
existsSync as
|
|
76916
|
+
existsSync as existsSync40,
|
|
76850
76917
|
mkdirSync as mkdirSync19,
|
|
76851
76918
|
readFileSync as readFileSync36,
|
|
76852
76919
|
writeFileSync as writeFileSync12
|
|
@@ -76889,7 +76956,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76889
76956
|
mkdirSync19(dir, { recursive: true });
|
|
76890
76957
|
const filePath = join69(dir, `${synthesis.taskId}.json`);
|
|
76891
76958
|
const existingRoot = Object.create(null);
|
|
76892
|
-
if (
|
|
76959
|
+
if (existsSync40(filePath)) {
|
|
76893
76960
|
try {
|
|
76894
76961
|
const parsed = JSON.parse(readFileSync36(filePath, "utf-8"));
|
|
76895
76962
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -76938,7 +77005,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76938
77005
|
|
|
76939
77006
|
// src/council/council-service.ts
|
|
76940
77007
|
import fs59 from "node:fs";
|
|
76941
|
-
import
|
|
77008
|
+
import path81 from "node:path";
|
|
76942
77009
|
|
|
76943
77010
|
// src/council/types.ts
|
|
76944
77011
|
var COUNCIL_DEFAULTS = {
|
|
@@ -77098,9 +77165,9 @@ function synthesizePhaseCouncilAdvisory(phaseNumber, phaseSummary, verdicts, rou
|
|
|
77098
77165
|
const unifiedFeedbackMd = buildPhaseCouncilFeedback(phaseNumber, phaseSummary, overallVerdict, rejectingMembers, requiredFixes, advisoryFindings, unresolvedConflicts, roundNumber, cfg.maxRounds);
|
|
77099
77166
|
const evidencePath = `.swarm/evidence/${phaseNumber}/phase-council.json`;
|
|
77100
77167
|
const baseDir = workingDir ?? process.cwd();
|
|
77101
|
-
const evidenceDir =
|
|
77168
|
+
const evidenceDir = path81.join(baseDir, ".swarm", "evidence", String(phaseNumber));
|
|
77102
77169
|
fs59.mkdirSync(evidenceDir, { recursive: true });
|
|
77103
|
-
const evidenceFile =
|
|
77170
|
+
const evidenceFile = path81.join(evidenceDir, "phase-council.json");
|
|
77104
77171
|
const evidenceBundle = {
|
|
77105
77172
|
entries: [
|
|
77106
77173
|
{
|
|
@@ -77203,7 +77270,7 @@ function buildPhaseCouncilFeedback(phaseNumber, phaseSummary, verdict, vetoedBy,
|
|
|
77203
77270
|
}
|
|
77204
77271
|
|
|
77205
77272
|
// src/council/criteria-store.ts
|
|
77206
|
-
import { existsSync as
|
|
77273
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync20, readFileSync as readFileSync37, writeFileSync as writeFileSync13 } from "node:fs";
|
|
77207
77274
|
import { join as join70 } from "node:path";
|
|
77208
77275
|
var COUNCIL_DIR = ".swarm/council";
|
|
77209
77276
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
@@ -77218,7 +77285,7 @@ function writeCriteria(workingDir, taskId, criteria) {
|
|
|
77218
77285
|
}
|
|
77219
77286
|
function readCriteria(workingDir, taskId) {
|
|
77220
77287
|
const filePath = join70(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
|
|
77221
|
-
if (!
|
|
77288
|
+
if (!existsSync41(filePath))
|
|
77222
77289
|
return null;
|
|
77223
77290
|
try {
|
|
77224
77291
|
const parsed = JSON.parse(readFileSync37(filePath, "utf-8"));
|
|
@@ -77370,7 +77437,7 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
77370
77437
|
init_zod();
|
|
77371
77438
|
init_loader();
|
|
77372
77439
|
import * as fs60 from "node:fs";
|
|
77373
|
-
import * as
|
|
77440
|
+
import * as path82 from "node:path";
|
|
77374
77441
|
|
|
77375
77442
|
// src/council/general-council-advisory.ts
|
|
77376
77443
|
var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
|
|
@@ -77798,10 +77865,10 @@ var convene_general_council = createSwarmTool({
|
|
|
77798
77865
|
const round1 = input.round1Responses;
|
|
77799
77866
|
const round2 = input.round2Responses ?? [];
|
|
77800
77867
|
const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
|
|
77801
|
-
const evidenceDir =
|
|
77868
|
+
const evidenceDir = path82.join(workingDir, ".swarm", "council", "general");
|
|
77802
77869
|
const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
|
|
77803
77870
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
77804
|
-
const evidencePath =
|
|
77871
|
+
const evidencePath = path82.join(evidenceDir, evidenceFile);
|
|
77805
77872
|
try {
|
|
77806
77873
|
await fs60.promises.mkdir(evidenceDir, { recursive: true });
|
|
77807
77874
|
await fs60.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
@@ -78036,7 +78103,7 @@ init_state();
|
|
|
78036
78103
|
init_task_id();
|
|
78037
78104
|
init_create_tool();
|
|
78038
78105
|
import * as fs61 from "node:fs";
|
|
78039
|
-
import * as
|
|
78106
|
+
import * as path83 from "node:path";
|
|
78040
78107
|
function validateTaskIdFormat2(taskId) {
|
|
78041
78108
|
return validateTaskIdFormat(taskId);
|
|
78042
78109
|
}
|
|
@@ -78110,8 +78177,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78110
78177
|
};
|
|
78111
78178
|
}
|
|
78112
78179
|
}
|
|
78113
|
-
normalizedDir =
|
|
78114
|
-
const pathParts = normalizedDir.split(
|
|
78180
|
+
normalizedDir = path83.normalize(args2.working_directory);
|
|
78181
|
+
const pathParts = normalizedDir.split(path83.sep);
|
|
78115
78182
|
if (pathParts.includes("..")) {
|
|
78116
78183
|
return {
|
|
78117
78184
|
success: false,
|
|
@@ -78121,10 +78188,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78121
78188
|
]
|
|
78122
78189
|
};
|
|
78123
78190
|
}
|
|
78124
|
-
const resolvedDir =
|
|
78191
|
+
const resolvedDir = path83.resolve(normalizedDir);
|
|
78125
78192
|
try {
|
|
78126
78193
|
const realPath = fs61.realpathSync(resolvedDir);
|
|
78127
|
-
const planPath2 =
|
|
78194
|
+
const planPath2 = path83.join(realPath, ".swarm", "plan.json");
|
|
78128
78195
|
if (!fs61.existsSync(planPath2)) {
|
|
78129
78196
|
return {
|
|
78130
78197
|
success: false,
|
|
@@ -78148,7 +78215,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78148
78215
|
console.warn("[declare-scope] fallbackDir is undefined, falling back to process.cwd()");
|
|
78149
78216
|
}
|
|
78150
78217
|
const directory = normalizedDir || fallbackDir;
|
|
78151
|
-
const planPath =
|
|
78218
|
+
const planPath = path83.resolve(directory, ".swarm", "plan.json");
|
|
78152
78219
|
if (!fs61.existsSync(planPath)) {
|
|
78153
78220
|
return {
|
|
78154
78221
|
success: false,
|
|
@@ -78188,8 +78255,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
78188
78255
|
const normalizeErrors = [];
|
|
78189
78256
|
const dir = normalizedDir || fallbackDir || process.cwd();
|
|
78190
78257
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
78191
|
-
if (
|
|
78192
|
-
const relativePath =
|
|
78258
|
+
if (path83.isAbsolute(file3)) {
|
|
78259
|
+
const relativePath = path83.relative(dir, file3).replace(/\\/g, "/");
|
|
78193
78260
|
if (relativePath.startsWith("..")) {
|
|
78194
78261
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
78195
78262
|
return file3;
|
|
@@ -78250,7 +78317,7 @@ var declare_scope = createSwarmTool({
|
|
|
78250
78317
|
init_zod();
|
|
78251
78318
|
import * as child_process7 from "node:child_process";
|
|
78252
78319
|
import * as fs62 from "node:fs";
|
|
78253
|
-
import * as
|
|
78320
|
+
import * as path84 from "node:path";
|
|
78254
78321
|
init_create_tool();
|
|
78255
78322
|
var MAX_DIFF_LINES = 500;
|
|
78256
78323
|
var DIFF_TIMEOUT_MS = 30000;
|
|
@@ -78279,20 +78346,20 @@ function validateBase(base) {
|
|
|
78279
78346
|
function validatePaths(paths) {
|
|
78280
78347
|
if (!paths)
|
|
78281
78348
|
return null;
|
|
78282
|
-
for (const
|
|
78283
|
-
if (!
|
|
78349
|
+
for (const path85 of paths) {
|
|
78350
|
+
if (!path85 || path85.length === 0) {
|
|
78284
78351
|
return "empty path not allowed";
|
|
78285
78352
|
}
|
|
78286
|
-
if (
|
|
78353
|
+
if (path85.length > MAX_PATH_LENGTH) {
|
|
78287
78354
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
78288
78355
|
}
|
|
78289
|
-
if (SHELL_METACHARACTERS2.test(
|
|
78356
|
+
if (SHELL_METACHARACTERS2.test(path85)) {
|
|
78290
78357
|
return "path contains shell metacharacters";
|
|
78291
78358
|
}
|
|
78292
|
-
if (
|
|
78359
|
+
if (path85.startsWith("-")) {
|
|
78293
78360
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
78294
78361
|
}
|
|
78295
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
78362
|
+
if (CONTROL_CHAR_PATTERN2.test(path85)) {
|
|
78296
78363
|
return "path contains control characters";
|
|
78297
78364
|
}
|
|
78298
78365
|
}
|
|
@@ -78398,8 +78465,8 @@ var diff = createSwarmTool({
|
|
|
78398
78465
|
if (parts2.length >= 3) {
|
|
78399
78466
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
78400
78467
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
78401
|
-
const
|
|
78402
|
-
files.push({ path:
|
|
78468
|
+
const path85 = parts2[2];
|
|
78469
|
+
files.push({ path: path85, additions, deletions });
|
|
78403
78470
|
}
|
|
78404
78471
|
}
|
|
78405
78472
|
const contractChanges = [];
|
|
@@ -78439,7 +78506,7 @@ var diff = createSwarmTool({
|
|
|
78439
78506
|
} else if (base === "unstaged") {
|
|
78440
78507
|
const oldRef = `:${file3.path}`;
|
|
78441
78508
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
78442
|
-
newContent = fs62.readFileSync(
|
|
78509
|
+
newContent = fs62.readFileSync(path84.join(directory, file3.path), "utf-8");
|
|
78443
78510
|
} else {
|
|
78444
78511
|
const oldRef = `${base}:${file3.path}`;
|
|
78445
78512
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -78514,7 +78581,7 @@ var diff = createSwarmTool({
|
|
|
78514
78581
|
init_zod();
|
|
78515
78582
|
import * as child_process8 from "node:child_process";
|
|
78516
78583
|
import * as fs63 from "node:fs";
|
|
78517
|
-
import * as
|
|
78584
|
+
import * as path85 from "node:path";
|
|
78518
78585
|
init_create_tool();
|
|
78519
78586
|
var diff_summary = createSwarmTool({
|
|
78520
78587
|
description: "Generate a filtered semantic diff summary from AST analysis. Returns SemanticDiffSummary with optional filtering by classification or riskLevel.",
|
|
@@ -78562,7 +78629,7 @@ var diff_summary = createSwarmTool({
|
|
|
78562
78629
|
}
|
|
78563
78630
|
try {
|
|
78564
78631
|
let oldContent;
|
|
78565
|
-
const newContent = fs63.readFileSync(
|
|
78632
|
+
const newContent = fs63.readFileSync(path85.join(workingDir, filePath), "utf-8");
|
|
78566
78633
|
if (fileExistsInHead) {
|
|
78567
78634
|
oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
|
|
78568
78635
|
encoding: "utf-8",
|
|
@@ -78791,7 +78858,7 @@ init_zod();
|
|
|
78791
78858
|
init_create_tool();
|
|
78792
78859
|
init_path_security();
|
|
78793
78860
|
import * as fs64 from "node:fs";
|
|
78794
|
-
import * as
|
|
78861
|
+
import * as path86 from "node:path";
|
|
78795
78862
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
78796
78863
|
var MAX_EVIDENCE_FILES = 1000;
|
|
78797
78864
|
var EVIDENCE_DIR3 = ".swarm/evidence";
|
|
@@ -78818,9 +78885,9 @@ function validateRequiredTypes(input) {
|
|
|
78818
78885
|
return null;
|
|
78819
78886
|
}
|
|
78820
78887
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
78821
|
-
const normalizedCwd =
|
|
78822
|
-
const swarmPath =
|
|
78823
|
-
const normalizedPath =
|
|
78888
|
+
const normalizedCwd = path86.resolve(cwd);
|
|
78889
|
+
const swarmPath = path86.join(normalizedCwd, ".swarm");
|
|
78890
|
+
const normalizedPath = path86.resolve(filePath);
|
|
78824
78891
|
return normalizedPath.startsWith(swarmPath);
|
|
78825
78892
|
}
|
|
78826
78893
|
function parseCompletedTasks(planContent) {
|
|
@@ -78850,15 +78917,15 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
78850
78917
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
78851
78918
|
continue;
|
|
78852
78919
|
}
|
|
78853
|
-
const filePath =
|
|
78920
|
+
const filePath = path86.join(evidenceDir, filename);
|
|
78854
78921
|
try {
|
|
78855
|
-
const resolvedPath =
|
|
78856
|
-
const evidenceDirResolved =
|
|
78922
|
+
const resolvedPath = path86.resolve(filePath);
|
|
78923
|
+
const evidenceDirResolved = path86.resolve(evidenceDir);
|
|
78857
78924
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
78858
78925
|
continue;
|
|
78859
78926
|
}
|
|
78860
|
-
const
|
|
78861
|
-
if (!
|
|
78927
|
+
const stat7 = fs64.lstatSync(filePath);
|
|
78928
|
+
if (!stat7.isFile()) {
|
|
78862
78929
|
continue;
|
|
78863
78930
|
}
|
|
78864
78931
|
} catch {
|
|
@@ -78971,7 +79038,7 @@ var evidence_check = createSwarmTool({
|
|
|
78971
79038
|
return JSON.stringify(errorResult, null, 2);
|
|
78972
79039
|
}
|
|
78973
79040
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
78974
|
-
const planPath =
|
|
79041
|
+
const planPath = path86.join(cwd, PLAN_FILE);
|
|
78975
79042
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
78976
79043
|
const errorResult = {
|
|
78977
79044
|
error: "plan file path validation failed",
|
|
@@ -79003,7 +79070,7 @@ var evidence_check = createSwarmTool({
|
|
|
79003
79070
|
};
|
|
79004
79071
|
return JSON.stringify(result2, null, 2);
|
|
79005
79072
|
}
|
|
79006
|
-
const evidenceDir =
|
|
79073
|
+
const evidenceDir = path86.join(cwd, EVIDENCE_DIR3);
|
|
79007
79074
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
79008
79075
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
79009
79076
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -79021,7 +79088,7 @@ var evidence_check = createSwarmTool({
|
|
|
79021
79088
|
init_zod();
|
|
79022
79089
|
init_create_tool();
|
|
79023
79090
|
import * as fs65 from "node:fs";
|
|
79024
|
-
import * as
|
|
79091
|
+
import * as path87 from "node:path";
|
|
79025
79092
|
var EXT_MAP = {
|
|
79026
79093
|
python: ".py",
|
|
79027
79094
|
py: ".py",
|
|
@@ -79102,12 +79169,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
79102
79169
|
if (prefix) {
|
|
79103
79170
|
filename = `${prefix}_${filename}`;
|
|
79104
79171
|
}
|
|
79105
|
-
let filepath =
|
|
79106
|
-
const base =
|
|
79107
|
-
const ext =
|
|
79172
|
+
let filepath = path87.join(targetDir, filename);
|
|
79173
|
+
const base = path87.basename(filepath, path87.extname(filepath));
|
|
79174
|
+
const ext = path87.extname(filepath);
|
|
79108
79175
|
let counter = 1;
|
|
79109
79176
|
while (fs65.existsSync(filepath)) {
|
|
79110
|
-
filepath =
|
|
79177
|
+
filepath = path87.join(targetDir, `${base}_${counter}${ext}`);
|
|
79111
79178
|
counter++;
|
|
79112
79179
|
}
|
|
79113
79180
|
try {
|
|
@@ -79283,7 +79350,7 @@ init_create_tool();
|
|
|
79283
79350
|
var GITINGEST_TIMEOUT_MS = 1e4;
|
|
79284
79351
|
var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
|
|
79285
79352
|
var GITINGEST_MAX_RETRIES = 2;
|
|
79286
|
-
var delay = (ms) => new Promise((
|
|
79353
|
+
var delay = (ms) => new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
79287
79354
|
async function fetchGitingest(args2) {
|
|
79288
79355
|
for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
|
|
79289
79356
|
try {
|
|
@@ -79371,7 +79438,7 @@ init_zod();
|
|
|
79371
79438
|
init_create_tool();
|
|
79372
79439
|
init_path_security();
|
|
79373
79440
|
import * as fs66 from "node:fs";
|
|
79374
|
-
import * as
|
|
79441
|
+
import * as path88 from "node:path";
|
|
79375
79442
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
79376
79443
|
var MAX_SYMBOL_LENGTH = 256;
|
|
79377
79444
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -79419,7 +79486,7 @@ function validateSymbolInput(symbol3) {
|
|
|
79419
79486
|
return null;
|
|
79420
79487
|
}
|
|
79421
79488
|
function isBinaryFile2(filePath, buffer) {
|
|
79422
|
-
const ext =
|
|
79489
|
+
const ext = path88.extname(filePath).toLowerCase();
|
|
79423
79490
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
79424
79491
|
return false;
|
|
79425
79492
|
}
|
|
@@ -79443,15 +79510,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
79443
79510
|
const imports = [];
|
|
79444
79511
|
let _resolvedTarget;
|
|
79445
79512
|
try {
|
|
79446
|
-
_resolvedTarget =
|
|
79513
|
+
_resolvedTarget = path88.resolve(targetFile);
|
|
79447
79514
|
} catch {
|
|
79448
79515
|
_resolvedTarget = targetFile;
|
|
79449
79516
|
}
|
|
79450
|
-
const targetBasename =
|
|
79517
|
+
const targetBasename = path88.basename(targetFile, path88.extname(targetFile));
|
|
79451
79518
|
const targetWithExt = targetFile;
|
|
79452
79519
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
79453
|
-
const normalizedTargetWithExt =
|
|
79454
|
-
const normalizedTargetWithoutExt =
|
|
79520
|
+
const normalizedTargetWithExt = path88.normalize(targetWithExt).replace(/\\/g, "/");
|
|
79521
|
+
const normalizedTargetWithoutExt = path88.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
79455
79522
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
79456
79523
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
79457
79524
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -79474,9 +79541,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
79474
79541
|
}
|
|
79475
79542
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
79476
79543
|
let isMatch = false;
|
|
79477
|
-
const _targetDir =
|
|
79478
|
-
const targetExt =
|
|
79479
|
-
const targetBasenameNoExt =
|
|
79544
|
+
const _targetDir = path88.dirname(targetFile);
|
|
79545
|
+
const targetExt = path88.extname(targetFile);
|
|
79546
|
+
const targetBasenameNoExt = path88.basename(targetFile, targetExt);
|
|
79480
79547
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
79481
79548
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
79482
79549
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -79544,13 +79611,13 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
79544
79611
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
79545
79612
|
for (const entry of entries) {
|
|
79546
79613
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
79547
|
-
stats.skippedDirs.push(
|
|
79614
|
+
stats.skippedDirs.push(path88.join(dir, entry));
|
|
79548
79615
|
continue;
|
|
79549
79616
|
}
|
|
79550
|
-
const fullPath =
|
|
79551
|
-
let
|
|
79617
|
+
const fullPath = path88.join(dir, entry);
|
|
79618
|
+
let stat7;
|
|
79552
79619
|
try {
|
|
79553
|
-
|
|
79620
|
+
stat7 = fs66.statSync(fullPath);
|
|
79554
79621
|
} catch (e) {
|
|
79555
79622
|
stats.fileErrors.push({
|
|
79556
79623
|
path: fullPath,
|
|
@@ -79558,10 +79625,10 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
79558
79625
|
});
|
|
79559
79626
|
continue;
|
|
79560
79627
|
}
|
|
79561
|
-
if (
|
|
79628
|
+
if (stat7.isDirectory()) {
|
|
79562
79629
|
findSourceFiles2(fullPath, files, stats);
|
|
79563
|
-
} else if (
|
|
79564
|
-
const ext =
|
|
79630
|
+
} else if (stat7.isFile()) {
|
|
79631
|
+
const ext = path88.extname(fullPath).toLowerCase();
|
|
79565
79632
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
79566
79633
|
files.push(fullPath);
|
|
79567
79634
|
}
|
|
@@ -79618,7 +79685,7 @@ var imports = createSwarmTool({
|
|
|
79618
79685
|
return JSON.stringify(errorResult, null, 2);
|
|
79619
79686
|
}
|
|
79620
79687
|
try {
|
|
79621
|
-
const targetFile =
|
|
79688
|
+
const targetFile = path88.resolve(file3);
|
|
79622
79689
|
if (!fs66.existsSync(targetFile)) {
|
|
79623
79690
|
const errorResult = {
|
|
79624
79691
|
error: `target file not found: ${file3}`,
|
|
@@ -79640,7 +79707,7 @@ var imports = createSwarmTool({
|
|
|
79640
79707
|
};
|
|
79641
79708
|
return JSON.stringify(errorResult, null, 2);
|
|
79642
79709
|
}
|
|
79643
|
-
const baseDir =
|
|
79710
|
+
const baseDir = path88.dirname(targetFile);
|
|
79644
79711
|
const scanStats = {
|
|
79645
79712
|
skippedDirs: [],
|
|
79646
79713
|
skippedFiles: 0,
|
|
@@ -79655,8 +79722,8 @@ var imports = createSwarmTool({
|
|
|
79655
79722
|
if (consumers.length >= MAX_CONSUMERS)
|
|
79656
79723
|
break;
|
|
79657
79724
|
try {
|
|
79658
|
-
const
|
|
79659
|
-
if (
|
|
79725
|
+
const stat7 = fs66.statSync(filePath);
|
|
79726
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES7) {
|
|
79660
79727
|
skippedFileCount++;
|
|
79661
79728
|
continue;
|
|
79662
79729
|
}
|
|
@@ -79873,7 +79940,7 @@ init_zod();
|
|
|
79873
79940
|
init_config();
|
|
79874
79941
|
init_knowledge_store();
|
|
79875
79942
|
init_create_tool();
|
|
79876
|
-
import { existsSync as
|
|
79943
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
79877
79944
|
var DEFAULT_LIMIT = 10;
|
|
79878
79945
|
var MAX_LESSON_LENGTH = 200;
|
|
79879
79946
|
var VALID_CATEGORIES3 = [
|
|
@@ -79943,14 +80010,14 @@ function validateLimit(limit) {
|
|
|
79943
80010
|
}
|
|
79944
80011
|
async function readSwarmKnowledge(directory) {
|
|
79945
80012
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
79946
|
-
if (!
|
|
80013
|
+
if (!existsSync46(swarmPath)) {
|
|
79947
80014
|
return [];
|
|
79948
80015
|
}
|
|
79949
80016
|
return readKnowledge(swarmPath);
|
|
79950
80017
|
}
|
|
79951
80018
|
async function readHiveKnowledge() {
|
|
79952
80019
|
const hivePath = resolveHiveKnowledgePath();
|
|
79953
|
-
if (!
|
|
80020
|
+
if (!existsSync46(hivePath)) {
|
|
79954
80021
|
return [];
|
|
79955
80022
|
}
|
|
79956
80023
|
return readKnowledge(hivePath);
|
|
@@ -80186,7 +80253,7 @@ init_qa_gate_profile();
|
|
|
80186
80253
|
init_manager2();
|
|
80187
80254
|
init_curator();
|
|
80188
80255
|
import * as fs68 from "node:fs";
|
|
80189
|
-
import * as
|
|
80256
|
+
import * as path90 from "node:path";
|
|
80190
80257
|
init_knowledge_curator();
|
|
80191
80258
|
init_knowledge_reader();
|
|
80192
80259
|
init_knowledge_store();
|
|
@@ -80199,16 +80266,16 @@ init_plan_schema();
|
|
|
80199
80266
|
init_ledger();
|
|
80200
80267
|
init_manager();
|
|
80201
80268
|
import * as fs67 from "node:fs";
|
|
80202
|
-
import * as
|
|
80269
|
+
import * as path89 from "node:path";
|
|
80203
80270
|
async function writeCheckpoint(directory) {
|
|
80204
80271
|
try {
|
|
80205
80272
|
const plan = await loadPlan(directory);
|
|
80206
80273
|
if (!plan)
|
|
80207
80274
|
return;
|
|
80208
|
-
const swarmDir =
|
|
80275
|
+
const swarmDir = path89.join(directory, ".swarm");
|
|
80209
80276
|
fs67.mkdirSync(swarmDir, { recursive: true });
|
|
80210
|
-
const jsonPath =
|
|
80211
|
-
const mdPath =
|
|
80277
|
+
const jsonPath = path89.join(swarmDir, "SWARM_PLAN.json");
|
|
80278
|
+
const mdPath = path89.join(swarmDir, "SWARM_PLAN.md");
|
|
80212
80279
|
fs67.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
80213
80280
|
const md = derivePlanMarkdown(plan);
|
|
80214
80281
|
fs67.writeFileSync(mdPath, md, "utf8");
|
|
@@ -80443,7 +80510,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80443
80510
|
let driftCheckEnabled = true;
|
|
80444
80511
|
let driftHasSpecMd = false;
|
|
80445
80512
|
try {
|
|
80446
|
-
const specMdPath =
|
|
80513
|
+
const specMdPath = path90.join(dir, ".swarm", "spec.md");
|
|
80447
80514
|
driftHasSpecMd = fs68.existsSync(specMdPath);
|
|
80448
80515
|
const gatePlan = await loadPlan(dir);
|
|
80449
80516
|
if (gatePlan) {
|
|
@@ -80465,7 +80532,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80465
80532
|
} else {
|
|
80466
80533
|
let phaseType;
|
|
80467
80534
|
try {
|
|
80468
|
-
const planPath =
|
|
80535
|
+
const planPath = path90.join(dir, ".swarm", "plan.json");
|
|
80469
80536
|
if (fs68.existsSync(planPath)) {
|
|
80470
80537
|
const planRaw = fs68.readFileSync(planPath, "utf-8");
|
|
80471
80538
|
const plan = JSON.parse(planRaw);
|
|
@@ -80478,7 +80545,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80478
80545
|
warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
|
|
80479
80546
|
} else {
|
|
80480
80547
|
try {
|
|
80481
|
-
const driftEvidencePath =
|
|
80548
|
+
const driftEvidencePath = path90.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
80482
80549
|
let driftVerdictFound = false;
|
|
80483
80550
|
let driftVerdictApproved = false;
|
|
80484
80551
|
try {
|
|
@@ -80516,7 +80583,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80516
80583
|
let incompleteTaskCount = 0;
|
|
80517
80584
|
let planParseable = false;
|
|
80518
80585
|
try {
|
|
80519
|
-
const planPath =
|
|
80586
|
+
const planPath = path90.join(dir, ".swarm", "plan.json");
|
|
80520
80587
|
if (fs68.existsSync(planPath)) {
|
|
80521
80588
|
const planRaw = fs68.readFileSync(planPath, "utf-8");
|
|
80522
80589
|
const plan = JSON.parse(planRaw);
|
|
@@ -80583,7 +80650,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80583
80650
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
80584
80651
|
const effective = getEffectiveGates(profile, overrides);
|
|
80585
80652
|
if (effective.hallucination_guard === true) {
|
|
80586
|
-
const hgPath =
|
|
80653
|
+
const hgPath = path90.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
80587
80654
|
let hgVerdictFound = false;
|
|
80588
80655
|
let hgVerdictApproved = false;
|
|
80589
80656
|
try {
|
|
@@ -80655,7 +80722,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80655
80722
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
80656
80723
|
const effective = getEffectiveGates(profile, overrides);
|
|
80657
80724
|
if (effective.mutation_test === true) {
|
|
80658
|
-
const mgPath =
|
|
80725
|
+
const mgPath = path90.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
80659
80726
|
let mgVerdictFound = false;
|
|
80660
80727
|
let mgVerdict;
|
|
80661
80728
|
try {
|
|
@@ -80729,7 +80796,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
80729
80796
|
const effective = getEffectiveGates(profile, overrides);
|
|
80730
80797
|
if (effective.council_mode === true) {
|
|
80731
80798
|
councilModeEnabled = true;
|
|
80732
|
-
const pcPath =
|
|
80799
|
+
const pcPath = path90.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
80733
80800
|
let pcVerdictFound = false;
|
|
80734
80801
|
let _pcVerdict;
|
|
80735
80802
|
let pcQuorumSize;
|
|
@@ -80931,7 +80998,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80931
80998
|
}
|
|
80932
80999
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
80933
81000
|
try {
|
|
80934
|
-
const projectName =
|
|
81001
|
+
const projectName = path90.basename(dir);
|
|
80935
81002
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
80936
81003
|
if (curationResult) {
|
|
80937
81004
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -81301,7 +81368,7 @@ init_utils();
|
|
|
81301
81368
|
init_bun_compat();
|
|
81302
81369
|
init_create_tool();
|
|
81303
81370
|
import * as fs69 from "node:fs";
|
|
81304
|
-
import * as
|
|
81371
|
+
import * as path91 from "node:path";
|
|
81305
81372
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
81306
81373
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
81307
81374
|
function isValidEcosystem(value) {
|
|
@@ -81329,16 +81396,16 @@ function validateArgs3(args2) {
|
|
|
81329
81396
|
function detectEcosystems(directory) {
|
|
81330
81397
|
const ecosystems = [];
|
|
81331
81398
|
const cwd = directory;
|
|
81332
|
-
if (fs69.existsSync(
|
|
81399
|
+
if (fs69.existsSync(path91.join(cwd, "package.json"))) {
|
|
81333
81400
|
ecosystems.push("npm");
|
|
81334
81401
|
}
|
|
81335
|
-
if (fs69.existsSync(
|
|
81402
|
+
if (fs69.existsSync(path91.join(cwd, "pyproject.toml")) || fs69.existsSync(path91.join(cwd, "requirements.txt"))) {
|
|
81336
81403
|
ecosystems.push("pip");
|
|
81337
81404
|
}
|
|
81338
|
-
if (fs69.existsSync(
|
|
81405
|
+
if (fs69.existsSync(path91.join(cwd, "Cargo.toml"))) {
|
|
81339
81406
|
ecosystems.push("cargo");
|
|
81340
81407
|
}
|
|
81341
|
-
if (fs69.existsSync(
|
|
81408
|
+
if (fs69.existsSync(path91.join(cwd, "go.mod"))) {
|
|
81342
81409
|
ecosystems.push("go");
|
|
81343
81410
|
}
|
|
81344
81411
|
try {
|
|
@@ -81347,13 +81414,13 @@ function detectEcosystems(directory) {
|
|
|
81347
81414
|
ecosystems.push("dotnet");
|
|
81348
81415
|
}
|
|
81349
81416
|
} catch {}
|
|
81350
|
-
if (fs69.existsSync(
|
|
81417
|
+
if (fs69.existsSync(path91.join(cwd, "Gemfile")) || fs69.existsSync(path91.join(cwd, "Gemfile.lock"))) {
|
|
81351
81418
|
ecosystems.push("ruby");
|
|
81352
81419
|
}
|
|
81353
|
-
if (fs69.existsSync(
|
|
81420
|
+
if (fs69.existsSync(path91.join(cwd, "pubspec.yaml"))) {
|
|
81354
81421
|
ecosystems.push("dart");
|
|
81355
81422
|
}
|
|
81356
|
-
if (fs69.existsSync(
|
|
81423
|
+
if (fs69.existsSync(path91.join(cwd, "composer.lock"))) {
|
|
81357
81424
|
ecosystems.push("composer");
|
|
81358
81425
|
}
|
|
81359
81426
|
return ecosystems;
|
|
@@ -81366,7 +81433,7 @@ async function runNpmAudit(directory) {
|
|
|
81366
81433
|
stderr: "pipe",
|
|
81367
81434
|
cwd: directory
|
|
81368
81435
|
});
|
|
81369
|
-
const timeoutPromise = new Promise((
|
|
81436
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81370
81437
|
const result = await Promise.race([
|
|
81371
81438
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
81372
81439
|
timeoutPromise
|
|
@@ -81486,7 +81553,7 @@ async function runPipAudit(directory) {
|
|
|
81486
81553
|
stderr: "pipe",
|
|
81487
81554
|
cwd: directory
|
|
81488
81555
|
});
|
|
81489
|
-
const timeoutPromise = new Promise((
|
|
81556
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81490
81557
|
const result = await Promise.race([
|
|
81491
81558
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
81492
81559
|
timeoutPromise
|
|
@@ -81614,7 +81681,7 @@ async function runCargoAudit(directory) {
|
|
|
81614
81681
|
stderr: "pipe",
|
|
81615
81682
|
cwd: directory
|
|
81616
81683
|
});
|
|
81617
|
-
const timeoutPromise = new Promise((
|
|
81684
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81618
81685
|
const result = await Promise.race([
|
|
81619
81686
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81620
81687
|
timeoutPromise
|
|
@@ -81738,7 +81805,7 @@ async function runGoAudit(directory) {
|
|
|
81738
81805
|
stderr: "pipe",
|
|
81739
81806
|
cwd: directory
|
|
81740
81807
|
});
|
|
81741
|
-
const timeoutPromise = new Promise((
|
|
81808
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81742
81809
|
const result = await Promise.race([
|
|
81743
81810
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81744
81811
|
timeoutPromise
|
|
@@ -81871,7 +81938,7 @@ async function runDotnetAudit(directory) {
|
|
|
81871
81938
|
stderr: "pipe",
|
|
81872
81939
|
cwd: directory
|
|
81873
81940
|
});
|
|
81874
|
-
const timeoutPromise = new Promise((
|
|
81941
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81875
81942
|
const result = await Promise.race([
|
|
81876
81943
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81877
81944
|
timeoutPromise
|
|
@@ -81987,7 +82054,7 @@ async function runBundleAudit(directory) {
|
|
|
81987
82054
|
stderr: "pipe",
|
|
81988
82055
|
cwd: directory
|
|
81989
82056
|
});
|
|
81990
|
-
const timeoutPromise = new Promise((
|
|
82057
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
81991
82058
|
const result = await Promise.race([
|
|
81992
82059
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
81993
82060
|
timeoutPromise
|
|
@@ -82132,7 +82199,7 @@ async function runDartAudit(directory) {
|
|
|
82132
82199
|
stderr: "pipe",
|
|
82133
82200
|
cwd: directory
|
|
82134
82201
|
});
|
|
82135
|
-
const timeoutPromise = new Promise((
|
|
82202
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
82136
82203
|
const result = await Promise.race([
|
|
82137
82204
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
82138
82205
|
timeoutPromise
|
|
@@ -82247,7 +82314,7 @@ async function runComposerAudit(directory) {
|
|
|
82247
82314
|
stderr: "pipe",
|
|
82248
82315
|
cwd: directory
|
|
82249
82316
|
});
|
|
82250
|
-
const timeoutPromise = new Promise((
|
|
82317
|
+
const timeoutPromise = new Promise((resolve32) => setTimeout(() => resolve32("timeout"), AUDIT_TIMEOUT_MS));
|
|
82251
82318
|
const result = await Promise.race([
|
|
82252
82319
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
82253
82320
|
timeoutPromise
|
|
@@ -82489,7 +82556,7 @@ var pkg_audit = createSwarmTool({
|
|
|
82489
82556
|
init_zod();
|
|
82490
82557
|
init_manager2();
|
|
82491
82558
|
import * as fs70 from "node:fs";
|
|
82492
|
-
import * as
|
|
82559
|
+
import * as path92 from "node:path";
|
|
82493
82560
|
init_utils();
|
|
82494
82561
|
init_create_tool();
|
|
82495
82562
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -82612,7 +82679,7 @@ function isScaffoldFile(filePath) {
|
|
|
82612
82679
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
82613
82680
|
return true;
|
|
82614
82681
|
}
|
|
82615
|
-
const filename =
|
|
82682
|
+
const filename = path92.basename(filePath);
|
|
82616
82683
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
82617
82684
|
return true;
|
|
82618
82685
|
}
|
|
@@ -82629,7 +82696,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
82629
82696
|
if (regex.test(normalizedPath)) {
|
|
82630
82697
|
return true;
|
|
82631
82698
|
}
|
|
82632
|
-
const filename =
|
|
82699
|
+
const filename = path92.basename(filePath);
|
|
82633
82700
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
82634
82701
|
if (filenameRegex.test(filename)) {
|
|
82635
82702
|
return true;
|
|
@@ -82638,7 +82705,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
82638
82705
|
return false;
|
|
82639
82706
|
}
|
|
82640
82707
|
function isParserSupported(filePath) {
|
|
82641
|
-
const ext =
|
|
82708
|
+
const ext = path92.extname(filePath).toLowerCase();
|
|
82642
82709
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
82643
82710
|
}
|
|
82644
82711
|
function isPlanFile(filePath) {
|
|
@@ -82885,9 +82952,9 @@ async function placeholderScan(input, directory) {
|
|
|
82885
82952
|
let filesScanned = 0;
|
|
82886
82953
|
const filesWithFindings = new Set;
|
|
82887
82954
|
for (const filePath of changed_files) {
|
|
82888
|
-
const fullPath =
|
|
82889
|
-
const resolvedDirectory =
|
|
82890
|
-
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) {
|
|
82891
82958
|
continue;
|
|
82892
82959
|
}
|
|
82893
82960
|
if (!fs70.existsSync(fullPath)) {
|
|
@@ -82896,14 +82963,14 @@ async function placeholderScan(input, directory) {
|
|
|
82896
82963
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
82897
82964
|
continue;
|
|
82898
82965
|
}
|
|
82899
|
-
const relativeFilePath =
|
|
82966
|
+
const relativeFilePath = path92.relative(directory, fullPath).replace(/\\/g, "/");
|
|
82900
82967
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
82901
82968
|
continue;
|
|
82902
82969
|
}
|
|
82903
82970
|
let content;
|
|
82904
82971
|
try {
|
|
82905
|
-
const
|
|
82906
|
-
if (
|
|
82972
|
+
const stat7 = fs70.statSync(fullPath);
|
|
82973
|
+
if (stat7.size > MAX_FILE_SIZE) {
|
|
82907
82974
|
continue;
|
|
82908
82975
|
}
|
|
82909
82976
|
content = fs70.readFileSync(fullPath, "utf-8");
|
|
@@ -82968,7 +83035,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
82968
83035
|
});
|
|
82969
83036
|
// src/tools/pre-check-batch.ts
|
|
82970
83037
|
import * as fs73 from "node:fs";
|
|
82971
|
-
import * as
|
|
83038
|
+
import * as path95 from "node:path";
|
|
82972
83039
|
init_zod();
|
|
82973
83040
|
init_manager2();
|
|
82974
83041
|
init_utils();
|
|
@@ -83106,7 +83173,7 @@ init_zod();
|
|
|
83106
83173
|
init_manager2();
|
|
83107
83174
|
init_detector();
|
|
83108
83175
|
import * as fs72 from "node:fs";
|
|
83109
|
-
import * as
|
|
83176
|
+
import * as path94 from "node:path";
|
|
83110
83177
|
import { extname as extname18 } from "node:path";
|
|
83111
83178
|
|
|
83112
83179
|
// src/sast/rules/c.ts
|
|
@@ -83887,7 +83954,7 @@ function mapSemgrepSeverity(severity) {
|
|
|
83887
83954
|
}
|
|
83888
83955
|
}
|
|
83889
83956
|
async function executeWithTimeout(command, args2, options) {
|
|
83890
|
-
return new Promise((
|
|
83957
|
+
return new Promise((resolve33) => {
|
|
83891
83958
|
const child = child_process9.spawn(command, args2, {
|
|
83892
83959
|
shell: false,
|
|
83893
83960
|
cwd: options.cwd
|
|
@@ -83896,7 +83963,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83896
83963
|
let stderr = "";
|
|
83897
83964
|
const timeout = setTimeout(() => {
|
|
83898
83965
|
child.kill("SIGTERM");
|
|
83899
|
-
|
|
83966
|
+
resolve33({
|
|
83900
83967
|
stdout,
|
|
83901
83968
|
stderr: "Process timed out",
|
|
83902
83969
|
exitCode: 124
|
|
@@ -83910,7 +83977,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83910
83977
|
});
|
|
83911
83978
|
child.on("close", (code) => {
|
|
83912
83979
|
clearTimeout(timeout);
|
|
83913
|
-
|
|
83980
|
+
resolve33({
|
|
83914
83981
|
stdout,
|
|
83915
83982
|
stderr,
|
|
83916
83983
|
exitCode: code ?? 0
|
|
@@ -83918,7 +83985,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
83918
83985
|
});
|
|
83919
83986
|
child.on("error", (err2) => {
|
|
83920
83987
|
clearTimeout(timeout);
|
|
83921
|
-
|
|
83988
|
+
resolve33({
|
|
83922
83989
|
stdout,
|
|
83923
83990
|
stderr: err2.message,
|
|
83924
83991
|
exitCode: 1
|
|
@@ -84000,24 +84067,24 @@ init_create_tool();
|
|
|
84000
84067
|
init_utils2();
|
|
84001
84068
|
import * as crypto8 from "node:crypto";
|
|
84002
84069
|
import * as fs71 from "node:fs";
|
|
84003
|
-
import * as
|
|
84070
|
+
import * as path93 from "node:path";
|
|
84004
84071
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
84005
84072
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
84006
84073
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
84007
84074
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
84008
84075
|
function normalizeFindingPath(directory, file3) {
|
|
84009
|
-
const resolved =
|
|
84010
|
-
const rel =
|
|
84076
|
+
const resolved = path93.isAbsolute(file3) ? file3 : path93.resolve(directory, file3);
|
|
84077
|
+
const rel = path93.relative(path93.resolve(directory), resolved);
|
|
84011
84078
|
return rel.replace(/\\/g, "/");
|
|
84012
84079
|
}
|
|
84013
84080
|
function baselineRelPath(phase) {
|
|
84014
|
-
return
|
|
84081
|
+
return path93.join("evidence", String(phase), "sast-baseline.json");
|
|
84015
84082
|
}
|
|
84016
84083
|
function tempRelPath(phase) {
|
|
84017
|
-
return
|
|
84084
|
+
return path93.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
84018
84085
|
}
|
|
84019
84086
|
function lockRelPath(phase) {
|
|
84020
|
-
return
|
|
84087
|
+
return path93.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
84021
84088
|
}
|
|
84022
84089
|
function getLine(lines, idx) {
|
|
84023
84090
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -84103,7 +84170,7 @@ async function acquireLock(lockPath) {
|
|
|
84103
84170
|
};
|
|
84104
84171
|
} catch {
|
|
84105
84172
|
if (attempt < LOCK_RETRY_DELAYS_MS.length) {
|
|
84106
|
-
await new Promise((
|
|
84173
|
+
await new Promise((resolve34) => setTimeout(resolve34, LOCK_RETRY_DELAYS_MS[attempt]));
|
|
84107
84174
|
}
|
|
84108
84175
|
}
|
|
84109
84176
|
}
|
|
@@ -84138,8 +84205,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
84138
84205
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
84139
84206
|
};
|
|
84140
84207
|
}
|
|
84141
|
-
fs71.mkdirSync(
|
|
84142
|
-
fs71.mkdirSync(
|
|
84208
|
+
fs71.mkdirSync(path93.dirname(baselinePath), { recursive: true });
|
|
84209
|
+
fs71.mkdirSync(path93.dirname(tempPath), { recursive: true });
|
|
84143
84210
|
const releaseLock = await acquireLock(lockPath);
|
|
84144
84211
|
try {
|
|
84145
84212
|
let existing = null;
|
|
@@ -84406,9 +84473,9 @@ async function sastScan(input, directory, config3) {
|
|
|
84406
84473
|
_filesSkipped++;
|
|
84407
84474
|
continue;
|
|
84408
84475
|
}
|
|
84409
|
-
const resolvedPath =
|
|
84410
|
-
const resolvedDirectory =
|
|
84411
|
-
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) {
|
|
84412
84479
|
_filesSkipped++;
|
|
84413
84480
|
continue;
|
|
84414
84481
|
}
|
|
@@ -84719,18 +84786,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
84719
84786
|
let resolved;
|
|
84720
84787
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
84721
84788
|
if (isWinAbs) {
|
|
84722
|
-
resolved =
|
|
84723
|
-
} else if (
|
|
84724
|
-
resolved =
|
|
84789
|
+
resolved = path95.win32.resolve(inputPath);
|
|
84790
|
+
} else if (path95.isAbsolute(inputPath)) {
|
|
84791
|
+
resolved = path95.resolve(inputPath);
|
|
84725
84792
|
} else {
|
|
84726
|
-
resolved =
|
|
84793
|
+
resolved = path95.resolve(baseDir, inputPath);
|
|
84727
84794
|
}
|
|
84728
|
-
const workspaceResolved =
|
|
84795
|
+
const workspaceResolved = path95.resolve(workspaceDir);
|
|
84729
84796
|
let relative20;
|
|
84730
84797
|
if (isWinAbs) {
|
|
84731
|
-
relative20 =
|
|
84798
|
+
relative20 = path95.win32.relative(workspaceResolved, resolved);
|
|
84732
84799
|
} else {
|
|
84733
|
-
relative20 =
|
|
84800
|
+
relative20 = path95.relative(workspaceResolved, resolved);
|
|
84734
84801
|
}
|
|
84735
84802
|
if (relative20.startsWith("..")) {
|
|
84736
84803
|
return "path traversal detected";
|
|
@@ -84795,7 +84862,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
84795
84862
|
if (typeof file3 !== "string") {
|
|
84796
84863
|
continue;
|
|
84797
84864
|
}
|
|
84798
|
-
const resolvedPath =
|
|
84865
|
+
const resolvedPath = path95.resolve(file3);
|
|
84799
84866
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
84800
84867
|
if (validationError) {
|
|
84801
84868
|
continue;
|
|
@@ -84952,7 +85019,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
84952
85019
|
skippedFiles++;
|
|
84953
85020
|
continue;
|
|
84954
85021
|
}
|
|
84955
|
-
const resolvedPath =
|
|
85022
|
+
const resolvedPath = path95.resolve(file3);
|
|
84956
85023
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
84957
85024
|
if (validationError) {
|
|
84958
85025
|
skippedFiles++;
|
|
@@ -84970,19 +85037,19 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
84970
85037
|
};
|
|
84971
85038
|
}
|
|
84972
85039
|
for (const file3 of validatedFiles) {
|
|
84973
|
-
const ext =
|
|
85040
|
+
const ext = path95.extname(file3).toLowerCase();
|
|
84974
85041
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
84975
85042
|
skippedFiles++;
|
|
84976
85043
|
continue;
|
|
84977
85044
|
}
|
|
84978
|
-
let
|
|
85045
|
+
let stat7;
|
|
84979
85046
|
try {
|
|
84980
|
-
|
|
85047
|
+
stat7 = fs73.statSync(file3);
|
|
84981
85048
|
} catch {
|
|
84982
85049
|
skippedFiles++;
|
|
84983
85050
|
continue;
|
|
84984
85051
|
}
|
|
84985
|
-
if (
|
|
85052
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES9) {
|
|
84986
85053
|
skippedFiles++;
|
|
84987
85054
|
continue;
|
|
84988
85055
|
}
|
|
@@ -85189,7 +85256,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
85189
85256
|
const preexistingFindings = [];
|
|
85190
85257
|
for (const finding of findings) {
|
|
85191
85258
|
const filePath = finding.location.file;
|
|
85192
|
-
const normalised =
|
|
85259
|
+
const normalised = path95.relative(directory, filePath).replace(/\\/g, "/");
|
|
85193
85260
|
const changedLines = changedLineRanges.get(normalised);
|
|
85194
85261
|
if (changedLines?.has(finding.location.line)) {
|
|
85195
85262
|
newFindings.push(finding);
|
|
@@ -85240,7 +85307,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
85240
85307
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
85241
85308
|
continue;
|
|
85242
85309
|
}
|
|
85243
|
-
changedFiles.push(
|
|
85310
|
+
changedFiles.push(path95.resolve(directory, file3));
|
|
85244
85311
|
}
|
|
85245
85312
|
if (changedFiles.length === 0) {
|
|
85246
85313
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -85441,7 +85508,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
85441
85508
|
};
|
|
85442
85509
|
return JSON.stringify(errorResult, null, 2);
|
|
85443
85510
|
}
|
|
85444
|
-
const resolvedDirectory =
|
|
85511
|
+
const resolvedDirectory = path95.resolve(typedArgs.directory);
|
|
85445
85512
|
const workspaceAnchor = resolvedDirectory;
|
|
85446
85513
|
const dirError = validateDirectory2(resolvedDirectory, workspaceAnchor);
|
|
85447
85514
|
if (dirError) {
|
|
@@ -85482,7 +85549,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
85482
85549
|
});
|
|
85483
85550
|
// src/tools/repo-map.ts
|
|
85484
85551
|
init_zod();
|
|
85485
|
-
import * as
|
|
85552
|
+
import * as path96 from "node:path";
|
|
85486
85553
|
init_path_security();
|
|
85487
85554
|
init_create_tool();
|
|
85488
85555
|
var VALID_ACTIONS = [
|
|
@@ -85507,7 +85574,7 @@ function validateFile(p) {
|
|
|
85507
85574
|
return "file contains control characters";
|
|
85508
85575
|
if (containsPathTraversal(p))
|
|
85509
85576
|
return "file contains path traversal";
|
|
85510
|
-
if (
|
|
85577
|
+
if (path96.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
85511
85578
|
return "file must be a workspace-relative path, not absolute";
|
|
85512
85579
|
}
|
|
85513
85580
|
return null;
|
|
@@ -85530,8 +85597,8 @@ function ok(action, payload) {
|
|
|
85530
85597
|
}
|
|
85531
85598
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
85532
85599
|
const normalized = input.replace(/\\/g, "/");
|
|
85533
|
-
if (
|
|
85534
|
-
const rel =
|
|
85600
|
+
if (path96.isAbsolute(normalized)) {
|
|
85601
|
+
const rel = path96.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
85535
85602
|
return normalizeGraphPath2(rel);
|
|
85536
85603
|
}
|
|
85537
85604
|
return normalizeGraphPath2(normalized);
|
|
@@ -85676,7 +85743,7 @@ var repo_map = createSwarmTool({
|
|
|
85676
85743
|
init_zod();
|
|
85677
85744
|
init_create_tool();
|
|
85678
85745
|
import * as fs74 from "node:fs";
|
|
85679
|
-
import * as
|
|
85746
|
+
import * as path97 from "node:path";
|
|
85680
85747
|
var SPEC_FILE = ".swarm/spec.md";
|
|
85681
85748
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
85682
85749
|
var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -85745,10 +85812,10 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85745
85812
|
return [];
|
|
85746
85813
|
}
|
|
85747
85814
|
for (const entry of entries) {
|
|
85748
|
-
const entryPath =
|
|
85815
|
+
const entryPath = path97.join(evidenceDir, entry);
|
|
85749
85816
|
try {
|
|
85750
|
-
const
|
|
85751
|
-
if (!
|
|
85817
|
+
const stat7 = fs74.statSync(entryPath);
|
|
85818
|
+
if (!stat7.isDirectory()) {
|
|
85752
85819
|
continue;
|
|
85753
85820
|
}
|
|
85754
85821
|
} catch {
|
|
@@ -85761,18 +85828,18 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85761
85828
|
if (entryPhase !== String(phase)) {
|
|
85762
85829
|
continue;
|
|
85763
85830
|
}
|
|
85764
|
-
const evidenceFilePath =
|
|
85831
|
+
const evidenceFilePath = path97.join(entryPath, "evidence.json");
|
|
85765
85832
|
try {
|
|
85766
|
-
const resolvedPath =
|
|
85767
|
-
const evidenceDirResolved =
|
|
85768
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
85833
|
+
const resolvedPath = path97.resolve(evidenceFilePath);
|
|
85834
|
+
const evidenceDirResolved = path97.resolve(evidenceDir);
|
|
85835
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path97.sep)) {
|
|
85769
85836
|
continue;
|
|
85770
85837
|
}
|
|
85771
|
-
const
|
|
85772
|
-
if (!
|
|
85838
|
+
const stat7 = fs74.lstatSync(evidenceFilePath);
|
|
85839
|
+
if (!stat7.isFile()) {
|
|
85773
85840
|
continue;
|
|
85774
85841
|
}
|
|
85775
|
-
if (
|
|
85842
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES9) {
|
|
85776
85843
|
continue;
|
|
85777
85844
|
}
|
|
85778
85845
|
} catch {
|
|
@@ -85799,7 +85866,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85799
85866
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
85800
85867
|
for (const file3 of diffEntry.files_changed) {
|
|
85801
85868
|
if (typeof file3 === "string") {
|
|
85802
|
-
touchedFiles.add(
|
|
85869
|
+
touchedFiles.add(path97.resolve(cwd, file3));
|
|
85803
85870
|
}
|
|
85804
85871
|
}
|
|
85805
85872
|
}
|
|
@@ -85812,8 +85879,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
85812
85879
|
}
|
|
85813
85880
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
85814
85881
|
try {
|
|
85815
|
-
const resolvedPath =
|
|
85816
|
-
const cwdResolved =
|
|
85882
|
+
const resolvedPath = path97.resolve(filePath);
|
|
85883
|
+
const cwdResolved = path97.resolve(cwd);
|
|
85817
85884
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
85818
85885
|
return false;
|
|
85819
85886
|
}
|
|
@@ -85947,7 +86014,7 @@ var req_coverage = createSwarmTool({
|
|
|
85947
86014
|
}, null, 2);
|
|
85948
86015
|
}
|
|
85949
86016
|
const cwd = inputDirectory || directory;
|
|
85950
|
-
const specPath =
|
|
86017
|
+
const specPath = path97.join(cwd, SPEC_FILE);
|
|
85951
86018
|
let specContent;
|
|
85952
86019
|
try {
|
|
85953
86020
|
specContent = fs74.readFileSync(specPath, "utf-8");
|
|
@@ -85974,7 +86041,7 @@ var req_coverage = createSwarmTool({
|
|
|
85974
86041
|
message: "No FR requirements found in spec.md"
|
|
85975
86042
|
}, null, 2);
|
|
85976
86043
|
}
|
|
85977
|
-
const evidenceDir =
|
|
86044
|
+
const evidenceDir = path97.join(cwd, EVIDENCE_DIR4);
|
|
85978
86045
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
85979
86046
|
const analyzedRequirements = [];
|
|
85980
86047
|
let coveredCount = 0;
|
|
@@ -86000,7 +86067,7 @@ var req_coverage = createSwarmTool({
|
|
|
86000
86067
|
requirements: analyzedRequirements
|
|
86001
86068
|
};
|
|
86002
86069
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
86003
|
-
const reportPath =
|
|
86070
|
+
const reportPath = path97.join(evidenceDir, reportFilename);
|
|
86004
86071
|
try {
|
|
86005
86072
|
if (!fs74.existsSync(evidenceDir)) {
|
|
86006
86073
|
fs74.mkdirSync(evidenceDir, { recursive: true });
|
|
@@ -86088,7 +86155,7 @@ init_qa_gate_profile();
|
|
|
86088
86155
|
init_file_locks();
|
|
86089
86156
|
import * as crypto9 from "node:crypto";
|
|
86090
86157
|
import * as fs75 from "node:fs";
|
|
86091
|
-
import * as
|
|
86158
|
+
import * as path98 from "node:path";
|
|
86092
86159
|
init_ledger();
|
|
86093
86160
|
init_manager();
|
|
86094
86161
|
init_state();
|
|
@@ -86166,8 +86233,8 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86166
86233
|
};
|
|
86167
86234
|
}
|
|
86168
86235
|
if (args2.working_directory && fallbackDir) {
|
|
86169
|
-
const resolvedTarget =
|
|
86170
|
-
const resolvedRoot =
|
|
86236
|
+
const resolvedTarget = path98.resolve(args2.working_directory);
|
|
86237
|
+
const resolvedRoot = path98.resolve(fallbackDir);
|
|
86171
86238
|
let fallbackExists = false;
|
|
86172
86239
|
try {
|
|
86173
86240
|
fs75.accessSync(resolvedRoot, fs75.constants.F_OK);
|
|
@@ -86176,7 +86243,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86176
86243
|
fallbackExists = false;
|
|
86177
86244
|
}
|
|
86178
86245
|
if (fallbackExists) {
|
|
86179
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
86246
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path98.sep);
|
|
86180
86247
|
if (isSubdirectory) {
|
|
86181
86248
|
return {
|
|
86182
86249
|
success: false,
|
|
@@ -86192,10 +86259,10 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86192
86259
|
let specMtime;
|
|
86193
86260
|
let specHash;
|
|
86194
86261
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
86195
|
-
const specPath =
|
|
86262
|
+
const specPath = path98.join(targetWorkspace, ".swarm", "spec.md");
|
|
86196
86263
|
try {
|
|
86197
|
-
const
|
|
86198
|
-
specMtime =
|
|
86264
|
+
const stat7 = await fs75.promises.stat(specPath);
|
|
86265
|
+
specMtime = stat7.mtime.toISOString();
|
|
86199
86266
|
const content = await fs75.promises.readFile(specPath, "utf8");
|
|
86200
86267
|
specHash = crypto9.createHash("sha256").update(content).digest("hex");
|
|
86201
86268
|
} catch {
|
|
@@ -86208,7 +86275,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86208
86275
|
}
|
|
86209
86276
|
}
|
|
86210
86277
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
86211
|
-
const contextPath =
|
|
86278
|
+
const contextPath = path98.join(targetWorkspace, ".swarm", "context.md");
|
|
86212
86279
|
let contextContent = "";
|
|
86213
86280
|
try {
|
|
86214
86281
|
contextContent = await fs75.promises.readFile(contextPath, "utf8");
|
|
@@ -86358,7 +86425,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86358
86425
|
}
|
|
86359
86426
|
await writeCheckpoint(dir).catch(() => {});
|
|
86360
86427
|
try {
|
|
86361
|
-
const markerPath =
|
|
86428
|
+
const markerPath = path98.join(dir, ".swarm", ".plan-write-marker");
|
|
86362
86429
|
const marker = JSON.stringify({
|
|
86363
86430
|
source: "save_plan",
|
|
86364
86431
|
timestamp: new Date().toISOString(),
|
|
@@ -86381,7 +86448,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
86381
86448
|
return {
|
|
86382
86449
|
success: true,
|
|
86383
86450
|
message: "Plan saved successfully",
|
|
86384
|
-
plan_path:
|
|
86451
|
+
plan_path: path98.join(dir, ".swarm", "plan.json"),
|
|
86385
86452
|
phases_count: plan.phases.length,
|
|
86386
86453
|
tasks_count: tasksCount,
|
|
86387
86454
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -86434,7 +86501,7 @@ var save_plan = createSwarmTool({
|
|
|
86434
86501
|
init_zod();
|
|
86435
86502
|
init_manager2();
|
|
86436
86503
|
import * as fs76 from "node:fs";
|
|
86437
|
-
import * as
|
|
86504
|
+
import * as path99 from "node:path";
|
|
86438
86505
|
|
|
86439
86506
|
// src/sbom/detectors/index.ts
|
|
86440
86507
|
init_utils();
|
|
@@ -87284,7 +87351,7 @@ function findManifestFiles(rootDir) {
|
|
|
87284
87351
|
try {
|
|
87285
87352
|
const entries = fs76.readdirSync(dir, { withFileTypes: true });
|
|
87286
87353
|
for (const entry of entries) {
|
|
87287
|
-
const fullPath =
|
|
87354
|
+
const fullPath = path99.join(dir, entry.name);
|
|
87288
87355
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
87289
87356
|
continue;
|
|
87290
87357
|
}
|
|
@@ -87293,7 +87360,7 @@ function findManifestFiles(rootDir) {
|
|
|
87293
87360
|
} else if (entry.isFile()) {
|
|
87294
87361
|
for (const pattern of patterns) {
|
|
87295
87362
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
87296
|
-
manifestFiles.push(
|
|
87363
|
+
manifestFiles.push(path99.relative(rootDir, fullPath));
|
|
87297
87364
|
break;
|
|
87298
87365
|
}
|
|
87299
87366
|
}
|
|
@@ -87311,11 +87378,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
87311
87378
|
try {
|
|
87312
87379
|
const entries = fs76.readdirSync(dir, { withFileTypes: true });
|
|
87313
87380
|
for (const entry of entries) {
|
|
87314
|
-
const fullPath =
|
|
87381
|
+
const fullPath = path99.join(dir, entry.name);
|
|
87315
87382
|
if (entry.isFile()) {
|
|
87316
87383
|
for (const pattern of patterns) {
|
|
87317
87384
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
87318
|
-
found.push(
|
|
87385
|
+
found.push(path99.relative(workingDir, fullPath));
|
|
87319
87386
|
break;
|
|
87320
87387
|
}
|
|
87321
87388
|
}
|
|
@@ -87328,11 +87395,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
87328
87395
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
87329
87396
|
const dirs = new Set;
|
|
87330
87397
|
for (const file3 of changedFiles) {
|
|
87331
|
-
let currentDir =
|
|
87398
|
+
let currentDir = path99.dirname(file3);
|
|
87332
87399
|
while (true) {
|
|
87333
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
87334
|
-
dirs.add(
|
|
87335
|
-
const parent =
|
|
87400
|
+
if (currentDir && currentDir !== "." && currentDir !== path99.sep) {
|
|
87401
|
+
dirs.add(path99.join(workingDir, currentDir));
|
|
87402
|
+
const parent = path99.dirname(currentDir);
|
|
87336
87403
|
if (parent === currentDir)
|
|
87337
87404
|
break;
|
|
87338
87405
|
currentDir = parent;
|
|
@@ -87416,7 +87483,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87416
87483
|
const changedFiles = obj.changed_files;
|
|
87417
87484
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
87418
87485
|
const workingDir = directory;
|
|
87419
|
-
const outputDir =
|
|
87486
|
+
const outputDir = path99.isAbsolute(relativeOutputDir) ? relativeOutputDir : path99.join(workingDir, relativeOutputDir);
|
|
87420
87487
|
let manifestFiles = [];
|
|
87421
87488
|
if (scope === "all") {
|
|
87422
87489
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -87439,7 +87506,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87439
87506
|
const processedFiles = [];
|
|
87440
87507
|
for (const manifestFile of manifestFiles) {
|
|
87441
87508
|
try {
|
|
87442
|
-
const fullPath =
|
|
87509
|
+
const fullPath = path99.isAbsolute(manifestFile) ? manifestFile : path99.join(workingDir, manifestFile);
|
|
87443
87510
|
if (!fs76.existsSync(fullPath)) {
|
|
87444
87511
|
continue;
|
|
87445
87512
|
}
|
|
@@ -87456,7 +87523,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87456
87523
|
const bom = generateCycloneDX(allComponents);
|
|
87457
87524
|
const bomJson = serializeCycloneDX(bom);
|
|
87458
87525
|
const filename = generateSbomFilename();
|
|
87459
|
-
const outputPath =
|
|
87526
|
+
const outputPath = path99.join(outputDir, filename);
|
|
87460
87527
|
fs76.writeFileSync(outputPath, bomJson, "utf-8");
|
|
87461
87528
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
87462
87529
|
try {
|
|
@@ -87500,7 +87567,7 @@ var sbom_generate = createSwarmTool({
|
|
|
87500
87567
|
init_zod();
|
|
87501
87568
|
init_create_tool();
|
|
87502
87569
|
import * as fs77 from "node:fs";
|
|
87503
|
-
import * as
|
|
87570
|
+
import * as path100 from "node:path";
|
|
87504
87571
|
var SPEC_CANDIDATES = [
|
|
87505
87572
|
"openapi.json",
|
|
87506
87573
|
"openapi.yaml",
|
|
@@ -87532,12 +87599,12 @@ function normalizePath3(p) {
|
|
|
87532
87599
|
}
|
|
87533
87600
|
function discoverSpecFile(cwd, specFileArg) {
|
|
87534
87601
|
if (specFileArg) {
|
|
87535
|
-
const resolvedPath =
|
|
87536
|
-
const normalizedCwd = cwd.endsWith(
|
|
87602
|
+
const resolvedPath = path100.resolve(cwd, specFileArg);
|
|
87603
|
+
const normalizedCwd = cwd.endsWith(path100.sep) ? cwd : cwd + path100.sep;
|
|
87537
87604
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
87538
87605
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
87539
87606
|
}
|
|
87540
|
-
const ext =
|
|
87607
|
+
const ext = path100.extname(resolvedPath).toLowerCase();
|
|
87541
87608
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
87542
87609
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
87543
87610
|
}
|
|
@@ -87551,7 +87618,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
87551
87618
|
return resolvedPath;
|
|
87552
87619
|
}
|
|
87553
87620
|
for (const candidate of SPEC_CANDIDATES) {
|
|
87554
|
-
const candidatePath =
|
|
87621
|
+
const candidatePath = path100.resolve(cwd, candidate);
|
|
87555
87622
|
if (fs77.existsSync(candidatePath)) {
|
|
87556
87623
|
const stats = fs77.statSync(candidatePath);
|
|
87557
87624
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -87563,7 +87630,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
87563
87630
|
}
|
|
87564
87631
|
function parseSpec(specFile) {
|
|
87565
87632
|
const content = fs77.readFileSync(specFile, "utf-8");
|
|
87566
|
-
const ext =
|
|
87633
|
+
const ext = path100.extname(specFile).toLowerCase();
|
|
87567
87634
|
if (ext === ".json") {
|
|
87568
87635
|
return parseJsonSpec(content);
|
|
87569
87636
|
}
|
|
@@ -87639,7 +87706,7 @@ function extractRoutes(cwd) {
|
|
|
87639
87706
|
return;
|
|
87640
87707
|
}
|
|
87641
87708
|
for (const entry of entries) {
|
|
87642
|
-
const fullPath =
|
|
87709
|
+
const fullPath = path100.join(dir, entry.name);
|
|
87643
87710
|
if (entry.isSymbolicLink()) {
|
|
87644
87711
|
continue;
|
|
87645
87712
|
}
|
|
@@ -87649,7 +87716,7 @@ function extractRoutes(cwd) {
|
|
|
87649
87716
|
}
|
|
87650
87717
|
walkDir(fullPath);
|
|
87651
87718
|
} else if (entry.isFile()) {
|
|
87652
|
-
const ext =
|
|
87719
|
+
const ext = path100.extname(entry.name).toLowerCase();
|
|
87653
87720
|
const baseName = entry.name.toLowerCase();
|
|
87654
87721
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
87655
87722
|
continue;
|
|
@@ -87817,7 +87884,7 @@ init_bun_compat();
|
|
|
87817
87884
|
init_path_security();
|
|
87818
87885
|
init_create_tool();
|
|
87819
87886
|
import * as fs78 from "node:fs";
|
|
87820
|
-
import * as
|
|
87887
|
+
import * as path101 from "node:path";
|
|
87821
87888
|
var DEFAULT_MAX_RESULTS = 100;
|
|
87822
87889
|
var DEFAULT_MAX_LINES = 200;
|
|
87823
87890
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -87853,11 +87920,11 @@ function containsWindowsAttacks3(str) {
|
|
|
87853
87920
|
}
|
|
87854
87921
|
function isPathInWorkspace3(filePath, workspace) {
|
|
87855
87922
|
try {
|
|
87856
|
-
const resolvedPath =
|
|
87923
|
+
const resolvedPath = path101.resolve(workspace, filePath);
|
|
87857
87924
|
const realWorkspace = fs78.realpathSync(workspace);
|
|
87858
87925
|
const realResolvedPath = fs78.realpathSync(resolvedPath);
|
|
87859
|
-
const relativePath =
|
|
87860
|
-
if (relativePath.startsWith("..") ||
|
|
87926
|
+
const relativePath = path101.relative(realWorkspace, realResolvedPath);
|
|
87927
|
+
if (relativePath.startsWith("..") || path101.isAbsolute(relativePath)) {
|
|
87861
87928
|
return false;
|
|
87862
87929
|
}
|
|
87863
87930
|
return true;
|
|
@@ -87870,11 +87937,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
87870
87937
|
}
|
|
87871
87938
|
function findRgInEnvPath() {
|
|
87872
87939
|
const searchPath = process.env.PATH ?? "";
|
|
87873
|
-
for (const dir of searchPath.split(
|
|
87940
|
+
for (const dir of searchPath.split(path101.delimiter)) {
|
|
87874
87941
|
if (!dir)
|
|
87875
87942
|
continue;
|
|
87876
87943
|
const isWindows = process.platform === "win32";
|
|
87877
|
-
const candidate =
|
|
87944
|
+
const candidate = path101.join(dir, isWindows ? "rg.exe" : "rg");
|
|
87878
87945
|
if (fs78.existsSync(candidate))
|
|
87879
87946
|
return candidate;
|
|
87880
87947
|
}
|
|
@@ -87929,7 +87996,7 @@ async function ripgrepSearch(opts) {
|
|
|
87929
87996
|
stderr: "pipe",
|
|
87930
87997
|
cwd: opts.workspace
|
|
87931
87998
|
});
|
|
87932
|
-
const timeout = new Promise((
|
|
87999
|
+
const timeout = new Promise((resolve40) => setTimeout(() => resolve40("timeout"), REGEX_TIMEOUT_MS));
|
|
87933
88000
|
const exitPromise = proc.exited;
|
|
87934
88001
|
const result = await Promise.race([exitPromise, timeout]);
|
|
87935
88002
|
if (result === "timeout") {
|
|
@@ -88004,8 +88071,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
88004
88071
|
try {
|
|
88005
88072
|
const entries = fs78.readdirSync(dir, { withFileTypes: true });
|
|
88006
88073
|
for (const entry of entries) {
|
|
88007
|
-
const fullPath =
|
|
88008
|
-
const relativePath =
|
|
88074
|
+
const fullPath = path101.join(dir, entry.name);
|
|
88075
|
+
const relativePath = path101.relative(workspace, fullPath);
|
|
88009
88076
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
88010
88077
|
continue;
|
|
88011
88078
|
}
|
|
@@ -88046,7 +88113,7 @@ async function fallbackSearch(opts) {
|
|
|
88046
88113
|
const matches = [];
|
|
88047
88114
|
let total = 0;
|
|
88048
88115
|
for (const file3 of files) {
|
|
88049
|
-
const fullPath =
|
|
88116
|
+
const fullPath = path101.join(opts.workspace, file3);
|
|
88050
88117
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
88051
88118
|
continue;
|
|
88052
88119
|
}
|
|
@@ -88427,7 +88494,7 @@ init_zod();
|
|
|
88427
88494
|
init_path_security();
|
|
88428
88495
|
init_create_tool();
|
|
88429
88496
|
import * as fs79 from "node:fs";
|
|
88430
|
-
import * as
|
|
88497
|
+
import * as path102 from "node:path";
|
|
88431
88498
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
88432
88499
|
function containsWindowsAttacks4(str) {
|
|
88433
88500
|
if (/:[^\\/]/.test(str))
|
|
@@ -88441,14 +88508,14 @@ function containsWindowsAttacks4(str) {
|
|
|
88441
88508
|
}
|
|
88442
88509
|
function isPathInWorkspace4(filePath, workspace) {
|
|
88443
88510
|
try {
|
|
88444
|
-
const resolvedPath =
|
|
88511
|
+
const resolvedPath = path102.resolve(workspace, filePath);
|
|
88445
88512
|
if (!fs79.existsSync(resolvedPath)) {
|
|
88446
88513
|
return true;
|
|
88447
88514
|
}
|
|
88448
88515
|
const realWorkspace = fs79.realpathSync(workspace);
|
|
88449
88516
|
const realResolvedPath = fs79.realpathSync(resolvedPath);
|
|
88450
|
-
const relativePath =
|
|
88451
|
-
if (relativePath.startsWith("..") ||
|
|
88517
|
+
const relativePath = path102.relative(realWorkspace, realResolvedPath);
|
|
88518
|
+
if (relativePath.startsWith("..") || path102.isAbsolute(relativePath)) {
|
|
88452
88519
|
return false;
|
|
88453
88520
|
}
|
|
88454
88521
|
return true;
|
|
@@ -88656,7 +88723,7 @@ var suggestPatch = createSwarmTool({
|
|
|
88656
88723
|
});
|
|
88657
88724
|
continue;
|
|
88658
88725
|
}
|
|
88659
|
-
const fullPath =
|
|
88726
|
+
const fullPath = path102.resolve(directory, change.file);
|
|
88660
88727
|
if (!fs79.existsSync(fullPath)) {
|
|
88661
88728
|
errors5.push({
|
|
88662
88729
|
success: false,
|
|
@@ -88919,7 +88986,7 @@ var generate_mutants = createSwarmTool({
|
|
|
88919
88986
|
init_spec_schema();
|
|
88920
88987
|
init_create_tool();
|
|
88921
88988
|
import * as fs80 from "node:fs";
|
|
88922
|
-
import * as
|
|
88989
|
+
import * as path103 from "node:path";
|
|
88923
88990
|
var SPEC_FILE_NAME = "spec.md";
|
|
88924
88991
|
var SWARM_DIR2 = ".swarm";
|
|
88925
88992
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -88972,7 +89039,7 @@ var lint_spec = createSwarmTool({
|
|
|
88972
89039
|
async execute(_args, directory) {
|
|
88973
89040
|
const errors5 = [];
|
|
88974
89041
|
const warnings = [];
|
|
88975
|
-
const specPath =
|
|
89042
|
+
const specPath = path103.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
88976
89043
|
if (!fs80.existsSync(specPath)) {
|
|
88977
89044
|
const result2 = {
|
|
88978
89045
|
valid: false,
|
|
@@ -89043,12 +89110,12 @@ var lint_spec = createSwarmTool({
|
|
|
89043
89110
|
// src/tools/mutation-test.ts
|
|
89044
89111
|
init_zod();
|
|
89045
89112
|
import * as fs81 from "node:fs";
|
|
89046
|
-
import * as
|
|
89113
|
+
import * as path105 from "node:path";
|
|
89047
89114
|
|
|
89048
89115
|
// src/mutation/engine.ts
|
|
89049
89116
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
89050
89117
|
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync20 } from "node:fs";
|
|
89051
|
-
import * as
|
|
89118
|
+
import * as path104 from "node:path";
|
|
89052
89119
|
|
|
89053
89120
|
// src/mutation/equivalence.ts
|
|
89054
89121
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -89183,7 +89250,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
89183
89250
|
let patchFile;
|
|
89184
89251
|
try {
|
|
89185
89252
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
89186
|
-
patchFile =
|
|
89253
|
+
patchFile = path104.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
89187
89254
|
try {
|
|
89188
89255
|
writeFileSync20(patchFile, patch.patch);
|
|
89189
89256
|
} catch (writeErr) {
|
|
@@ -89577,7 +89644,7 @@ var mutation_test = createSwarmTool({
|
|
|
89577
89644
|
];
|
|
89578
89645
|
for (const filePath of uniquePaths) {
|
|
89579
89646
|
try {
|
|
89580
|
-
const resolvedPath =
|
|
89647
|
+
const resolvedPath = path105.resolve(cwd, filePath);
|
|
89581
89648
|
sourceFiles.set(filePath, fs81.readFileSync(resolvedPath, "utf-8"));
|
|
89582
89649
|
} catch {}
|
|
89583
89650
|
}
|
|
@@ -89597,7 +89664,7 @@ init_zod();
|
|
|
89597
89664
|
init_manager2();
|
|
89598
89665
|
init_detector();
|
|
89599
89666
|
import * as fs82 from "node:fs";
|
|
89600
|
-
import * as
|
|
89667
|
+
import * as path106 from "node:path";
|
|
89601
89668
|
init_create_tool();
|
|
89602
89669
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
89603
89670
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -89663,7 +89730,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89663
89730
|
if (languages?.length) {
|
|
89664
89731
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
89665
89732
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
89666
|
-
const ext =
|
|
89733
|
+
const ext = path106.extname(file3.path).toLowerCase();
|
|
89667
89734
|
const langDef = getLanguageForExtension(ext);
|
|
89668
89735
|
const fileProfile = getProfileForFile(file3.path);
|
|
89669
89736
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -89676,7 +89743,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89676
89743
|
let skippedCount = 0;
|
|
89677
89744
|
for (const fileInfo of filesToCheck) {
|
|
89678
89745
|
const { path: filePath } = fileInfo;
|
|
89679
|
-
const fullPath =
|
|
89746
|
+
const fullPath = path106.isAbsolute(filePath) ? filePath : path106.join(directory, filePath);
|
|
89680
89747
|
const result = {
|
|
89681
89748
|
path: filePath,
|
|
89682
89749
|
language: "",
|
|
@@ -89725,7 +89792,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
89725
89792
|
results.push(result);
|
|
89726
89793
|
continue;
|
|
89727
89794
|
}
|
|
89728
|
-
const ext =
|
|
89795
|
+
const ext = path106.extname(filePath).toLowerCase();
|
|
89729
89796
|
const langDef = getLanguageForExtension(ext);
|
|
89730
89797
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
89731
89798
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -89818,7 +89885,7 @@ init_utils();
|
|
|
89818
89885
|
init_create_tool();
|
|
89819
89886
|
init_path_security();
|
|
89820
89887
|
import * as fs83 from "node:fs";
|
|
89821
|
-
import * as
|
|
89888
|
+
import * as path107 from "node:path";
|
|
89822
89889
|
var MAX_TEXT_LENGTH = 200;
|
|
89823
89890
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
89824
89891
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -89884,9 +89951,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
89884
89951
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
89885
89952
|
}
|
|
89886
89953
|
try {
|
|
89887
|
-
const resolvedPath =
|
|
89888
|
-
const normalizedCwd =
|
|
89889
|
-
const normalizedResolved =
|
|
89954
|
+
const resolvedPath = path107.resolve(paths);
|
|
89955
|
+
const normalizedCwd = path107.resolve(cwd);
|
|
89956
|
+
const normalizedResolved = path107.resolve(resolvedPath);
|
|
89890
89957
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
89891
89958
|
return {
|
|
89892
89959
|
error: "paths must be within the current working directory",
|
|
@@ -89902,7 +89969,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
89902
89969
|
}
|
|
89903
89970
|
}
|
|
89904
89971
|
function isSupportedExtension(filePath) {
|
|
89905
|
-
const ext =
|
|
89972
|
+
const ext = path107.extname(filePath).toLowerCase();
|
|
89906
89973
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
89907
89974
|
}
|
|
89908
89975
|
function findSourceFiles3(dir, files = []) {
|
|
@@ -89917,16 +89984,16 @@ function findSourceFiles3(dir, files = []) {
|
|
|
89917
89984
|
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
89918
89985
|
continue;
|
|
89919
89986
|
}
|
|
89920
|
-
const fullPath =
|
|
89921
|
-
let
|
|
89987
|
+
const fullPath = path107.join(dir, entry);
|
|
89988
|
+
let stat7;
|
|
89922
89989
|
try {
|
|
89923
|
-
|
|
89990
|
+
stat7 = fs83.statSync(fullPath);
|
|
89924
89991
|
} catch {
|
|
89925
89992
|
continue;
|
|
89926
89993
|
}
|
|
89927
|
-
if (
|
|
89994
|
+
if (stat7.isDirectory()) {
|
|
89928
89995
|
findSourceFiles3(fullPath, files);
|
|
89929
|
-
} else if (
|
|
89996
|
+
} else if (stat7.isFile()) {
|
|
89930
89997
|
if (isSupportedExtension(fullPath)) {
|
|
89931
89998
|
files.push(fullPath);
|
|
89932
89999
|
}
|
|
@@ -90023,13 +90090,13 @@ var todo_extract = createSwarmTool({
|
|
|
90023
90090
|
return JSON.stringify(errorResult, null, 2);
|
|
90024
90091
|
}
|
|
90025
90092
|
const filesToScan = [];
|
|
90026
|
-
const
|
|
90027
|
-
if (
|
|
90093
|
+
const stat7 = fs83.statSync(scanPath);
|
|
90094
|
+
if (stat7.isFile()) {
|
|
90028
90095
|
if (isSupportedExtension(scanPath)) {
|
|
90029
90096
|
filesToScan.push(scanPath);
|
|
90030
90097
|
} else {
|
|
90031
90098
|
const errorResult = {
|
|
90032
|
-
error: `unsupported file extension: ${
|
|
90099
|
+
error: `unsupported file extension: ${path107.extname(scanPath)}`,
|
|
90033
90100
|
total: 0,
|
|
90034
90101
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
90035
90102
|
entries: []
|
|
@@ -90078,17 +90145,17 @@ init_schema();
|
|
|
90078
90145
|
init_qa_gate_profile();
|
|
90079
90146
|
init_gate_evidence();
|
|
90080
90147
|
import * as fs86 from "node:fs";
|
|
90081
|
-
import * as
|
|
90148
|
+
import * as path110 from "node:path";
|
|
90082
90149
|
|
|
90083
90150
|
// src/hooks/diff-scope.ts
|
|
90084
90151
|
init_bun_compat();
|
|
90085
90152
|
import * as fs85 from "node:fs";
|
|
90086
|
-
import * as
|
|
90153
|
+
import * as path109 from "node:path";
|
|
90087
90154
|
|
|
90088
90155
|
// src/utils/gitignore-warning.ts
|
|
90089
90156
|
init_bun_compat();
|
|
90090
90157
|
import * as fs84 from "node:fs";
|
|
90091
|
-
import * as
|
|
90158
|
+
import * as path108 from "node:path";
|
|
90092
90159
|
var _internals = { bunSpawn };
|
|
90093
90160
|
var _swarmGitExcludedChecked = false;
|
|
90094
90161
|
function fileCoversSwarm(content) {
|
|
@@ -90162,10 +90229,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
90162
90229
|
const excludeRelPath = excludePathRaw.trim();
|
|
90163
90230
|
if (!excludeRelPath)
|
|
90164
90231
|
return;
|
|
90165
|
-
const excludePath =
|
|
90232
|
+
const excludePath = path108.isAbsolute(excludeRelPath) ? excludeRelPath : path108.join(directory, excludeRelPath);
|
|
90166
90233
|
if (checkIgnoreExitCode !== 0) {
|
|
90167
90234
|
try {
|
|
90168
|
-
fs84.mkdirSync(
|
|
90235
|
+
fs84.mkdirSync(path108.dirname(excludePath), { recursive: true });
|
|
90169
90236
|
let existing = "";
|
|
90170
90237
|
try {
|
|
90171
90238
|
existing = fs84.readFileSync(excludePath, "utf8");
|
|
@@ -90209,7 +90276,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
90209
90276
|
var _internals2 = { bunSpawn };
|
|
90210
90277
|
function getDeclaredScope(taskId, directory) {
|
|
90211
90278
|
try {
|
|
90212
|
-
const planPath =
|
|
90279
|
+
const planPath = path109.join(directory, ".swarm", "plan.json");
|
|
90213
90280
|
if (!fs85.existsSync(planPath))
|
|
90214
90281
|
return null;
|
|
90215
90282
|
const raw = fs85.readFileSync(planPath, "utf-8");
|
|
@@ -90346,7 +90413,7 @@ var TIER_3_PATTERNS = [
|
|
|
90346
90413
|
];
|
|
90347
90414
|
function matchesTier3Pattern(files) {
|
|
90348
90415
|
for (const file3 of files) {
|
|
90349
|
-
const fileName =
|
|
90416
|
+
const fileName = path110.basename(file3);
|
|
90350
90417
|
for (const pattern of TIER_3_PATTERNS) {
|
|
90351
90418
|
if (pattern.test(fileName)) {
|
|
90352
90419
|
return true;
|
|
@@ -90360,7 +90427,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
90360
90427
|
if (hasActiveTurboMode()) {
|
|
90361
90428
|
const resolvedDir2 = workingDirectory;
|
|
90362
90429
|
try {
|
|
90363
|
-
const planPath =
|
|
90430
|
+
const planPath = path110.join(resolvedDir2, ".swarm", "plan.json");
|
|
90364
90431
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90365
90432
|
const plan = JSON.parse(planRaw);
|
|
90366
90433
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -90430,7 +90497,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
90430
90497
|
}
|
|
90431
90498
|
try {
|
|
90432
90499
|
const resolvedDir2 = workingDirectory;
|
|
90433
|
-
const planPath =
|
|
90500
|
+
const planPath = path110.join(resolvedDir2, ".swarm", "plan.json");
|
|
90434
90501
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90435
90502
|
const plan = JSON.parse(planRaw);
|
|
90436
90503
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -90620,8 +90687,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90620
90687
|
};
|
|
90621
90688
|
}
|
|
90622
90689
|
}
|
|
90623
|
-
normalizedDir =
|
|
90624
|
-
const pathParts = normalizedDir.split(
|
|
90690
|
+
normalizedDir = path110.normalize(args2.working_directory);
|
|
90691
|
+
const pathParts = normalizedDir.split(path110.sep);
|
|
90625
90692
|
if (pathParts.includes("..")) {
|
|
90626
90693
|
return {
|
|
90627
90694
|
success: false,
|
|
@@ -90631,10 +90698,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90631
90698
|
]
|
|
90632
90699
|
};
|
|
90633
90700
|
}
|
|
90634
|
-
const resolvedDir =
|
|
90701
|
+
const resolvedDir = path110.resolve(normalizedDir);
|
|
90635
90702
|
try {
|
|
90636
90703
|
const realPath = fs86.realpathSync(resolvedDir);
|
|
90637
|
-
const planPath =
|
|
90704
|
+
const planPath = path110.join(realPath, ".swarm", "plan.json");
|
|
90638
90705
|
if (!fs86.existsSync(planPath)) {
|
|
90639
90706
|
return {
|
|
90640
90707
|
success: false,
|
|
@@ -90666,8 +90733,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90666
90733
|
}
|
|
90667
90734
|
if (args2.status === "in_progress") {
|
|
90668
90735
|
try {
|
|
90669
|
-
const evidencePath =
|
|
90670
|
-
fs86.mkdirSync(
|
|
90736
|
+
const evidencePath = path110.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
90737
|
+
fs86.mkdirSync(path110.dirname(evidencePath), { recursive: true });
|
|
90671
90738
|
const fd = fs86.openSync(evidencePath, "wx");
|
|
90672
90739
|
let writeOk = false;
|
|
90673
90740
|
try {
|
|
@@ -90691,7 +90758,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
90691
90758
|
recoverTaskStateFromDelegations(args2.task_id);
|
|
90692
90759
|
let phaseRequiresReviewer = true;
|
|
90693
90760
|
try {
|
|
90694
|
-
const planPath =
|
|
90761
|
+
const planPath = path110.join(directory, ".swarm", "plan.json");
|
|
90695
90762
|
const planRaw = fs86.readFileSync(planPath, "utf-8");
|
|
90696
90763
|
const plan = JSON.parse(planRaw);
|
|
90697
90764
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -91003,7 +91070,7 @@ init_ledger();
|
|
|
91003
91070
|
init_manager();
|
|
91004
91071
|
init_create_tool();
|
|
91005
91072
|
import fs87 from "node:fs";
|
|
91006
|
-
import
|
|
91073
|
+
import path111 from "node:path";
|
|
91007
91074
|
function derivePlanId5(plan) {
|
|
91008
91075
|
return `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
91009
91076
|
}
|
|
@@ -91054,7 +91121,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
91054
91121
|
entries: [evidenceEntry]
|
|
91055
91122
|
};
|
|
91056
91123
|
const filename = "drift-verifier.json";
|
|
91057
|
-
const relativePath =
|
|
91124
|
+
const relativePath = path111.join("evidence", String(phase), filename);
|
|
91058
91125
|
let validatedPath;
|
|
91059
91126
|
try {
|
|
91060
91127
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91065,10 +91132,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
91065
91132
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91066
91133
|
}, null, 2);
|
|
91067
91134
|
}
|
|
91068
|
-
const evidenceDir =
|
|
91135
|
+
const evidenceDir = path111.dirname(validatedPath);
|
|
91069
91136
|
try {
|
|
91070
91137
|
await fs87.promises.mkdir(evidenceDir, { recursive: true });
|
|
91071
|
-
const tempPath =
|
|
91138
|
+
const tempPath = path111.join(evidenceDir, `.${filename}.tmp`);
|
|
91072
91139
|
await fs87.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91073
91140
|
await fs87.promises.rename(tempPath, validatedPath);
|
|
91074
91141
|
let snapshotInfo;
|
|
@@ -91165,7 +91232,7 @@ init_zod();
|
|
|
91165
91232
|
init_utils2();
|
|
91166
91233
|
init_create_tool();
|
|
91167
91234
|
import fs88 from "node:fs";
|
|
91168
|
-
import
|
|
91235
|
+
import path112 from "node:path";
|
|
91169
91236
|
function normalizeVerdict2(verdict) {
|
|
91170
91237
|
switch (verdict) {
|
|
91171
91238
|
case "APPROVED":
|
|
@@ -91213,7 +91280,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
91213
91280
|
entries: [evidenceEntry]
|
|
91214
91281
|
};
|
|
91215
91282
|
const filename = "hallucination-guard.json";
|
|
91216
|
-
const relativePath =
|
|
91283
|
+
const relativePath = path112.join("evidence", String(phase), filename);
|
|
91217
91284
|
let validatedPath;
|
|
91218
91285
|
try {
|
|
91219
91286
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91224,10 +91291,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
91224
91291
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91225
91292
|
}, null, 2);
|
|
91226
91293
|
}
|
|
91227
|
-
const evidenceDir =
|
|
91294
|
+
const evidenceDir = path112.dirname(validatedPath);
|
|
91228
91295
|
try {
|
|
91229
91296
|
await fs88.promises.mkdir(evidenceDir, { recursive: true });
|
|
91230
|
-
const tempPath =
|
|
91297
|
+
const tempPath = path112.join(evidenceDir, `.${filename}.tmp`);
|
|
91231
91298
|
await fs88.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91232
91299
|
await fs88.promises.rename(tempPath, validatedPath);
|
|
91233
91300
|
return JSON.stringify({
|
|
@@ -91276,7 +91343,7 @@ init_zod();
|
|
|
91276
91343
|
init_utils2();
|
|
91277
91344
|
init_create_tool();
|
|
91278
91345
|
import fs89 from "node:fs";
|
|
91279
|
-
import
|
|
91346
|
+
import path113 from "node:path";
|
|
91280
91347
|
function normalizeVerdict3(verdict) {
|
|
91281
91348
|
switch (verdict) {
|
|
91282
91349
|
case "PASS":
|
|
@@ -91350,7 +91417,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
91350
91417
|
entries: [evidenceEntry]
|
|
91351
91418
|
};
|
|
91352
91419
|
const filename = "mutation-gate.json";
|
|
91353
|
-
const relativePath =
|
|
91420
|
+
const relativePath = path113.join("evidence", String(phase), filename);
|
|
91354
91421
|
let validatedPath;
|
|
91355
91422
|
try {
|
|
91356
91423
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -91361,10 +91428,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
91361
91428
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
91362
91429
|
}, null, 2);
|
|
91363
91430
|
}
|
|
91364
|
-
const evidenceDir =
|
|
91431
|
+
const evidenceDir = path113.dirname(validatedPath);
|
|
91365
91432
|
try {
|
|
91366
91433
|
await fs89.promises.mkdir(evidenceDir, { recursive: true });
|
|
91367
|
-
const tempPath =
|
|
91434
|
+
const tempPath = path113.join(evidenceDir, `.${filename}.tmp`);
|
|
91368
91435
|
await fs89.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
91369
91436
|
await fs89.promises.rename(tempPath, validatedPath);
|
|
91370
91437
|
return JSON.stringify({
|
|
@@ -91658,7 +91725,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
91658
91725
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
91659
91726
|
preflightTriggerManager = new PTM(automationConfig);
|
|
91660
91727
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
91661
|
-
const swarmDir =
|
|
91728
|
+
const swarmDir = path114.resolve(ctx.directory, ".swarm");
|
|
91662
91729
|
statusArtifact = new ASA(swarmDir);
|
|
91663
91730
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
91664
91731
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|