opencode-swarm 6.46.0 → 6.47.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 +341 -240
- package/dist/commands/close.d.ts +1 -1
- package/dist/index.js +621 -520
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32533,7 +32533,7 @@ __export(exports_co_change_analyzer, {
|
|
|
32533
32533
|
import * as child_process2 from "child_process";
|
|
32534
32534
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
32535
32535
|
import { readdir as readdir2, readFile as readFile4, stat } from "fs/promises";
|
|
32536
|
-
import * as
|
|
32536
|
+
import * as path20 from "path";
|
|
32537
32537
|
import { promisify } from "util";
|
|
32538
32538
|
function getExecFileAsync() {
|
|
32539
32539
|
return promisify(child_process2.execFile);
|
|
@@ -32635,7 +32635,7 @@ async function scanSourceFiles(dir) {
|
|
|
32635
32635
|
try {
|
|
32636
32636
|
const entries = await readdir2(dir, { withFileTypes: true });
|
|
32637
32637
|
for (const entry of entries) {
|
|
32638
|
-
const fullPath =
|
|
32638
|
+
const fullPath = path20.join(dir, entry.name);
|
|
32639
32639
|
if (entry.isDirectory()) {
|
|
32640
32640
|
if (skipDirs.has(entry.name)) {
|
|
32641
32641
|
continue;
|
|
@@ -32643,7 +32643,7 @@ async function scanSourceFiles(dir) {
|
|
|
32643
32643
|
const subFiles = await scanSourceFiles(fullPath);
|
|
32644
32644
|
results.push(...subFiles);
|
|
32645
32645
|
} else if (entry.isFile()) {
|
|
32646
|
-
const ext =
|
|
32646
|
+
const ext = path20.extname(entry.name);
|
|
32647
32647
|
if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
|
|
32648
32648
|
results.push(fullPath);
|
|
32649
32649
|
}
|
|
@@ -32665,8 +32665,8 @@ async function getStaticEdges(directory) {
|
|
|
32665
32665
|
continue;
|
|
32666
32666
|
}
|
|
32667
32667
|
try {
|
|
32668
|
-
const sourceDir =
|
|
32669
|
-
const resolvedPath =
|
|
32668
|
+
const sourceDir = path20.dirname(sourceFile);
|
|
32669
|
+
const resolvedPath = path20.resolve(sourceDir, importPath);
|
|
32670
32670
|
const extensions = [
|
|
32671
32671
|
"",
|
|
32672
32672
|
".ts",
|
|
@@ -32691,8 +32691,8 @@ async function getStaticEdges(directory) {
|
|
|
32691
32691
|
if (!targetFile) {
|
|
32692
32692
|
continue;
|
|
32693
32693
|
}
|
|
32694
|
-
const relSource =
|
|
32695
|
-
const relTarget =
|
|
32694
|
+
const relSource = path20.relative(directory, sourceFile).replace(/\\/g, "/");
|
|
32695
|
+
const relTarget = path20.relative(directory, targetFile).replace(/\\/g, "/");
|
|
32696
32696
|
const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
|
|
32697
32697
|
edges.add(key);
|
|
32698
32698
|
} catch {}
|
|
@@ -32704,7 +32704,7 @@ async function getStaticEdges(directory) {
|
|
|
32704
32704
|
function isTestImplementationPair(fileA, fileB) {
|
|
32705
32705
|
const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
|
|
32706
32706
|
const getBaseName = (filePath) => {
|
|
32707
|
-
const base =
|
|
32707
|
+
const base = path20.basename(filePath);
|
|
32708
32708
|
for (const pattern of testPatterns) {
|
|
32709
32709
|
if (base.endsWith(pattern)) {
|
|
32710
32710
|
return base.slice(0, -pattern.length);
|
|
@@ -32714,16 +32714,16 @@ function isTestImplementationPair(fileA, fileB) {
|
|
|
32714
32714
|
};
|
|
32715
32715
|
const baseA = getBaseName(fileA);
|
|
32716
32716
|
const baseB = getBaseName(fileB);
|
|
32717
|
-
return baseA === baseB && baseA !==
|
|
32717
|
+
return baseA === baseB && baseA !== path20.basename(fileA) && baseA !== path20.basename(fileB);
|
|
32718
32718
|
}
|
|
32719
32719
|
function hasSharedPrefix(fileA, fileB) {
|
|
32720
|
-
const dirA =
|
|
32721
|
-
const dirB =
|
|
32720
|
+
const dirA = path20.dirname(fileA);
|
|
32721
|
+
const dirB = path20.dirname(fileB);
|
|
32722
32722
|
if (dirA !== dirB) {
|
|
32723
32723
|
return false;
|
|
32724
32724
|
}
|
|
32725
|
-
const baseA =
|
|
32726
|
-
const baseB =
|
|
32725
|
+
const baseA = path20.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
|
|
32726
|
+
const baseB = path20.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
|
|
32727
32727
|
if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
|
|
32728
32728
|
return true;
|
|
32729
32729
|
}
|
|
@@ -32777,8 +32777,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
|
|
|
32777
32777
|
const entries = [];
|
|
32778
32778
|
const now = new Date().toISOString();
|
|
32779
32779
|
for (const pair of pairs.slice(0, 10)) {
|
|
32780
|
-
const baseA =
|
|
32781
|
-
const baseB =
|
|
32780
|
+
const baseA = path20.basename(pair.fileA);
|
|
32781
|
+
const baseB = path20.basename(pair.fileB);
|
|
32782
32782
|
let lesson = `Files ${pair.fileA} and ${pair.fileB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
|
|
32783
32783
|
if (lesson.length > 280) {
|
|
32784
32784
|
lesson = `Files ${baseA} and ${baseB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
|
|
@@ -32887,13 +32887,13 @@ __export(exports_config_doctor, {
|
|
|
32887
32887
|
import * as crypto3 from "crypto";
|
|
32888
32888
|
import * as fs13 from "fs";
|
|
32889
32889
|
import * as os5 from "os";
|
|
32890
|
-
import * as
|
|
32890
|
+
import * as path23 from "path";
|
|
32891
32891
|
function getUserConfigDir3() {
|
|
32892
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
32892
|
+
return process.env.XDG_CONFIG_HOME || path23.join(os5.homedir(), ".config");
|
|
32893
32893
|
}
|
|
32894
32894
|
function getConfigPaths(directory) {
|
|
32895
|
-
const userConfigPath =
|
|
32896
|
-
const projectConfigPath =
|
|
32895
|
+
const userConfigPath = path23.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
32896
|
+
const projectConfigPath = path23.join(directory, ".opencode", "opencode-swarm.json");
|
|
32897
32897
|
return { userConfigPath, projectConfigPath };
|
|
32898
32898
|
}
|
|
32899
32899
|
function computeHash(content) {
|
|
@@ -32918,9 +32918,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
32918
32918
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
32919
32919
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
32920
32920
|
try {
|
|
32921
|
-
const resolvedConfig =
|
|
32922
|
-
const resolvedUser =
|
|
32923
|
-
const resolvedProject =
|
|
32921
|
+
const resolvedConfig = path23.resolve(configPath);
|
|
32922
|
+
const resolvedUser = path23.resolve(normalizedUser);
|
|
32923
|
+
const resolvedProject = path23.resolve(normalizedProject);
|
|
32924
32924
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
32925
32925
|
} catch {
|
|
32926
32926
|
return false;
|
|
@@ -32960,12 +32960,12 @@ function createConfigBackup(directory) {
|
|
|
32960
32960
|
};
|
|
32961
32961
|
}
|
|
32962
32962
|
function writeBackupArtifact(directory, backup) {
|
|
32963
|
-
const swarmDir =
|
|
32963
|
+
const swarmDir = path23.join(directory, ".swarm");
|
|
32964
32964
|
if (!fs13.existsSync(swarmDir)) {
|
|
32965
32965
|
fs13.mkdirSync(swarmDir, { recursive: true });
|
|
32966
32966
|
}
|
|
32967
32967
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
32968
|
-
const backupPath =
|
|
32968
|
+
const backupPath = path23.join(swarmDir, backupFilename);
|
|
32969
32969
|
const artifact = {
|
|
32970
32970
|
createdAt: backup.createdAt,
|
|
32971
32971
|
configPath: backup.configPath,
|
|
@@ -32995,7 +32995,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
32995
32995
|
return null;
|
|
32996
32996
|
}
|
|
32997
32997
|
const targetPath = artifact.configPath;
|
|
32998
|
-
const targetDir =
|
|
32998
|
+
const targetDir = path23.dirname(targetPath);
|
|
32999
32999
|
if (!fs13.existsSync(targetDir)) {
|
|
33000
33000
|
fs13.mkdirSync(targetDir, { recursive: true });
|
|
33001
33001
|
}
|
|
@@ -33026,9 +33026,9 @@ function readConfigFromFile(directory) {
|
|
|
33026
33026
|
return null;
|
|
33027
33027
|
}
|
|
33028
33028
|
}
|
|
33029
|
-
function validateConfigKey(
|
|
33029
|
+
function validateConfigKey(path24, value, _config) {
|
|
33030
33030
|
const findings = [];
|
|
33031
|
-
switch (
|
|
33031
|
+
switch (path24) {
|
|
33032
33032
|
case "agents": {
|
|
33033
33033
|
if (value !== undefined) {
|
|
33034
33034
|
findings.push({
|
|
@@ -33275,27 +33275,27 @@ function validateConfigKey(path23, value, _config) {
|
|
|
33275
33275
|
}
|
|
33276
33276
|
return findings;
|
|
33277
33277
|
}
|
|
33278
|
-
function walkConfigAndValidate(obj,
|
|
33278
|
+
function walkConfigAndValidate(obj, path24, config3, findings) {
|
|
33279
33279
|
if (obj === null || obj === undefined) {
|
|
33280
33280
|
return;
|
|
33281
33281
|
}
|
|
33282
|
-
if (
|
|
33283
|
-
const keyFindings = validateConfigKey(
|
|
33282
|
+
if (path24 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
33283
|
+
const keyFindings = validateConfigKey(path24, obj, config3);
|
|
33284
33284
|
findings.push(...keyFindings);
|
|
33285
33285
|
}
|
|
33286
33286
|
if (typeof obj !== "object") {
|
|
33287
|
-
const keyFindings = validateConfigKey(
|
|
33287
|
+
const keyFindings = validateConfigKey(path24, obj, config3);
|
|
33288
33288
|
findings.push(...keyFindings);
|
|
33289
33289
|
return;
|
|
33290
33290
|
}
|
|
33291
33291
|
if (Array.isArray(obj)) {
|
|
33292
33292
|
obj.forEach((item, index) => {
|
|
33293
|
-
walkConfigAndValidate(item, `${
|
|
33293
|
+
walkConfigAndValidate(item, `${path24}[${index}]`, config3, findings);
|
|
33294
33294
|
});
|
|
33295
33295
|
return;
|
|
33296
33296
|
}
|
|
33297
33297
|
for (const [key, value] of Object.entries(obj)) {
|
|
33298
|
-
const newPath =
|
|
33298
|
+
const newPath = path24 ? `${path24}.${key}` : key;
|
|
33299
33299
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
33300
33300
|
}
|
|
33301
33301
|
}
|
|
@@ -33415,7 +33415,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
33415
33415
|
}
|
|
33416
33416
|
}
|
|
33417
33417
|
if (appliedFixes.length > 0) {
|
|
33418
|
-
const configDir =
|
|
33418
|
+
const configDir = path23.dirname(configPath);
|
|
33419
33419
|
if (!fs13.existsSync(configDir)) {
|
|
33420
33420
|
fs13.mkdirSync(configDir, { recursive: true });
|
|
33421
33421
|
}
|
|
@@ -33425,12 +33425,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
33425
33425
|
return { appliedFixes, updatedConfigPath };
|
|
33426
33426
|
}
|
|
33427
33427
|
function writeDoctorArtifact(directory, result) {
|
|
33428
|
-
const swarmDir =
|
|
33428
|
+
const swarmDir = path23.join(directory, ".swarm");
|
|
33429
33429
|
if (!fs13.existsSync(swarmDir)) {
|
|
33430
33430
|
fs13.mkdirSync(swarmDir, { recursive: true });
|
|
33431
33431
|
}
|
|
33432
33432
|
const artifactFilename = "config-doctor.json";
|
|
33433
|
-
const artifactPath =
|
|
33433
|
+
const artifactPath = path23.join(swarmDir, artifactFilename);
|
|
33434
33434
|
const guiOutput = {
|
|
33435
33435
|
timestamp: result.timestamp,
|
|
33436
33436
|
summary: result.summary,
|
|
@@ -34484,7 +34484,7 @@ var init_detector = __esm(() => {
|
|
|
34484
34484
|
|
|
34485
34485
|
// src/build/discovery.ts
|
|
34486
34486
|
import * as fs14 from "fs";
|
|
34487
|
-
import * as
|
|
34487
|
+
import * as path25 from "path";
|
|
34488
34488
|
function isCommandAvailable(command) {
|
|
34489
34489
|
if (toolchainCache.has(command)) {
|
|
34490
34490
|
return toolchainCache.get(command);
|
|
@@ -34517,11 +34517,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
34517
34517
|
const regex = simpleGlobToRegex(pattern);
|
|
34518
34518
|
const matches = files.filter((f) => regex.test(f));
|
|
34519
34519
|
if (matches.length > 0) {
|
|
34520
|
-
return
|
|
34520
|
+
return path25.join(dir, matches[0]);
|
|
34521
34521
|
}
|
|
34522
34522
|
} catch {}
|
|
34523
34523
|
} else {
|
|
34524
|
-
const filePath =
|
|
34524
|
+
const filePath = path25.join(workingDir, pattern);
|
|
34525
34525
|
if (fs14.existsSync(filePath)) {
|
|
34526
34526
|
return filePath;
|
|
34527
34527
|
}
|
|
@@ -34530,7 +34530,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
34530
34530
|
return null;
|
|
34531
34531
|
}
|
|
34532
34532
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
34533
|
-
const packageJsonPath =
|
|
34533
|
+
const packageJsonPath = path25.join(workingDir, "package.json");
|
|
34534
34534
|
if (!fs14.existsSync(packageJsonPath)) {
|
|
34535
34535
|
return [];
|
|
34536
34536
|
}
|
|
@@ -34571,7 +34571,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
34571
34571
|
const regex = simpleGlobToRegex(pattern);
|
|
34572
34572
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
34573
34573
|
} else {
|
|
34574
|
-
const filePath =
|
|
34574
|
+
const filePath = path25.join(workingDir, pattern);
|
|
34575
34575
|
if (fs14.existsSync(filePath)) {
|
|
34576
34576
|
allBuildFiles.add(filePath);
|
|
34577
34577
|
}
|
|
@@ -34584,7 +34584,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
34584
34584
|
try {
|
|
34585
34585
|
const entries = fs14.readdirSync(dir, { withFileTypes: true });
|
|
34586
34586
|
for (const entry of entries) {
|
|
34587
|
-
const fullPath =
|
|
34587
|
+
const fullPath = path25.join(dir, entry.name);
|
|
34588
34588
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
34589
34589
|
findFilesRecursive(fullPath, regex, results);
|
|
34590
34590
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -34607,7 +34607,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
34607
34607
|
let foundCommand = false;
|
|
34608
34608
|
for (const cmd of sortedCommands) {
|
|
34609
34609
|
if (cmd.detectFile) {
|
|
34610
|
-
const detectFilePath =
|
|
34610
|
+
const detectFilePath = path25.join(workingDir, cmd.detectFile);
|
|
34611
34611
|
if (!fs14.existsSync(detectFilePath)) {
|
|
34612
34612
|
continue;
|
|
34613
34613
|
}
|
|
@@ -34864,7 +34864,7 @@ function validateDirectory(directory) {
|
|
|
34864
34864
|
|
|
34865
34865
|
// src/tools/lint.ts
|
|
34866
34866
|
import * as fs15 from "fs";
|
|
34867
|
-
import * as
|
|
34867
|
+
import * as path26 from "path";
|
|
34868
34868
|
function validateArgs(args2) {
|
|
34869
34869
|
if (typeof args2 !== "object" || args2 === null)
|
|
34870
34870
|
return false;
|
|
@@ -34875,9 +34875,9 @@ function validateArgs(args2) {
|
|
|
34875
34875
|
}
|
|
34876
34876
|
function getLinterCommand(linter, mode, projectDir) {
|
|
34877
34877
|
const isWindows = process.platform === "win32";
|
|
34878
|
-
const binDir =
|
|
34879
|
-
const biomeBin = isWindows ?
|
|
34880
|
-
const eslintBin = isWindows ?
|
|
34878
|
+
const binDir = path26.join(projectDir, "node_modules", ".bin");
|
|
34879
|
+
const biomeBin = isWindows ? path26.join(binDir, "biome.EXE") : path26.join(binDir, "biome");
|
|
34880
|
+
const eslintBin = isWindows ? path26.join(binDir, "eslint.cmd") : path26.join(binDir, "eslint");
|
|
34881
34881
|
switch (linter) {
|
|
34882
34882
|
case "biome":
|
|
34883
34883
|
if (mode === "fix") {
|
|
@@ -34893,7 +34893,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
34893
34893
|
}
|
|
34894
34894
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
34895
34895
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
34896
|
-
const gradlew = fs15.existsSync(
|
|
34896
|
+
const gradlew = fs15.existsSync(path26.join(cwd, gradlewName)) ? path26.join(cwd, gradlewName) : null;
|
|
34897
34897
|
switch (linter) {
|
|
34898
34898
|
case "ruff":
|
|
34899
34899
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -34927,10 +34927,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
34927
34927
|
}
|
|
34928
34928
|
}
|
|
34929
34929
|
function detectRuff(cwd) {
|
|
34930
|
-
if (fs15.existsSync(
|
|
34930
|
+
if (fs15.existsSync(path26.join(cwd, "ruff.toml")))
|
|
34931
34931
|
return isCommandAvailable("ruff");
|
|
34932
34932
|
try {
|
|
34933
|
-
const pyproject =
|
|
34933
|
+
const pyproject = path26.join(cwd, "pyproject.toml");
|
|
34934
34934
|
if (fs15.existsSync(pyproject)) {
|
|
34935
34935
|
const content = fs15.readFileSync(pyproject, "utf-8");
|
|
34936
34936
|
if (content.includes("[tool.ruff]"))
|
|
@@ -34940,19 +34940,19 @@ function detectRuff(cwd) {
|
|
|
34940
34940
|
return false;
|
|
34941
34941
|
}
|
|
34942
34942
|
function detectClippy(cwd) {
|
|
34943
|
-
return fs15.existsSync(
|
|
34943
|
+
return fs15.existsSync(path26.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
34944
34944
|
}
|
|
34945
34945
|
function detectGolangciLint(cwd) {
|
|
34946
|
-
return fs15.existsSync(
|
|
34946
|
+
return fs15.existsSync(path26.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
34947
34947
|
}
|
|
34948
34948
|
function detectCheckstyle(cwd) {
|
|
34949
|
-
const hasMaven = fs15.existsSync(
|
|
34950
|
-
const hasGradle = fs15.existsSync(
|
|
34951
|
-
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs15.existsSync(
|
|
34949
|
+
const hasMaven = fs15.existsSync(path26.join(cwd, "pom.xml"));
|
|
34950
|
+
const hasGradle = fs15.existsSync(path26.join(cwd, "build.gradle")) || fs15.existsSync(path26.join(cwd, "build.gradle.kts"));
|
|
34951
|
+
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs15.existsSync(path26.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
|
|
34952
34952
|
return (hasMaven || hasGradle) && hasBinary;
|
|
34953
34953
|
}
|
|
34954
34954
|
function detectKtlint(cwd) {
|
|
34955
|
-
const hasKotlin = fs15.existsSync(
|
|
34955
|
+
const hasKotlin = fs15.existsSync(path26.join(cwd, "build.gradle.kts")) || fs15.existsSync(path26.join(cwd, "build.gradle")) || (() => {
|
|
34956
34956
|
try {
|
|
34957
34957
|
return fs15.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
34958
34958
|
} catch {
|
|
@@ -34971,11 +34971,11 @@ function detectDotnetFormat(cwd) {
|
|
|
34971
34971
|
}
|
|
34972
34972
|
}
|
|
34973
34973
|
function detectCppcheck(cwd) {
|
|
34974
|
-
if (fs15.existsSync(
|
|
34974
|
+
if (fs15.existsSync(path26.join(cwd, "CMakeLists.txt"))) {
|
|
34975
34975
|
return isCommandAvailable("cppcheck");
|
|
34976
34976
|
}
|
|
34977
34977
|
try {
|
|
34978
|
-
const dirsToCheck = [cwd,
|
|
34978
|
+
const dirsToCheck = [cwd, path26.join(cwd, "src")];
|
|
34979
34979
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
34980
34980
|
try {
|
|
34981
34981
|
return fs15.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
@@ -34989,13 +34989,13 @@ function detectCppcheck(cwd) {
|
|
|
34989
34989
|
}
|
|
34990
34990
|
}
|
|
34991
34991
|
function detectSwiftlint(cwd) {
|
|
34992
|
-
return fs15.existsSync(
|
|
34992
|
+
return fs15.existsSync(path26.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
34993
34993
|
}
|
|
34994
34994
|
function detectDartAnalyze(cwd) {
|
|
34995
|
-
return fs15.existsSync(
|
|
34995
|
+
return fs15.existsSync(path26.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
34996
34996
|
}
|
|
34997
34997
|
function detectRubocop(cwd) {
|
|
34998
|
-
return (fs15.existsSync(
|
|
34998
|
+
return (fs15.existsSync(path26.join(cwd, "Gemfile")) || fs15.existsSync(path26.join(cwd, "gems.rb")) || fs15.existsSync(path26.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
|
|
34999
34999
|
}
|
|
35000
35000
|
function detectAdditionalLinter(cwd) {
|
|
35001
35001
|
if (detectRuff(cwd))
|
|
@@ -35023,10 +35023,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
35023
35023
|
function resolveLinterBinPath(linter, projectDir) {
|
|
35024
35024
|
const isWindows = process.platform === "win32";
|
|
35025
35025
|
const binName = linter === "biome" ? isWindows ? "biome.EXE" : "biome" : isWindows ? "eslint.cmd" : "eslint";
|
|
35026
|
-
const localBin =
|
|
35026
|
+
const localBin = path26.join(projectDir, "node_modules", ".bin", binName);
|
|
35027
35027
|
if (fs15.existsSync(localBin))
|
|
35028
35028
|
return localBin;
|
|
35029
|
-
const ancestor = findBinInAncestors(
|
|
35029
|
+
const ancestor = findBinInAncestors(path26.dirname(projectDir), binName);
|
|
35030
35030
|
if (ancestor)
|
|
35031
35031
|
return ancestor;
|
|
35032
35032
|
const fromPath = findBinInEnvPath(binName);
|
|
@@ -35037,10 +35037,10 @@ function resolveLinterBinPath(linter, projectDir) {
|
|
|
35037
35037
|
function findBinInAncestors(startDir, binName) {
|
|
35038
35038
|
let dir = startDir;
|
|
35039
35039
|
while (true) {
|
|
35040
|
-
const candidate =
|
|
35040
|
+
const candidate = path26.join(dir, "node_modules", ".bin", binName);
|
|
35041
35041
|
if (fs15.existsSync(candidate))
|
|
35042
35042
|
return candidate;
|
|
35043
|
-
const parent =
|
|
35043
|
+
const parent = path26.dirname(dir);
|
|
35044
35044
|
if (parent === dir)
|
|
35045
35045
|
break;
|
|
35046
35046
|
dir = parent;
|
|
@@ -35049,10 +35049,10 @@ function findBinInAncestors(startDir, binName) {
|
|
|
35049
35049
|
}
|
|
35050
35050
|
function findBinInEnvPath(binName) {
|
|
35051
35051
|
const searchPath = process.env.PATH ?? "";
|
|
35052
|
-
for (const dir of searchPath.split(
|
|
35052
|
+
for (const dir of searchPath.split(path26.delimiter)) {
|
|
35053
35053
|
if (!dir)
|
|
35054
35054
|
continue;
|
|
35055
|
-
const candidate =
|
|
35055
|
+
const candidate = path26.join(dir, binName);
|
|
35056
35056
|
if (fs15.existsSync(candidate))
|
|
35057
35057
|
return candidate;
|
|
35058
35058
|
}
|
|
@@ -35065,13 +35065,13 @@ async function detectAvailableLinter(directory) {
|
|
|
35065
35065
|
return null;
|
|
35066
35066
|
const projectDir = directory;
|
|
35067
35067
|
const isWindows = process.platform === "win32";
|
|
35068
|
-
const biomeBin = isWindows ?
|
|
35069
|
-
const eslintBin = isWindows ?
|
|
35068
|
+
const biomeBin = isWindows ? path26.join(projectDir, "node_modules", ".bin", "biome.EXE") : path26.join(projectDir, "node_modules", ".bin", "biome");
|
|
35069
|
+
const eslintBin = isWindows ? path26.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path26.join(projectDir, "node_modules", ".bin", "eslint");
|
|
35070
35070
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
35071
35071
|
if (localResult)
|
|
35072
35072
|
return localResult;
|
|
35073
|
-
const biomeAncestor = findBinInAncestors(
|
|
35074
|
-
const eslintAncestor = findBinInAncestors(
|
|
35073
|
+
const biomeAncestor = findBinInAncestors(path26.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
|
|
35074
|
+
const eslintAncestor = findBinInAncestors(path26.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
|
|
35075
35075
|
if (biomeAncestor || eslintAncestor) {
|
|
35076
35076
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
35077
35077
|
}
|
|
@@ -35286,7 +35286,7 @@ For Rust: rustup component add clippy`
|
|
|
35286
35286
|
|
|
35287
35287
|
// src/tools/secretscan.ts
|
|
35288
35288
|
import * as fs16 from "fs";
|
|
35289
|
-
import * as
|
|
35289
|
+
import * as path27 from "path";
|
|
35290
35290
|
function calculateShannonEntropy(str) {
|
|
35291
35291
|
if (str.length === 0)
|
|
35292
35292
|
return 0;
|
|
@@ -35334,7 +35334,7 @@ function isGlobOrPathPattern(pattern) {
|
|
|
35334
35334
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
35335
35335
|
}
|
|
35336
35336
|
function loadSecretScanIgnore(scanDir) {
|
|
35337
|
-
const ignorePath =
|
|
35337
|
+
const ignorePath = path27.join(scanDir, ".secretscanignore");
|
|
35338
35338
|
try {
|
|
35339
35339
|
if (!fs16.existsSync(ignorePath))
|
|
35340
35340
|
return [];
|
|
@@ -35357,7 +35357,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
35357
35357
|
if (exactNames.has(entry))
|
|
35358
35358
|
return true;
|
|
35359
35359
|
for (const pattern of globPatterns) {
|
|
35360
|
-
if (
|
|
35360
|
+
if (path27.matchesGlob(relPath, pattern))
|
|
35361
35361
|
return true;
|
|
35362
35362
|
}
|
|
35363
35363
|
return false;
|
|
@@ -35378,7 +35378,7 @@ function validateDirectoryInput(dir) {
|
|
|
35378
35378
|
return null;
|
|
35379
35379
|
}
|
|
35380
35380
|
function isBinaryFile(filePath, buffer) {
|
|
35381
|
-
const ext =
|
|
35381
|
+
const ext = path27.extname(filePath).toLowerCase();
|
|
35382
35382
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
35383
35383
|
return true;
|
|
35384
35384
|
}
|
|
@@ -35514,9 +35514,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
35514
35514
|
return false;
|
|
35515
35515
|
}
|
|
35516
35516
|
function isPathWithinScope(realPath, scanDir) {
|
|
35517
|
-
const resolvedScanDir =
|
|
35518
|
-
const resolvedRealPath =
|
|
35519
|
-
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir +
|
|
35517
|
+
const resolvedScanDir = path27.resolve(scanDir);
|
|
35518
|
+
const resolvedRealPath = path27.resolve(realPath);
|
|
35519
|
+
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path27.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
|
|
35520
35520
|
}
|
|
35521
35521
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
35522
35522
|
skippedDirs: 0,
|
|
@@ -35542,8 +35542,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
35542
35542
|
return a.localeCompare(b);
|
|
35543
35543
|
});
|
|
35544
35544
|
for (const entry of entries) {
|
|
35545
|
-
const fullPath =
|
|
35546
|
-
const relPath =
|
|
35545
|
+
const fullPath = path27.join(dir, entry);
|
|
35546
|
+
const relPath = path27.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
35547
35547
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
35548
35548
|
stats.skippedDirs++;
|
|
35549
35549
|
continue;
|
|
@@ -35578,7 +35578,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
35578
35578
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
35579
35579
|
files.push(...subFiles);
|
|
35580
35580
|
} else if (lstat.isFile()) {
|
|
35581
|
-
const ext =
|
|
35581
|
+
const ext = path27.extname(fullPath).toLowerCase();
|
|
35582
35582
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
35583
35583
|
files.push(fullPath);
|
|
35584
35584
|
} else {
|
|
@@ -35836,7 +35836,7 @@ var init_secretscan = __esm(() => {
|
|
|
35836
35836
|
}
|
|
35837
35837
|
}
|
|
35838
35838
|
try {
|
|
35839
|
-
const _scanDirRaw =
|
|
35839
|
+
const _scanDirRaw = path27.resolve(directory);
|
|
35840
35840
|
const scanDir = (() => {
|
|
35841
35841
|
try {
|
|
35842
35842
|
return fs16.realpathSync(_scanDirRaw);
|
|
@@ -35979,7 +35979,7 @@ var init_secretscan = __esm(() => {
|
|
|
35979
35979
|
|
|
35980
35980
|
// src/tools/resolve-working-directory.ts
|
|
35981
35981
|
import * as fs17 from "fs";
|
|
35982
|
-
import * as
|
|
35982
|
+
import * as path28 from "path";
|
|
35983
35983
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
35984
35984
|
if (workingDirectory == null || workingDirectory === "") {
|
|
35985
35985
|
return { success: true, directory: fallbackDirectory };
|
|
@@ -35999,15 +35999,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
35999
35999
|
};
|
|
36000
36000
|
}
|
|
36001
36001
|
}
|
|
36002
|
-
const normalizedDir =
|
|
36003
|
-
const pathParts = normalizedDir.split(
|
|
36002
|
+
const normalizedDir = path28.normalize(workingDirectory);
|
|
36003
|
+
const pathParts = normalizedDir.split(path28.sep);
|
|
36004
36004
|
if (pathParts.includes("..")) {
|
|
36005
36005
|
return {
|
|
36006
36006
|
success: false,
|
|
36007
36007
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
36008
36008
|
};
|
|
36009
36009
|
}
|
|
36010
|
-
const resolvedDir =
|
|
36010
|
+
const resolvedDir = path28.resolve(normalizedDir);
|
|
36011
36011
|
try {
|
|
36012
36012
|
const realPath = fs17.realpathSync(resolvedDir);
|
|
36013
36013
|
return { success: true, directory: realPath };
|
|
@@ -36022,7 +36022,7 @@ var init_resolve_working_directory = () => {};
|
|
|
36022
36022
|
|
|
36023
36023
|
// src/tools/test-runner.ts
|
|
36024
36024
|
import * as fs18 from "fs";
|
|
36025
|
-
import * as
|
|
36025
|
+
import * as path29 from "path";
|
|
36026
36026
|
function isAbsolutePath(str) {
|
|
36027
36027
|
if (str.startsWith("/"))
|
|
36028
36028
|
return true;
|
|
@@ -36087,14 +36087,14 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
36087
36087
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
36088
36088
|
}
|
|
36089
36089
|
function detectGoTest(cwd) {
|
|
36090
|
-
return fs18.existsSync(
|
|
36090
|
+
return fs18.existsSync(path29.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
36091
36091
|
}
|
|
36092
36092
|
function detectJavaMaven(cwd) {
|
|
36093
|
-
return fs18.existsSync(
|
|
36093
|
+
return fs18.existsSync(path29.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
36094
36094
|
}
|
|
36095
36095
|
function detectGradle(cwd) {
|
|
36096
|
-
const hasBuildFile = fs18.existsSync(
|
|
36097
|
-
const hasGradlew = fs18.existsSync(
|
|
36096
|
+
const hasBuildFile = fs18.existsSync(path29.join(cwd, "build.gradle")) || fs18.existsSync(path29.join(cwd, "build.gradle.kts"));
|
|
36097
|
+
const hasGradlew = fs18.existsSync(path29.join(cwd, "gradlew")) || fs18.existsSync(path29.join(cwd, "gradlew.bat"));
|
|
36098
36098
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
36099
36099
|
}
|
|
36100
36100
|
function detectDotnetTest(cwd) {
|
|
@@ -36107,30 +36107,30 @@ function detectDotnetTest(cwd) {
|
|
|
36107
36107
|
}
|
|
36108
36108
|
}
|
|
36109
36109
|
function detectCTest(cwd) {
|
|
36110
|
-
const hasSource = fs18.existsSync(
|
|
36111
|
-
const hasBuildCache = fs18.existsSync(
|
|
36110
|
+
const hasSource = fs18.existsSync(path29.join(cwd, "CMakeLists.txt"));
|
|
36111
|
+
const hasBuildCache = fs18.existsSync(path29.join(cwd, "CMakeCache.txt")) || fs18.existsSync(path29.join(cwd, "build", "CMakeCache.txt"));
|
|
36112
36112
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
36113
36113
|
}
|
|
36114
36114
|
function detectSwiftTest(cwd) {
|
|
36115
|
-
return fs18.existsSync(
|
|
36115
|
+
return fs18.existsSync(path29.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
36116
36116
|
}
|
|
36117
36117
|
function detectDartTest(cwd) {
|
|
36118
|
-
return fs18.existsSync(
|
|
36118
|
+
return fs18.existsSync(path29.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
36119
36119
|
}
|
|
36120
36120
|
function detectRSpec(cwd) {
|
|
36121
|
-
const hasRSpecFile = fs18.existsSync(
|
|
36122
|
-
const hasGemfile = fs18.existsSync(
|
|
36123
|
-
const hasSpecDir = fs18.existsSync(
|
|
36121
|
+
const hasRSpecFile = fs18.existsSync(path29.join(cwd, ".rspec"));
|
|
36122
|
+
const hasGemfile = fs18.existsSync(path29.join(cwd, "Gemfile"));
|
|
36123
|
+
const hasSpecDir = fs18.existsSync(path29.join(cwd, "spec"));
|
|
36124
36124
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
36125
36125
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
36126
36126
|
}
|
|
36127
36127
|
function detectMinitest(cwd) {
|
|
36128
|
-
return fs18.existsSync(
|
|
36128
|
+
return fs18.existsSync(path29.join(cwd, "test")) && (fs18.existsSync(path29.join(cwd, "Gemfile")) || fs18.existsSync(path29.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
36129
36129
|
}
|
|
36130
36130
|
async function detectTestFramework(cwd) {
|
|
36131
36131
|
const baseDir = cwd;
|
|
36132
36132
|
try {
|
|
36133
|
-
const packageJsonPath =
|
|
36133
|
+
const packageJsonPath = path29.join(baseDir, "package.json");
|
|
36134
36134
|
if (fs18.existsSync(packageJsonPath)) {
|
|
36135
36135
|
const content = fs18.readFileSync(packageJsonPath, "utf-8");
|
|
36136
36136
|
const pkg = JSON.parse(content);
|
|
@@ -36151,16 +36151,16 @@ async function detectTestFramework(cwd) {
|
|
|
36151
36151
|
return "jest";
|
|
36152
36152
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
36153
36153
|
return "mocha";
|
|
36154
|
-
if (fs18.existsSync(
|
|
36154
|
+
if (fs18.existsSync(path29.join(baseDir, "bun.lockb")) || fs18.existsSync(path29.join(baseDir, "bun.lock"))) {
|
|
36155
36155
|
if (scripts.test?.includes("bun"))
|
|
36156
36156
|
return "bun";
|
|
36157
36157
|
}
|
|
36158
36158
|
}
|
|
36159
36159
|
} catch {}
|
|
36160
36160
|
try {
|
|
36161
|
-
const pyprojectTomlPath =
|
|
36162
|
-
const setupCfgPath =
|
|
36163
|
-
const requirementsTxtPath =
|
|
36161
|
+
const pyprojectTomlPath = path29.join(baseDir, "pyproject.toml");
|
|
36162
|
+
const setupCfgPath = path29.join(baseDir, "setup.cfg");
|
|
36163
|
+
const requirementsTxtPath = path29.join(baseDir, "requirements.txt");
|
|
36164
36164
|
if (fs18.existsSync(pyprojectTomlPath)) {
|
|
36165
36165
|
const content = fs18.readFileSync(pyprojectTomlPath, "utf-8");
|
|
36166
36166
|
if (content.includes("[tool.pytest"))
|
|
@@ -36180,7 +36180,7 @@ async function detectTestFramework(cwd) {
|
|
|
36180
36180
|
}
|
|
36181
36181
|
} catch {}
|
|
36182
36182
|
try {
|
|
36183
|
-
const cargoTomlPath =
|
|
36183
|
+
const cargoTomlPath = path29.join(baseDir, "Cargo.toml");
|
|
36184
36184
|
if (fs18.existsSync(cargoTomlPath)) {
|
|
36185
36185
|
const content = fs18.readFileSync(cargoTomlPath, "utf-8");
|
|
36186
36186
|
if (content.includes("[dev-dependencies]")) {
|
|
@@ -36191,9 +36191,9 @@ async function detectTestFramework(cwd) {
|
|
|
36191
36191
|
}
|
|
36192
36192
|
} catch {}
|
|
36193
36193
|
try {
|
|
36194
|
-
const pesterConfigPath =
|
|
36195
|
-
const pesterConfigJsonPath =
|
|
36196
|
-
const pesterPs1Path =
|
|
36194
|
+
const pesterConfigPath = path29.join(baseDir, "pester.config.ps1");
|
|
36195
|
+
const pesterConfigJsonPath = path29.join(baseDir, "pester.config.ps1.json");
|
|
36196
|
+
const pesterPs1Path = path29.join(baseDir, "tests.ps1");
|
|
36197
36197
|
if (fs18.existsSync(pesterConfigPath) || fs18.existsSync(pesterConfigJsonPath) || fs18.existsSync(pesterPs1Path)) {
|
|
36198
36198
|
return "pester";
|
|
36199
36199
|
}
|
|
@@ -36226,8 +36226,8 @@ function getTestFilesFromConvention(sourceFiles) {
|
|
|
36226
36226
|
const testFiles = [];
|
|
36227
36227
|
for (const file3 of sourceFiles) {
|
|
36228
36228
|
const normalizedPath = file3.replace(/\\/g, "/");
|
|
36229
|
-
const basename5 =
|
|
36230
|
-
const dirname12 =
|
|
36229
|
+
const basename5 = path29.basename(file3);
|
|
36230
|
+
const dirname12 = path29.dirname(file3);
|
|
36231
36231
|
if (hasCompoundTestExtension(basename5) || basename5.includes(".spec.") || basename5.includes(".test.") || normalizedPath.includes("/__tests__/") || normalizedPath.includes("/tests/") || normalizedPath.includes("/test/")) {
|
|
36232
36232
|
if (!testFiles.includes(file3)) {
|
|
36233
36233
|
testFiles.push(file3);
|
|
@@ -36236,13 +36236,13 @@ function getTestFilesFromConvention(sourceFiles) {
|
|
|
36236
36236
|
}
|
|
36237
36237
|
for (const _pattern of TEST_PATTERNS) {
|
|
36238
36238
|
const nameWithoutExt = basename5.replace(/\.[^.]+$/, "");
|
|
36239
|
-
const ext =
|
|
36239
|
+
const ext = path29.extname(basename5);
|
|
36240
36240
|
const possibleTestFiles = [
|
|
36241
|
-
|
|
36242
|
-
|
|
36243
|
-
|
|
36244
|
-
|
|
36245
|
-
|
|
36241
|
+
path29.join(dirname12, `${nameWithoutExt}.spec${ext}`),
|
|
36242
|
+
path29.join(dirname12, `${nameWithoutExt}.test${ext}`),
|
|
36243
|
+
path29.join(dirname12, "__tests__", `${nameWithoutExt}${ext}`),
|
|
36244
|
+
path29.join(dirname12, "tests", `${nameWithoutExt}${ext}`),
|
|
36245
|
+
path29.join(dirname12, "test", `${nameWithoutExt}${ext}`)
|
|
36246
36246
|
];
|
|
36247
36247
|
for (const testFile of possibleTestFiles) {
|
|
36248
36248
|
if (fs18.existsSync(testFile) && !testFiles.includes(testFile)) {
|
|
@@ -36262,7 +36262,7 @@ async function getTestFilesFromGraph(sourceFiles) {
|
|
|
36262
36262
|
for (const testFile of candidateTestFiles) {
|
|
36263
36263
|
try {
|
|
36264
36264
|
const content = fs18.readFileSync(testFile, "utf-8");
|
|
36265
|
-
const testDir =
|
|
36265
|
+
const testDir = path29.dirname(testFile);
|
|
36266
36266
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
36267
36267
|
let match;
|
|
36268
36268
|
match = importRegex.exec(content);
|
|
@@ -36270,8 +36270,8 @@ async function getTestFilesFromGraph(sourceFiles) {
|
|
|
36270
36270
|
const importPath = match[1];
|
|
36271
36271
|
let resolvedImport;
|
|
36272
36272
|
if (importPath.startsWith(".")) {
|
|
36273
|
-
resolvedImport =
|
|
36274
|
-
const existingExt =
|
|
36273
|
+
resolvedImport = path29.resolve(testDir, importPath);
|
|
36274
|
+
const existingExt = path29.extname(resolvedImport);
|
|
36275
36275
|
if (!existingExt) {
|
|
36276
36276
|
for (const extToTry of [
|
|
36277
36277
|
".ts",
|
|
@@ -36291,12 +36291,12 @@ async function getTestFilesFromGraph(sourceFiles) {
|
|
|
36291
36291
|
} else {
|
|
36292
36292
|
continue;
|
|
36293
36293
|
}
|
|
36294
|
-
const importBasename =
|
|
36295
|
-
const importDir =
|
|
36294
|
+
const importBasename = path29.basename(resolvedImport, path29.extname(resolvedImport));
|
|
36295
|
+
const importDir = path29.dirname(resolvedImport);
|
|
36296
36296
|
for (const sourceFile of sourceFiles) {
|
|
36297
|
-
const sourceDir =
|
|
36298
|
-
const sourceBasename =
|
|
36299
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
36297
|
+
const sourceDir = path29.dirname(sourceFile);
|
|
36298
|
+
const sourceBasename = path29.basename(sourceFile, path29.extname(sourceFile));
|
|
36299
|
+
const isRelatedDir = importDir === sourceDir || importDir === path29.join(sourceDir, "__tests__") || importDir === path29.join(sourceDir, "tests") || importDir === path29.join(sourceDir, "test");
|
|
36300
36300
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
36301
36301
|
if (!testFiles.includes(testFile)) {
|
|
36302
36302
|
testFiles.push(testFile);
|
|
@@ -36311,8 +36311,8 @@ async function getTestFilesFromGraph(sourceFiles) {
|
|
|
36311
36311
|
while (match !== null) {
|
|
36312
36312
|
const importPath = match[1];
|
|
36313
36313
|
if (importPath.startsWith(".")) {
|
|
36314
|
-
let resolvedImport =
|
|
36315
|
-
const existingExt =
|
|
36314
|
+
let resolvedImport = path29.resolve(testDir, importPath);
|
|
36315
|
+
const existingExt = path29.extname(resolvedImport);
|
|
36316
36316
|
if (!existingExt) {
|
|
36317
36317
|
for (const extToTry of [
|
|
36318
36318
|
".ts",
|
|
@@ -36329,12 +36329,12 @@ async function getTestFilesFromGraph(sourceFiles) {
|
|
|
36329
36329
|
}
|
|
36330
36330
|
}
|
|
36331
36331
|
}
|
|
36332
|
-
const importDir =
|
|
36333
|
-
const importBasename =
|
|
36332
|
+
const importDir = path29.dirname(resolvedImport);
|
|
36333
|
+
const importBasename = path29.basename(resolvedImport, path29.extname(resolvedImport));
|
|
36334
36334
|
for (const sourceFile of sourceFiles) {
|
|
36335
|
-
const sourceDir =
|
|
36336
|
-
const sourceBasename =
|
|
36337
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
36335
|
+
const sourceDir = path29.dirname(sourceFile);
|
|
36336
|
+
const sourceBasename = path29.basename(sourceFile, path29.extname(sourceFile));
|
|
36337
|
+
const isRelatedDir = importDir === sourceDir || importDir === path29.join(sourceDir, "__tests__") || importDir === path29.join(sourceDir, "tests") || importDir === path29.join(sourceDir, "test");
|
|
36338
36338
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
36339
36339
|
if (!testFiles.includes(testFile)) {
|
|
36340
36340
|
testFiles.push(testFile);
|
|
@@ -36419,8 +36419,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
|
|
|
36419
36419
|
return ["mvn", "test"];
|
|
36420
36420
|
case "gradle": {
|
|
36421
36421
|
const isWindows = process.platform === "win32";
|
|
36422
|
-
const hasGradlewBat = fs18.existsSync(
|
|
36423
|
-
const hasGradlew = fs18.existsSync(
|
|
36422
|
+
const hasGradlewBat = fs18.existsSync(path29.join(baseDir, "gradlew.bat"));
|
|
36423
|
+
const hasGradlew = fs18.existsSync(path29.join(baseDir, "gradlew"));
|
|
36424
36424
|
if (hasGradlewBat && isWindows)
|
|
36425
36425
|
return ["gradlew.bat", "test"];
|
|
36426
36426
|
if (hasGradlew)
|
|
@@ -36437,7 +36437,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
|
|
|
36437
36437
|
"cmake-build-release",
|
|
36438
36438
|
"out"
|
|
36439
36439
|
];
|
|
36440
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs18.existsSync(
|
|
36440
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs18.existsSync(path29.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
36441
36441
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
36442
36442
|
}
|
|
36443
36443
|
case "swift-test":
|
|
@@ -37005,7 +37005,7 @@ var init_test_runner = __esm(() => {
|
|
|
37005
37005
|
let effectiveScope = scope;
|
|
37006
37006
|
if (scope === "all") {} else if (scope === "convention") {
|
|
37007
37007
|
const sourceFiles = args2.files.filter((f) => {
|
|
37008
|
-
const ext =
|
|
37008
|
+
const ext = path29.extname(f).toLowerCase();
|
|
37009
37009
|
return SOURCE_EXTENSIONS.has(ext);
|
|
37010
37010
|
});
|
|
37011
37011
|
if (sourceFiles.length === 0) {
|
|
@@ -37021,7 +37021,7 @@ var init_test_runner = __esm(() => {
|
|
|
37021
37021
|
testFiles = getTestFilesFromConvention(sourceFiles);
|
|
37022
37022
|
} else if (scope === "graph") {
|
|
37023
37023
|
const sourceFiles = args2.files.filter((f) => {
|
|
37024
|
-
const ext =
|
|
37024
|
+
const ext = path29.extname(f).toLowerCase();
|
|
37025
37025
|
return SOURCE_EXTENSIONS.has(ext);
|
|
37026
37026
|
});
|
|
37027
37027
|
if (sourceFiles.length === 0) {
|
|
@@ -37075,7 +37075,7 @@ var init_test_runner = __esm(() => {
|
|
|
37075
37075
|
|
|
37076
37076
|
// src/services/preflight-service.ts
|
|
37077
37077
|
import * as fs19 from "fs";
|
|
37078
|
-
import * as
|
|
37078
|
+
import * as path30 from "path";
|
|
37079
37079
|
function validateDirectoryPath(dir) {
|
|
37080
37080
|
if (!dir || typeof dir !== "string") {
|
|
37081
37081
|
throw new Error("Directory path is required");
|
|
@@ -37083,8 +37083,8 @@ function validateDirectoryPath(dir) {
|
|
|
37083
37083
|
if (dir.includes("..")) {
|
|
37084
37084
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
37085
37085
|
}
|
|
37086
|
-
const normalized =
|
|
37087
|
-
const absolutePath =
|
|
37086
|
+
const normalized = path30.normalize(dir);
|
|
37087
|
+
const absolutePath = path30.isAbsolute(normalized) ? normalized : path30.resolve(normalized);
|
|
37088
37088
|
return absolutePath;
|
|
37089
37089
|
}
|
|
37090
37090
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -37107,7 +37107,7 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
37107
37107
|
}
|
|
37108
37108
|
function getPackageVersion(dir) {
|
|
37109
37109
|
try {
|
|
37110
|
-
const packagePath =
|
|
37110
|
+
const packagePath = path30.join(dir, "package.json");
|
|
37111
37111
|
if (fs19.existsSync(packagePath)) {
|
|
37112
37112
|
const content = fs19.readFileSync(packagePath, "utf-8");
|
|
37113
37113
|
const pkg = JSON.parse(content);
|
|
@@ -37118,7 +37118,7 @@ function getPackageVersion(dir) {
|
|
|
37118
37118
|
}
|
|
37119
37119
|
function getChangelogVersion(dir) {
|
|
37120
37120
|
try {
|
|
37121
|
-
const changelogPath =
|
|
37121
|
+
const changelogPath = path30.join(dir, "CHANGELOG.md");
|
|
37122
37122
|
if (fs19.existsSync(changelogPath)) {
|
|
37123
37123
|
const content = fs19.readFileSync(changelogPath, "utf-8");
|
|
37124
37124
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
@@ -37132,7 +37132,7 @@ function getChangelogVersion(dir) {
|
|
|
37132
37132
|
function getVersionFileVersion(dir) {
|
|
37133
37133
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
37134
37134
|
for (const file3 of possibleFiles) {
|
|
37135
|
-
const filePath =
|
|
37135
|
+
const filePath = path30.join(dir, file3);
|
|
37136
37136
|
if (fs19.existsSync(filePath)) {
|
|
37137
37137
|
try {
|
|
37138
37138
|
const content = fs19.readFileSync(filePath, "utf-8").trim();
|
|
@@ -37660,7 +37660,7 @@ __export(exports_gate_evidence, {
|
|
|
37660
37660
|
DEFAULT_REQUIRED_GATES: () => DEFAULT_REQUIRED_GATES
|
|
37661
37661
|
});
|
|
37662
37662
|
import { mkdirSync as mkdirSync12, readFileSync as readFileSync17, renameSync as renameSync10, unlinkSync as unlinkSync5 } from "fs";
|
|
37663
|
-
import * as
|
|
37663
|
+
import * as path37 from "path";
|
|
37664
37664
|
function isValidTaskId2(taskId) {
|
|
37665
37665
|
if (!taskId)
|
|
37666
37666
|
return false;
|
|
@@ -37707,10 +37707,10 @@ function expandRequiredGates(existingGates, newAgentType) {
|
|
|
37707
37707
|
return combined.sort();
|
|
37708
37708
|
}
|
|
37709
37709
|
function getEvidenceDir(directory) {
|
|
37710
|
-
return
|
|
37710
|
+
return path37.join(directory, ".swarm", "evidence");
|
|
37711
37711
|
}
|
|
37712
37712
|
function getEvidencePath(directory, taskId) {
|
|
37713
|
-
return
|
|
37713
|
+
return path37.join(getEvidenceDir(directory), `${taskId}.json`);
|
|
37714
37714
|
}
|
|
37715
37715
|
function readExisting(evidencePath) {
|
|
37716
37716
|
try {
|
|
@@ -37821,12 +37821,12 @@ __export(exports_review_receipt, {
|
|
|
37821
37821
|
});
|
|
37822
37822
|
import * as crypto5 from "crypto";
|
|
37823
37823
|
import * as fs28 from "fs";
|
|
37824
|
-
import * as
|
|
37824
|
+
import * as path39 from "path";
|
|
37825
37825
|
function resolveReceiptsDir(directory) {
|
|
37826
|
-
return
|
|
37826
|
+
return path39.join(directory, ".swarm", "review-receipts");
|
|
37827
37827
|
}
|
|
37828
37828
|
function resolveReceiptIndexPath(directory) {
|
|
37829
|
-
return
|
|
37829
|
+
return path39.join(resolveReceiptsDir(directory), "index.json");
|
|
37830
37830
|
}
|
|
37831
37831
|
function buildReceiptFilename(id, date9) {
|
|
37832
37832
|
const dateStr = date9.toISOString().slice(0, 10);
|
|
@@ -37865,7 +37865,7 @@ async function readReceiptIndex(directory) {
|
|
|
37865
37865
|
}
|
|
37866
37866
|
async function writeReceiptIndex(directory, index) {
|
|
37867
37867
|
const indexPath = resolveReceiptIndexPath(directory);
|
|
37868
|
-
const dir =
|
|
37868
|
+
const dir = path39.dirname(indexPath);
|
|
37869
37869
|
await fs28.promises.mkdir(dir, { recursive: true });
|
|
37870
37870
|
const tmpPath = `${indexPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
37871
37871
|
await fs28.promises.writeFile(tmpPath, JSON.stringify(index, null, 2), "utf-8");
|
|
@@ -37876,7 +37876,7 @@ async function persistReviewReceipt(directory, receipt) {
|
|
|
37876
37876
|
await fs28.promises.mkdir(receiptsDir, { recursive: true });
|
|
37877
37877
|
const now = new Date(receipt.reviewed_at);
|
|
37878
37878
|
const filename = buildReceiptFilename(receipt.id, now);
|
|
37879
|
-
const receiptPath =
|
|
37879
|
+
const receiptPath = path39.join(receiptsDir, filename);
|
|
37880
37880
|
const tmpPath = `${receiptPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
37881
37881
|
await fs28.promises.writeFile(tmpPath, JSON.stringify(receipt, null, 2), "utf-8");
|
|
37882
37882
|
fs28.renameSync(tmpPath, receiptPath);
|
|
@@ -37898,7 +37898,7 @@ async function readReceiptById(directory, receiptId) {
|
|
|
37898
37898
|
const entry = index.entries.find((e) => e.id === receiptId);
|
|
37899
37899
|
if (!entry)
|
|
37900
37900
|
return null;
|
|
37901
|
-
const receiptPath =
|
|
37901
|
+
const receiptPath = path39.join(resolveReceiptsDir(directory), entry.filename);
|
|
37902
37902
|
try {
|
|
37903
37903
|
const content = await fs28.promises.readFile(receiptPath, "utf-8");
|
|
37904
37904
|
return JSON.parse(content);
|
|
@@ -37911,7 +37911,7 @@ async function readReceiptsByScopeHash(directory, scopeHash) {
|
|
|
37911
37911
|
const matching = index.entries.filter((e) => e.scope_hash === scopeHash).sort((a, b) => b.reviewed_at.localeCompare(a.reviewed_at));
|
|
37912
37912
|
const receipts = [];
|
|
37913
37913
|
for (const entry of matching) {
|
|
37914
|
-
const receiptPath =
|
|
37914
|
+
const receiptPath = path39.join(resolveReceiptsDir(directory), entry.filename);
|
|
37915
37915
|
try {
|
|
37916
37916
|
const content = await fs28.promises.readFile(receiptPath, "utf-8");
|
|
37917
37917
|
receipts.push(JSON.parse(content));
|
|
@@ -37924,7 +37924,7 @@ async function readAllReceipts(directory) {
|
|
|
37924
37924
|
const sorted = [...index.entries].sort((a, b) => b.reviewed_at.localeCompare(a.reviewed_at));
|
|
37925
37925
|
const receipts = [];
|
|
37926
37926
|
for (const entry of sorted) {
|
|
37927
|
-
const receiptPath =
|
|
37927
|
+
const receiptPath = path39.join(resolveReceiptsDir(directory), entry.filename);
|
|
37928
37928
|
try {
|
|
37929
37929
|
const content = await fs28.promises.readFile(receiptPath, "utf-8");
|
|
37930
37930
|
receipts.push(JSON.parse(content));
|
|
@@ -38060,13 +38060,13 @@ __export(exports_doc_scan, {
|
|
|
38060
38060
|
import * as crypto6 from "crypto";
|
|
38061
38061
|
import * as fs31 from "fs";
|
|
38062
38062
|
import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
|
|
38063
|
-
import * as
|
|
38063
|
+
import * as path43 from "path";
|
|
38064
38064
|
function normalizeSeparators(filePath) {
|
|
38065
38065
|
return filePath.replace(/\\/g, "/");
|
|
38066
38066
|
}
|
|
38067
38067
|
function matchesDocPattern(filePath, patterns) {
|
|
38068
38068
|
const normalizedPath = normalizeSeparators(filePath);
|
|
38069
|
-
const basename6 =
|
|
38069
|
+
const basename6 = path43.basename(filePath);
|
|
38070
38070
|
for (const pattern of patterns) {
|
|
38071
38071
|
if (!pattern.includes("/") && !pattern.includes("\\")) {
|
|
38072
38072
|
if (basename6 === pattern) {
|
|
@@ -38122,7 +38122,7 @@ function stripMarkdown(text) {
|
|
|
38122
38122
|
return text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s*[-*\u2022]\s+/gm, "").replace(/^\s*\d+\.\s+/gm, "").trim();
|
|
38123
38123
|
}
|
|
38124
38124
|
async function scanDocIndex(directory) {
|
|
38125
|
-
const manifestPath =
|
|
38125
|
+
const manifestPath = path43.join(directory, ".swarm", "doc-manifest.json");
|
|
38126
38126
|
const defaultPatterns = DocsConfigSchema.parse({}).doc_patterns;
|
|
38127
38127
|
const extraPatterns = [
|
|
38128
38128
|
"ARCHITECTURE.md",
|
|
@@ -38139,7 +38139,7 @@ async function scanDocIndex(directory) {
|
|
|
38139
38139
|
let cacheValid = true;
|
|
38140
38140
|
for (const file3 of existingManifest.files) {
|
|
38141
38141
|
try {
|
|
38142
|
-
const fullPath =
|
|
38142
|
+
const fullPath = path43.join(directory, file3.path);
|
|
38143
38143
|
const stat2 = fs31.statSync(fullPath);
|
|
38144
38144
|
if (stat2.mtimeMs > new Date(existingManifest.scanned_at).getTime()) {
|
|
38145
38145
|
cacheValid = false;
|
|
@@ -38169,7 +38169,7 @@ async function scanDocIndex(directory) {
|
|
|
38169
38169
|
}
|
|
38170
38170
|
const entries = rawEntries.filter((e) => typeof e === "string");
|
|
38171
38171
|
for (const entry of entries) {
|
|
38172
|
-
const fullPath =
|
|
38172
|
+
const fullPath = path43.join(directory, entry);
|
|
38173
38173
|
let stat2;
|
|
38174
38174
|
try {
|
|
38175
38175
|
stat2 = fs31.statSync(fullPath);
|
|
@@ -38205,7 +38205,7 @@ async function scanDocIndex(directory) {
|
|
|
38205
38205
|
} catch {
|
|
38206
38206
|
continue;
|
|
38207
38207
|
}
|
|
38208
|
-
const { title, summary } = extractTitleAndSummary(content,
|
|
38208
|
+
const { title, summary } = extractTitleAndSummary(content, path43.basename(entry));
|
|
38209
38209
|
const lineCount = content.split(`
|
|
38210
38210
|
`).length;
|
|
38211
38211
|
discoveredFiles.push({
|
|
@@ -38231,7 +38231,7 @@ async function scanDocIndex(directory) {
|
|
|
38231
38231
|
files: discoveredFiles
|
|
38232
38232
|
};
|
|
38233
38233
|
try {
|
|
38234
|
-
await mkdir6(
|
|
38234
|
+
await mkdir6(path43.dirname(manifestPath), { recursive: true });
|
|
38235
38235
|
await writeFile5(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
38236
38236
|
} catch {}
|
|
38237
38237
|
return { manifest, cached: false };
|
|
@@ -38270,7 +38270,7 @@ function extractConstraintsFromContent(content) {
|
|
|
38270
38270
|
return constraints;
|
|
38271
38271
|
}
|
|
38272
38272
|
async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
38273
|
-
const manifestPath =
|
|
38273
|
+
const manifestPath = path43.join(directory, ".swarm", "doc-manifest.json");
|
|
38274
38274
|
let manifest;
|
|
38275
38275
|
try {
|
|
38276
38276
|
const content = await readFile6(manifestPath, "utf-8");
|
|
@@ -38296,7 +38296,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
38296
38296
|
}
|
|
38297
38297
|
let fullContent;
|
|
38298
38298
|
try {
|
|
38299
|
-
fullContent = await readFile6(
|
|
38299
|
+
fullContent = await readFile6(path43.join(directory, docFile.path), "utf-8");
|
|
38300
38300
|
} catch {
|
|
38301
38301
|
skippedCount++;
|
|
38302
38302
|
continue;
|
|
@@ -38319,7 +38319,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
38319
38319
|
tier: "swarm",
|
|
38320
38320
|
lesson: constraint,
|
|
38321
38321
|
category: "architecture",
|
|
38322
|
-
tags: ["doc-scan",
|
|
38322
|
+
tags: ["doc-scan", path43.basename(docFile.path)],
|
|
38323
38323
|
scope: "global",
|
|
38324
38324
|
confidence: 0.5,
|
|
38325
38325
|
status: "candidate",
|
|
@@ -38392,7 +38392,7 @@ var init_doc_scan = __esm(() => {
|
|
|
38392
38392
|
}
|
|
38393
38393
|
} catch {}
|
|
38394
38394
|
if (force) {
|
|
38395
|
-
const manifestPath =
|
|
38395
|
+
const manifestPath = path43.join(directory, ".swarm", "doc-manifest.json");
|
|
38396
38396
|
try {
|
|
38397
38397
|
fs31.unlinkSync(manifestPath);
|
|
38398
38398
|
} catch {}
|
|
@@ -38447,9 +38447,9 @@ __export(exports_curator_drift, {
|
|
|
38447
38447
|
buildDriftInjectionText: () => buildDriftInjectionText
|
|
38448
38448
|
});
|
|
38449
38449
|
import * as fs34 from "fs";
|
|
38450
|
-
import * as
|
|
38450
|
+
import * as path46 from "path";
|
|
38451
38451
|
async function readPriorDriftReports(directory) {
|
|
38452
|
-
const swarmDir =
|
|
38452
|
+
const swarmDir = path46.join(directory, ".swarm");
|
|
38453
38453
|
const entries = await fs34.promises.readdir(swarmDir).catch(() => null);
|
|
38454
38454
|
if (entries === null)
|
|
38455
38455
|
return [];
|
|
@@ -38476,7 +38476,7 @@ async function readPriorDriftReports(directory) {
|
|
|
38476
38476
|
async function writeDriftReport(directory, report) {
|
|
38477
38477
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
38478
38478
|
const filePath = validateSwarmPath(directory, filename);
|
|
38479
|
-
const swarmDir =
|
|
38479
|
+
const swarmDir = path46.dirname(filePath);
|
|
38480
38480
|
await fs34.promises.mkdir(swarmDir, { recursive: true });
|
|
38481
38481
|
try {
|
|
38482
38482
|
await fs34.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
@@ -40069,11 +40069,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
40069
40069
|
throw toThrow;
|
|
40070
40070
|
}, "quit_");
|
|
40071
40071
|
var scriptDirectory = "";
|
|
40072
|
-
function locateFile(
|
|
40072
|
+
function locateFile(path56) {
|
|
40073
40073
|
if (Module["locateFile"]) {
|
|
40074
|
-
return Module["locateFile"](
|
|
40074
|
+
return Module["locateFile"](path56, scriptDirectory);
|
|
40075
40075
|
}
|
|
40076
|
-
return scriptDirectory +
|
|
40076
|
+
return scriptDirectory + path56;
|
|
40077
40077
|
}
|
|
40078
40078
|
__name(locateFile, "locateFile");
|
|
40079
40079
|
var readAsync, readBinary;
|
|
@@ -41813,13 +41813,13 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
41813
41813
|
});
|
|
41814
41814
|
|
|
41815
41815
|
// src/lang/runtime.ts
|
|
41816
|
-
import * as
|
|
41816
|
+
import * as path56 from "path";
|
|
41817
41817
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
41818
41818
|
async function initTreeSitter() {
|
|
41819
41819
|
if (treeSitterInitialized) {
|
|
41820
41820
|
return;
|
|
41821
41821
|
}
|
|
41822
|
-
const thisDir =
|
|
41822
|
+
const thisDir = path56.dirname(fileURLToPath2(import.meta.url));
|
|
41823
41823
|
const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
|
|
41824
41824
|
if (isSource) {
|
|
41825
41825
|
await Parser.init();
|
|
@@ -41827,7 +41827,7 @@ async function initTreeSitter() {
|
|
|
41827
41827
|
const grammarsDir = getGrammarsDirAbsolute();
|
|
41828
41828
|
await Parser.init({
|
|
41829
41829
|
locateFile(scriptName) {
|
|
41830
|
-
return
|
|
41830
|
+
return path56.join(grammarsDir, scriptName);
|
|
41831
41831
|
}
|
|
41832
41832
|
});
|
|
41833
41833
|
}
|
|
@@ -41848,9 +41848,9 @@ function getWasmFileName(languageId) {
|
|
|
41848
41848
|
return `tree-sitter-${sanitized}.wasm`;
|
|
41849
41849
|
}
|
|
41850
41850
|
function getGrammarsDirAbsolute() {
|
|
41851
|
-
const thisDir =
|
|
41851
|
+
const thisDir = path56.dirname(fileURLToPath2(import.meta.url));
|
|
41852
41852
|
const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
|
|
41853
|
-
return isSource ?
|
|
41853
|
+
return isSource ? path56.join(thisDir, "grammars") : path56.join(thisDir, "lang", "grammars");
|
|
41854
41854
|
}
|
|
41855
41855
|
async function loadGrammar(languageId) {
|
|
41856
41856
|
if (typeof languageId !== "string" || languageId.length > 100) {
|
|
@@ -41866,7 +41866,7 @@ async function loadGrammar(languageId) {
|
|
|
41866
41866
|
await initTreeSitter();
|
|
41867
41867
|
const parser = new Parser;
|
|
41868
41868
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
41869
|
-
const wasmPath =
|
|
41869
|
+
const wasmPath = path56.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
41870
41870
|
const { existsSync: existsSync33 } = await import("fs");
|
|
41871
41871
|
if (!existsSync33(wasmPath)) {
|
|
41872
41872
|
throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
|
|
@@ -41913,7 +41913,7 @@ var init_runtime = __esm(() => {
|
|
|
41913
41913
|
});
|
|
41914
41914
|
|
|
41915
41915
|
// src/index.ts
|
|
41916
|
-
import * as
|
|
41916
|
+
import * as path74 from "path";
|
|
41917
41917
|
|
|
41918
41918
|
// src/agents/index.ts
|
|
41919
41919
|
init_config();
|
|
@@ -46680,7 +46680,9 @@ async function handleClarifyCommand(_directory, args2) {
|
|
|
46680
46680
|
// src/commands/close.ts
|
|
46681
46681
|
init_schema();
|
|
46682
46682
|
init_manager();
|
|
46683
|
+
import { execFileSync } from "child_process";
|
|
46683
46684
|
import { promises as fs11 } from "fs";
|
|
46685
|
+
import path17 from "path";
|
|
46684
46686
|
|
|
46685
46687
|
// src/hooks/knowledge-reader.ts
|
|
46686
46688
|
init_knowledge_store();
|
|
@@ -48065,87 +48067,183 @@ var write_retro = createSwarmTool({
|
|
|
48065
48067
|
});
|
|
48066
48068
|
|
|
48067
48069
|
// src/commands/close.ts
|
|
48068
|
-
async function handleCloseCommand(directory,
|
|
48070
|
+
async function handleCloseCommand(directory, args2) {
|
|
48069
48071
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
48070
|
-
let
|
|
48072
|
+
let planExists = false;
|
|
48073
|
+
let planData = {
|
|
48074
|
+
title: path17.basename(directory) || "Ad-hoc session",
|
|
48075
|
+
phases: []
|
|
48076
|
+
};
|
|
48071
48077
|
try {
|
|
48072
48078
|
const content = await fs11.readFile(planPath, "utf-8");
|
|
48073
48079
|
planData = JSON.parse(content);
|
|
48080
|
+
planExists = true;
|
|
48074
48081
|
} catch (error93) {
|
|
48075
|
-
|
|
48082
|
+
if (error93?.code !== "ENOENT") {
|
|
48083
|
+
return `\u274C Failed to read plan.json: ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
48084
|
+
}
|
|
48085
|
+
const swarmDirExists = await fs11.access(path17.join(directory, ".swarm")).then(() => true).catch(() => false);
|
|
48086
|
+
if (!swarmDirExists) {
|
|
48087
|
+
return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
|
|
48088
|
+
}
|
|
48076
48089
|
}
|
|
48077
48090
|
const phases = planData.phases ?? [];
|
|
48078
48091
|
const inProgressPhases = phases.filter((p) => p.status === "in_progress");
|
|
48079
|
-
|
|
48080
|
-
if (
|
|
48081
|
-
|
|
48082
|
-
const blockedCount = phases.filter((p) => p.status === "blocked").length;
|
|
48083
|
-
const completeCount = phases.filter((p) => p.status === "complete" || p.status === "completed").length;
|
|
48084
|
-
return `\u2139\uFE0F Swarm already closed. ${completeCount} phases complete, ${closedCount} phases closed, ${blockedCount} phases blocked. No action taken.`;
|
|
48092
|
+
let planAlreadyDone = false;
|
|
48093
|
+
if (planExists) {
|
|
48094
|
+
planAlreadyDone = phases.length > 0 && phases.every((p) => p.status === "complete" || p.status === "completed" || p.status === "blocked" || p.status === "closed");
|
|
48085
48095
|
}
|
|
48086
48096
|
const config3 = KnowledgeConfigSchema.parse({});
|
|
48087
48097
|
const projectName = planData.title ?? "Unknown Project";
|
|
48088
48098
|
const closedPhases = [];
|
|
48089
48099
|
const closedTasks = [];
|
|
48090
48100
|
const warnings = [];
|
|
48091
|
-
|
|
48092
|
-
|
|
48093
|
-
|
|
48094
|
-
|
|
48095
|
-
|
|
48096
|
-
|
|
48097
|
-
|
|
48098
|
-
|
|
48099
|
-
|
|
48100
|
-
|
|
48101
|
-
|
|
48102
|
-
|
|
48103
|
-
|
|
48104
|
-
|
|
48105
|
-
|
|
48106
|
-
|
|
48107
|
-
|
|
48108
|
-
|
|
48101
|
+
if (!planAlreadyDone) {
|
|
48102
|
+
for (const phase of inProgressPhases) {
|
|
48103
|
+
closedPhases.push(phase.id);
|
|
48104
|
+
let retroResult;
|
|
48105
|
+
try {
|
|
48106
|
+
retroResult = await executeWriteRetro({
|
|
48107
|
+
phase: phase.id,
|
|
48108
|
+
summary: "Phase closed via /swarm close",
|
|
48109
|
+
task_count: Math.max(1, (phase.tasks ?? []).length),
|
|
48110
|
+
task_complexity: "simple",
|
|
48111
|
+
total_tool_calls: 0,
|
|
48112
|
+
coder_revisions: 0,
|
|
48113
|
+
reviewer_rejections: 0,
|
|
48114
|
+
test_failures: 0,
|
|
48115
|
+
security_findings: 0,
|
|
48116
|
+
integration_issues: 0
|
|
48117
|
+
}, directory);
|
|
48118
|
+
} catch (retroError) {
|
|
48119
|
+
warnings.push(`Retrospective write threw for phase ${phase.id}: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
|
|
48120
|
+
}
|
|
48121
|
+
if (retroResult !== undefined) {
|
|
48122
|
+
try {
|
|
48123
|
+
const parsed = JSON.parse(retroResult);
|
|
48124
|
+
if (parsed.success !== true) {
|
|
48125
|
+
warnings.push(`Retrospective write failed for phase ${phase.id}`);
|
|
48126
|
+
}
|
|
48127
|
+
} catch {}
|
|
48109
48128
|
}
|
|
48110
|
-
|
|
48111
|
-
|
|
48112
|
-
|
|
48113
|
-
|
|
48129
|
+
for (const task of phase.tasks ?? []) {
|
|
48130
|
+
if (task.status !== "completed" && task.status !== "complete") {
|
|
48131
|
+
closedTasks.push(task.id);
|
|
48132
|
+
}
|
|
48114
48133
|
}
|
|
48115
48134
|
}
|
|
48116
48135
|
}
|
|
48136
|
+
const lessonsFilePath = path17.join(directory, ".swarm", "close-lessons.md");
|
|
48137
|
+
let explicitLessons = [];
|
|
48138
|
+
try {
|
|
48139
|
+
const lessonsText = await fs11.readFile(lessonsFilePath, "utf-8");
|
|
48140
|
+
explicitLessons = lessonsText.split(`
|
|
48141
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
48142
|
+
} catch {}
|
|
48143
|
+
let curationSucceeded = false;
|
|
48117
48144
|
try {
|
|
48118
|
-
await curateAndStoreSwarm(
|
|
48145
|
+
await curateAndStoreSwarm(explicitLessons, projectName, { phase_number: 0 }, directory, config3);
|
|
48146
|
+
curationSucceeded = true;
|
|
48119
48147
|
} catch (error93) {
|
|
48120
48148
|
console.warn("[close-command] curateAndStoreSwarm error:", error93);
|
|
48121
48149
|
}
|
|
48122
|
-
|
|
48123
|
-
|
|
48124
|
-
|
|
48125
|
-
|
|
48126
|
-
|
|
48150
|
+
if (curationSucceeded && explicitLessons.length > 0) {
|
|
48151
|
+
await fs11.unlink(lessonsFilePath).catch(() => {});
|
|
48152
|
+
}
|
|
48153
|
+
if (planExists && !planAlreadyDone) {
|
|
48154
|
+
for (const phase of phases) {
|
|
48155
|
+
if (phase.status !== "complete" && phase.status !== "completed") {
|
|
48156
|
+
phase.status = "closed";
|
|
48157
|
+
if (!closedPhases.includes(phase.id)) {
|
|
48158
|
+
closedPhases.push(phase.id);
|
|
48159
|
+
}
|
|
48127
48160
|
}
|
|
48128
|
-
|
|
48129
|
-
|
|
48130
|
-
|
|
48131
|
-
|
|
48132
|
-
|
|
48133
|
-
|
|
48161
|
+
for (const task of phase.tasks ?? []) {
|
|
48162
|
+
if (task.status !== "completed" && task.status !== "complete") {
|
|
48163
|
+
task.status = "closed";
|
|
48164
|
+
if (!closedTasks.includes(task.id)) {
|
|
48165
|
+
closedTasks.push(task.id);
|
|
48166
|
+
}
|
|
48134
48167
|
}
|
|
48135
48168
|
}
|
|
48136
48169
|
}
|
|
48170
|
+
try {
|
|
48171
|
+
await fs11.writeFile(planPath, JSON.stringify(planData, null, 2), "utf-8");
|
|
48172
|
+
} catch (error93) {
|
|
48173
|
+
console.warn("[close-command] Failed to write plan.json:", error93);
|
|
48174
|
+
}
|
|
48137
48175
|
}
|
|
48138
48176
|
try {
|
|
48139
|
-
await
|
|
48177
|
+
await archiveEvidence(directory, 30, 10);
|
|
48140
48178
|
} catch (error93) {
|
|
48141
|
-
console.warn("[close-command]
|
|
48179
|
+
console.warn("[close-command] archiveEvidence error:", error93);
|
|
48142
48180
|
}
|
|
48181
|
+
const swarmDir = path17.join(directory, ".swarm");
|
|
48182
|
+
let configBackupsRemoved = 0;
|
|
48143
48183
|
try {
|
|
48144
|
-
await
|
|
48184
|
+
const swarmFiles = await fs11.readdir(swarmDir);
|
|
48185
|
+
const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
|
|
48186
|
+
for (const backup of configBackups) {
|
|
48187
|
+
try {
|
|
48188
|
+
await fs11.unlink(path17.join(swarmDir, backup));
|
|
48189
|
+
configBackupsRemoved++;
|
|
48190
|
+
} catch {}
|
|
48191
|
+
}
|
|
48192
|
+
} catch {}
|
|
48193
|
+
const contextPath = path17.join(directory, ".swarm", "context.md");
|
|
48194
|
+
const contextContent = [
|
|
48195
|
+
"# Context",
|
|
48196
|
+
"",
|
|
48197
|
+
"## Status",
|
|
48198
|
+
`Session closed after: ${projectName}`,
|
|
48199
|
+
`Closed: ${new Date().toISOString()}`,
|
|
48200
|
+
"No active plan. Next session starts fresh.",
|
|
48201
|
+
""
|
|
48202
|
+
].join(`
|
|
48203
|
+
`);
|
|
48204
|
+
try {
|
|
48205
|
+
await fs11.writeFile(contextPath, contextContent, "utf-8");
|
|
48145
48206
|
} catch (error93) {
|
|
48146
|
-
console.warn("[close-command]
|
|
48207
|
+
console.warn("[close-command] Failed to write context.md:", error93);
|
|
48208
|
+
}
|
|
48209
|
+
const pruneBranches = args2.includes("--prune-branches");
|
|
48210
|
+
const prunedBranches = [];
|
|
48211
|
+
const pruneErrors = [];
|
|
48212
|
+
if (pruneBranches) {
|
|
48213
|
+
try {
|
|
48214
|
+
const branchOutput = execFileSync("git", ["branch", "-vv"], {
|
|
48215
|
+
cwd: directory,
|
|
48216
|
+
encoding: "utf-8",
|
|
48217
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
48218
|
+
});
|
|
48219
|
+
const goneBranches = branchOutput.split(`
|
|
48220
|
+
`).filter((line) => line.includes(": gone]")).map((line) => line.trim().replace(/^[*+]\s+/, "").split(/\s+/)[0]).filter(Boolean);
|
|
48221
|
+
for (const branch of goneBranches) {
|
|
48222
|
+
try {
|
|
48223
|
+
execFileSync("git", ["branch", "-d", branch], {
|
|
48224
|
+
cwd: directory,
|
|
48225
|
+
encoding: "utf-8",
|
|
48226
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
48227
|
+
});
|
|
48228
|
+
prunedBranches.push(branch);
|
|
48229
|
+
} catch {
|
|
48230
|
+
pruneErrors.push(branch);
|
|
48231
|
+
}
|
|
48232
|
+
}
|
|
48233
|
+
} catch {}
|
|
48147
48234
|
}
|
|
48148
48235
|
const closeSummaryPath = validateSwarmPath(directory, "close-summary.md");
|
|
48236
|
+
const actionsPerformed = [
|
|
48237
|
+
...!planAlreadyDone && inProgressPhases.length > 0 ? ["- Wrote retrospectives for in-progress phases"] : [],
|
|
48238
|
+
"- Archived evidence bundles",
|
|
48239
|
+
"- Reset context.md for next session",
|
|
48240
|
+
...configBackupsRemoved > 0 ? [`- Removed ${configBackupsRemoved} stale config backup file(s)`] : [],
|
|
48241
|
+
...prunedBranches.length > 0 ? [
|
|
48242
|
+
`- Pruned ${prunedBranches.length} stale local git branch(es): ${prunedBranches.join(", ")}`
|
|
48243
|
+
] : [],
|
|
48244
|
+
"- Cleared agent sessions and delegation chains",
|
|
48245
|
+
...planExists && !planAlreadyDone ? ["- Set non-completed phases/tasks to closed status"] : []
|
|
48246
|
+
];
|
|
48149
48247
|
const summaryContent = [
|
|
48150
48248
|
"# Swarm Close Summary",
|
|
48151
48249
|
"",
|
|
@@ -48153,18 +48251,15 @@ async function handleCloseCommand(directory, _args) {
|
|
|
48153
48251
|
`**Closed:** ${new Date().toISOString()}`,
|
|
48154
48252
|
"",
|
|
48155
48253
|
`## Phases Closed: ${closedPhases.length}`,
|
|
48156
|
-
closedPhases.map((id) => `- Phase ${id}`).join(`
|
|
48157
|
-
`),
|
|
48254
|
+
!planExists ? "_No plan \u2014 ad-hoc session_" : closedPhases.length > 0 ? closedPhases.map((id) => `- Phase ${id}`).join(`
|
|
48255
|
+
`) : "_No phases to close_",
|
|
48158
48256
|
"",
|
|
48159
48257
|
`## Tasks Closed: ${closedTasks.length}`,
|
|
48160
48258
|
closedTasks.length > 0 ? closedTasks.map((id) => `- ${id}`).join(`
|
|
48161
48259
|
`) : "_No incomplete tasks_",
|
|
48162
48260
|
"",
|
|
48163
48261
|
"## Actions Performed",
|
|
48164
|
-
|
|
48165
|
-
"- Archived evidence bundles",
|
|
48166
|
-
"- Cleared agent sessions and delegation chains",
|
|
48167
|
-
"- Set non-completed phases/tasks to closed status"
|
|
48262
|
+
...actionsPerformed
|
|
48168
48263
|
].join(`
|
|
48169
48264
|
`);
|
|
48170
48265
|
try {
|
|
@@ -48180,21 +48275,27 @@ async function handleCloseCommand(directory, _args) {
|
|
|
48180
48275
|
await writeCheckpoint(directory).catch(() => {});
|
|
48181
48276
|
swarmState.agentSessions.clear();
|
|
48182
48277
|
swarmState.delegationChains.clear();
|
|
48278
|
+
if (pruneErrors.length > 0) {
|
|
48279
|
+
warnings.push(`Could not prune ${pruneErrors.length} branch(es) (unmerged or checked out): ${pruneErrors.join(", ")}`);
|
|
48280
|
+
}
|
|
48183
48281
|
const warningMsg = warnings.length > 0 ? ` Warnings: ${warnings.join("; ")}.` : "";
|
|
48282
|
+
if (planAlreadyDone) {
|
|
48283
|
+
return `\u2705 Session closed. Plan was already in a terminal state \u2014 cleanup steps applied.${warningMsg}`;
|
|
48284
|
+
}
|
|
48184
48285
|
return `\u2705 Swarm closed successfully. ${closedPhases.length} phase(s) closed, ${closedTasks.length} incomplete task(s) marked closed.${warningMsg}`;
|
|
48185
48286
|
}
|
|
48186
48287
|
|
|
48187
48288
|
// src/commands/config.ts
|
|
48188
48289
|
init_loader();
|
|
48189
48290
|
import * as os4 from "os";
|
|
48190
|
-
import * as
|
|
48291
|
+
import * as path18 from "path";
|
|
48191
48292
|
function getUserConfigDir2() {
|
|
48192
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
48293
|
+
return process.env.XDG_CONFIG_HOME || path18.join(os4.homedir(), ".config");
|
|
48193
48294
|
}
|
|
48194
48295
|
async function handleConfigCommand(directory, _args) {
|
|
48195
48296
|
const config3 = loadPluginConfig(directory);
|
|
48196
|
-
const userConfigPath =
|
|
48197
|
-
const projectConfigPath =
|
|
48297
|
+
const userConfigPath = path18.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
|
|
48298
|
+
const projectConfigPath = path18.join(directory, ".opencode", "opencode-swarm.json");
|
|
48198
48299
|
const lines = [
|
|
48199
48300
|
"## Swarm Configuration",
|
|
48200
48301
|
"",
|
|
@@ -48217,7 +48318,7 @@ init_schema();
|
|
|
48217
48318
|
// src/hooks/curator.ts
|
|
48218
48319
|
import { randomUUID } from "crypto";
|
|
48219
48320
|
import * as fs12 from "fs";
|
|
48220
|
-
import * as
|
|
48321
|
+
import * as path19 from "path";
|
|
48221
48322
|
init_event_bus();
|
|
48222
48323
|
init_manager2();
|
|
48223
48324
|
init_knowledge_store();
|
|
@@ -48271,7 +48372,7 @@ async function readCuratorSummary(directory) {
|
|
|
48271
48372
|
}
|
|
48272
48373
|
async function writeCuratorSummary(directory, summary) {
|
|
48273
48374
|
const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
|
|
48274
|
-
fs12.mkdirSync(
|
|
48375
|
+
fs12.mkdirSync(path19.dirname(resolvedPath), { recursive: true });
|
|
48275
48376
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
48276
48377
|
await Bun.write(tempPath, JSON.stringify(summary, null, 2));
|
|
48277
48378
|
fs12.renameSync(tempPath, resolvedPath);
|
|
@@ -48642,7 +48743,7 @@ ${phaseDigest.summary}`,
|
|
|
48642
48743
|
};
|
|
48643
48744
|
}
|
|
48644
48745
|
await writeCuratorSummary(directory, updatedSummary);
|
|
48645
|
-
const eventsPath =
|
|
48746
|
+
const eventsPath = path19.join(directory, ".swarm", "events.jsonl");
|
|
48646
48747
|
for (const obs of complianceObservations) {
|
|
48647
48748
|
await appendKnowledge(eventsPath, {
|
|
48648
48749
|
type: "curator_compliance",
|
|
@@ -48784,7 +48885,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, _knowled
|
|
|
48784
48885
|
created_at: now,
|
|
48785
48886
|
updated_at: now,
|
|
48786
48887
|
auto_generated: true,
|
|
48787
|
-
project_name:
|
|
48888
|
+
project_name: path19.basename(directory)
|
|
48788
48889
|
};
|
|
48789
48890
|
await appendKnowledge(knowledgePath, newEntry);
|
|
48790
48891
|
applied++;
|
|
@@ -49002,7 +49103,7 @@ function formatCurationSummary(summary) {
|
|
|
49002
49103
|
// src/commands/dark-matter.ts
|
|
49003
49104
|
init_knowledge_store();
|
|
49004
49105
|
init_co_change_analyzer();
|
|
49005
|
-
import
|
|
49106
|
+
import path21 from "path";
|
|
49006
49107
|
async function handleDarkMatterCommand(directory, args2) {
|
|
49007
49108
|
const options = {};
|
|
49008
49109
|
for (let i2 = 0;i2 < args2.length; i2++) {
|
|
@@ -49024,7 +49125,7 @@ async function handleDarkMatterCommand(directory, args2) {
|
|
|
49024
49125
|
const output = formatDarkMatterOutput(pairs);
|
|
49025
49126
|
if (pairs.length > 0) {
|
|
49026
49127
|
try {
|
|
49027
|
-
const projectName =
|
|
49128
|
+
const projectName = path21.basename(path21.resolve(directory));
|
|
49028
49129
|
const entries = darkMatterToKnowledgeEntries(pairs, projectName);
|
|
49029
49130
|
if (entries.length > 0) {
|
|
49030
49131
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
@@ -49050,7 +49151,7 @@ init_utils2();
|
|
|
49050
49151
|
init_manager2();
|
|
49051
49152
|
import * as child_process3 from "child_process";
|
|
49052
49153
|
import { existsSync as existsSync10, readdirSync as readdirSync2, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
|
|
49053
|
-
import
|
|
49154
|
+
import path22 from "path";
|
|
49054
49155
|
import { fileURLToPath } from "url";
|
|
49055
49156
|
function validateTaskDag(plan) {
|
|
49056
49157
|
const allTaskIds = new Set;
|
|
@@ -49347,7 +49448,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
49347
49448
|
};
|
|
49348
49449
|
}
|
|
49349
49450
|
async function checkConfigParseability(directory) {
|
|
49350
|
-
const configPath =
|
|
49451
|
+
const configPath = path22.join(directory, ".opencode/opencode-swarm.json");
|
|
49351
49452
|
if (!existsSync10(configPath)) {
|
|
49352
49453
|
return {
|
|
49353
49454
|
name: "Config Parseability",
|
|
@@ -49394,15 +49495,15 @@ async function checkGrammarWasmFiles() {
|
|
|
49394
49495
|
"tree-sitter-ini.wasm",
|
|
49395
49496
|
"tree-sitter-regex.wasm"
|
|
49396
49497
|
];
|
|
49397
|
-
const thisDir =
|
|
49498
|
+
const thisDir = path22.dirname(fileURLToPath(import.meta.url));
|
|
49398
49499
|
const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/services");
|
|
49399
|
-
const grammarDir = isSource ?
|
|
49500
|
+
const grammarDir = isSource ? path22.join(thisDir, "..", "lang", "grammars") : path22.join(thisDir, "lang", "grammars");
|
|
49400
49501
|
const missing = [];
|
|
49401
|
-
if (!existsSync10(
|
|
49502
|
+
if (!existsSync10(path22.join(grammarDir, "tree-sitter.wasm"))) {
|
|
49402
49503
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
49403
49504
|
}
|
|
49404
49505
|
for (const file3 of grammarFiles) {
|
|
49405
|
-
if (!existsSync10(
|
|
49506
|
+
if (!existsSync10(path22.join(grammarDir, file3))) {
|
|
49406
49507
|
missing.push(file3);
|
|
49407
49508
|
}
|
|
49408
49509
|
}
|
|
@@ -49420,7 +49521,7 @@ async function checkGrammarWasmFiles() {
|
|
|
49420
49521
|
};
|
|
49421
49522
|
}
|
|
49422
49523
|
async function checkCheckpointManifest(directory) {
|
|
49423
|
-
const manifestPath =
|
|
49524
|
+
const manifestPath = path22.join(directory, ".swarm/checkpoints.json");
|
|
49424
49525
|
if (!existsSync10(manifestPath)) {
|
|
49425
49526
|
return {
|
|
49426
49527
|
name: "Checkpoint Manifest",
|
|
@@ -49472,7 +49573,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
49472
49573
|
}
|
|
49473
49574
|
}
|
|
49474
49575
|
async function checkEventStreamIntegrity(directory) {
|
|
49475
|
-
const eventsPath =
|
|
49576
|
+
const eventsPath = path22.join(directory, ".swarm/events.jsonl");
|
|
49476
49577
|
if (!existsSync10(eventsPath)) {
|
|
49477
49578
|
return {
|
|
49478
49579
|
name: "Event Stream",
|
|
@@ -49513,7 +49614,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
49513
49614
|
}
|
|
49514
49615
|
}
|
|
49515
49616
|
async function checkSteeringDirectives(directory) {
|
|
49516
|
-
const eventsPath =
|
|
49617
|
+
const eventsPath = path22.join(directory, ".swarm/events.jsonl");
|
|
49517
49618
|
if (!existsSync10(eventsPath)) {
|
|
49518
49619
|
return {
|
|
49519
49620
|
name: "Steering Directives",
|
|
@@ -49569,7 +49670,7 @@ async function checkCurator(directory) {
|
|
|
49569
49670
|
detail: "Disabled (enable via curator.enabled)"
|
|
49570
49671
|
};
|
|
49571
49672
|
}
|
|
49572
|
-
const summaryPath =
|
|
49673
|
+
const summaryPath = path22.join(directory, ".swarm/curator-summary.json");
|
|
49573
49674
|
if (!existsSync10(summaryPath)) {
|
|
49574
49675
|
return {
|
|
49575
49676
|
name: "Curator",
|
|
@@ -50471,10 +50572,10 @@ init_knowledge_store();
|
|
|
50471
50572
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
50472
50573
|
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
|
|
50473
50574
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
50474
|
-
import * as
|
|
50575
|
+
import * as path24 from "path";
|
|
50475
50576
|
async function migrateContextToKnowledge(directory, config3) {
|
|
50476
|
-
const sentinelPath =
|
|
50477
|
-
const contextPath =
|
|
50577
|
+
const sentinelPath = path24.join(directory, ".swarm", ".knowledge-migrated");
|
|
50578
|
+
const contextPath = path24.join(directory, ".swarm", "context.md");
|
|
50478
50579
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
50479
50580
|
if (existsSync12(sentinelPath)) {
|
|
50480
50581
|
return {
|
|
@@ -50670,7 +50771,7 @@ function truncateLesson(text) {
|
|
|
50670
50771
|
return `${text.slice(0, 277)}...`;
|
|
50671
50772
|
}
|
|
50672
50773
|
function inferProjectName(directory) {
|
|
50673
|
-
const packageJsonPath =
|
|
50774
|
+
const packageJsonPath = path24.join(directory, "package.json");
|
|
50674
50775
|
if (existsSync12(packageJsonPath)) {
|
|
50675
50776
|
try {
|
|
50676
50777
|
const pkg = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
|
|
@@ -50679,7 +50780,7 @@ function inferProjectName(directory) {
|
|
|
50679
50780
|
}
|
|
50680
50781
|
} catch {}
|
|
50681
50782
|
}
|
|
50682
|
-
return
|
|
50783
|
+
return path24.basename(directory);
|
|
50683
50784
|
}
|
|
50684
50785
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
50685
50786
|
const sentinel = {
|
|
@@ -50691,7 +50792,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
50691
50792
|
schema_version: 1,
|
|
50692
50793
|
migration_tool: "knowledge-migrator.ts"
|
|
50693
50794
|
};
|
|
50694
|
-
await mkdir4(
|
|
50795
|
+
await mkdir4(path24.dirname(sentinelPath), { recursive: true });
|
|
50695
50796
|
await writeFile4(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
50696
50797
|
}
|
|
50697
50798
|
|
|
@@ -50931,7 +51032,7 @@ init_preflight_service();
|
|
|
50931
51032
|
// src/knowledge/hive-promoter.ts
|
|
50932
51033
|
import * as fs20 from "fs";
|
|
50933
51034
|
import * as os6 from "os";
|
|
50934
|
-
import * as
|
|
51035
|
+
import * as path31 from "path";
|
|
50935
51036
|
var DANGEROUS_PATTERNS = [
|
|
50936
51037
|
[/rm\s+-rf/, "rm\\s+-rf"],
|
|
50937
51038
|
[/:\s*!\s*\|/, ":\\s*!\\s*\\|"],
|
|
@@ -50977,13 +51078,13 @@ function getHiveFilePath() {
|
|
|
50977
51078
|
const home = os6.homedir();
|
|
50978
51079
|
let dataDir;
|
|
50979
51080
|
if (platform === "win32") {
|
|
50980
|
-
dataDir =
|
|
51081
|
+
dataDir = path31.join(process.env.LOCALAPPDATA || path31.join(home, "AppData", "Local"), "opencode-swarm", "Data");
|
|
50981
51082
|
} else if (platform === "darwin") {
|
|
50982
|
-
dataDir =
|
|
51083
|
+
dataDir = path31.join(home, "Library", "Application Support", "opencode-swarm");
|
|
50983
51084
|
} else {
|
|
50984
|
-
dataDir =
|
|
51085
|
+
dataDir = path31.join(process.env.XDG_DATA_HOME || path31.join(home, ".local", "share"), "opencode-swarm");
|
|
50985
51086
|
}
|
|
50986
|
-
return
|
|
51087
|
+
return path31.join(dataDir, "hive-knowledge.jsonl");
|
|
50987
51088
|
}
|
|
50988
51089
|
async function promoteToHive(_directory, lesson, category) {
|
|
50989
51090
|
const trimmed = (lesson ?? "").trim();
|
|
@@ -50995,7 +51096,7 @@ async function promoteToHive(_directory, lesson, category) {
|
|
|
50995
51096
|
throw new Error(`Lesson rejected by validator: ${validation.reason}`);
|
|
50996
51097
|
}
|
|
50997
51098
|
const hivePath = getHiveFilePath();
|
|
50998
|
-
const hiveDir =
|
|
51099
|
+
const hiveDir = path31.dirname(hivePath);
|
|
50999
51100
|
if (!fs20.existsSync(hiveDir)) {
|
|
51000
51101
|
fs20.mkdirSync(hiveDir, { recursive: true });
|
|
51001
51102
|
}
|
|
@@ -51017,7 +51118,7 @@ async function promoteToHive(_directory, lesson, category) {
|
|
|
51017
51118
|
return `Promoted to hive: "${preview}" (confidence: 1.0, source: manual)`;
|
|
51018
51119
|
}
|
|
51019
51120
|
async function promoteFromSwarm(directory, lessonId) {
|
|
51020
|
-
const knowledgePath =
|
|
51121
|
+
const knowledgePath = path31.join(directory, ".swarm", "knowledge.jsonl");
|
|
51021
51122
|
const entries = [];
|
|
51022
51123
|
if (fs20.existsSync(knowledgePath)) {
|
|
51023
51124
|
const content = fs20.readFileSync(knowledgePath, "utf-8");
|
|
@@ -51044,7 +51145,7 @@ async function promoteFromSwarm(directory, lessonId) {
|
|
|
51044
51145
|
throw new Error(`Lesson rejected by validator: ${validation.reason}`);
|
|
51045
51146
|
}
|
|
51046
51147
|
const hivePath = getHiveFilePath();
|
|
51047
|
-
const hiveDir =
|
|
51148
|
+
const hiveDir = path31.dirname(hivePath);
|
|
51048
51149
|
if (!fs20.existsSync(hiveDir)) {
|
|
51049
51150
|
fs20.mkdirSync(hiveDir, { recursive: true });
|
|
51050
51151
|
}
|
|
@@ -51175,7 +51276,7 @@ async function handleResetCommand(directory, args2) {
|
|
|
51175
51276
|
// src/commands/reset-session.ts
|
|
51176
51277
|
init_utils2();
|
|
51177
51278
|
import * as fs22 from "fs";
|
|
51178
|
-
import * as
|
|
51279
|
+
import * as path32 from "path";
|
|
51179
51280
|
async function handleResetSessionCommand(directory, _args) {
|
|
51180
51281
|
const results = [];
|
|
51181
51282
|
try {
|
|
@@ -51190,13 +51291,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
51190
51291
|
results.push("\u274C Failed to delete state.json");
|
|
51191
51292
|
}
|
|
51192
51293
|
try {
|
|
51193
|
-
const sessionDir =
|
|
51294
|
+
const sessionDir = path32.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
51194
51295
|
if (fs22.existsSync(sessionDir)) {
|
|
51195
51296
|
const files = fs22.readdirSync(sessionDir);
|
|
51196
51297
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
51197
51298
|
let deletedCount = 0;
|
|
51198
51299
|
for (const file3 of otherFiles) {
|
|
51199
|
-
const filePath =
|
|
51300
|
+
const filePath = path32.join(sessionDir, file3);
|
|
51200
51301
|
if (fs22.lstatSync(filePath).isFile()) {
|
|
51201
51302
|
fs22.unlinkSync(filePath);
|
|
51202
51303
|
deletedCount++;
|
|
@@ -51227,7 +51328,7 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
51227
51328
|
init_utils2();
|
|
51228
51329
|
init_utils();
|
|
51229
51330
|
import { mkdirSync as mkdirSync11, readdirSync as readdirSync8, renameSync as renameSync8, rmSync as rmSync3, statSync as statSync8 } from "fs";
|
|
51230
|
-
import * as
|
|
51331
|
+
import * as path33 from "path";
|
|
51231
51332
|
var SUMMARY_ID_REGEX = /^S\d+$/;
|
|
51232
51333
|
function sanitizeSummaryId(id) {
|
|
51233
51334
|
if (!id || id.length === 0) {
|
|
@@ -51262,9 +51363,9 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
|
|
|
51262
51363
|
if (serializedSize > maxStoredBytes) {
|
|
51263
51364
|
throw new Error(`Summary entry size (${serializedSize} bytes) exceeds maximum (${maxStoredBytes} bytes)`);
|
|
51264
51365
|
}
|
|
51265
|
-
const relativePath =
|
|
51366
|
+
const relativePath = path33.join("summaries", `${sanitizedId}.json`);
|
|
51266
51367
|
const summaryPath = validateSwarmPath(directory, relativePath);
|
|
51267
|
-
const summaryDir =
|
|
51368
|
+
const summaryDir = path33.dirname(summaryPath);
|
|
51268
51369
|
const entry = {
|
|
51269
51370
|
id: sanitizedId,
|
|
51270
51371
|
summaryText,
|
|
@@ -51274,7 +51375,7 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
|
|
|
51274
51375
|
};
|
|
51275
51376
|
const entryJson = JSON.stringify(entry);
|
|
51276
51377
|
mkdirSync11(summaryDir, { recursive: true });
|
|
51277
|
-
const tempPath =
|
|
51378
|
+
const tempPath = path33.join(summaryDir, `${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);
|
|
51278
51379
|
try {
|
|
51279
51380
|
await Bun.write(tempPath, entryJson);
|
|
51280
51381
|
renameSync8(tempPath, summaryPath);
|
|
@@ -51287,7 +51388,7 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
|
|
|
51287
51388
|
}
|
|
51288
51389
|
async function loadFullOutput(directory, id) {
|
|
51289
51390
|
const sanitizedId = sanitizeSummaryId(id);
|
|
51290
|
-
const relativePath =
|
|
51391
|
+
const relativePath = path33.join("summaries", `${sanitizedId}.json`);
|
|
51291
51392
|
validateSwarmPath(directory, relativePath);
|
|
51292
51393
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
51293
51394
|
if (content === null) {
|
|
@@ -51341,7 +51442,7 @@ ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
|
51341
51442
|
// src/commands/rollback.ts
|
|
51342
51443
|
init_utils2();
|
|
51343
51444
|
import * as fs23 from "fs";
|
|
51344
|
-
import * as
|
|
51445
|
+
import * as path34 from "path";
|
|
51345
51446
|
async function handleRollbackCommand(directory, args2) {
|
|
51346
51447
|
const phaseArg = args2[0];
|
|
51347
51448
|
if (!phaseArg) {
|
|
@@ -51399,8 +51500,8 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
51399
51500
|
const successes = [];
|
|
51400
51501
|
const failures = [];
|
|
51401
51502
|
for (const file3 of checkpointFiles) {
|
|
51402
|
-
const src =
|
|
51403
|
-
const dest =
|
|
51503
|
+
const src = path34.join(checkpointDir, file3);
|
|
51504
|
+
const dest = path34.join(swarmDir, file3);
|
|
51404
51505
|
try {
|
|
51405
51506
|
fs23.cpSync(src, dest, { recursive: true, force: true });
|
|
51406
51507
|
successes.push(file3);
|
|
@@ -51464,9 +51565,9 @@ async function handleSimulateCommand(directory, args2) {
|
|
|
51464
51565
|
const report = reportLines.filter(Boolean).join(`
|
|
51465
51566
|
`);
|
|
51466
51567
|
const fs24 = await import("fs/promises");
|
|
51467
|
-
const
|
|
51468
|
-
const reportPath =
|
|
51469
|
-
await fs24.mkdir(
|
|
51568
|
+
const path35 = await import("path");
|
|
51569
|
+
const reportPath = path35.join(directory, ".swarm", "simulate-report.md");
|
|
51570
|
+
await fs24.mkdir(path35.dirname(reportPath), { recursive: true });
|
|
51470
51571
|
await fs24.writeFile(reportPath, report, "utf-8");
|
|
51471
51572
|
return `${darkMatterPairs.length} hidden coupling pairs detected`;
|
|
51472
51573
|
}
|
|
@@ -51825,7 +51926,7 @@ init_manager2();
|
|
|
51825
51926
|
|
|
51826
51927
|
// src/services/compaction-service.ts
|
|
51827
51928
|
import * as fs24 from "fs";
|
|
51828
|
-
import * as
|
|
51929
|
+
import * as path35 from "path";
|
|
51829
51930
|
function makeInitialState() {
|
|
51830
51931
|
return {
|
|
51831
51932
|
lastObservationAt: 0,
|
|
@@ -51848,7 +51949,7 @@ function getSessionState(sessionId) {
|
|
|
51848
51949
|
}
|
|
51849
51950
|
function appendSnapshot(directory, tier, budgetPct, message) {
|
|
51850
51951
|
try {
|
|
51851
|
-
const snapshotPath =
|
|
51952
|
+
const snapshotPath = path35.join(directory, ".swarm", "context-snapshot.md");
|
|
51852
51953
|
const timestamp = new Date().toISOString();
|
|
51853
51954
|
const entry = `
|
|
51854
51955
|
## [${tier.toUpperCase()}] ${timestamp} \u2014 ${budgetPct.toFixed(1)}% used
|
|
@@ -52579,11 +52680,11 @@ async function doFlush(directory) {
|
|
|
52579
52680
|
const activitySection = renderActivitySection();
|
|
52580
52681
|
const updated = replaceOrAppendSection(existing, "## Agent Activity", activitySection);
|
|
52581
52682
|
const flushedCount = swarmState.pendingEvents;
|
|
52582
|
-
const
|
|
52583
|
-
const tempPath = `${
|
|
52683
|
+
const path36 = nodePath2.join(directory, ".swarm", "context.md");
|
|
52684
|
+
const tempPath = `${path36}.tmp`;
|
|
52584
52685
|
try {
|
|
52585
52686
|
await Bun.write(tempPath, updated);
|
|
52586
|
-
renameSync9(tempPath,
|
|
52687
|
+
renameSync9(tempPath, path36);
|
|
52587
52688
|
} catch (writeError) {
|
|
52588
52689
|
try {
|
|
52589
52690
|
unlinkSync4(tempPath);
|
|
@@ -53260,7 +53361,7 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
|
|
|
53260
53361
|
// src/hooks/delegation-gate.ts
|
|
53261
53362
|
init_schema();
|
|
53262
53363
|
import * as fs26 from "fs";
|
|
53263
|
-
import * as
|
|
53364
|
+
import * as path38 from "path";
|
|
53264
53365
|
|
|
53265
53366
|
// src/parallel/review-router.ts
|
|
53266
53367
|
async function computeComplexity(directory, changedFiles) {
|
|
@@ -53273,8 +53374,8 @@ async function computeComplexity(directory, changedFiles) {
|
|
|
53273
53374
|
}
|
|
53274
53375
|
try {
|
|
53275
53376
|
const fs26 = await import("fs");
|
|
53276
|
-
const
|
|
53277
|
-
const filePath =
|
|
53377
|
+
const path36 = await import("path");
|
|
53378
|
+
const filePath = path36.join(directory, file3);
|
|
53278
53379
|
if (!fs26.existsSync(filePath)) {
|
|
53279
53380
|
continue;
|
|
53280
53381
|
}
|
|
@@ -53326,7 +53427,7 @@ function shouldParallelizeReview(routing) {
|
|
|
53326
53427
|
init_telemetry();
|
|
53327
53428
|
|
|
53328
53429
|
// src/hooks/guardrails.ts
|
|
53329
|
-
import * as
|
|
53430
|
+
import * as path36 from "path";
|
|
53330
53431
|
init_constants();
|
|
53331
53432
|
init_schema();
|
|
53332
53433
|
|
|
@@ -53490,10 +53591,10 @@ function isArchitect(sessionId) {
|
|
|
53490
53591
|
function isOutsideSwarmDir(filePath, directory) {
|
|
53491
53592
|
if (!filePath)
|
|
53492
53593
|
return false;
|
|
53493
|
-
const swarmDir =
|
|
53494
|
-
const resolved =
|
|
53495
|
-
const relative5 =
|
|
53496
|
-
return relative5.startsWith("..") ||
|
|
53594
|
+
const swarmDir = path36.resolve(directory, ".swarm");
|
|
53595
|
+
const resolved = path36.resolve(directory, filePath);
|
|
53596
|
+
const relative5 = path36.relative(swarmDir, resolved);
|
|
53597
|
+
return relative5.startsWith("..") || path36.isAbsolute(relative5);
|
|
53497
53598
|
}
|
|
53498
53599
|
function isSourceCodePath(filePath) {
|
|
53499
53600
|
if (!filePath)
|
|
@@ -53561,13 +53662,13 @@ function getCurrentTaskId(sessionId) {
|
|
|
53561
53662
|
}
|
|
53562
53663
|
function isInDeclaredScope(filePath, scopeEntries, cwd) {
|
|
53563
53664
|
const dir = cwd ?? process.cwd();
|
|
53564
|
-
const resolvedFile =
|
|
53665
|
+
const resolvedFile = path36.resolve(dir, filePath);
|
|
53565
53666
|
return scopeEntries.some((scope) => {
|
|
53566
|
-
const resolvedScope =
|
|
53667
|
+
const resolvedScope = path36.resolve(dir, scope);
|
|
53567
53668
|
if (resolvedFile === resolvedScope)
|
|
53568
53669
|
return true;
|
|
53569
|
-
const rel =
|
|
53570
|
-
return rel.length > 0 && !rel.startsWith("..") && !
|
|
53670
|
+
const rel = path36.relative(resolvedScope, resolvedFile);
|
|
53671
|
+
return rel.length > 0 && !rel.startsWith("..") && !path36.isAbsolute(rel);
|
|
53571
53672
|
});
|
|
53572
53673
|
}
|
|
53573
53674
|
function createGuardrailsHooks(directory, directoryOrConfig, config3, authorityConfig) {
|
|
@@ -53826,18 +53927,18 @@ function createGuardrailsHooks(directory, directoryOrConfig, config3, authorityC
|
|
|
53826
53927
|
const toolArgs = args2;
|
|
53827
53928
|
const targetPath = toolArgs?.filePath ?? toolArgs?.path ?? toolArgs?.file ?? toolArgs?.target;
|
|
53828
53929
|
if (typeof targetPath === "string" && targetPath.length > 0) {
|
|
53829
|
-
const resolvedTarget =
|
|
53830
|
-
const planMdPath =
|
|
53831
|
-
const planJsonPath =
|
|
53930
|
+
const resolvedTarget = path36.resolve(effectiveDirectory, targetPath).toLowerCase();
|
|
53931
|
+
const planMdPath = path36.resolve(effectiveDirectory, ".swarm", "plan.md").toLowerCase();
|
|
53932
|
+
const planJsonPath = path36.resolve(effectiveDirectory, ".swarm", "plan.json").toLowerCase();
|
|
53832
53933
|
if (resolvedTarget === planMdPath || resolvedTarget === planJsonPath) {
|
|
53833
53934
|
throw new Error("PLAN STATE VIOLATION: Direct writes to .swarm/plan.md and .swarm/plan.json are blocked. " + "plan.md is auto-regenerated from plan.json by PlanSyncWorker. " + "Use update_task_status() to mark tasks complete, " + "phase_complete() for phase transitions, or " + "save_plan to create/restructure plans.");
|
|
53834
53935
|
}
|
|
53835
53936
|
}
|
|
53836
53937
|
if (!targetPath && (tool3 === "apply_patch" || tool3 === "patch")) {
|
|
53837
53938
|
for (const p of extractPatchTargetPaths(tool3, args2)) {
|
|
53838
|
-
const resolvedP =
|
|
53839
|
-
const planMdPath =
|
|
53840
|
-
const planJsonPath =
|
|
53939
|
+
const resolvedP = path36.resolve(effectiveDirectory, p);
|
|
53940
|
+
const planMdPath = path36.resolve(effectiveDirectory, ".swarm", "plan.md").toLowerCase();
|
|
53941
|
+
const planJsonPath = path36.resolve(effectiveDirectory, ".swarm", "plan.json").toLowerCase();
|
|
53841
53942
|
if (resolvedP.toLowerCase() === planMdPath || resolvedP.toLowerCase() === planJsonPath) {
|
|
53842
53943
|
throw new Error("PLAN STATE VIOLATION: Direct writes to .swarm/plan.md and .swarm/plan.json are blocked. " + "plan.md is auto-regenerated from plan.json by PlanSyncWorker. " + "Use update_task_status() to mark tasks complete, " + "phase_complete() for phase transitions, or " + "save_plan to create/restructure plans.");
|
|
53843
53944
|
}
|
|
@@ -53856,7 +53957,7 @@ function createGuardrailsHooks(directory, directoryOrConfig, config3, authorityC
|
|
|
53856
53957
|
}
|
|
53857
53958
|
}
|
|
53858
53959
|
}
|
|
53859
|
-
if (typeof targetPath === "string" && targetPath.length > 0 && isOutsideSwarmDir(targetPath, effectiveDirectory) && isSourceCodePath(
|
|
53960
|
+
if (typeof targetPath === "string" && targetPath.length > 0 && isOutsideSwarmDir(targetPath, effectiveDirectory) && isSourceCodePath(path36.relative(effectiveDirectory, path36.resolve(effectiveDirectory, targetPath)))) {
|
|
53860
53961
|
const session = swarmState.agentSessions.get(sessionID);
|
|
53861
53962
|
if (session) {
|
|
53862
53963
|
session.architectWriteCount++;
|
|
@@ -54531,8 +54632,8 @@ function checkFileAuthorityWithRules(agentName, filePath, cwd, effectiveRules) {
|
|
|
54531
54632
|
const normalizedAgent = agentName.toLowerCase();
|
|
54532
54633
|
const strippedAgent = stripKnownSwarmPrefix(agentName).toLowerCase();
|
|
54533
54634
|
const dir = cwd || process.cwd();
|
|
54534
|
-
const resolved =
|
|
54535
|
-
const normalizedPath =
|
|
54635
|
+
const resolved = path36.resolve(dir, filePath);
|
|
54636
|
+
const normalizedPath = path36.relative(dir, resolved).replace(/\\/g, "/");
|
|
54536
54637
|
const rules = effectiveRules[normalizedAgent] ?? effectiveRules[strippedAgent];
|
|
54537
54638
|
if (!rules) {
|
|
54538
54639
|
return { allowed: false, reason: `Unknown agent: ${agentName}` };
|
|
@@ -54614,10 +54715,10 @@ async function getEvidenceTaskId(session, directory) {
|
|
|
54614
54715
|
if (typeof directory !== "string" || directory.length === 0) {
|
|
54615
54716
|
return null;
|
|
54616
54717
|
}
|
|
54617
|
-
const resolvedDirectory =
|
|
54618
|
-
const planPath =
|
|
54619
|
-
const resolvedPlanPath =
|
|
54620
|
-
if (!resolvedPlanPath.startsWith(resolvedDirectory +
|
|
54718
|
+
const resolvedDirectory = path38.resolve(directory);
|
|
54719
|
+
const planPath = path38.join(resolvedDirectory, ".swarm", "plan.json");
|
|
54720
|
+
const resolvedPlanPath = path38.resolve(planPath);
|
|
54721
|
+
if (!resolvedPlanPath.startsWith(resolvedDirectory + path38.sep) && resolvedPlanPath !== resolvedDirectory) {
|
|
54621
54722
|
return null;
|
|
54622
54723
|
}
|
|
54623
54724
|
const planContent = await fs26.promises.readFile(resolvedPlanPath, "utf-8");
|
|
@@ -55345,7 +55446,7 @@ function consolidateSystemMessages(messages) {
|
|
|
55345
55446
|
// src/hooks/phase-monitor.ts
|
|
55346
55447
|
init_schema();
|
|
55347
55448
|
init_manager2();
|
|
55348
|
-
import * as
|
|
55449
|
+
import * as path40 from "path";
|
|
55349
55450
|
init_utils2();
|
|
55350
55451
|
function createPhaseMonitorHook(directory, preflightManager, curatorRunner, delegateFactory) {
|
|
55351
55452
|
let lastKnownPhase = null;
|
|
@@ -55366,9 +55467,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner, dele
|
|
|
55366
55467
|
const llmDelegate = delegateFactory?.(sessionId);
|
|
55367
55468
|
const initResult = await runner(directory, curatorConfig, llmDelegate);
|
|
55368
55469
|
if (initResult.briefing) {
|
|
55369
|
-
const briefingPath =
|
|
55470
|
+
const briefingPath = path40.join(directory, ".swarm", "curator-briefing.md");
|
|
55370
55471
|
const { mkdir: mkdir5, writeFile: writeFile5 } = await import("fs/promises");
|
|
55371
|
-
await mkdir5(
|
|
55472
|
+
await mkdir5(path40.dirname(briefingPath), { recursive: true });
|
|
55372
55473
|
await writeFile5(briefingPath, initResult.briefing, "utf-8");
|
|
55373
55474
|
const { buildApprovedReceipt: buildApprovedReceipt2, persistReviewReceipt: persistReviewReceipt2 } = await Promise.resolve().then(() => (init_review_receipt(), exports_review_receipt));
|
|
55374
55475
|
const initReceipt = buildApprovedReceipt2({
|
|
@@ -55502,14 +55603,14 @@ init_manager();
|
|
|
55502
55603
|
init_detector();
|
|
55503
55604
|
init_manager2();
|
|
55504
55605
|
import * as fs32 from "fs";
|
|
55505
|
-
import * as
|
|
55606
|
+
import * as path44 from "path";
|
|
55506
55607
|
|
|
55507
55608
|
// src/services/decision-drift-analyzer.ts
|
|
55508
55609
|
init_utils2();
|
|
55509
55610
|
init_manager2();
|
|
55510
55611
|
init_utils();
|
|
55511
55612
|
import * as fs29 from "fs";
|
|
55512
|
-
import * as
|
|
55613
|
+
import * as path41 from "path";
|
|
55513
55614
|
var DEFAULT_DRIFT_CONFIG = {
|
|
55514
55615
|
staleThresholdPhases: 1,
|
|
55515
55616
|
detectContradictions: true,
|
|
@@ -55663,7 +55764,7 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
55663
55764
|
currentPhase = legacyPhase;
|
|
55664
55765
|
}
|
|
55665
55766
|
}
|
|
55666
|
-
const contextPath =
|
|
55767
|
+
const contextPath = path41.join(directory, ".swarm", "context.md");
|
|
55667
55768
|
let contextContent = "";
|
|
55668
55769
|
try {
|
|
55669
55770
|
if (fs29.existsSync(contextPath)) {
|
|
@@ -55793,7 +55894,7 @@ init_utils();
|
|
|
55793
55894
|
init_constants();
|
|
55794
55895
|
init_schema();
|
|
55795
55896
|
import * as fs30 from "fs/promises";
|
|
55796
|
-
import * as
|
|
55897
|
+
import * as path42 from "path";
|
|
55797
55898
|
function safeGet(obj, key) {
|
|
55798
55899
|
if (!obj || !Object.hasOwn(obj, key))
|
|
55799
55900
|
return;
|
|
@@ -56007,9 +56108,9 @@ async function handleDebuggingSpiral(match, taskId, directory) {
|
|
|
56007
56108
|
let eventLogged = false;
|
|
56008
56109
|
let checkpointCreated = false;
|
|
56009
56110
|
try {
|
|
56010
|
-
const swarmDir =
|
|
56111
|
+
const swarmDir = path42.join(directory, ".swarm");
|
|
56011
56112
|
await fs30.mkdir(swarmDir, { recursive: true });
|
|
56012
|
-
const eventsPath =
|
|
56113
|
+
const eventsPath = path42.join(swarmDir, "events.jsonl");
|
|
56013
56114
|
await fs30.appendFile(eventsPath, `${formatDebuggingSpiralEvent(match, taskId)}
|
|
56014
56115
|
`);
|
|
56015
56116
|
eventLogged = true;
|
|
@@ -56406,7 +56507,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
56406
56507
|
await fs32.promises.writeFile(darkMatterPath, darkMatterReport, "utf-8");
|
|
56407
56508
|
warn(`[system-enhancer] Dark matter scan complete: ${darkMatter.length} co-change patterns found`);
|
|
56408
56509
|
try {
|
|
56409
|
-
const projectName =
|
|
56510
|
+
const projectName = path44.basename(path44.resolve(directory));
|
|
56410
56511
|
const knowledgeEntries = darkMatterToKnowledgeEntries2(darkMatter, projectName);
|
|
56411
56512
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
56412
56513
|
const existingEntries = await readKnowledge(knowledgePath);
|
|
@@ -57530,7 +57631,7 @@ function isReadTool(toolName) {
|
|
|
57530
57631
|
|
|
57531
57632
|
// src/hooks/incremental-verify.ts
|
|
57532
57633
|
import * as fs33 from "fs";
|
|
57533
|
-
import * as
|
|
57634
|
+
import * as path45 from "path";
|
|
57534
57635
|
|
|
57535
57636
|
// src/hooks/spawn-helper.ts
|
|
57536
57637
|
import * as child_process4 from "child_process";
|
|
@@ -57608,18 +57709,18 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
57608
57709
|
// src/hooks/incremental-verify.ts
|
|
57609
57710
|
var emittedSkipAdvisories = new Set;
|
|
57610
57711
|
function detectPackageManager(projectDir) {
|
|
57611
|
-
if (fs33.existsSync(
|
|
57712
|
+
if (fs33.existsSync(path45.join(projectDir, "bun.lockb")))
|
|
57612
57713
|
return "bun";
|
|
57613
|
-
if (fs33.existsSync(
|
|
57714
|
+
if (fs33.existsSync(path45.join(projectDir, "pnpm-lock.yaml")))
|
|
57614
57715
|
return "pnpm";
|
|
57615
|
-
if (fs33.existsSync(
|
|
57716
|
+
if (fs33.existsSync(path45.join(projectDir, "yarn.lock")))
|
|
57616
57717
|
return "yarn";
|
|
57617
|
-
if (fs33.existsSync(
|
|
57718
|
+
if (fs33.existsSync(path45.join(projectDir, "package-lock.json")))
|
|
57618
57719
|
return "npm";
|
|
57619
57720
|
return "bun";
|
|
57620
57721
|
}
|
|
57621
57722
|
function detectTypecheckCommand(projectDir) {
|
|
57622
|
-
const pkgPath =
|
|
57723
|
+
const pkgPath = path45.join(projectDir, "package.json");
|
|
57623
57724
|
if (fs33.existsSync(pkgPath)) {
|
|
57624
57725
|
try {
|
|
57625
57726
|
const pkg = JSON.parse(fs33.readFileSync(pkgPath, "utf8"));
|
|
@@ -57636,8 +57737,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
57636
57737
|
...pkg.dependencies,
|
|
57637
57738
|
...pkg.devDependencies
|
|
57638
57739
|
};
|
|
57639
|
-
if (!deps?.typescript && !fs33.existsSync(
|
|
57640
|
-
const hasTSMarkers = deps?.typescript || fs33.existsSync(
|
|
57740
|
+
if (!deps?.typescript && !fs33.existsSync(path45.join(projectDir, "tsconfig.json"))) {}
|
|
57741
|
+
const hasTSMarkers = deps?.typescript || fs33.existsSync(path45.join(projectDir, "tsconfig.json"));
|
|
57641
57742
|
if (hasTSMarkers) {
|
|
57642
57743
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
57643
57744
|
}
|
|
@@ -57645,13 +57746,13 @@ function detectTypecheckCommand(projectDir) {
|
|
|
57645
57746
|
return null;
|
|
57646
57747
|
}
|
|
57647
57748
|
}
|
|
57648
|
-
if (fs33.existsSync(
|
|
57749
|
+
if (fs33.existsSync(path45.join(projectDir, "go.mod"))) {
|
|
57649
57750
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
57650
57751
|
}
|
|
57651
|
-
if (fs33.existsSync(
|
|
57752
|
+
if (fs33.existsSync(path45.join(projectDir, "Cargo.toml"))) {
|
|
57652
57753
|
return { command: ["cargo", "check"], language: "rust" };
|
|
57653
57754
|
}
|
|
57654
|
-
if (fs33.existsSync(
|
|
57755
|
+
if (fs33.existsSync(path45.join(projectDir, "pyproject.toml")) || fs33.existsSync(path45.join(projectDir, "requirements.txt")) || fs33.existsSync(path45.join(projectDir, "setup.py"))) {
|
|
57655
57756
|
return { command: null, language: "python" };
|
|
57656
57757
|
}
|
|
57657
57758
|
try {
|
|
@@ -57952,7 +58053,7 @@ ${injectionText}`;
|
|
|
57952
58053
|
// src/hooks/scope-guard.ts
|
|
57953
58054
|
init_constants();
|
|
57954
58055
|
init_schema();
|
|
57955
|
-
import * as
|
|
58056
|
+
import * as path47 from "path";
|
|
57956
58057
|
var WRITE_TOOLS = new Set(WRITE_TOOL_NAMES);
|
|
57957
58058
|
function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
57958
58059
|
const enabled = config3.enabled ?? true;
|
|
@@ -58004,13 +58105,13 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
|
58004
58105
|
}
|
|
58005
58106
|
function isFileInScope(filePath, scopeEntries, directory) {
|
|
58006
58107
|
const dir = directory ?? process.cwd();
|
|
58007
|
-
const resolvedFile =
|
|
58108
|
+
const resolvedFile = path47.resolve(dir, filePath);
|
|
58008
58109
|
return scopeEntries.some((scope) => {
|
|
58009
|
-
const resolvedScope =
|
|
58110
|
+
const resolvedScope = path47.resolve(dir, scope);
|
|
58010
58111
|
if (resolvedFile === resolvedScope)
|
|
58011
58112
|
return true;
|
|
58012
|
-
const rel =
|
|
58013
|
-
return rel.length > 0 && !rel.startsWith("..") && !
|
|
58113
|
+
const rel = path47.relative(resolvedScope, resolvedFile);
|
|
58114
|
+
return rel.length > 0 && !rel.startsWith("..") && !path47.isAbsolute(rel);
|
|
58014
58115
|
});
|
|
58015
58116
|
}
|
|
58016
58117
|
|
|
@@ -58060,7 +58161,7 @@ function createSelfReviewHook(config3, injectAdvisory) {
|
|
|
58060
58161
|
|
|
58061
58162
|
// src/hooks/slop-detector.ts
|
|
58062
58163
|
import * as fs35 from "fs";
|
|
58063
|
-
import * as
|
|
58164
|
+
import * as path48 from "path";
|
|
58064
58165
|
var WRITE_EDIT_TOOLS = new Set([
|
|
58065
58166
|
"write",
|
|
58066
58167
|
"edit",
|
|
@@ -58110,7 +58211,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
58110
58211
|
break;
|
|
58111
58212
|
if (entry.isSymbolicLink())
|
|
58112
58213
|
continue;
|
|
58113
|
-
const full =
|
|
58214
|
+
const full = path48.join(dir, entry.name);
|
|
58114
58215
|
if (entry.isDirectory()) {
|
|
58115
58216
|
if (entry.name === "node_modules" || entry.name === ".git")
|
|
58116
58217
|
continue;
|
|
@@ -58125,7 +58226,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
58125
58226
|
return results;
|
|
58126
58227
|
}
|
|
58127
58228
|
function checkDeadExports(content, projectDir, startTime) {
|
|
58128
|
-
const hasPackageJson = fs35.existsSync(
|
|
58229
|
+
const hasPackageJson = fs35.existsSync(path48.join(projectDir, "package.json"));
|
|
58129
58230
|
if (!hasPackageJson)
|
|
58130
58231
|
return null;
|
|
58131
58232
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -58528,13 +58629,13 @@ init_telemetry();
|
|
|
58528
58629
|
init_tool();
|
|
58529
58630
|
init_create_tool();
|
|
58530
58631
|
import * as fs38 from "fs";
|
|
58531
|
-
import * as
|
|
58632
|
+
import * as path50 from "path";
|
|
58532
58633
|
|
|
58533
58634
|
// src/tools/symbols.ts
|
|
58534
58635
|
init_tool();
|
|
58535
58636
|
init_create_tool();
|
|
58536
58637
|
import * as fs37 from "fs";
|
|
58537
|
-
import * as
|
|
58638
|
+
import * as path49 from "path";
|
|
58538
58639
|
var MAX_FILE_SIZE_BYTES2 = 1024 * 1024;
|
|
58539
58640
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
58540
58641
|
function containsWindowsAttacks(str) {
|
|
@@ -58551,11 +58652,11 @@ function containsWindowsAttacks(str) {
|
|
|
58551
58652
|
}
|
|
58552
58653
|
function isPathInWorkspace(filePath, workspace) {
|
|
58553
58654
|
try {
|
|
58554
|
-
const resolvedPath =
|
|
58655
|
+
const resolvedPath = path49.resolve(workspace, filePath);
|
|
58555
58656
|
const realWorkspace = fs37.realpathSync(workspace);
|
|
58556
58657
|
const realResolvedPath = fs37.realpathSync(resolvedPath);
|
|
58557
|
-
const relativePath =
|
|
58558
|
-
if (relativePath.startsWith("..") ||
|
|
58658
|
+
const relativePath = path49.relative(realWorkspace, realResolvedPath);
|
|
58659
|
+
if (relativePath.startsWith("..") || path49.isAbsolute(relativePath)) {
|
|
58559
58660
|
return false;
|
|
58560
58661
|
}
|
|
58561
58662
|
return true;
|
|
@@ -58567,7 +58668,7 @@ function validatePathForRead(filePath, workspace) {
|
|
|
58567
58668
|
return isPathInWorkspace(filePath, workspace);
|
|
58568
58669
|
}
|
|
58569
58670
|
function extractTSSymbols(filePath, cwd) {
|
|
58570
|
-
const fullPath =
|
|
58671
|
+
const fullPath = path49.join(cwd, filePath);
|
|
58571
58672
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
58572
58673
|
return [];
|
|
58573
58674
|
}
|
|
@@ -58719,7 +58820,7 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
58719
58820
|
});
|
|
58720
58821
|
}
|
|
58721
58822
|
function extractPythonSymbols(filePath, cwd) {
|
|
58722
|
-
const fullPath =
|
|
58823
|
+
const fullPath = path49.join(cwd, filePath);
|
|
58723
58824
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
58724
58825
|
return [];
|
|
58725
58826
|
}
|
|
@@ -58802,7 +58903,7 @@ var symbols = createSwarmTool({
|
|
|
58802
58903
|
}, null, 2);
|
|
58803
58904
|
}
|
|
58804
58905
|
const cwd = directory;
|
|
58805
|
-
const ext =
|
|
58906
|
+
const ext = path49.extname(file3);
|
|
58806
58907
|
if (containsControlChars(file3)) {
|
|
58807
58908
|
return JSON.stringify({
|
|
58808
58909
|
file: file3,
|
|
@@ -58878,14 +58979,14 @@ function containsWindowsAttacks2(str) {
|
|
|
58878
58979
|
}
|
|
58879
58980
|
function isPathInWorkspace2(filePath, workspace) {
|
|
58880
58981
|
try {
|
|
58881
|
-
const resolvedPath =
|
|
58982
|
+
const resolvedPath = path50.resolve(workspace, filePath);
|
|
58882
58983
|
if (!fs38.existsSync(resolvedPath)) {
|
|
58883
58984
|
return true;
|
|
58884
58985
|
}
|
|
58885
58986
|
const realWorkspace = fs38.realpathSync(workspace);
|
|
58886
58987
|
const realResolvedPath = fs38.realpathSync(resolvedPath);
|
|
58887
|
-
const relativePath =
|
|
58888
|
-
if (relativePath.startsWith("..") ||
|
|
58988
|
+
const relativePath = path50.relative(realWorkspace, realResolvedPath);
|
|
58989
|
+
if (relativePath.startsWith("..") || path50.isAbsolute(relativePath)) {
|
|
58889
58990
|
return false;
|
|
58890
58991
|
}
|
|
58891
58992
|
return true;
|
|
@@ -58894,7 +58995,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
58894
58995
|
}
|
|
58895
58996
|
}
|
|
58896
58997
|
function processFile(file3, cwd, exportedOnly) {
|
|
58897
|
-
const ext =
|
|
58998
|
+
const ext = path50.extname(file3);
|
|
58898
58999
|
if (containsControlChars(file3)) {
|
|
58899
59000
|
return {
|
|
58900
59001
|
file: file3,
|
|
@@ -58927,7 +59028,7 @@ function processFile(file3, cwd, exportedOnly) {
|
|
|
58927
59028
|
errorType: "path-outside-workspace"
|
|
58928
59029
|
};
|
|
58929
59030
|
}
|
|
58930
|
-
const fullPath =
|
|
59031
|
+
const fullPath = path50.join(cwd, file3);
|
|
58931
59032
|
if (!fs38.existsSync(fullPath)) {
|
|
58932
59033
|
return {
|
|
58933
59034
|
file: file3,
|
|
@@ -59218,7 +59319,7 @@ init_manager();
|
|
|
59218
59319
|
init_create_tool();
|
|
59219
59320
|
init_resolve_working_directory();
|
|
59220
59321
|
import * as fs39 from "fs";
|
|
59221
|
-
import * as
|
|
59322
|
+
import * as path51 from "path";
|
|
59222
59323
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
59223
59324
|
var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
|
|
59224
59325
|
function isValidTaskId3(taskId) {
|
|
@@ -59235,9 +59336,9 @@ function isValidTaskId3(taskId) {
|
|
|
59235
59336
|
return TASK_ID_PATTERN2.test(taskId);
|
|
59236
59337
|
}
|
|
59237
59338
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
59238
|
-
const normalizedWorkspace =
|
|
59239
|
-
const swarmPath =
|
|
59240
|
-
const normalizedPath =
|
|
59339
|
+
const normalizedWorkspace = path51.resolve(workspaceRoot);
|
|
59340
|
+
const swarmPath = path51.join(normalizedWorkspace, ".swarm", "evidence");
|
|
59341
|
+
const normalizedPath = path51.resolve(filePath);
|
|
59241
59342
|
return normalizedPath.startsWith(swarmPath);
|
|
59242
59343
|
}
|
|
59243
59344
|
function readEvidenceFile(evidencePath) {
|
|
@@ -59318,7 +59419,7 @@ var check_gate_status = createSwarmTool({
|
|
|
59318
59419
|
};
|
|
59319
59420
|
return JSON.stringify(errorResult, null, 2);
|
|
59320
59421
|
}
|
|
59321
|
-
const evidencePath =
|
|
59422
|
+
const evidencePath = path51.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
59322
59423
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
59323
59424
|
const errorResult = {
|
|
59324
59425
|
taskId: taskIdInput,
|
|
@@ -59412,7 +59513,7 @@ init_co_change_analyzer();
|
|
|
59412
59513
|
init_dist();
|
|
59413
59514
|
init_utils2();
|
|
59414
59515
|
import * as fs40 from "fs";
|
|
59415
|
-
import * as
|
|
59516
|
+
import * as path52 from "path";
|
|
59416
59517
|
init_create_tool();
|
|
59417
59518
|
init_resolve_working_directory();
|
|
59418
59519
|
function extractMatches(regex, text) {
|
|
@@ -59566,10 +59667,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
59566
59667
|
let hasFileReadFailure = false;
|
|
59567
59668
|
for (const filePath of fileTargets) {
|
|
59568
59669
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
59569
|
-
const resolvedPath =
|
|
59570
|
-
const projectRoot =
|
|
59571
|
-
const relative9 =
|
|
59572
|
-
const withinProject = relative9 === "" || !relative9.startsWith("..") && !
|
|
59670
|
+
const resolvedPath = path52.resolve(directory, normalizedPath);
|
|
59671
|
+
const projectRoot = path52.resolve(directory);
|
|
59672
|
+
const relative9 = path52.relative(projectRoot, resolvedPath);
|
|
59673
|
+
const withinProject = relative9 === "" || !relative9.startsWith("..") && !path52.isAbsolute(relative9);
|
|
59573
59674
|
if (!withinProject) {
|
|
59574
59675
|
blockedTasks.push({
|
|
59575
59676
|
task_id: task.id,
|
|
@@ -59624,8 +59725,8 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
59624
59725
|
blockedTasks
|
|
59625
59726
|
};
|
|
59626
59727
|
try {
|
|
59627
|
-
const evidenceDir =
|
|
59628
|
-
const evidencePath =
|
|
59728
|
+
const evidenceDir = path52.join(directory, ".swarm", "evidence", `${phase}`);
|
|
59729
|
+
const evidencePath = path52.join(evidenceDir, "completion-verify.json");
|
|
59629
59730
|
fs40.mkdirSync(evidenceDir, { recursive: true });
|
|
59630
59731
|
const evidenceBundle = {
|
|
59631
59732
|
schema_version: "1.0.0",
|
|
@@ -59702,11 +59803,11 @@ var completion_verify = createSwarmTool({
|
|
|
59702
59803
|
// src/tools/complexity-hotspots.ts
|
|
59703
59804
|
init_dist();
|
|
59704
59805
|
import * as fs42 from "fs";
|
|
59705
|
-
import * as
|
|
59806
|
+
import * as path54 from "path";
|
|
59706
59807
|
|
|
59707
59808
|
// src/quality/metrics.ts
|
|
59708
59809
|
import * as fs41 from "fs";
|
|
59709
|
-
import * as
|
|
59810
|
+
import * as path53 from "path";
|
|
59710
59811
|
var MAX_FILE_SIZE_BYTES3 = 256 * 1024;
|
|
59711
59812
|
var MIN_DUPLICATION_LINES = 10;
|
|
59712
59813
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -59758,7 +59859,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
59758
59859
|
let totalComplexity = 0;
|
|
59759
59860
|
const analyzedFiles = [];
|
|
59760
59861
|
for (const file3 of files) {
|
|
59761
|
-
const fullPath =
|
|
59862
|
+
const fullPath = path53.isAbsolute(file3) ? file3 : path53.join(workingDir, file3);
|
|
59762
59863
|
if (!fs41.existsSync(fullPath)) {
|
|
59763
59864
|
continue;
|
|
59764
59865
|
}
|
|
@@ -59881,7 +59982,7 @@ function countGoExports(content) {
|
|
|
59881
59982
|
function getExportCountForFile(filePath) {
|
|
59882
59983
|
try {
|
|
59883
59984
|
const content = fs41.readFileSync(filePath, "utf-8");
|
|
59884
|
-
const ext =
|
|
59985
|
+
const ext = path53.extname(filePath).toLowerCase();
|
|
59885
59986
|
switch (ext) {
|
|
59886
59987
|
case ".ts":
|
|
59887
59988
|
case ".tsx":
|
|
@@ -59907,7 +60008,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
59907
60008
|
let totalExports = 0;
|
|
59908
60009
|
const analyzedFiles = [];
|
|
59909
60010
|
for (const file3 of files) {
|
|
59910
|
-
const fullPath =
|
|
60011
|
+
const fullPath = path53.isAbsolute(file3) ? file3 : path53.join(workingDir, file3);
|
|
59911
60012
|
if (!fs41.existsSync(fullPath)) {
|
|
59912
60013
|
continue;
|
|
59913
60014
|
}
|
|
@@ -59941,7 +60042,7 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
59941
60042
|
let duplicateLines = 0;
|
|
59942
60043
|
const analyzedFiles = [];
|
|
59943
60044
|
for (const file3 of files) {
|
|
59944
|
-
const fullPath =
|
|
60045
|
+
const fullPath = path53.isAbsolute(file3) ? file3 : path53.join(workingDir, file3);
|
|
59945
60046
|
if (!fs41.existsSync(fullPath)) {
|
|
59946
60047
|
continue;
|
|
59947
60048
|
}
|
|
@@ -59974,8 +60075,8 @@ function countCodeLines(content) {
|
|
|
59974
60075
|
return lines.length;
|
|
59975
60076
|
}
|
|
59976
60077
|
function isTestFile(filePath) {
|
|
59977
|
-
const basename8 =
|
|
59978
|
-
const _ext =
|
|
60078
|
+
const basename8 = path53.basename(filePath);
|
|
60079
|
+
const _ext = path53.extname(filePath).toLowerCase();
|
|
59979
60080
|
const testPatterns = [
|
|
59980
60081
|
".test.",
|
|
59981
60082
|
".spec.",
|
|
@@ -60056,8 +60157,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
60056
60157
|
}
|
|
60057
60158
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
60058
60159
|
}
|
|
60059
|
-
function matchesGlobSegment(
|
|
60060
|
-
const normalizedPath =
|
|
60160
|
+
function matchesGlobSegment(path54, glob) {
|
|
60161
|
+
const normalizedPath = path54.replace(/\\/g, "/");
|
|
60061
60162
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
60062
60163
|
if (normalizedPath.includes("//")) {
|
|
60063
60164
|
return false;
|
|
@@ -60088,8 +60189,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
60088
60189
|
function hasGlobstar(glob) {
|
|
60089
60190
|
return glob.includes("**");
|
|
60090
60191
|
}
|
|
60091
|
-
function globMatches(
|
|
60092
|
-
const normalizedPath =
|
|
60192
|
+
function globMatches(path54, glob) {
|
|
60193
|
+
const normalizedPath = path54.replace(/\\/g, "/");
|
|
60093
60194
|
if (!glob || glob === "") {
|
|
60094
60195
|
if (normalizedPath.includes("//")) {
|
|
60095
60196
|
return false;
|
|
@@ -60125,7 +60226,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
60125
60226
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
60126
60227
|
let testLines = 0;
|
|
60127
60228
|
let codeLines = 0;
|
|
60128
|
-
const srcDir =
|
|
60229
|
+
const srcDir = path53.join(workingDir, "src");
|
|
60129
60230
|
if (fs41.existsSync(srcDir)) {
|
|
60130
60231
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
60131
60232
|
codeLines += lines;
|
|
@@ -60133,14 +60234,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
60133
60234
|
}
|
|
60134
60235
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
60135
60236
|
for (const dir of possibleSrcDirs) {
|
|
60136
|
-
const dirPath =
|
|
60237
|
+
const dirPath = path53.join(workingDir, dir);
|
|
60137
60238
|
if (fs41.existsSync(dirPath)) {
|
|
60138
60239
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
60139
60240
|
codeLines += lines;
|
|
60140
60241
|
});
|
|
60141
60242
|
}
|
|
60142
60243
|
}
|
|
60143
|
-
const testsDir =
|
|
60244
|
+
const testsDir = path53.join(workingDir, "tests");
|
|
60144
60245
|
if (fs41.existsSync(testsDir)) {
|
|
60145
60246
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
60146
60247
|
testLines += lines;
|
|
@@ -60148,7 +60249,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
60148
60249
|
}
|
|
60149
60250
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
60150
60251
|
for (const dir of possibleTestDirs) {
|
|
60151
|
-
const dirPath =
|
|
60252
|
+
const dirPath = path53.join(workingDir, dir);
|
|
60152
60253
|
if (fs41.existsSync(dirPath) && dirPath !== testsDir) {
|
|
60153
60254
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
60154
60255
|
testLines += lines;
|
|
@@ -60163,7 +60264,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
60163
60264
|
try {
|
|
60164
60265
|
const entries = fs41.readdirSync(dirPath, { withFileTypes: true });
|
|
60165
60266
|
for (const entry of entries) {
|
|
60166
|
-
const fullPath =
|
|
60267
|
+
const fullPath = path53.join(dirPath, entry.name);
|
|
60167
60268
|
if (entry.isDirectory()) {
|
|
60168
60269
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
60169
60270
|
continue;
|
|
@@ -60171,7 +60272,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
60171
60272
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
60172
60273
|
} else if (entry.isFile()) {
|
|
60173
60274
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
60174
|
-
const ext =
|
|
60275
|
+
const ext = path53.extname(entry.name).toLowerCase();
|
|
60175
60276
|
const validExts = [
|
|
60176
60277
|
".ts",
|
|
60177
60278
|
".tsx",
|
|
@@ -60423,7 +60524,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
60423
60524
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
60424
60525
|
const filteredChurn = new Map;
|
|
60425
60526
|
for (const [file3, count] of churnMap) {
|
|
60426
|
-
const ext =
|
|
60527
|
+
const ext = path54.extname(file3).toLowerCase();
|
|
60427
60528
|
if (extSet.has(ext)) {
|
|
60428
60529
|
filteredChurn.set(file3, count);
|
|
60429
60530
|
}
|
|
@@ -60434,7 +60535,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
60434
60535
|
for (const [file3, churnCount] of filteredChurn) {
|
|
60435
60536
|
let fullPath = file3;
|
|
60436
60537
|
if (!fs42.existsSync(fullPath)) {
|
|
60437
|
-
fullPath =
|
|
60538
|
+
fullPath = path54.join(cwd, file3);
|
|
60438
60539
|
}
|
|
60439
60540
|
const complexity = getComplexityForFile2(fullPath);
|
|
60440
60541
|
if (complexity !== null) {
|
|
@@ -60682,7 +60783,7 @@ var curator_analyze = createSwarmTool({
|
|
|
60682
60783
|
// src/tools/declare-scope.ts
|
|
60683
60784
|
init_tool();
|
|
60684
60785
|
import * as fs43 from "fs";
|
|
60685
|
-
import * as
|
|
60786
|
+
import * as path55 from "path";
|
|
60686
60787
|
init_create_tool();
|
|
60687
60788
|
function validateTaskIdFormat(taskId) {
|
|
60688
60789
|
const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -60761,8 +60862,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
60761
60862
|
};
|
|
60762
60863
|
}
|
|
60763
60864
|
}
|
|
60764
|
-
normalizedDir =
|
|
60765
|
-
const pathParts = normalizedDir.split(
|
|
60865
|
+
normalizedDir = path55.normalize(args2.working_directory);
|
|
60866
|
+
const pathParts = normalizedDir.split(path55.sep);
|
|
60766
60867
|
if (pathParts.includes("..")) {
|
|
60767
60868
|
return {
|
|
60768
60869
|
success: false,
|
|
@@ -60772,10 +60873,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
60772
60873
|
]
|
|
60773
60874
|
};
|
|
60774
60875
|
}
|
|
60775
|
-
const resolvedDir =
|
|
60876
|
+
const resolvedDir = path55.resolve(normalizedDir);
|
|
60776
60877
|
try {
|
|
60777
60878
|
const realPath = fs43.realpathSync(resolvedDir);
|
|
60778
|
-
const planPath2 =
|
|
60879
|
+
const planPath2 = path55.join(realPath, ".swarm", "plan.json");
|
|
60779
60880
|
if (!fs43.existsSync(planPath2)) {
|
|
60780
60881
|
return {
|
|
60781
60882
|
success: false,
|
|
@@ -60799,7 +60900,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
60799
60900
|
console.warn("[declare-scope] fallbackDir is undefined, falling back to process.cwd()");
|
|
60800
60901
|
}
|
|
60801
60902
|
const directory = normalizedDir || fallbackDir;
|
|
60802
|
-
const planPath =
|
|
60903
|
+
const planPath = path55.resolve(directory, ".swarm", "plan.json");
|
|
60803
60904
|
if (!fs43.existsSync(planPath)) {
|
|
60804
60905
|
return {
|
|
60805
60906
|
success: false,
|
|
@@ -60841,8 +60942,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
60841
60942
|
const normalizeErrors = [];
|
|
60842
60943
|
const dir = normalizedDir || fallbackDir || process.cwd();
|
|
60843
60944
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
60844
|
-
if (
|
|
60845
|
-
const relativePath =
|
|
60945
|
+
if (path55.isAbsolute(file3)) {
|
|
60946
|
+
const relativePath = path55.relative(dir, file3).replace(/\\/g, "/");
|
|
60846
60947
|
if (relativePath.startsWith("..")) {
|
|
60847
60948
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
60848
60949
|
return file3;
|
|
@@ -61168,20 +61269,20 @@ function validateBase(base) {
|
|
|
61168
61269
|
function validatePaths(paths) {
|
|
61169
61270
|
if (!paths)
|
|
61170
61271
|
return null;
|
|
61171
|
-
for (const
|
|
61172
|
-
if (!
|
|
61272
|
+
for (const path57 of paths) {
|
|
61273
|
+
if (!path57 || path57.length === 0) {
|
|
61173
61274
|
return "empty path not allowed";
|
|
61174
61275
|
}
|
|
61175
|
-
if (
|
|
61276
|
+
if (path57.length > MAX_PATH_LENGTH) {
|
|
61176
61277
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
61177
61278
|
}
|
|
61178
|
-
if (SHELL_METACHARACTERS2.test(
|
|
61279
|
+
if (SHELL_METACHARACTERS2.test(path57)) {
|
|
61179
61280
|
return "path contains shell metacharacters";
|
|
61180
61281
|
}
|
|
61181
|
-
if (
|
|
61282
|
+
if (path57.startsWith("-")) {
|
|
61182
61283
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
61183
61284
|
}
|
|
61184
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
61285
|
+
if (CONTROL_CHAR_PATTERN2.test(path57)) {
|
|
61185
61286
|
return "path contains control characters";
|
|
61186
61287
|
}
|
|
61187
61288
|
}
|
|
@@ -61262,8 +61363,8 @@ var diff = createSwarmTool({
|
|
|
61262
61363
|
if (parts2.length >= 3) {
|
|
61263
61364
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
61264
61365
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
61265
|
-
const
|
|
61266
|
-
files.push({ path:
|
|
61366
|
+
const path57 = parts2[2];
|
|
61367
|
+
files.push({ path: path57, additions, deletions });
|
|
61267
61368
|
}
|
|
61268
61369
|
}
|
|
61269
61370
|
const contractChanges = [];
|
|
@@ -61546,7 +61647,7 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
61546
61647
|
init_dist();
|
|
61547
61648
|
init_create_tool();
|
|
61548
61649
|
import * as fs44 from "fs";
|
|
61549
|
-
import * as
|
|
61650
|
+
import * as path57 from "path";
|
|
61550
61651
|
var MAX_FILE_SIZE_BYTES5 = 1024 * 1024;
|
|
61551
61652
|
var MAX_EVIDENCE_FILES = 1000;
|
|
61552
61653
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
@@ -61573,9 +61674,9 @@ function validateRequiredTypes(input) {
|
|
|
61573
61674
|
return null;
|
|
61574
61675
|
}
|
|
61575
61676
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
61576
|
-
const normalizedCwd =
|
|
61577
|
-
const swarmPath =
|
|
61578
|
-
const normalizedPath =
|
|
61677
|
+
const normalizedCwd = path57.resolve(cwd);
|
|
61678
|
+
const swarmPath = path57.join(normalizedCwd, ".swarm");
|
|
61679
|
+
const normalizedPath = path57.resolve(filePath);
|
|
61579
61680
|
return normalizedPath.startsWith(swarmPath);
|
|
61580
61681
|
}
|
|
61581
61682
|
function parseCompletedTasks(planContent) {
|
|
@@ -61605,10 +61706,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
61605
61706
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
61606
61707
|
continue;
|
|
61607
61708
|
}
|
|
61608
|
-
const filePath =
|
|
61709
|
+
const filePath = path57.join(evidenceDir, filename);
|
|
61609
61710
|
try {
|
|
61610
|
-
const resolvedPath =
|
|
61611
|
-
const evidenceDirResolved =
|
|
61711
|
+
const resolvedPath = path57.resolve(filePath);
|
|
61712
|
+
const evidenceDirResolved = path57.resolve(evidenceDir);
|
|
61612
61713
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
61613
61714
|
continue;
|
|
61614
61715
|
}
|
|
@@ -61726,7 +61827,7 @@ var evidence_check = createSwarmTool({
|
|
|
61726
61827
|
return JSON.stringify(errorResult, null, 2);
|
|
61727
61828
|
}
|
|
61728
61829
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
61729
|
-
const planPath =
|
|
61830
|
+
const planPath = path57.join(cwd, PLAN_FILE);
|
|
61730
61831
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
61731
61832
|
const errorResult = {
|
|
61732
61833
|
error: "plan file path validation failed",
|
|
@@ -61758,7 +61859,7 @@ var evidence_check = createSwarmTool({
|
|
|
61758
61859
|
};
|
|
61759
61860
|
return JSON.stringify(result2, null, 2);
|
|
61760
61861
|
}
|
|
61761
|
-
const evidenceDir =
|
|
61862
|
+
const evidenceDir = path57.join(cwd, EVIDENCE_DIR2);
|
|
61762
61863
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
61763
61864
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
61764
61865
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -61776,7 +61877,7 @@ var evidence_check = createSwarmTool({
|
|
|
61776
61877
|
init_tool();
|
|
61777
61878
|
init_create_tool();
|
|
61778
61879
|
import * as fs45 from "fs";
|
|
61779
|
-
import * as
|
|
61880
|
+
import * as path58 from "path";
|
|
61780
61881
|
var EXT_MAP = {
|
|
61781
61882
|
python: ".py",
|
|
61782
61883
|
py: ".py",
|
|
@@ -61857,12 +61958,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
61857
61958
|
if (prefix) {
|
|
61858
61959
|
filename = `${prefix}_${filename}`;
|
|
61859
61960
|
}
|
|
61860
|
-
let filepath =
|
|
61861
|
-
const base =
|
|
61862
|
-
const ext =
|
|
61961
|
+
let filepath = path58.join(targetDir, filename);
|
|
61962
|
+
const base = path58.basename(filepath, path58.extname(filepath));
|
|
61963
|
+
const ext = path58.extname(filepath);
|
|
61863
61964
|
let counter = 1;
|
|
61864
61965
|
while (fs45.existsSync(filepath)) {
|
|
61865
|
-
filepath =
|
|
61966
|
+
filepath = path58.join(targetDir, `${base}_${counter}${ext}`);
|
|
61866
61967
|
counter++;
|
|
61867
61968
|
}
|
|
61868
61969
|
try {
|
|
@@ -61983,7 +62084,7 @@ var gitingest = createSwarmTool({
|
|
|
61983
62084
|
init_dist();
|
|
61984
62085
|
init_create_tool();
|
|
61985
62086
|
import * as fs46 from "fs";
|
|
61986
|
-
import * as
|
|
62087
|
+
import * as path59 from "path";
|
|
61987
62088
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
61988
62089
|
var MAX_SYMBOL_LENGTH = 256;
|
|
61989
62090
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
@@ -62031,7 +62132,7 @@ function validateSymbolInput(symbol3) {
|
|
|
62031
62132
|
return null;
|
|
62032
62133
|
}
|
|
62033
62134
|
function isBinaryFile2(filePath, buffer) {
|
|
62034
|
-
const ext =
|
|
62135
|
+
const ext = path59.extname(filePath).toLowerCase();
|
|
62035
62136
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
62036
62137
|
return false;
|
|
62037
62138
|
}
|
|
@@ -62055,15 +62156,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
62055
62156
|
const imports = [];
|
|
62056
62157
|
let _resolvedTarget;
|
|
62057
62158
|
try {
|
|
62058
|
-
_resolvedTarget =
|
|
62159
|
+
_resolvedTarget = path59.resolve(targetFile);
|
|
62059
62160
|
} catch {
|
|
62060
62161
|
_resolvedTarget = targetFile;
|
|
62061
62162
|
}
|
|
62062
|
-
const targetBasename =
|
|
62163
|
+
const targetBasename = path59.basename(targetFile, path59.extname(targetFile));
|
|
62063
62164
|
const targetWithExt = targetFile;
|
|
62064
62165
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
62065
|
-
const normalizedTargetWithExt =
|
|
62066
|
-
const normalizedTargetWithoutExt =
|
|
62166
|
+
const normalizedTargetWithExt = path59.normalize(targetWithExt).replace(/\\/g, "/");
|
|
62167
|
+
const normalizedTargetWithoutExt = path59.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
62067
62168
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
62068
62169
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
62069
62170
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -62086,9 +62187,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
62086
62187
|
}
|
|
62087
62188
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
62088
62189
|
let isMatch = false;
|
|
62089
|
-
const _targetDir =
|
|
62090
|
-
const targetExt =
|
|
62091
|
-
const targetBasenameNoExt =
|
|
62190
|
+
const _targetDir = path59.dirname(targetFile);
|
|
62191
|
+
const targetExt = path59.extname(targetFile);
|
|
62192
|
+
const targetBasenameNoExt = path59.basename(targetFile, targetExt);
|
|
62092
62193
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
62093
62194
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
62094
62195
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -62156,10 +62257,10 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
62156
62257
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
62157
62258
|
for (const entry of entries) {
|
|
62158
62259
|
if (SKIP_DIRECTORIES3.has(entry)) {
|
|
62159
|
-
stats.skippedDirs.push(
|
|
62260
|
+
stats.skippedDirs.push(path59.join(dir, entry));
|
|
62160
62261
|
continue;
|
|
62161
62262
|
}
|
|
62162
|
-
const fullPath =
|
|
62263
|
+
const fullPath = path59.join(dir, entry);
|
|
62163
62264
|
let stat2;
|
|
62164
62265
|
try {
|
|
62165
62266
|
stat2 = fs46.statSync(fullPath);
|
|
@@ -62173,7 +62274,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
62173
62274
|
if (stat2.isDirectory()) {
|
|
62174
62275
|
findSourceFiles(fullPath, files, stats);
|
|
62175
62276
|
} else if (stat2.isFile()) {
|
|
62176
|
-
const ext =
|
|
62277
|
+
const ext = path59.extname(fullPath).toLowerCase();
|
|
62177
62278
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
62178
62279
|
files.push(fullPath);
|
|
62179
62280
|
}
|
|
@@ -62230,7 +62331,7 @@ var imports = createSwarmTool({
|
|
|
62230
62331
|
return JSON.stringify(errorResult, null, 2);
|
|
62231
62332
|
}
|
|
62232
62333
|
try {
|
|
62233
|
-
const targetFile =
|
|
62334
|
+
const targetFile = path59.resolve(file3);
|
|
62234
62335
|
if (!fs46.existsSync(targetFile)) {
|
|
62235
62336
|
const errorResult = {
|
|
62236
62337
|
error: `target file not found: ${file3}`,
|
|
@@ -62252,7 +62353,7 @@ var imports = createSwarmTool({
|
|
|
62252
62353
|
};
|
|
62253
62354
|
return JSON.stringify(errorResult, null, 2);
|
|
62254
62355
|
}
|
|
62255
|
-
const baseDir =
|
|
62356
|
+
const baseDir = path59.dirname(targetFile);
|
|
62256
62357
|
const scanStats = {
|
|
62257
62358
|
skippedDirs: [],
|
|
62258
62359
|
skippedFiles: 0,
|
|
@@ -62862,7 +62963,7 @@ init_config();
|
|
|
62862
62963
|
init_schema();
|
|
62863
62964
|
init_manager();
|
|
62864
62965
|
import * as fs47 from "fs";
|
|
62865
|
-
import * as
|
|
62966
|
+
import * as path60 from "path";
|
|
62866
62967
|
init_review_receipt();
|
|
62867
62968
|
init_utils2();
|
|
62868
62969
|
init_ledger();
|
|
@@ -63086,7 +63187,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
63086
63187
|
safeWarn(`[phase_complete] Completion verify error (non-blocking):`, completionError);
|
|
63087
63188
|
}
|
|
63088
63189
|
try {
|
|
63089
|
-
const driftEvidencePath =
|
|
63190
|
+
const driftEvidencePath = path60.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
63090
63191
|
let driftVerdictFound = false;
|
|
63091
63192
|
let driftVerdictApproved = false;
|
|
63092
63193
|
try {
|
|
@@ -63120,7 +63221,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
63120
63221
|
driftVerdictFound = false;
|
|
63121
63222
|
}
|
|
63122
63223
|
if (!driftVerdictFound) {
|
|
63123
|
-
const specPath =
|
|
63224
|
+
const specPath = path60.join(dir, ".swarm", "spec.md");
|
|
63124
63225
|
const specExists = fs47.existsSync(specPath);
|
|
63125
63226
|
if (!specExists) {
|
|
63126
63227
|
let incompleteTaskCount = 0;
|
|
@@ -63172,7 +63273,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
63172
63273
|
const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
|
|
63173
63274
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
63174
63275
|
try {
|
|
63175
|
-
const projectName =
|
|
63276
|
+
const projectName = path60.basename(dir);
|
|
63176
63277
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
63177
63278
|
if (curationResult) {
|
|
63178
63279
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -63492,7 +63593,7 @@ init_discovery();
|
|
|
63492
63593
|
init_utils();
|
|
63493
63594
|
init_create_tool();
|
|
63494
63595
|
import * as fs48 from "fs";
|
|
63495
|
-
import * as
|
|
63596
|
+
import * as path61 from "path";
|
|
63496
63597
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
63497
63598
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
63498
63599
|
function isValidEcosystem(value) {
|
|
@@ -63510,16 +63611,16 @@ function validateArgs3(args2) {
|
|
|
63510
63611
|
function detectEcosystems(directory) {
|
|
63511
63612
|
const ecosystems = [];
|
|
63512
63613
|
const cwd = directory;
|
|
63513
|
-
if (fs48.existsSync(
|
|
63614
|
+
if (fs48.existsSync(path61.join(cwd, "package.json"))) {
|
|
63514
63615
|
ecosystems.push("npm");
|
|
63515
63616
|
}
|
|
63516
|
-
if (fs48.existsSync(
|
|
63617
|
+
if (fs48.existsSync(path61.join(cwd, "pyproject.toml")) || fs48.existsSync(path61.join(cwd, "requirements.txt"))) {
|
|
63517
63618
|
ecosystems.push("pip");
|
|
63518
63619
|
}
|
|
63519
|
-
if (fs48.existsSync(
|
|
63620
|
+
if (fs48.existsSync(path61.join(cwd, "Cargo.toml"))) {
|
|
63520
63621
|
ecosystems.push("cargo");
|
|
63521
63622
|
}
|
|
63522
|
-
if (fs48.existsSync(
|
|
63623
|
+
if (fs48.existsSync(path61.join(cwd, "go.mod"))) {
|
|
63523
63624
|
ecosystems.push("go");
|
|
63524
63625
|
}
|
|
63525
63626
|
try {
|
|
@@ -63528,10 +63629,10 @@ function detectEcosystems(directory) {
|
|
|
63528
63629
|
ecosystems.push("dotnet");
|
|
63529
63630
|
}
|
|
63530
63631
|
} catch {}
|
|
63531
|
-
if (fs48.existsSync(
|
|
63632
|
+
if (fs48.existsSync(path61.join(cwd, "Gemfile")) || fs48.existsSync(path61.join(cwd, "Gemfile.lock"))) {
|
|
63532
63633
|
ecosystems.push("ruby");
|
|
63533
63634
|
}
|
|
63534
|
-
if (fs48.existsSync(
|
|
63635
|
+
if (fs48.existsSync(path61.join(cwd, "pubspec.yaml"))) {
|
|
63535
63636
|
ecosystems.push("dart");
|
|
63536
63637
|
}
|
|
63537
63638
|
return ecosystems;
|
|
@@ -64554,7 +64655,7 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
|
|
|
64554
64655
|
// src/tools/pre-check-batch.ts
|
|
64555
64656
|
init_dist();
|
|
64556
64657
|
import * as fs50 from "fs";
|
|
64557
|
-
import * as
|
|
64658
|
+
import * as path63 from "path";
|
|
64558
64659
|
|
|
64559
64660
|
// node_modules/yocto-queue/index.js
|
|
64560
64661
|
class Node2 {
|
|
@@ -64829,7 +64930,7 @@ init_dist();
|
|
|
64829
64930
|
init_manager();
|
|
64830
64931
|
init_detector();
|
|
64831
64932
|
import * as fs49 from "fs";
|
|
64832
|
-
import * as
|
|
64933
|
+
import * as path62 from "path";
|
|
64833
64934
|
import { extname as extname12 } from "path";
|
|
64834
64935
|
|
|
64835
64936
|
// src/sast/rules/c.ts
|
|
@@ -65795,9 +65896,9 @@ async function sastScan(input, directory, config3) {
|
|
|
65795
65896
|
_filesSkipped++;
|
|
65796
65897
|
continue;
|
|
65797
65898
|
}
|
|
65798
|
-
const resolvedPath =
|
|
65799
|
-
const resolvedDirectory =
|
|
65800
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
65899
|
+
const resolvedPath = path62.isAbsolute(filePath) ? filePath : path62.resolve(directory, filePath);
|
|
65900
|
+
const resolvedDirectory = path62.resolve(directory);
|
|
65901
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path62.sep) && resolvedPath !== resolvedDirectory) {
|
|
65801
65902
|
_filesSkipped++;
|
|
65802
65903
|
continue;
|
|
65803
65904
|
}
|
|
@@ -65999,18 +66100,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
65999
66100
|
let resolved;
|
|
66000
66101
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
66001
66102
|
if (isWinAbs) {
|
|
66002
|
-
resolved =
|
|
66003
|
-
} else if (
|
|
66004
|
-
resolved =
|
|
66103
|
+
resolved = path63.win32.resolve(inputPath);
|
|
66104
|
+
} else if (path63.isAbsolute(inputPath)) {
|
|
66105
|
+
resolved = path63.resolve(inputPath);
|
|
66005
66106
|
} else {
|
|
66006
|
-
resolved =
|
|
66107
|
+
resolved = path63.resolve(baseDir, inputPath);
|
|
66007
66108
|
}
|
|
66008
|
-
const workspaceResolved =
|
|
66109
|
+
const workspaceResolved = path63.resolve(workspaceDir);
|
|
66009
66110
|
let relative11;
|
|
66010
66111
|
if (isWinAbs) {
|
|
66011
|
-
relative11 =
|
|
66112
|
+
relative11 = path63.win32.relative(workspaceResolved, resolved);
|
|
66012
66113
|
} else {
|
|
66013
|
-
relative11 =
|
|
66114
|
+
relative11 = path63.relative(workspaceResolved, resolved);
|
|
66014
66115
|
}
|
|
66015
66116
|
if (relative11.startsWith("..")) {
|
|
66016
66117
|
return "path traversal detected";
|
|
@@ -66075,7 +66176,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
66075
66176
|
if (typeof file3 !== "string") {
|
|
66076
66177
|
continue;
|
|
66077
66178
|
}
|
|
66078
|
-
const resolvedPath =
|
|
66179
|
+
const resolvedPath = path63.resolve(file3);
|
|
66079
66180
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
66080
66181
|
if (validationError) {
|
|
66081
66182
|
continue;
|
|
@@ -66232,7 +66333,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
66232
66333
|
skippedFiles++;
|
|
66233
66334
|
continue;
|
|
66234
66335
|
}
|
|
66235
|
-
const resolvedPath =
|
|
66336
|
+
const resolvedPath = path63.resolve(file3);
|
|
66236
66337
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
66237
66338
|
if (validationError) {
|
|
66238
66339
|
skippedFiles++;
|
|
@@ -66250,7 +66351,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
66250
66351
|
};
|
|
66251
66352
|
}
|
|
66252
66353
|
for (const file3 of validatedFiles) {
|
|
66253
|
-
const ext =
|
|
66354
|
+
const ext = path63.extname(file3).toLowerCase();
|
|
66254
66355
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
66255
66356
|
skippedFiles++;
|
|
66256
66357
|
continue;
|
|
@@ -66456,7 +66557,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
66456
66557
|
const preexistingFindings = [];
|
|
66457
66558
|
for (const finding of findings) {
|
|
66458
66559
|
const filePath = finding.location.file;
|
|
66459
|
-
const normalised =
|
|
66560
|
+
const normalised = path63.relative(directory, filePath).replace(/\\/g, "/");
|
|
66460
66561
|
const changedLines = changedLineRanges.get(normalised);
|
|
66461
66562
|
if (changedLines && changedLines.has(finding.location.line)) {
|
|
66462
66563
|
newFindings.push(finding);
|
|
@@ -66507,7 +66608,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
66507
66608
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
66508
66609
|
continue;
|
|
66509
66610
|
}
|
|
66510
|
-
changedFiles.push(
|
|
66611
|
+
changedFiles.push(path63.resolve(directory, file3));
|
|
66511
66612
|
}
|
|
66512
66613
|
if (changedFiles.length === 0) {
|
|
66513
66614
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -66695,7 +66796,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
66695
66796
|
};
|
|
66696
66797
|
return JSON.stringify(errorResult, null, 2);
|
|
66697
66798
|
}
|
|
66698
|
-
const resolvedDirectory =
|
|
66799
|
+
const resolvedDirectory = path63.resolve(typedArgs.directory);
|
|
66699
66800
|
const workspaceAnchor = resolvedDirectory;
|
|
66700
66801
|
const dirError = validateDirectory2(resolvedDirectory, workspaceAnchor);
|
|
66701
66802
|
if (dirError) {
|
|
@@ -66802,25 +66903,25 @@ ${paginatedContent}`;
|
|
|
66802
66903
|
// src/tools/save-plan.ts
|
|
66803
66904
|
init_tool();
|
|
66804
66905
|
import * as fs52 from "fs";
|
|
66805
|
-
import * as
|
|
66906
|
+
import * as path65 from "path";
|
|
66806
66907
|
|
|
66807
66908
|
// src/parallel/file-locks.ts
|
|
66808
66909
|
var import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
|
|
66809
66910
|
import * as fs51 from "fs";
|
|
66810
|
-
import * as
|
|
66911
|
+
import * as path64 from "path";
|
|
66811
66912
|
var LOCKS_DIR = ".swarm/locks";
|
|
66812
66913
|
var LOCK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
66813
66914
|
function getLockFilePath(directory, filePath) {
|
|
66814
|
-
const normalized =
|
|
66815
|
-
if (!normalized.startsWith(
|
|
66915
|
+
const normalized = path64.resolve(directory, filePath);
|
|
66916
|
+
if (!normalized.startsWith(path64.resolve(directory))) {
|
|
66816
66917
|
throw new Error("Invalid file path: path traversal not allowed");
|
|
66817
66918
|
}
|
|
66818
66919
|
const hash3 = Buffer.from(normalized).toString("base64").replace(/[/+=]/g, "_");
|
|
66819
|
-
return
|
|
66920
|
+
return path64.join(directory, LOCKS_DIR, `${hash3}.lock`);
|
|
66820
66921
|
}
|
|
66821
66922
|
async function tryAcquireLock(directory, filePath, agent, taskId) {
|
|
66822
66923
|
const lockPath = getLockFilePath(directory, filePath);
|
|
66823
|
-
const locksDir =
|
|
66924
|
+
const locksDir = path64.dirname(lockPath);
|
|
66824
66925
|
if (!fs51.existsSync(locksDir)) {
|
|
66825
66926
|
fs51.mkdirSync(locksDir, { recursive: true });
|
|
66826
66927
|
}
|
|
@@ -66973,7 +67074,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
66973
67074
|
await savePlan(dir, plan);
|
|
66974
67075
|
await writeCheckpoint(dir).catch(() => {});
|
|
66975
67076
|
try {
|
|
66976
|
-
const markerPath =
|
|
67077
|
+
const markerPath = path65.join(dir, ".swarm", ".plan-write-marker");
|
|
66977
67078
|
const marker = JSON.stringify({
|
|
66978
67079
|
source: "save_plan",
|
|
66979
67080
|
timestamp: new Date().toISOString(),
|
|
@@ -66996,7 +67097,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
66996
67097
|
return {
|
|
66997
67098
|
success: true,
|
|
66998
67099
|
message: "Plan saved successfully",
|
|
66999
|
-
plan_path:
|
|
67100
|
+
plan_path: path65.join(dir, ".swarm", "plan.json"),
|
|
67000
67101
|
phases_count: plan.phases.length,
|
|
67001
67102
|
tasks_count: tasksCount,
|
|
67002
67103
|
...warnings.length > 0 ? { warnings } : {}
|
|
@@ -67041,7 +67142,7 @@ var save_plan = createSwarmTool({
|
|
|
67041
67142
|
init_dist();
|
|
67042
67143
|
init_manager();
|
|
67043
67144
|
import * as fs53 from "fs";
|
|
67044
|
-
import * as
|
|
67145
|
+
import * as path66 from "path";
|
|
67045
67146
|
|
|
67046
67147
|
// src/sbom/detectors/index.ts
|
|
67047
67148
|
init_utils();
|
|
@@ -67891,7 +67992,7 @@ function findManifestFiles(rootDir) {
|
|
|
67891
67992
|
try {
|
|
67892
67993
|
const entries = fs53.readdirSync(dir, { withFileTypes: true });
|
|
67893
67994
|
for (const entry of entries) {
|
|
67894
|
-
const fullPath =
|
|
67995
|
+
const fullPath = path66.join(dir, entry.name);
|
|
67895
67996
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
67896
67997
|
continue;
|
|
67897
67998
|
}
|
|
@@ -67900,7 +68001,7 @@ function findManifestFiles(rootDir) {
|
|
|
67900
68001
|
} else if (entry.isFile()) {
|
|
67901
68002
|
for (const pattern of patterns) {
|
|
67902
68003
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
67903
|
-
manifestFiles.push(
|
|
68004
|
+
manifestFiles.push(path66.relative(rootDir, fullPath));
|
|
67904
68005
|
break;
|
|
67905
68006
|
}
|
|
67906
68007
|
}
|
|
@@ -67918,11 +68019,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
67918
68019
|
try {
|
|
67919
68020
|
const entries = fs53.readdirSync(dir, { withFileTypes: true });
|
|
67920
68021
|
for (const entry of entries) {
|
|
67921
|
-
const fullPath =
|
|
68022
|
+
const fullPath = path66.join(dir, entry.name);
|
|
67922
68023
|
if (entry.isFile()) {
|
|
67923
68024
|
for (const pattern of patterns) {
|
|
67924
68025
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
67925
|
-
found.push(
|
|
68026
|
+
found.push(path66.relative(workingDir, fullPath));
|
|
67926
68027
|
break;
|
|
67927
68028
|
}
|
|
67928
68029
|
}
|
|
@@ -67935,11 +68036,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
67935
68036
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
67936
68037
|
const dirs = new Set;
|
|
67937
68038
|
for (const file3 of changedFiles) {
|
|
67938
|
-
let currentDir =
|
|
68039
|
+
let currentDir = path66.dirname(file3);
|
|
67939
68040
|
while (true) {
|
|
67940
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
67941
|
-
dirs.add(
|
|
67942
|
-
const parent =
|
|
68041
|
+
if (currentDir && currentDir !== "." && currentDir !== path66.sep) {
|
|
68042
|
+
dirs.add(path66.join(workingDir, currentDir));
|
|
68043
|
+
const parent = path66.dirname(currentDir);
|
|
67943
68044
|
if (parent === currentDir)
|
|
67944
68045
|
break;
|
|
67945
68046
|
currentDir = parent;
|
|
@@ -68023,7 +68124,7 @@ var sbom_generate = createSwarmTool({
|
|
|
68023
68124
|
const changedFiles = obj.changed_files;
|
|
68024
68125
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
68025
68126
|
const workingDir = directory;
|
|
68026
|
-
const outputDir =
|
|
68127
|
+
const outputDir = path66.isAbsolute(relativeOutputDir) ? relativeOutputDir : path66.join(workingDir, relativeOutputDir);
|
|
68027
68128
|
let manifestFiles = [];
|
|
68028
68129
|
if (scope === "all") {
|
|
68029
68130
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -68046,7 +68147,7 @@ var sbom_generate = createSwarmTool({
|
|
|
68046
68147
|
const processedFiles = [];
|
|
68047
68148
|
for (const manifestFile of manifestFiles) {
|
|
68048
68149
|
try {
|
|
68049
|
-
const fullPath =
|
|
68150
|
+
const fullPath = path66.isAbsolute(manifestFile) ? manifestFile : path66.join(workingDir, manifestFile);
|
|
68050
68151
|
if (!fs53.existsSync(fullPath)) {
|
|
68051
68152
|
continue;
|
|
68052
68153
|
}
|
|
@@ -68063,7 +68164,7 @@ var sbom_generate = createSwarmTool({
|
|
|
68063
68164
|
const bom = generateCycloneDX(allComponents);
|
|
68064
68165
|
const bomJson = serializeCycloneDX(bom);
|
|
68065
68166
|
const filename = generateSbomFilename();
|
|
68066
|
-
const outputPath =
|
|
68167
|
+
const outputPath = path66.join(outputDir, filename);
|
|
68067
68168
|
fs53.writeFileSync(outputPath, bomJson, "utf-8");
|
|
68068
68169
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
68069
68170
|
try {
|
|
@@ -68107,7 +68208,7 @@ var sbom_generate = createSwarmTool({
|
|
|
68107
68208
|
init_dist();
|
|
68108
68209
|
init_create_tool();
|
|
68109
68210
|
import * as fs54 from "fs";
|
|
68110
|
-
import * as
|
|
68211
|
+
import * as path67 from "path";
|
|
68111
68212
|
var SPEC_CANDIDATES = [
|
|
68112
68213
|
"openapi.json",
|
|
68113
68214
|
"openapi.yaml",
|
|
@@ -68139,12 +68240,12 @@ function normalizePath2(p) {
|
|
|
68139
68240
|
}
|
|
68140
68241
|
function discoverSpecFile(cwd, specFileArg) {
|
|
68141
68242
|
if (specFileArg) {
|
|
68142
|
-
const resolvedPath =
|
|
68143
|
-
const normalizedCwd = cwd.endsWith(
|
|
68243
|
+
const resolvedPath = path67.resolve(cwd, specFileArg);
|
|
68244
|
+
const normalizedCwd = cwd.endsWith(path67.sep) ? cwd : cwd + path67.sep;
|
|
68144
68245
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
68145
68246
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
68146
68247
|
}
|
|
68147
|
-
const ext =
|
|
68248
|
+
const ext = path67.extname(resolvedPath).toLowerCase();
|
|
68148
68249
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
68149
68250
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
68150
68251
|
}
|
|
@@ -68158,7 +68259,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
68158
68259
|
return resolvedPath;
|
|
68159
68260
|
}
|
|
68160
68261
|
for (const candidate of SPEC_CANDIDATES) {
|
|
68161
|
-
const candidatePath =
|
|
68262
|
+
const candidatePath = path67.resolve(cwd, candidate);
|
|
68162
68263
|
if (fs54.existsSync(candidatePath)) {
|
|
68163
68264
|
const stats = fs54.statSync(candidatePath);
|
|
68164
68265
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -68170,7 +68271,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
68170
68271
|
}
|
|
68171
68272
|
function parseSpec(specFile) {
|
|
68172
68273
|
const content = fs54.readFileSync(specFile, "utf-8");
|
|
68173
|
-
const ext =
|
|
68274
|
+
const ext = path67.extname(specFile).toLowerCase();
|
|
68174
68275
|
if (ext === ".json") {
|
|
68175
68276
|
return parseJsonSpec(content);
|
|
68176
68277
|
}
|
|
@@ -68246,7 +68347,7 @@ function extractRoutes(cwd) {
|
|
|
68246
68347
|
return;
|
|
68247
68348
|
}
|
|
68248
68349
|
for (const entry of entries) {
|
|
68249
|
-
const fullPath =
|
|
68350
|
+
const fullPath = path67.join(dir, entry.name);
|
|
68250
68351
|
if (entry.isSymbolicLink()) {
|
|
68251
68352
|
continue;
|
|
68252
68353
|
}
|
|
@@ -68256,7 +68357,7 @@ function extractRoutes(cwd) {
|
|
|
68256
68357
|
}
|
|
68257
68358
|
walkDir(fullPath);
|
|
68258
68359
|
} else if (entry.isFile()) {
|
|
68259
|
-
const ext =
|
|
68360
|
+
const ext = path67.extname(entry.name).toLowerCase();
|
|
68260
68361
|
const baseName = entry.name.toLowerCase();
|
|
68261
68362
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
68262
68363
|
continue;
|
|
@@ -68422,7 +68523,7 @@ var schema_drift = createSwarmTool({
|
|
|
68422
68523
|
init_tool();
|
|
68423
68524
|
init_create_tool();
|
|
68424
68525
|
import * as fs55 from "fs";
|
|
68425
|
-
import * as
|
|
68526
|
+
import * as path68 from "path";
|
|
68426
68527
|
var DEFAULT_MAX_RESULTS = 100;
|
|
68427
68528
|
var DEFAULT_MAX_LINES = 200;
|
|
68428
68529
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -68458,11 +68559,11 @@ function containsWindowsAttacks3(str) {
|
|
|
68458
68559
|
}
|
|
68459
68560
|
function isPathInWorkspace3(filePath, workspace) {
|
|
68460
68561
|
try {
|
|
68461
|
-
const resolvedPath =
|
|
68562
|
+
const resolvedPath = path68.resolve(workspace, filePath);
|
|
68462
68563
|
const realWorkspace = fs55.realpathSync(workspace);
|
|
68463
68564
|
const realResolvedPath = fs55.realpathSync(resolvedPath);
|
|
68464
|
-
const relativePath =
|
|
68465
|
-
if (relativePath.startsWith("..") ||
|
|
68565
|
+
const relativePath = path68.relative(realWorkspace, realResolvedPath);
|
|
68566
|
+
if (relativePath.startsWith("..") || path68.isAbsolute(relativePath)) {
|
|
68466
68567
|
return false;
|
|
68467
68568
|
}
|
|
68468
68569
|
return true;
|
|
@@ -68475,11 +68576,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
68475
68576
|
}
|
|
68476
68577
|
function findRgInEnvPath() {
|
|
68477
68578
|
const searchPath = process.env.PATH ?? "";
|
|
68478
|
-
for (const dir of searchPath.split(
|
|
68579
|
+
for (const dir of searchPath.split(path68.delimiter)) {
|
|
68479
68580
|
if (!dir)
|
|
68480
68581
|
continue;
|
|
68481
68582
|
const isWindows = process.platform === "win32";
|
|
68482
|
-
const candidate =
|
|
68583
|
+
const candidate = path68.join(dir, isWindows ? "rg.exe" : "rg");
|
|
68483
68584
|
if (fs55.existsSync(candidate))
|
|
68484
68585
|
return candidate;
|
|
68485
68586
|
}
|
|
@@ -68609,8 +68710,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
68609
68710
|
try {
|
|
68610
68711
|
const entries = fs55.readdirSync(dir, { withFileTypes: true });
|
|
68611
68712
|
for (const entry of entries) {
|
|
68612
|
-
const fullPath =
|
|
68613
|
-
const relativePath =
|
|
68713
|
+
const fullPath = path68.join(dir, entry.name);
|
|
68714
|
+
const relativePath = path68.relative(workspace, fullPath);
|
|
68614
68715
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
68615
68716
|
continue;
|
|
68616
68717
|
}
|
|
@@ -68651,7 +68752,7 @@ async function fallbackSearch(opts) {
|
|
|
68651
68752
|
const matches = [];
|
|
68652
68753
|
let total = 0;
|
|
68653
68754
|
for (const file3 of files) {
|
|
68654
|
-
const fullPath =
|
|
68755
|
+
const fullPath = path68.join(opts.workspace, file3);
|
|
68655
68756
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
68656
68757
|
continue;
|
|
68657
68758
|
}
|
|
@@ -68822,7 +68923,7 @@ init_secretscan();
|
|
|
68822
68923
|
init_tool();
|
|
68823
68924
|
init_create_tool();
|
|
68824
68925
|
import * as fs56 from "fs";
|
|
68825
|
-
import * as
|
|
68926
|
+
import * as path69 from "path";
|
|
68826
68927
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
68827
68928
|
function containsWindowsAttacks4(str) {
|
|
68828
68929
|
if (/:[^\\/]/.test(str))
|
|
@@ -68836,14 +68937,14 @@ function containsWindowsAttacks4(str) {
|
|
|
68836
68937
|
}
|
|
68837
68938
|
function isPathInWorkspace4(filePath, workspace) {
|
|
68838
68939
|
try {
|
|
68839
|
-
const resolvedPath =
|
|
68940
|
+
const resolvedPath = path69.resolve(workspace, filePath);
|
|
68840
68941
|
if (!fs56.existsSync(resolvedPath)) {
|
|
68841
68942
|
return true;
|
|
68842
68943
|
}
|
|
68843
68944
|
const realWorkspace = fs56.realpathSync(workspace);
|
|
68844
68945
|
const realResolvedPath = fs56.realpathSync(resolvedPath);
|
|
68845
|
-
const relativePath =
|
|
68846
|
-
if (relativePath.startsWith("..") ||
|
|
68946
|
+
const relativePath = path69.relative(realWorkspace, realResolvedPath);
|
|
68947
|
+
if (relativePath.startsWith("..") || path69.isAbsolute(relativePath)) {
|
|
68847
68948
|
return false;
|
|
68848
68949
|
}
|
|
68849
68950
|
return true;
|
|
@@ -69051,7 +69152,7 @@ var suggestPatch = createSwarmTool({
|
|
|
69051
69152
|
});
|
|
69052
69153
|
continue;
|
|
69053
69154
|
}
|
|
69054
|
-
const fullPath =
|
|
69155
|
+
const fullPath = path69.resolve(directory, change.file);
|
|
69055
69156
|
if (!fs56.existsSync(fullPath)) {
|
|
69056
69157
|
errors5.push({
|
|
69057
69158
|
success: false,
|
|
@@ -69155,7 +69256,7 @@ init_dist();
|
|
|
69155
69256
|
init_utils();
|
|
69156
69257
|
init_create_tool();
|
|
69157
69258
|
import * as fs57 from "fs";
|
|
69158
|
-
import * as
|
|
69259
|
+
import * as path70 from "path";
|
|
69159
69260
|
var MAX_TEXT_LENGTH = 200;
|
|
69160
69261
|
var MAX_FILE_SIZE_BYTES9 = 1024 * 1024;
|
|
69161
69262
|
var SUPPORTED_EXTENSIONS2 = new Set([
|
|
@@ -69220,9 +69321,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
69220
69321
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
69221
69322
|
}
|
|
69222
69323
|
try {
|
|
69223
|
-
const resolvedPath =
|
|
69224
|
-
const normalizedCwd =
|
|
69225
|
-
const normalizedResolved =
|
|
69324
|
+
const resolvedPath = path70.resolve(paths);
|
|
69325
|
+
const normalizedCwd = path70.resolve(cwd);
|
|
69326
|
+
const normalizedResolved = path70.resolve(resolvedPath);
|
|
69226
69327
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
69227
69328
|
return {
|
|
69228
69329
|
error: "paths must be within the current working directory",
|
|
@@ -69238,7 +69339,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
69238
69339
|
}
|
|
69239
69340
|
}
|
|
69240
69341
|
function isSupportedExtension(filePath) {
|
|
69241
|
-
const ext =
|
|
69342
|
+
const ext = path70.extname(filePath).toLowerCase();
|
|
69242
69343
|
return SUPPORTED_EXTENSIONS2.has(ext);
|
|
69243
69344
|
}
|
|
69244
69345
|
function findSourceFiles2(dir, files = []) {
|
|
@@ -69253,7 +69354,7 @@ function findSourceFiles2(dir, files = []) {
|
|
|
69253
69354
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
69254
69355
|
continue;
|
|
69255
69356
|
}
|
|
69256
|
-
const fullPath =
|
|
69357
|
+
const fullPath = path70.join(dir, entry);
|
|
69257
69358
|
let stat2;
|
|
69258
69359
|
try {
|
|
69259
69360
|
stat2 = fs57.statSync(fullPath);
|
|
@@ -69365,7 +69466,7 @@ var todo_extract = createSwarmTool({
|
|
|
69365
69466
|
filesToScan.push(scanPath);
|
|
69366
69467
|
} else {
|
|
69367
69468
|
const errorResult = {
|
|
69368
|
-
error: `unsupported file extension: ${
|
|
69469
|
+
error: `unsupported file extension: ${path70.extname(scanPath)}`,
|
|
69369
69470
|
total: 0,
|
|
69370
69471
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
69371
69472
|
entries: []
|
|
@@ -69412,14 +69513,14 @@ init_tool();
|
|
|
69412
69513
|
init_schema();
|
|
69413
69514
|
init_gate_evidence();
|
|
69414
69515
|
import * as fs59 from "fs";
|
|
69415
|
-
import * as
|
|
69516
|
+
import * as path72 from "path";
|
|
69416
69517
|
|
|
69417
69518
|
// src/hooks/diff-scope.ts
|
|
69418
69519
|
import * as fs58 from "fs";
|
|
69419
|
-
import * as
|
|
69520
|
+
import * as path71 from "path";
|
|
69420
69521
|
function getDeclaredScope(taskId, directory) {
|
|
69421
69522
|
try {
|
|
69422
|
-
const planPath =
|
|
69523
|
+
const planPath = path71.join(directory, ".swarm", "plan.json");
|
|
69423
69524
|
if (!fs58.existsSync(planPath))
|
|
69424
69525
|
return null;
|
|
69425
69526
|
const raw = fs58.readFileSync(planPath, "utf-8");
|
|
@@ -69535,7 +69636,7 @@ var TIER_3_PATTERNS = [
|
|
|
69535
69636
|
];
|
|
69536
69637
|
function matchesTier3Pattern(files) {
|
|
69537
69638
|
for (const file3 of files) {
|
|
69538
|
-
const fileName =
|
|
69639
|
+
const fileName = path72.basename(file3);
|
|
69539
69640
|
for (const pattern of TIER_3_PATTERNS) {
|
|
69540
69641
|
if (pattern.test(fileName)) {
|
|
69541
69642
|
return true;
|
|
@@ -69549,7 +69650,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
69549
69650
|
if (hasActiveTurboMode()) {
|
|
69550
69651
|
const resolvedDir2 = workingDirectory;
|
|
69551
69652
|
try {
|
|
69552
|
-
const planPath =
|
|
69653
|
+
const planPath = path72.join(resolvedDir2, ".swarm", "plan.json");
|
|
69553
69654
|
const planRaw = fs59.readFileSync(planPath, "utf-8");
|
|
69554
69655
|
const plan = JSON.parse(planRaw);
|
|
69555
69656
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -69616,7 +69717,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
69616
69717
|
}
|
|
69617
69718
|
try {
|
|
69618
69719
|
const resolvedDir2 = workingDirectory;
|
|
69619
|
-
const planPath =
|
|
69720
|
+
const planPath = path72.join(resolvedDir2, ".swarm", "plan.json");
|
|
69620
69721
|
const planRaw = fs59.readFileSync(planPath, "utf-8");
|
|
69621
69722
|
const plan = JSON.parse(planRaw);
|
|
69622
69723
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -69799,8 +69900,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
69799
69900
|
};
|
|
69800
69901
|
}
|
|
69801
69902
|
}
|
|
69802
|
-
normalizedDir =
|
|
69803
|
-
const pathParts = normalizedDir.split(
|
|
69903
|
+
normalizedDir = path72.normalize(args2.working_directory);
|
|
69904
|
+
const pathParts = normalizedDir.split(path72.sep);
|
|
69804
69905
|
if (pathParts.includes("..")) {
|
|
69805
69906
|
return {
|
|
69806
69907
|
success: false,
|
|
@@ -69810,10 +69911,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
69810
69911
|
]
|
|
69811
69912
|
};
|
|
69812
69913
|
}
|
|
69813
|
-
const resolvedDir =
|
|
69914
|
+
const resolvedDir = path72.resolve(normalizedDir);
|
|
69814
69915
|
try {
|
|
69815
69916
|
const realPath = fs59.realpathSync(resolvedDir);
|
|
69816
|
-
const planPath =
|
|
69917
|
+
const planPath = path72.join(realPath, ".swarm", "plan.json");
|
|
69817
69918
|
if (!fs59.existsSync(planPath)) {
|
|
69818
69919
|
return {
|
|
69819
69920
|
success: false,
|
|
@@ -69847,7 +69948,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
69847
69948
|
recoverTaskStateFromDelegations(args2.task_id);
|
|
69848
69949
|
let phaseRequiresReviewer = true;
|
|
69849
69950
|
try {
|
|
69850
|
-
const planPath =
|
|
69951
|
+
const planPath = path72.join(directory, ".swarm", "plan.json");
|
|
69851
69952
|
const planRaw = fs59.readFileSync(planPath, "utf-8");
|
|
69852
69953
|
const plan = JSON.parse(planRaw);
|
|
69853
69954
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -69912,7 +70013,7 @@ init_tool();
|
|
|
69912
70013
|
init_utils2();
|
|
69913
70014
|
init_create_tool();
|
|
69914
70015
|
import fs60 from "fs";
|
|
69915
|
-
import
|
|
70016
|
+
import path73 from "path";
|
|
69916
70017
|
function normalizeVerdict(verdict) {
|
|
69917
70018
|
switch (verdict) {
|
|
69918
70019
|
case "APPROVED":
|
|
@@ -69959,7 +70060,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
69959
70060
|
entries: [evidenceEntry]
|
|
69960
70061
|
};
|
|
69961
70062
|
const filename = "drift-verifier.json";
|
|
69962
|
-
const relativePath =
|
|
70063
|
+
const relativePath = path73.join("evidence", String(phase), filename);
|
|
69963
70064
|
let validatedPath;
|
|
69964
70065
|
try {
|
|
69965
70066
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -69970,10 +70071,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
69970
70071
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
69971
70072
|
}, null, 2);
|
|
69972
70073
|
}
|
|
69973
|
-
const evidenceDir =
|
|
70074
|
+
const evidenceDir = path73.dirname(validatedPath);
|
|
69974
70075
|
try {
|
|
69975
70076
|
await fs60.promises.mkdir(evidenceDir, { recursive: true });
|
|
69976
|
-
const tempPath =
|
|
70077
|
+
const tempPath = path73.join(evidenceDir, `.${filename}.tmp`);
|
|
69977
70078
|
await fs60.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
69978
70079
|
await fs60.promises.rename(tempPath, validatedPath);
|
|
69979
70080
|
return JSON.stringify({
|
|
@@ -70167,7 +70268,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
70167
70268
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
70168
70269
|
preflightTriggerManager = new PTM(automationConfig);
|
|
70169
70270
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
70170
|
-
const swarmDir =
|
|
70271
|
+
const swarmDir = path74.resolve(ctx.directory, ".swarm");
|
|
70171
70272
|
statusArtifact = new ASA(swarmDir);
|
|
70172
70273
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
70173
70274
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|