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/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 path19 from "path";
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 = path19.join(dir, entry.name);
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 = path19.extname(entry.name);
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 = path19.dirname(sourceFile);
32669
- const resolvedPath = path19.resolve(sourceDir, importPath);
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 = path19.relative(directory, sourceFile).replace(/\\/g, "/");
32695
- const relTarget = path19.relative(directory, targetFile).replace(/\\/g, "/");
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 = path19.basename(filePath);
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 !== path19.basename(fileA) && baseA !== path19.basename(fileB);
32717
+ return baseA === baseB && baseA !== path20.basename(fileA) && baseA !== path20.basename(fileB);
32718
32718
  }
32719
32719
  function hasSharedPrefix(fileA, fileB) {
32720
- const dirA = path19.dirname(fileA);
32721
- const dirB = path19.dirname(fileB);
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 = path19.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
32726
- const baseB = path19.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
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 = path19.basename(pair.fileA);
32781
- const baseB = path19.basename(pair.fileB);
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 path22 from "path";
32890
+ import * as path23 from "path";
32891
32891
  function getUserConfigDir3() {
32892
- return process.env.XDG_CONFIG_HOME || path22.join(os5.homedir(), ".config");
32892
+ return process.env.XDG_CONFIG_HOME || path23.join(os5.homedir(), ".config");
32893
32893
  }
32894
32894
  function getConfigPaths(directory) {
32895
- const userConfigPath = path22.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
32896
- const projectConfigPath = path22.join(directory, ".opencode", "opencode-swarm.json");
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 = path22.resolve(configPath);
32922
- const resolvedUser = path22.resolve(normalizedUser);
32923
- const resolvedProject = path22.resolve(normalizedProject);
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 = path22.join(directory, ".swarm");
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 = path22.join(swarmDir, backupFilename);
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 = path22.dirname(targetPath);
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(path23, value, _config) {
33029
+ function validateConfigKey(path24, value, _config) {
33030
33030
  const findings = [];
33031
- switch (path23) {
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, path23, config3, findings) {
33278
+ function walkConfigAndValidate(obj, path24, config3, findings) {
33279
33279
  if (obj === null || obj === undefined) {
33280
33280
  return;
33281
33281
  }
33282
- if (path23 && typeof obj === "object" && !Array.isArray(obj)) {
33283
- const keyFindings = validateConfigKey(path23, obj, config3);
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(path23, obj, config3);
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, `${path23}[${index}]`, config3, findings);
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 = path23 ? `${path23}.${key}` : key;
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 = path22.dirname(configPath);
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 = path22.join(directory, ".swarm");
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 = path22.join(swarmDir, artifactFilename);
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 path24 from "path";
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 path24.join(dir, matches[0]);
34520
+ return path25.join(dir, matches[0]);
34521
34521
  }
34522
34522
  } catch {}
34523
34523
  } else {
34524
- const filePath = path24.join(workingDir, pattern);
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 = path24.join(workingDir, "package.json");
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 = path24.join(workingDir, pattern);
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 = path24.join(dir, entry.name);
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 = path24.join(workingDir, cmd.detectFile);
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 path25 from "path";
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 = path25.join(projectDir, "node_modules", ".bin");
34879
- const biomeBin = isWindows ? path25.join(binDir, "biome.EXE") : path25.join(binDir, "biome");
34880
- const eslintBin = isWindows ? path25.join(binDir, "eslint.cmd") : path25.join(binDir, "eslint");
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(path25.join(cwd, gradlewName)) ? path25.join(cwd, gradlewName) : null;
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(path25.join(cwd, "ruff.toml")))
34930
+ if (fs15.existsSync(path26.join(cwd, "ruff.toml")))
34931
34931
  return isCommandAvailable("ruff");
34932
34932
  try {
34933
- const pyproject = path25.join(cwd, "pyproject.toml");
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(path25.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
34943
+ return fs15.existsSync(path26.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
34944
34944
  }
34945
34945
  function detectGolangciLint(cwd) {
34946
- return fs15.existsSync(path25.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
34946
+ return fs15.existsSync(path26.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
34947
34947
  }
34948
34948
  function detectCheckstyle(cwd) {
34949
- const hasMaven = fs15.existsSync(path25.join(cwd, "pom.xml"));
34950
- const hasGradle = fs15.existsSync(path25.join(cwd, "build.gradle")) || fs15.existsSync(path25.join(cwd, "build.gradle.kts"));
34951
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs15.existsSync(path25.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
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(path25.join(cwd, "build.gradle.kts")) || fs15.existsSync(path25.join(cwd, "build.gradle")) || (() => {
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(path25.join(cwd, "CMakeLists.txt"))) {
34974
+ if (fs15.existsSync(path26.join(cwd, "CMakeLists.txt"))) {
34975
34975
  return isCommandAvailable("cppcheck");
34976
34976
  }
34977
34977
  try {
34978
- const dirsToCheck = [cwd, path25.join(cwd, "src")];
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(path25.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
34992
+ return fs15.existsSync(path26.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
34993
34993
  }
34994
34994
  function detectDartAnalyze(cwd) {
34995
- return fs15.existsSync(path25.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
34995
+ return fs15.existsSync(path26.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
34996
34996
  }
34997
34997
  function detectRubocop(cwd) {
34998
- return (fs15.existsSync(path25.join(cwd, "Gemfile")) || fs15.existsSync(path25.join(cwd, "gems.rb")) || fs15.existsSync(path25.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
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 = path25.join(projectDir, "node_modules", ".bin", binName);
35026
+ const localBin = path26.join(projectDir, "node_modules", ".bin", binName);
35027
35027
  if (fs15.existsSync(localBin))
35028
35028
  return localBin;
35029
- const ancestor = findBinInAncestors(path25.dirname(projectDir), binName);
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 = path25.join(dir, "node_modules", ".bin", binName);
35040
+ const candidate = path26.join(dir, "node_modules", ".bin", binName);
35041
35041
  if (fs15.existsSync(candidate))
35042
35042
  return candidate;
35043
- const parent = path25.dirname(dir);
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(path25.delimiter)) {
35052
+ for (const dir of searchPath.split(path26.delimiter)) {
35053
35053
  if (!dir)
35054
35054
  continue;
35055
- const candidate = path25.join(dir, binName);
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 ? path25.join(projectDir, "node_modules", ".bin", "biome.EXE") : path25.join(projectDir, "node_modules", ".bin", "biome");
35069
- const eslintBin = isWindows ? path25.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path25.join(projectDir, "node_modules", ".bin", "eslint");
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(path25.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
35074
- const eslintAncestor = findBinInAncestors(path25.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
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 path26 from "path";
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 = path26.join(scanDir, ".secretscanignore");
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 (path26.matchesGlob(relPath, pattern))
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 = path26.extname(filePath).toLowerCase();
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 = path26.resolve(scanDir);
35518
- const resolvedRealPath = path26.resolve(realPath);
35519
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path26.sep) || resolvedRealPath.startsWith(`${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 = path26.join(dir, entry);
35546
- const relPath = path26.relative(scanDir, fullPath).replace(/\\/g, "/");
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 = path26.extname(fullPath).toLowerCase();
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 = path26.resolve(directory);
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 path27 from "path";
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 = path27.normalize(workingDirectory);
36003
- const pathParts = normalizedDir.split(path27.sep);
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 = path27.resolve(normalizedDir);
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 path28 from "path";
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(path28.join(cwd, "go.mod")) && isCommandAvailable("go");
36090
+ return fs18.existsSync(path29.join(cwd, "go.mod")) && isCommandAvailable("go");
36091
36091
  }
36092
36092
  function detectJavaMaven(cwd) {
36093
- return fs18.existsSync(path28.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
36093
+ return fs18.existsSync(path29.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
36094
36094
  }
36095
36095
  function detectGradle(cwd) {
36096
- const hasBuildFile = fs18.existsSync(path28.join(cwd, "build.gradle")) || fs18.existsSync(path28.join(cwd, "build.gradle.kts"));
36097
- const hasGradlew = fs18.existsSync(path28.join(cwd, "gradlew")) || fs18.existsSync(path28.join(cwd, "gradlew.bat"));
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(path28.join(cwd, "CMakeLists.txt"));
36111
- const hasBuildCache = fs18.existsSync(path28.join(cwd, "CMakeCache.txt")) || fs18.existsSync(path28.join(cwd, "build", "CMakeCache.txt"));
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(path28.join(cwd, "Package.swift")) && isCommandAvailable("swift");
36115
+ return fs18.existsSync(path29.join(cwd, "Package.swift")) && isCommandAvailable("swift");
36116
36116
  }
36117
36117
  function detectDartTest(cwd) {
36118
- return fs18.existsSync(path28.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
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(path28.join(cwd, ".rspec"));
36122
- const hasGemfile = fs18.existsSync(path28.join(cwd, "Gemfile"));
36123
- const hasSpecDir = fs18.existsSync(path28.join(cwd, "spec"));
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(path28.join(cwd, "test")) && (fs18.existsSync(path28.join(cwd, "Gemfile")) || fs18.existsSync(path28.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
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 = path28.join(baseDir, "package.json");
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(path28.join(baseDir, "bun.lockb")) || fs18.existsSync(path28.join(baseDir, "bun.lock"))) {
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 = path28.join(baseDir, "pyproject.toml");
36162
- const setupCfgPath = path28.join(baseDir, "setup.cfg");
36163
- const requirementsTxtPath = path28.join(baseDir, "requirements.txt");
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 = path28.join(baseDir, "Cargo.toml");
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 = path28.join(baseDir, "pester.config.ps1");
36195
- const pesterConfigJsonPath = path28.join(baseDir, "pester.config.ps1.json");
36196
- const pesterPs1Path = path28.join(baseDir, "tests.ps1");
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 = path28.basename(file3);
36230
- const dirname12 = path28.dirname(file3);
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 = path28.extname(basename5);
36239
+ const ext = path29.extname(basename5);
36240
36240
  const possibleTestFiles = [
36241
- path28.join(dirname12, `${nameWithoutExt}.spec${ext}`),
36242
- path28.join(dirname12, `${nameWithoutExt}.test${ext}`),
36243
- path28.join(dirname12, "__tests__", `${nameWithoutExt}${ext}`),
36244
- path28.join(dirname12, "tests", `${nameWithoutExt}${ext}`),
36245
- path28.join(dirname12, "test", `${nameWithoutExt}${ext}`)
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 = path28.dirname(testFile);
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 = path28.resolve(testDir, importPath);
36274
- const existingExt = path28.extname(resolvedImport);
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 = path28.basename(resolvedImport, path28.extname(resolvedImport));
36295
- const importDir = path28.dirname(resolvedImport);
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 = path28.dirname(sourceFile);
36298
- const sourceBasename = path28.basename(sourceFile, path28.extname(sourceFile));
36299
- const isRelatedDir = importDir === sourceDir || importDir === path28.join(sourceDir, "__tests__") || importDir === path28.join(sourceDir, "tests") || importDir === path28.join(sourceDir, "test");
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 = path28.resolve(testDir, importPath);
36315
- const existingExt = path28.extname(resolvedImport);
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 = path28.dirname(resolvedImport);
36333
- const importBasename = path28.basename(resolvedImport, path28.extname(resolvedImport));
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 = path28.dirname(sourceFile);
36336
- const sourceBasename = path28.basename(sourceFile, path28.extname(sourceFile));
36337
- const isRelatedDir = importDir === sourceDir || importDir === path28.join(sourceDir, "__tests__") || importDir === path28.join(sourceDir, "tests") || importDir === path28.join(sourceDir, "test");
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(path28.join(baseDir, "gradlew.bat"));
36423
- const hasGradlew = fs18.existsSync(path28.join(baseDir, "gradlew"));
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(path28.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
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 = path28.extname(f).toLowerCase();
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 = path28.extname(f).toLowerCase();
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 path29 from "path";
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 = path29.normalize(dir);
37087
- const absolutePath = path29.isAbsolute(normalized) ? normalized : path29.resolve(normalized);
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 = path29.join(dir, "package.json");
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 = path29.join(dir, "CHANGELOG.md");
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 = path29.join(dir, file3);
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 path36 from "path";
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 path36.join(directory, ".swarm", "evidence");
37710
+ return path37.join(directory, ".swarm", "evidence");
37711
37711
  }
37712
37712
  function getEvidencePath(directory, taskId) {
37713
- return path36.join(getEvidenceDir(directory), `${taskId}.json`);
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 path38 from "path";
37824
+ import * as path39 from "path";
37825
37825
  function resolveReceiptsDir(directory) {
37826
- return path38.join(directory, ".swarm", "review-receipts");
37826
+ return path39.join(directory, ".swarm", "review-receipts");
37827
37827
  }
37828
37828
  function resolveReceiptIndexPath(directory) {
37829
- return path38.join(resolveReceiptsDir(directory), "index.json");
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 = path38.dirname(indexPath);
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 = path38.join(receiptsDir, filename);
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 = path38.join(resolveReceiptsDir(directory), entry.filename);
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 = path38.join(resolveReceiptsDir(directory), entry.filename);
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 = path38.join(resolveReceiptsDir(directory), entry.filename);
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 path42 from "path";
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 = path42.basename(filePath);
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 = path42.join(directory, ".swarm", "doc-manifest.json");
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 = path42.join(directory, file3.path);
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 = path42.join(directory, entry);
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, path42.basename(entry));
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(path42.dirname(manifestPath), { recursive: true });
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 = path42.join(directory, ".swarm", "doc-manifest.json");
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(path42.join(directory, docFile.path), "utf-8");
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", path42.basename(docFile.path)],
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 = path42.join(directory, ".swarm", "doc-manifest.json");
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 path45 from "path";
38450
+ import * as path46 from "path";
38451
38451
  async function readPriorDriftReports(directory) {
38452
- const swarmDir = path45.join(directory, ".swarm");
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 = path45.dirname(filePath);
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(path55) {
40072
+ function locateFile(path56) {
40073
40073
  if (Module["locateFile"]) {
40074
- return Module["locateFile"](path55, scriptDirectory);
40074
+ return Module["locateFile"](path56, scriptDirectory);
40075
40075
  }
40076
- return scriptDirectory + path55;
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 path55 from "path";
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 = path55.dirname(fileURLToPath2(import.meta.url));
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 path55.join(grammarsDir, scriptName);
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 = path55.dirname(fileURLToPath2(import.meta.url));
41851
+ const thisDir = path56.dirname(fileURLToPath2(import.meta.url));
41852
41852
  const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
41853
- return isSource ? path55.join(thisDir, "grammars") : path55.join(thisDir, "lang", "grammars");
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 = path55.join(getGrammarsDirAbsolute(), wasmFileName);
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 path73 from "path";
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, _args) {
48070
+ async function handleCloseCommand(directory, args2) {
48069
48071
  const planPath = validateSwarmPath(directory, "plan.json");
48070
- let planData;
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
- return `\u274C Failed to read plan.json: ${error93 instanceof Error ? error93.message : String(error93)}`;
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
- const allDone = phases.every((p) => p.status === "complete" || p.status === "completed" || p.status === "blocked" || p.status === "closed");
48080
- if (allDone) {
48081
- const closedCount = phases.filter((p) => p.status === "closed").length;
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
- for (const phase of inProgressPhases) {
48092
- closedPhases.push(phase.id);
48093
- const retroResult = await executeWriteRetro({
48094
- phase: phase.id,
48095
- summary: "Phase closed via /swarm close",
48096
- task_count: Math.max(1, (phase.tasks ?? []).length),
48097
- task_complexity: "simple",
48098
- total_tool_calls: 0,
48099
- coder_revisions: 0,
48100
- reviewer_rejections: 0,
48101
- test_failures: 0,
48102
- security_findings: 0,
48103
- integration_issues: 0
48104
- }, directory);
48105
- try {
48106
- const parsed = JSON.parse(retroResult);
48107
- if (parsed.success !== true) {
48108
- warnings.push(`Retrospective write failed for phase ${phase.id}`);
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
- } catch {}
48111
- for (const task of phase.tasks ?? []) {
48112
- if (task.status !== "completed" && task.status !== "complete") {
48113
- closedTasks.push(task.id);
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([], projectName, { phase_number: 0 }, directory, config3);
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
- for (const phase of phases) {
48123
- if (phase.status !== "complete" && phase.status !== "completed") {
48124
- phase.status = "closed";
48125
- if (!closedPhases.includes(phase.id)) {
48126
- closedPhases.push(phase.id);
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
- for (const task of phase.tasks ?? []) {
48130
- if (task.status !== "completed" && task.status !== "complete") {
48131
- task.status = "closed";
48132
- if (!closedTasks.includes(task.id)) {
48133
- closedTasks.push(task.id);
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 fs11.writeFile(planPath, JSON.stringify(planData, null, 2), "utf-8");
48177
+ await archiveEvidence(directory, 30, 10);
48140
48178
  } catch (error93) {
48141
- console.warn("[close-command] Failed to write plan.json:", error93);
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 archiveEvidence(directory, 30, 10);
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] archiveEvidence error:", error93);
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
- "- Wrote retrospectives for in-progress phases",
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 path17 from "path";
48291
+ import * as path18 from "path";
48191
48292
  function getUserConfigDir2() {
48192
- return process.env.XDG_CONFIG_HOME || path17.join(os4.homedir(), ".config");
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 = path17.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
48197
- const projectConfigPath = path17.join(directory, ".opencode", "opencode-swarm.json");
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 path18 from "path";
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(path18.dirname(resolvedPath), { recursive: true });
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 = path18.join(directory, ".swarm", "events.jsonl");
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: path18.basename(directory)
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 path20 from "path";
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 = path20.basename(path20.resolve(directory));
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 path21 from "path";
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 = path21.join(directory, ".opencode/opencode-swarm.json");
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 = path21.dirname(fileURLToPath(import.meta.url));
49498
+ const thisDir = path22.dirname(fileURLToPath(import.meta.url));
49398
49499
  const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/services");
49399
- const grammarDir = isSource ? path21.join(thisDir, "..", "lang", "grammars") : path21.join(thisDir, "lang", "grammars");
49500
+ const grammarDir = isSource ? path22.join(thisDir, "..", "lang", "grammars") : path22.join(thisDir, "lang", "grammars");
49400
49501
  const missing = [];
49401
- if (!existsSync10(path21.join(grammarDir, "tree-sitter.wasm"))) {
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(path21.join(grammarDir, file3))) {
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 = path21.join(directory, ".swarm/checkpoints.json");
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 = path21.join(directory, ".swarm/events.jsonl");
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 = path21.join(directory, ".swarm/events.jsonl");
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 = path21.join(directory, ".swarm/curator-summary.json");
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 path23 from "path";
50575
+ import * as path24 from "path";
50475
50576
  async function migrateContextToKnowledge(directory, config3) {
50476
- const sentinelPath = path23.join(directory, ".swarm", ".knowledge-migrated");
50477
- const contextPath = path23.join(directory, ".swarm", "context.md");
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 = path23.join(directory, "package.json");
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 path23.basename(directory);
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(path23.dirname(sentinelPath), { recursive: true });
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 path30 from "path";
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 = path30.join(process.env.LOCALAPPDATA || path30.join(home, "AppData", "Local"), "opencode-swarm", "Data");
51081
+ dataDir = path31.join(process.env.LOCALAPPDATA || path31.join(home, "AppData", "Local"), "opencode-swarm", "Data");
50981
51082
  } else if (platform === "darwin") {
50982
- dataDir = path30.join(home, "Library", "Application Support", "opencode-swarm");
51083
+ dataDir = path31.join(home, "Library", "Application Support", "opencode-swarm");
50983
51084
  } else {
50984
- dataDir = path30.join(process.env.XDG_DATA_HOME || path30.join(home, ".local", "share"), "opencode-swarm");
51085
+ dataDir = path31.join(process.env.XDG_DATA_HOME || path31.join(home, ".local", "share"), "opencode-swarm");
50985
51086
  }
50986
- return path30.join(dataDir, "hive-knowledge.jsonl");
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 = path30.dirname(hivePath);
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 = path30.join(directory, ".swarm", "knowledge.jsonl");
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 = path30.dirname(hivePath);
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 path31 from "path";
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 = path31.dirname(validateSwarmPath(directory, "session/state.json"));
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 = path31.join(sessionDir, file3);
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 path32 from "path";
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 = path32.join("summaries", `${sanitizedId}.json`);
51366
+ const relativePath = path33.join("summaries", `${sanitizedId}.json`);
51266
51367
  const summaryPath = validateSwarmPath(directory, relativePath);
51267
- const summaryDir = path32.dirname(summaryPath);
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 = path32.join(summaryDir, `${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);
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 = path32.join("summaries", `${sanitizedId}.json`);
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 path33 from "path";
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 = path33.join(checkpointDir, file3);
51403
- const dest = path33.join(swarmDir, file3);
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 path34 = await import("path");
51468
- const reportPath = path34.join(directory, ".swarm", "simulate-report.md");
51469
- await fs24.mkdir(path34.dirname(reportPath), { recursive: true });
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 path34 from "path";
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 = path34.join(directory, ".swarm", "context-snapshot.md");
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 path35 = nodePath2.join(directory, ".swarm", "context.md");
52583
- const tempPath = `${path35}.tmp`;
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, path35);
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 path37 from "path";
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 path35 = await import("path");
53277
- const filePath = path35.join(directory, file3);
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 path35 from "path";
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 = path35.resolve(directory, ".swarm");
53494
- const resolved = path35.resolve(directory, filePath);
53495
- const relative5 = path35.relative(swarmDir, resolved);
53496
- return relative5.startsWith("..") || path35.isAbsolute(relative5);
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 = path35.resolve(dir, filePath);
53665
+ const resolvedFile = path36.resolve(dir, filePath);
53565
53666
  return scopeEntries.some((scope) => {
53566
- const resolvedScope = path35.resolve(dir, scope);
53667
+ const resolvedScope = path36.resolve(dir, scope);
53567
53668
  if (resolvedFile === resolvedScope)
53568
53669
  return true;
53569
- const rel = path35.relative(resolvedScope, resolvedFile);
53570
- return rel.length > 0 && !rel.startsWith("..") && !path35.isAbsolute(rel);
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 = path35.resolve(effectiveDirectory, targetPath).toLowerCase();
53830
- const planMdPath = path35.resolve(effectiveDirectory, ".swarm", "plan.md").toLowerCase();
53831
- const planJsonPath = path35.resolve(effectiveDirectory, ".swarm", "plan.json").toLowerCase();
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 = path35.resolve(effectiveDirectory, p);
53839
- const planMdPath = path35.resolve(effectiveDirectory, ".swarm", "plan.md").toLowerCase();
53840
- const planJsonPath = path35.resolve(effectiveDirectory, ".swarm", "plan.json").toLowerCase();
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(path35.relative(effectiveDirectory, path35.resolve(effectiveDirectory, targetPath)))) {
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 = path35.resolve(dir, filePath);
54535
- const normalizedPath = path35.relative(dir, resolved).replace(/\\/g, "/");
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 = path37.resolve(directory);
54618
- const planPath = path37.join(resolvedDirectory, ".swarm", "plan.json");
54619
- const resolvedPlanPath = path37.resolve(planPath);
54620
- if (!resolvedPlanPath.startsWith(resolvedDirectory + path37.sep) && resolvedPlanPath !== 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 path39 from "path";
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 = path39.join(directory, ".swarm", "curator-briefing.md");
55470
+ const briefingPath = path40.join(directory, ".swarm", "curator-briefing.md");
55370
55471
  const { mkdir: mkdir5, writeFile: writeFile5 } = await import("fs/promises");
55371
- await mkdir5(path39.dirname(briefingPath), { recursive: true });
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 path43 from "path";
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 path40 from "path";
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 = path40.join(directory, ".swarm", "context.md");
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 path41 from "path";
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 = path41.join(directory, ".swarm");
56111
+ const swarmDir = path42.join(directory, ".swarm");
56011
56112
  await fs30.mkdir(swarmDir, { recursive: true });
56012
- const eventsPath = path41.join(swarmDir, "events.jsonl");
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 = path43.basename(path43.resolve(directory));
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 path44 from "path";
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(path44.join(projectDir, "bun.lockb")))
57712
+ if (fs33.existsSync(path45.join(projectDir, "bun.lockb")))
57612
57713
  return "bun";
57613
- if (fs33.existsSync(path44.join(projectDir, "pnpm-lock.yaml")))
57714
+ if (fs33.existsSync(path45.join(projectDir, "pnpm-lock.yaml")))
57614
57715
  return "pnpm";
57615
- if (fs33.existsSync(path44.join(projectDir, "yarn.lock")))
57716
+ if (fs33.existsSync(path45.join(projectDir, "yarn.lock")))
57616
57717
  return "yarn";
57617
- if (fs33.existsSync(path44.join(projectDir, "package-lock.json")))
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 = path44.join(projectDir, "package.json");
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(path44.join(projectDir, "tsconfig.json"))) {}
57640
- const hasTSMarkers = deps?.typescript || fs33.existsSync(path44.join(projectDir, "tsconfig.json"));
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(path44.join(projectDir, "go.mod"))) {
57749
+ if (fs33.existsSync(path45.join(projectDir, "go.mod"))) {
57649
57750
  return { command: ["go", "vet", "./..."], language: "go" };
57650
57751
  }
57651
- if (fs33.existsSync(path44.join(projectDir, "Cargo.toml"))) {
57752
+ if (fs33.existsSync(path45.join(projectDir, "Cargo.toml"))) {
57652
57753
  return { command: ["cargo", "check"], language: "rust" };
57653
57754
  }
57654
- if (fs33.existsSync(path44.join(projectDir, "pyproject.toml")) || fs33.existsSync(path44.join(projectDir, "requirements.txt")) || fs33.existsSync(path44.join(projectDir, "setup.py"))) {
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 path46 from "path";
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 = path46.resolve(dir, filePath);
58108
+ const resolvedFile = path47.resolve(dir, filePath);
58008
58109
  return scopeEntries.some((scope) => {
58009
- const resolvedScope = path46.resolve(dir, scope);
58110
+ const resolvedScope = path47.resolve(dir, scope);
58010
58111
  if (resolvedFile === resolvedScope)
58011
58112
  return true;
58012
- const rel = path46.relative(resolvedScope, resolvedFile);
58013
- return rel.length > 0 && !rel.startsWith("..") && !path46.isAbsolute(rel);
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 path47 from "path";
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 = path47.join(dir, entry.name);
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(path47.join(projectDir, "package.json"));
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 path49 from "path";
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 path48 from "path";
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 = path48.resolve(workspace, filePath);
58655
+ const resolvedPath = path49.resolve(workspace, filePath);
58555
58656
  const realWorkspace = fs37.realpathSync(workspace);
58556
58657
  const realResolvedPath = fs37.realpathSync(resolvedPath);
58557
- const relativePath = path48.relative(realWorkspace, realResolvedPath);
58558
- if (relativePath.startsWith("..") || path48.isAbsolute(relativePath)) {
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 = path48.join(cwd, filePath);
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 = path48.join(cwd, filePath);
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 = path48.extname(file3);
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 = path49.resolve(workspace, filePath);
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 = path49.relative(realWorkspace, realResolvedPath);
58888
- if (relativePath.startsWith("..") || path49.isAbsolute(relativePath)) {
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 = path49.extname(file3);
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 = path49.join(cwd, file3);
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 path50 from "path";
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 = path50.resolve(workspaceRoot);
59239
- const swarmPath = path50.join(normalizedWorkspace, ".swarm", "evidence");
59240
- const normalizedPath = path50.resolve(filePath);
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 = path50.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
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 path51 from "path";
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 = path51.resolve(directory, normalizedPath);
59570
- const projectRoot = path51.resolve(directory);
59571
- const relative9 = path51.relative(projectRoot, resolvedPath);
59572
- const withinProject = relative9 === "" || !relative9.startsWith("..") && !path51.isAbsolute(relative9);
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 = path51.join(directory, ".swarm", "evidence", `${phase}`);
59628
- const evidencePath = path51.join(evidenceDir, "completion-verify.json");
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 path53 from "path";
59806
+ import * as path54 from "path";
59706
59807
 
59707
59808
  // src/quality/metrics.ts
59708
59809
  import * as fs41 from "fs";
59709
- import * as path52 from "path";
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 = path52.isAbsolute(file3) ? file3 : path52.join(workingDir, file3);
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 = path52.extname(filePath).toLowerCase();
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 = path52.isAbsolute(file3) ? file3 : path52.join(workingDir, file3);
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 = path52.isAbsolute(file3) ? file3 : path52.join(workingDir, file3);
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 = path52.basename(filePath);
59978
- const _ext = path52.extname(filePath).toLowerCase();
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(path53, glob) {
60060
- const normalizedPath = path53.replace(/\\/g, "/");
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(path53, glob) {
60092
- const normalizedPath = path53.replace(/\\/g, "/");
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 = path52.join(workingDir, "src");
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 = path52.join(workingDir, dir);
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 = path52.join(workingDir, "tests");
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 = path52.join(workingDir, dir);
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 = path52.join(dirPath, entry.name);
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 = path52.extname(entry.name).toLowerCase();
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 = path53.extname(file3).toLowerCase();
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 = path53.join(cwd, file3);
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 path54 from "path";
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 = path54.normalize(args2.working_directory);
60765
- const pathParts = normalizedDir.split(path54.sep);
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 = path54.resolve(normalizedDir);
60876
+ const resolvedDir = path55.resolve(normalizedDir);
60776
60877
  try {
60777
60878
  const realPath = fs43.realpathSync(resolvedDir);
60778
- const planPath2 = path54.join(realPath, ".swarm", "plan.json");
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 = path54.resolve(directory, ".swarm", "plan.json");
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 (path54.isAbsolute(file3)) {
60845
- const relativePath = path54.relative(dir, file3).replace(/\\/g, "/");
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 path56 of paths) {
61172
- if (!path56 || path56.length === 0) {
61272
+ for (const path57 of paths) {
61273
+ if (!path57 || path57.length === 0) {
61173
61274
  return "empty path not allowed";
61174
61275
  }
61175
- if (path56.length > MAX_PATH_LENGTH) {
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(path56)) {
61279
+ if (SHELL_METACHARACTERS2.test(path57)) {
61179
61280
  return "path contains shell metacharacters";
61180
61281
  }
61181
- if (path56.startsWith("-")) {
61282
+ if (path57.startsWith("-")) {
61182
61283
  return 'path cannot start with "-" (option-like arguments not allowed)';
61183
61284
  }
61184
- if (CONTROL_CHAR_PATTERN2.test(path56)) {
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 path56 = parts2[2];
61266
- files.push({ path: path56, additions, deletions });
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 path56 from "path";
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 = path56.resolve(cwd);
61577
- const swarmPath = path56.join(normalizedCwd, ".swarm");
61578
- const normalizedPath = path56.resolve(filePath);
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 = path56.join(evidenceDir, filename);
61709
+ const filePath = path57.join(evidenceDir, filename);
61609
61710
  try {
61610
- const resolvedPath = path56.resolve(filePath);
61611
- const evidenceDirResolved = path56.resolve(evidenceDir);
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 = path56.join(cwd, PLAN_FILE);
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 = path56.join(cwd, EVIDENCE_DIR2);
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 path57 from "path";
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 = path57.join(targetDir, filename);
61861
- const base = path57.basename(filepath, path57.extname(filepath));
61862
- const ext = path57.extname(filepath);
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 = path57.join(targetDir, `${base}_${counter}${ext}`);
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 path58 from "path";
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 = path58.extname(filePath).toLowerCase();
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 = path58.resolve(targetFile);
62159
+ _resolvedTarget = path59.resolve(targetFile);
62059
62160
  } catch {
62060
62161
  _resolvedTarget = targetFile;
62061
62162
  }
62062
- const targetBasename = path58.basename(targetFile, path58.extname(targetFile));
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 = path58.normalize(targetWithExt).replace(/\\/g, "/");
62066
- const normalizedTargetWithoutExt = path58.normalize(targetWithoutExt).replace(/\\/g, "/");
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 = path58.dirname(targetFile);
62090
- const targetExt = path58.extname(targetFile);
62091
- const targetBasenameNoExt = path58.basename(targetFile, targetExt);
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(path58.join(dir, entry));
62260
+ stats.skippedDirs.push(path59.join(dir, entry));
62160
62261
  continue;
62161
62262
  }
62162
- const fullPath = path58.join(dir, entry);
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 = path58.extname(fullPath).toLowerCase();
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 = path58.resolve(file3);
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 = path58.dirname(targetFile);
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 path59 from "path";
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 = path59.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
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 = path59.join(dir, ".swarm", "spec.md");
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 = path59.basename(dir);
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 path60 from "path";
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(path60.join(cwd, "package.json"))) {
63614
+ if (fs48.existsSync(path61.join(cwd, "package.json"))) {
63514
63615
  ecosystems.push("npm");
63515
63616
  }
63516
- if (fs48.existsSync(path60.join(cwd, "pyproject.toml")) || fs48.existsSync(path60.join(cwd, "requirements.txt"))) {
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(path60.join(cwd, "Cargo.toml"))) {
63620
+ if (fs48.existsSync(path61.join(cwd, "Cargo.toml"))) {
63520
63621
  ecosystems.push("cargo");
63521
63622
  }
63522
- if (fs48.existsSync(path60.join(cwd, "go.mod"))) {
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(path60.join(cwd, "Gemfile")) || fs48.existsSync(path60.join(cwd, "Gemfile.lock"))) {
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(path60.join(cwd, "pubspec.yaml"))) {
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 path62 from "path";
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 path61 from "path";
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 = path61.isAbsolute(filePath) ? filePath : path61.resolve(directory, filePath);
65799
- const resolvedDirectory = path61.resolve(directory);
65800
- if (!resolvedPath.startsWith(resolvedDirectory + path61.sep) && resolvedPath !== 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 = path62.win32.resolve(inputPath);
66003
- } else if (path62.isAbsolute(inputPath)) {
66004
- resolved = path62.resolve(inputPath);
66103
+ resolved = path63.win32.resolve(inputPath);
66104
+ } else if (path63.isAbsolute(inputPath)) {
66105
+ resolved = path63.resolve(inputPath);
66005
66106
  } else {
66006
- resolved = path62.resolve(baseDir, inputPath);
66107
+ resolved = path63.resolve(baseDir, inputPath);
66007
66108
  }
66008
- const workspaceResolved = path62.resolve(workspaceDir);
66109
+ const workspaceResolved = path63.resolve(workspaceDir);
66009
66110
  let relative11;
66010
66111
  if (isWinAbs) {
66011
- relative11 = path62.win32.relative(workspaceResolved, resolved);
66112
+ relative11 = path63.win32.relative(workspaceResolved, resolved);
66012
66113
  } else {
66013
- relative11 = path62.relative(workspaceResolved, resolved);
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 = path62.resolve(file3);
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 = path62.resolve(file3);
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 = path62.extname(file3).toLowerCase();
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 = path62.relative(directory, filePath).replace(/\\/g, "/");
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(path62.resolve(directory, file3));
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 = path62.resolve(typedArgs.directory);
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 path64 from "path";
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 path63 from "path";
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 = path63.resolve(directory, filePath);
66815
- if (!normalized.startsWith(path63.resolve(directory))) {
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 path63.join(directory, LOCKS_DIR, `${hash3}.lock`);
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 = path63.dirname(lockPath);
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 = path64.join(dir, ".swarm", ".plan-write-marker");
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: path64.join(dir, ".swarm", "plan.json"),
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 path65 from "path";
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 = path65.join(dir, entry.name);
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(path65.relative(rootDir, fullPath));
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 = path65.join(dir, entry.name);
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(path65.relative(workingDir, fullPath));
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 = path65.dirname(file3);
68039
+ let currentDir = path66.dirname(file3);
67939
68040
  while (true) {
67940
- if (currentDir && currentDir !== "." && currentDir !== path65.sep) {
67941
- dirs.add(path65.join(workingDir, currentDir));
67942
- const parent = path65.dirname(currentDir);
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 = path65.isAbsolute(relativeOutputDir) ? relativeOutputDir : path65.join(workingDir, relativeOutputDir);
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 = path65.isAbsolute(manifestFile) ? manifestFile : path65.join(workingDir, manifestFile);
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 = path65.join(outputDir, filename);
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 path66 from "path";
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 = path66.resolve(cwd, specFileArg);
68143
- const normalizedCwd = cwd.endsWith(path66.sep) ? cwd : cwd + path66.sep;
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 = path66.extname(resolvedPath).toLowerCase();
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 = path66.resolve(cwd, candidate);
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 = path66.extname(specFile).toLowerCase();
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 = path66.join(dir, entry.name);
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 = path66.extname(entry.name).toLowerCase();
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 path67 from "path";
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 = path67.resolve(workspace, filePath);
68562
+ const resolvedPath = path68.resolve(workspace, filePath);
68462
68563
  const realWorkspace = fs55.realpathSync(workspace);
68463
68564
  const realResolvedPath = fs55.realpathSync(resolvedPath);
68464
- const relativePath = path67.relative(realWorkspace, realResolvedPath);
68465
- if (relativePath.startsWith("..") || path67.isAbsolute(relativePath)) {
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(path67.delimiter)) {
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 = path67.join(dir, isWindows ? "rg.exe" : "rg");
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 = path67.join(dir, entry.name);
68613
- const relativePath = path67.relative(workspace, fullPath);
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 = path67.join(opts.workspace, file3);
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 path68 from "path";
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 = path68.resolve(workspace, filePath);
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 = path68.relative(realWorkspace, realResolvedPath);
68846
- if (relativePath.startsWith("..") || path68.isAbsolute(relativePath)) {
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 = path68.resolve(directory, change.file);
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 path69 from "path";
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 = path69.resolve(paths);
69224
- const normalizedCwd = path69.resolve(cwd);
69225
- const normalizedResolved = path69.resolve(resolvedPath);
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 = path69.extname(filePath).toLowerCase();
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 = path69.join(dir, entry);
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: ${path69.extname(scanPath)}`,
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 path71 from "path";
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 path70 from "path";
69520
+ import * as path71 from "path";
69420
69521
  function getDeclaredScope(taskId, directory) {
69421
69522
  try {
69422
- const planPath = path70.join(directory, ".swarm", "plan.json");
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 = path71.basename(file3);
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 = path71.join(resolvedDir2, ".swarm", "plan.json");
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 = path71.join(resolvedDir2, ".swarm", "plan.json");
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 = path71.normalize(args2.working_directory);
69803
- const pathParts = normalizedDir.split(path71.sep);
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 = path71.resolve(normalizedDir);
69914
+ const resolvedDir = path72.resolve(normalizedDir);
69814
69915
  try {
69815
69916
  const realPath = fs59.realpathSync(resolvedDir);
69816
- const planPath = path71.join(realPath, ".swarm", "plan.json");
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 = path71.join(directory, ".swarm", "plan.json");
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 path72 from "path";
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 = path72.join("evidence", String(phase), filename);
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 = path72.dirname(validatedPath);
70074
+ const evidenceDir = path73.dirname(validatedPath);
69974
70075
  try {
69975
70076
  await fs60.promises.mkdir(evidenceDir, { recursive: true });
69976
- const tempPath = path72.join(evidenceDir, `.${filename}.tmp`);
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 = path73.resolve(ctx.directory, ".swarm");
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) {