opencode-swarm 6.86.8 → 6.86.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -17669,14 +17669,14 @@ __export(exports_config_doctor, {
17669
17669
  });
17670
17670
  import * as crypto3 from "crypto";
17671
17671
  import * as fs8 from "fs";
17672
- import * as os5 from "os";
17673
- import * as path18 from "path";
17672
+ import * as os6 from "os";
17673
+ import * as path19 from "path";
17674
17674
  function getUserConfigDir3() {
17675
- return process.env.XDG_CONFIG_HOME || path18.join(os5.homedir(), ".config");
17675
+ return process.env.XDG_CONFIG_HOME || path19.join(os6.homedir(), ".config");
17676
17676
  }
17677
17677
  function getConfigPaths(directory) {
17678
- const userConfigPath = path18.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
17679
- const projectConfigPath = path18.join(directory, ".opencode", "opencode-swarm.json");
17678
+ const userConfigPath = path19.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
17679
+ const projectConfigPath = path19.join(directory, ".opencode", "opencode-swarm.json");
17680
17680
  return { userConfigPath, projectConfigPath };
17681
17681
  }
17682
17682
  function computeHash(content) {
@@ -17701,9 +17701,9 @@ function isValidConfigPath(configPath, directory) {
17701
17701
  const normalizedUser = userConfigPath.replace(/\\/g, "/");
17702
17702
  const normalizedProject = projectConfigPath.replace(/\\/g, "/");
17703
17703
  try {
17704
- const resolvedConfig = path18.resolve(configPath);
17705
- const resolvedUser = path18.resolve(normalizedUser);
17706
- const resolvedProject = path18.resolve(normalizedProject);
17704
+ const resolvedConfig = path19.resolve(configPath);
17705
+ const resolvedUser = path19.resolve(normalizedUser);
17706
+ const resolvedProject = path19.resolve(normalizedProject);
17707
17707
  return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
17708
17708
  } catch {
17709
17709
  return false;
@@ -17743,12 +17743,12 @@ function createConfigBackup(directory) {
17743
17743
  };
17744
17744
  }
17745
17745
  function writeBackupArtifact(directory, backup) {
17746
- const swarmDir = path18.join(directory, ".swarm");
17746
+ const swarmDir = path19.join(directory, ".swarm");
17747
17747
  if (!fs8.existsSync(swarmDir)) {
17748
17748
  fs8.mkdirSync(swarmDir, { recursive: true });
17749
17749
  }
17750
17750
  const backupFilename = `config-backup-${backup.createdAt}.json`;
17751
- const backupPath = path18.join(swarmDir, backupFilename);
17751
+ const backupPath = path19.join(swarmDir, backupFilename);
17752
17752
  const artifact = {
17753
17753
  createdAt: backup.createdAt,
17754
17754
  configPath: backup.configPath,
@@ -17778,7 +17778,7 @@ function restoreFromBackup(backupPath, directory) {
17778
17778
  return null;
17779
17779
  }
17780
17780
  const targetPath = artifact.configPath;
17781
- const targetDir = path18.dirname(targetPath);
17781
+ const targetDir = path19.dirname(targetPath);
17782
17782
  if (!fs8.existsSync(targetDir)) {
17783
17783
  fs8.mkdirSync(targetDir, { recursive: true });
17784
17784
  }
@@ -17809,9 +17809,9 @@ function readConfigFromFile(directory) {
17809
17809
  return null;
17810
17810
  }
17811
17811
  }
17812
- function validateConfigKey(path19, value, _config) {
17812
+ function validateConfigKey(path20, value, _config) {
17813
17813
  const findings = [];
17814
- switch (path19) {
17814
+ switch (path20) {
17815
17815
  case "agents": {
17816
17816
  if (value !== undefined) {
17817
17817
  findings.push({
@@ -18058,27 +18058,27 @@ function validateConfigKey(path19, value, _config) {
18058
18058
  }
18059
18059
  return findings;
18060
18060
  }
18061
- function walkConfigAndValidate(obj, path19, config3, findings) {
18061
+ function walkConfigAndValidate(obj, path20, config3, findings) {
18062
18062
  if (obj === null || obj === undefined) {
18063
18063
  return;
18064
18064
  }
18065
- if (path19 && typeof obj === "object" && !Array.isArray(obj)) {
18066
- const keyFindings = validateConfigKey(path19, obj, config3);
18065
+ if (path20 && typeof obj === "object" && !Array.isArray(obj)) {
18066
+ const keyFindings = validateConfigKey(path20, obj, config3);
18067
18067
  findings.push(...keyFindings);
18068
18068
  }
18069
18069
  if (typeof obj !== "object") {
18070
- const keyFindings = validateConfigKey(path19, obj, config3);
18070
+ const keyFindings = validateConfigKey(path20, obj, config3);
18071
18071
  findings.push(...keyFindings);
18072
18072
  return;
18073
18073
  }
18074
18074
  if (Array.isArray(obj)) {
18075
18075
  obj.forEach((item, index) => {
18076
- walkConfigAndValidate(item, `${path19}[${index}]`, config3, findings);
18076
+ walkConfigAndValidate(item, `${path20}[${index}]`, config3, findings);
18077
18077
  });
18078
18078
  return;
18079
18079
  }
18080
18080
  for (const [key, value] of Object.entries(obj)) {
18081
- const newPath = path19 ? `${path19}.${key}` : key;
18081
+ const newPath = path20 ? `${path20}.${key}` : key;
18082
18082
  walkConfigAndValidate(value, newPath, config3, findings);
18083
18083
  }
18084
18084
  }
@@ -18198,7 +18198,7 @@ function applySafeAutoFixes(directory, result) {
18198
18198
  }
18199
18199
  }
18200
18200
  if (appliedFixes.length > 0) {
18201
- const configDir = path18.dirname(configPath);
18201
+ const configDir = path19.dirname(configPath);
18202
18202
  if (!fs8.existsSync(configDir)) {
18203
18203
  fs8.mkdirSync(configDir, { recursive: true });
18204
18204
  }
@@ -18208,12 +18208,12 @@ function applySafeAutoFixes(directory, result) {
18208
18208
  return { appliedFixes, updatedConfigPath };
18209
18209
  }
18210
18210
  function writeDoctorArtifact(directory, result) {
18211
- const swarmDir = path18.join(directory, ".swarm");
18211
+ const swarmDir = path19.join(directory, ".swarm");
18212
18212
  if (!fs8.existsSync(swarmDir)) {
18213
18213
  fs8.mkdirSync(swarmDir, { recursive: true });
18214
18214
  }
18215
18215
  const artifactFilename = "config-doctor.json";
18216
- const artifactPath = path18.join(swarmDir, artifactFilename);
18216
+ const artifactPath = path19.join(swarmDir, artifactFilename);
18217
18217
  const guiOutput = {
18218
18218
  timestamp: result.timestamp,
18219
18219
  summary: result.summary,
@@ -18575,12 +18575,12 @@ var init_evidence_summary_service = __esm(() => {
18575
18575
 
18576
18576
  // src/cli/index.ts
18577
18577
  import * as fs21 from "fs";
18578
- import * as os6 from "os";
18579
- import * as path32 from "path";
18578
+ import * as os7 from "os";
18579
+ import * as path33 from "path";
18580
18580
  // package.json
18581
18581
  var package_default = {
18582
18582
  name: "opencode-swarm",
18583
- version: "6.86.8",
18583
+ version: "6.86.9",
18584
18584
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
18585
18585
  main: "dist/index.js",
18586
18586
  types: "dist/index.d.ts",
@@ -36269,31 +36269,49 @@ async function handleDarkMatterCommand(directory, args) {
36269
36269
  // src/services/diagnose-service.ts
36270
36270
  import * as child_process4 from "child_process";
36271
36271
  import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync5 } from "fs";
36272
- import path17 from "path";
36272
+ import path18 from "path";
36273
36273
  import { fileURLToPath } from "url";
36274
+
36275
+ // src/config/cache-paths.ts
36276
+ import * as os5 from "os";
36277
+ import * as path17 from "path";
36278
+ function getPluginConfigDir() {
36279
+ return path17.join(process.env.XDG_CONFIG_HOME || path17.join(os5.homedir(), ".config"), "opencode");
36280
+ }
36281
+ function getPluginCachePaths() {
36282
+ const cacheBase = process.env.XDG_CACHE_HOME || path17.join(os5.homedir(), ".cache");
36283
+ const configDir = getPluginConfigDir();
36284
+ return [
36285
+ path17.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
36286
+ path17.join(configDir, "node_modules", "opencode-swarm"),
36287
+ path17.join(cacheBase, "opencode", "node_modules", "opencode-swarm")
36288
+ ];
36289
+ }
36290
+
36291
+ // src/services/diagnose-service.ts
36274
36292
  init_manager2();
36275
36293
  init_utils2();
36276
36294
  init_manager();
36277
36295
 
36278
36296
  // src/services/version-check.ts
36279
36297
  import { existsSync as existsSync8, mkdirSync as mkdirSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
36280
- import { homedir as homedir4 } from "os";
36281
- import { join as join14 } from "path";
36298
+ import { homedir as homedir5 } from "os";
36299
+ import { join as join15 } from "path";
36282
36300
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
36283
36301
  function cacheDir() {
36284
36302
  const xdg = process.env.XDG_CACHE_HOME;
36285
- const base = xdg && xdg.length > 0 ? xdg : join14(homedir4(), ".cache");
36286
- return join14(base, "opencode-swarm");
36303
+ const base = xdg && xdg.length > 0 ? xdg : join15(homedir5(), ".cache");
36304
+ return join15(base, "opencode-swarm");
36287
36305
  }
36288
36306
  function cacheFile() {
36289
- return join14(cacheDir(), "version-check.json");
36307
+ return join15(cacheDir(), "version-check.json");
36290
36308
  }
36291
36309
  function readVersionCache() {
36292
36310
  try {
36293
- const path17 = cacheFile();
36294
- if (!existsSync8(path17))
36311
+ const path18 = cacheFile();
36312
+ if (!existsSync8(path18))
36295
36313
  return null;
36296
- const raw = readFileSync5(path17, "utf-8");
36314
+ const raw = readFileSync5(path18, "utf-8");
36297
36315
  const parsed = JSON.parse(raw);
36298
36316
  if (typeof parsed?.checkedAt !== "number")
36299
36317
  return null;
@@ -36623,7 +36641,7 @@ async function checkSpecStaleness(directory, plan) {
36623
36641
  };
36624
36642
  }
36625
36643
  async function checkConfigParseability(directory) {
36626
- const configPath = path17.join(directory, ".opencode/opencode-swarm.json");
36644
+ const configPath = path18.join(directory, ".opencode/opencode-swarm.json");
36627
36645
  if (!existsSync9(configPath)) {
36628
36646
  return {
36629
36647
  name: "Config Parseability",
@@ -36652,7 +36670,7 @@ function resolveGrammarDir(thisDir) {
36652
36670
  const normalized = thisDir.replace(/\\/g, "/");
36653
36671
  const isSource = normalized.endsWith("/src/services");
36654
36672
  const isCliBundle = normalized.endsWith("/cli");
36655
- return isSource || isCliBundle ? path17.join(thisDir, "..", "lang", "grammars") : path17.join(thisDir, "lang", "grammars");
36673
+ return isSource || isCliBundle ? path18.join(thisDir, "..", "lang", "grammars") : path18.join(thisDir, "lang", "grammars");
36656
36674
  }
36657
36675
  async function checkGrammarWasmFiles() {
36658
36676
  const grammarFiles = [
@@ -36676,14 +36694,14 @@ async function checkGrammarWasmFiles() {
36676
36694
  "tree-sitter-ini.wasm",
36677
36695
  "tree-sitter-regex.wasm"
36678
36696
  ];
36679
- const thisDir = path17.dirname(fileURLToPath(import.meta.url));
36697
+ const thisDir = path18.dirname(fileURLToPath(import.meta.url));
36680
36698
  const grammarDir = resolveGrammarDir(thisDir);
36681
36699
  const missing = [];
36682
- if (!existsSync9(path17.join(grammarDir, "tree-sitter.wasm"))) {
36700
+ if (!existsSync9(path18.join(grammarDir, "tree-sitter.wasm"))) {
36683
36701
  missing.push("tree-sitter.wasm (core runtime)");
36684
36702
  }
36685
36703
  for (const file3 of grammarFiles) {
36686
- if (!existsSync9(path17.join(grammarDir, file3))) {
36704
+ if (!existsSync9(path18.join(grammarDir, file3))) {
36687
36705
  missing.push(file3);
36688
36706
  }
36689
36707
  }
@@ -36701,7 +36719,7 @@ async function checkGrammarWasmFiles() {
36701
36719
  };
36702
36720
  }
36703
36721
  async function checkCheckpointManifest(directory) {
36704
- const manifestPath = path17.join(directory, ".swarm/checkpoints.json");
36722
+ const manifestPath = path18.join(directory, ".swarm/checkpoints.json");
36705
36723
  if (!existsSync9(manifestPath)) {
36706
36724
  return {
36707
36725
  name: "Checkpoint Manifest",
@@ -36753,7 +36771,7 @@ async function checkCheckpointManifest(directory) {
36753
36771
  }
36754
36772
  }
36755
36773
  async function checkEventStreamIntegrity(directory) {
36756
- const eventsPath = path17.join(directory, ".swarm/events.jsonl");
36774
+ const eventsPath = path18.join(directory, ".swarm/events.jsonl");
36757
36775
  if (!existsSync9(eventsPath)) {
36758
36776
  return {
36759
36777
  name: "Event Stream",
@@ -36794,7 +36812,7 @@ async function checkEventStreamIntegrity(directory) {
36794
36812
  }
36795
36813
  }
36796
36814
  async function checkSteeringDirectives(directory) {
36797
- const eventsPath = path17.join(directory, ".swarm/events.jsonl");
36815
+ const eventsPath = path18.join(directory, ".swarm/events.jsonl");
36798
36816
  if (!existsSync9(eventsPath)) {
36799
36817
  return {
36800
36818
  name: "Steering Directives",
@@ -36850,7 +36868,7 @@ async function checkCurator(directory) {
36850
36868
  detail: "Disabled (enable via curator.enabled)"
36851
36869
  };
36852
36870
  }
36853
- const summaryPath = path17.join(directory, ".swarm/curator-summary.json");
36871
+ const summaryPath = path18.join(directory, ".swarm/curator-summary.json");
36854
36872
  if (!existsSync9(summaryPath)) {
36855
36873
  return {
36856
36874
  name: "Curator",
@@ -37016,7 +37034,7 @@ async function getDiagnoseData(directory) {
37016
37034
  checks5.push(await checkSteeringDirectives(directory));
37017
37035
  checks5.push(await checkCurator(directory));
37018
37036
  try {
37019
- const evidenceDir = path17.join(directory, ".swarm", "evidence");
37037
+ const evidenceDir = path18.join(directory, ".swarm", "evidence");
37020
37038
  const snapshotFiles = existsSync9(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
37021
37039
  if (snapshotFiles.length > 0) {
37022
37040
  const latest = snapshotFiles.sort().pop();
@@ -37046,7 +37064,36 @@ async function getDiagnoseData(directory) {
37046
37064
  detail: `${deferredWarnings.length} warning(s) deferred from init (run with verbose logs for details)`
37047
37065
  });
37048
37066
  }
37049
- const passCount = checks5.filter((c) => c.status === "\u2705").length;
37067
+ const cachePaths = getPluginCachePaths();
37068
+ const cacheRows = [];
37069
+ for (const cachePath of cachePaths) {
37070
+ try {
37071
+ if (!existsSync9(cachePath)) {
37072
+ cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
37073
+ continue;
37074
+ }
37075
+ const pkgJsonPath = path18.join(cachePath, "package.json");
37076
+ try {
37077
+ const raw = readFileSync6(pkgJsonPath, "utf-8");
37078
+ const parsed = JSON.parse(raw);
37079
+ const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
37080
+ cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
37081
+ } catch {
37082
+ cacheRows.push(`\u26A0\uFE0F ${cachePath} \u2014 present (package.json unreadable)`);
37083
+ }
37084
+ } catch {
37085
+ cacheRows.push(`\u26A0\uFE0F ${cachePath} \u2014 status unknown (read error)`);
37086
+ }
37087
+ }
37088
+ const hasCacheEntry = cacheRows.some((r) => r.startsWith("\u2705"));
37089
+ const hasCacheWarning = cacheRows.some((r) => r.startsWith("\u26A0\uFE0F"));
37090
+ const cacheStatus = hasCacheWarning ? "\u26A0\uFE0F" : hasCacheEntry ? "\u2705" : "\u2B1C";
37091
+ checks5.push({
37092
+ name: "Plugin Caches",
37093
+ status: cacheStatus,
37094
+ detail: cacheRows.join(" | ")
37095
+ });
37096
+ const passCount = checks5.filter((c) => c.status === "\u2705" || c.status === "\u2B1C").length;
37050
37097
  const totalCount = checks5.length;
37051
37098
  const allPassed = passCount === totalCount;
37052
37099
  return {
@@ -37084,15 +37131,15 @@ init_config_doctor();
37084
37131
 
37085
37132
  // src/services/tool-doctor.ts
37086
37133
  import * as fs10 from "fs";
37087
- import * as path20 from "path";
37134
+ import * as path21 from "path";
37088
37135
 
37089
37136
  // src/build/discovery.ts
37090
37137
  import * as fs9 from "fs";
37091
- import * as path19 from "path";
37138
+ import * as path20 from "path";
37092
37139
 
37093
37140
  // src/lang/detector.ts
37094
37141
  import { access as access2, readdir as readdir2 } from "fs/promises";
37095
- import { extname as extname2, join as join16 } from "path";
37142
+ import { extname as extname2, join as join17 } from "path";
37096
37143
 
37097
37144
  // src/lang/profiles.ts
37098
37145
  class LanguageRegistry {
@@ -38072,7 +38119,7 @@ async function detectProjectLanguages(projectDir) {
38072
38119
  if (detectFile.includes("*") || detectFile.includes("?"))
38073
38120
  continue;
38074
38121
  try {
38075
- await access2(join16(dir, detectFile));
38122
+ await access2(join17(dir, detectFile));
38076
38123
  detected.add(profile.id);
38077
38124
  break;
38078
38125
  } catch {}
@@ -38093,7 +38140,7 @@ async function detectProjectLanguages(projectDir) {
38093
38140
  const topEntries = await readdir2(projectDir, { withFileTypes: true });
38094
38141
  for (const entry of topEntries) {
38095
38142
  if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
38096
- await scanDir(join16(projectDir, entry.name));
38143
+ await scanDir(join17(projectDir, entry.name));
38097
38144
  }
38098
38145
  }
38099
38146
  } catch {}
@@ -38252,11 +38299,11 @@ function findBuildFiles(workingDir, patterns) {
38252
38299
  const regex = simpleGlobToRegex(pattern);
38253
38300
  const matches = files.filter((f) => regex.test(f));
38254
38301
  if (matches.length > 0) {
38255
- return path19.join(dir, matches[0]);
38302
+ return path20.join(dir, matches[0]);
38256
38303
  }
38257
38304
  } catch {}
38258
38305
  } else {
38259
- const filePath = path19.join(workingDir, pattern);
38306
+ const filePath = path20.join(workingDir, pattern);
38260
38307
  if (fs9.existsSync(filePath)) {
38261
38308
  return filePath;
38262
38309
  }
@@ -38265,7 +38312,7 @@ function findBuildFiles(workingDir, patterns) {
38265
38312
  return null;
38266
38313
  }
38267
38314
  function getRepoDefinedScripts(workingDir, scripts) {
38268
- const packageJsonPath = path19.join(workingDir, "package.json");
38315
+ const packageJsonPath = path20.join(workingDir, "package.json");
38269
38316
  if (!fs9.existsSync(packageJsonPath)) {
38270
38317
  return [];
38271
38318
  }
@@ -38306,7 +38353,7 @@ function findAllBuildFiles(workingDir) {
38306
38353
  const regex = simpleGlobToRegex(pattern);
38307
38354
  findFilesRecursive(workingDir, regex, allBuildFiles);
38308
38355
  } else {
38309
- const filePath = path19.join(workingDir, pattern);
38356
+ const filePath = path20.join(workingDir, pattern);
38310
38357
  if (fs9.existsSync(filePath)) {
38311
38358
  allBuildFiles.add(filePath);
38312
38359
  }
@@ -38319,7 +38366,7 @@ function findFilesRecursive(dir, regex, results) {
38319
38366
  try {
38320
38367
  const entries = fs9.readdirSync(dir, { withFileTypes: true });
38321
38368
  for (const entry of entries) {
38322
- const fullPath = path19.join(dir, entry.name);
38369
+ const fullPath = path20.join(dir, entry.name);
38323
38370
  if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
38324
38371
  findFilesRecursive(fullPath, regex, results);
38325
38372
  } else if (entry.isFile() && regex.test(entry.name)) {
@@ -38342,7 +38389,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
38342
38389
  let foundCommand = false;
38343
38390
  for (const cmd of sortedCommands) {
38344
38391
  if (cmd.detectFile) {
38345
- const detectFilePath = path19.join(workingDir, cmd.detectFile);
38392
+ const detectFilePath = path20.join(workingDir, cmd.detectFile);
38346
38393
  if (!fs9.existsSync(detectFilePath)) {
38347
38394
  continue;
38348
38395
  }
@@ -38517,8 +38564,8 @@ function checkBinaryReadiness() {
38517
38564
  }
38518
38565
  function runToolDoctor(_directory, pluginRoot) {
38519
38566
  const findings = [];
38520
- const resolvedPluginRoot = pluginRoot ?? path20.resolve(import.meta.dir, "..", "..");
38521
- const indexPath = path20.join(resolvedPluginRoot, "src", "index.ts");
38567
+ const resolvedPluginRoot = pluginRoot ?? path21.resolve(import.meta.dir, "..", "..");
38568
+ const indexPath = path21.join(resolvedPluginRoot, "src", "index.ts");
38522
38569
  if (!fs10.existsSync(indexPath)) {
38523
38570
  return {
38524
38571
  findings: [
@@ -39441,10 +39488,10 @@ async function handleHistoryCommand(directory, _args) {
39441
39488
  import { randomUUID as randomUUID2 } from "crypto";
39442
39489
  import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
39443
39490
  import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
39444
- import * as path21 from "path";
39491
+ import * as path22 from "path";
39445
39492
  async function migrateContextToKnowledge(directory, config3) {
39446
- const sentinelPath = path21.join(directory, ".swarm", ".knowledge-migrated");
39447
- const contextPath = path21.join(directory, ".swarm", "context.md");
39493
+ const sentinelPath = path22.join(directory, ".swarm", ".knowledge-migrated");
39494
+ const contextPath = path22.join(directory, ".swarm", "context.md");
39448
39495
  const knowledgePath = resolveSwarmKnowledgePath(directory);
39449
39496
  if (existsSync13(sentinelPath)) {
39450
39497
  return {
@@ -39640,7 +39687,7 @@ function truncateLesson(text) {
39640
39687
  return `${text.slice(0, 277)}...`;
39641
39688
  }
39642
39689
  function inferProjectName(directory) {
39643
- const packageJsonPath = path21.join(directory, "package.json");
39690
+ const packageJsonPath = path22.join(directory, "package.json");
39644
39691
  if (existsSync13(packageJsonPath)) {
39645
39692
  try {
39646
39693
  const pkg = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
@@ -39649,7 +39696,7 @@ function inferProjectName(directory) {
39649
39696
  }
39650
39697
  } catch {}
39651
39698
  }
39652
- return path21.basename(directory);
39699
+ return path22.basename(directory);
39653
39700
  }
39654
39701
  async function writeSentinel(sentinelPath, migrated, dropped) {
39655
39702
  const sentinel = {
@@ -39661,7 +39708,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
39661
39708
  schema_version: 1,
39662
39709
  migration_tool: "knowledge-migrator.ts"
39663
39710
  };
39664
- await mkdir3(path21.dirname(sentinelPath), { recursive: true });
39711
+ await mkdir3(path22.dirname(sentinelPath), { recursive: true });
39665
39712
  await writeFile4(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
39666
39713
  }
39667
39714
 
@@ -39898,12 +39945,12 @@ async function handlePlanCommand(directory, args) {
39898
39945
  init_manager2();
39899
39946
  init_manager();
39900
39947
  import * as fs17 from "fs";
39901
- import * as path28 from "path";
39948
+ import * as path29 from "path";
39902
39949
 
39903
39950
  // src/tools/lint.ts
39904
39951
  init_zod();
39905
39952
  import * as fs11 from "fs";
39906
- import * as path22 from "path";
39953
+ import * as path23 from "path";
39907
39954
  init_utils();
39908
39955
 
39909
39956
  // src/utils/path-security.ts
@@ -39949,9 +39996,9 @@ function validateArgs(args) {
39949
39996
  }
39950
39997
  function getLinterCommand(linter, mode, projectDir) {
39951
39998
  const isWindows = process.platform === "win32";
39952
- const binDir = path22.join(projectDir, "node_modules", ".bin");
39953
- const biomeBin = isWindows ? path22.join(binDir, "biome.EXE") : path22.join(binDir, "biome");
39954
- const eslintBin = isWindows ? path22.join(binDir, "eslint.cmd") : path22.join(binDir, "eslint");
39999
+ const binDir = path23.join(projectDir, "node_modules", ".bin");
40000
+ const biomeBin = isWindows ? path23.join(binDir, "biome.EXE") : path23.join(binDir, "biome");
40001
+ const eslintBin = isWindows ? path23.join(binDir, "eslint.cmd") : path23.join(binDir, "eslint");
39955
40002
  switch (linter) {
39956
40003
  case "biome":
39957
40004
  if (mode === "fix") {
@@ -39967,7 +40014,7 @@ function getLinterCommand(linter, mode, projectDir) {
39967
40014
  }
39968
40015
  function getAdditionalLinterCommand(linter, mode, cwd) {
39969
40016
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
39970
- const gradlew = fs11.existsSync(path22.join(cwd, gradlewName)) ? path22.join(cwd, gradlewName) : null;
40017
+ const gradlew = fs11.existsSync(path23.join(cwd, gradlewName)) ? path23.join(cwd, gradlewName) : null;
39971
40018
  switch (linter) {
39972
40019
  case "ruff":
39973
40020
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -40001,10 +40048,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
40001
40048
  }
40002
40049
  }
40003
40050
  function detectRuff(cwd) {
40004
- if (fs11.existsSync(path22.join(cwd, "ruff.toml")))
40051
+ if (fs11.existsSync(path23.join(cwd, "ruff.toml")))
40005
40052
  return isCommandAvailable("ruff");
40006
40053
  try {
40007
- const pyproject = path22.join(cwd, "pyproject.toml");
40054
+ const pyproject = path23.join(cwd, "pyproject.toml");
40008
40055
  if (fs11.existsSync(pyproject)) {
40009
40056
  const content = fs11.readFileSync(pyproject, "utf-8");
40010
40057
  if (content.includes("[tool.ruff]"))
@@ -40014,19 +40061,19 @@ function detectRuff(cwd) {
40014
40061
  return false;
40015
40062
  }
40016
40063
  function detectClippy(cwd) {
40017
- return fs11.existsSync(path22.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
40064
+ return fs11.existsSync(path23.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
40018
40065
  }
40019
40066
  function detectGolangciLint(cwd) {
40020
- return fs11.existsSync(path22.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
40067
+ return fs11.existsSync(path23.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
40021
40068
  }
40022
40069
  function detectCheckstyle(cwd) {
40023
- const hasMaven = fs11.existsSync(path22.join(cwd, "pom.xml"));
40024
- const hasGradle = fs11.existsSync(path22.join(cwd, "build.gradle")) || fs11.existsSync(path22.join(cwd, "build.gradle.kts"));
40025
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs11.existsSync(path22.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
40070
+ const hasMaven = fs11.existsSync(path23.join(cwd, "pom.xml"));
40071
+ const hasGradle = fs11.existsSync(path23.join(cwd, "build.gradle")) || fs11.existsSync(path23.join(cwd, "build.gradle.kts"));
40072
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs11.existsSync(path23.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
40026
40073
  return (hasMaven || hasGradle) && hasBinary;
40027
40074
  }
40028
40075
  function detectKtlint(cwd) {
40029
- const hasKotlin = fs11.existsSync(path22.join(cwd, "build.gradle.kts")) || fs11.existsSync(path22.join(cwd, "build.gradle")) || (() => {
40076
+ const hasKotlin = fs11.existsSync(path23.join(cwd, "build.gradle.kts")) || fs11.existsSync(path23.join(cwd, "build.gradle")) || (() => {
40030
40077
  try {
40031
40078
  return fs11.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
40032
40079
  } catch {
@@ -40045,11 +40092,11 @@ function detectDotnetFormat(cwd) {
40045
40092
  }
40046
40093
  }
40047
40094
  function detectCppcheck(cwd) {
40048
- if (fs11.existsSync(path22.join(cwd, "CMakeLists.txt"))) {
40095
+ if (fs11.existsSync(path23.join(cwd, "CMakeLists.txt"))) {
40049
40096
  return isCommandAvailable("cppcheck");
40050
40097
  }
40051
40098
  try {
40052
- const dirsToCheck = [cwd, path22.join(cwd, "src")];
40099
+ const dirsToCheck = [cwd, path23.join(cwd, "src")];
40053
40100
  const hasCpp = dirsToCheck.some((dir) => {
40054
40101
  try {
40055
40102
  return fs11.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
@@ -40063,13 +40110,13 @@ function detectCppcheck(cwd) {
40063
40110
  }
40064
40111
  }
40065
40112
  function detectSwiftlint(cwd) {
40066
- return fs11.existsSync(path22.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
40113
+ return fs11.existsSync(path23.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
40067
40114
  }
40068
40115
  function detectDartAnalyze(cwd) {
40069
- return fs11.existsSync(path22.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
40116
+ return fs11.existsSync(path23.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
40070
40117
  }
40071
40118
  function detectRubocop(cwd) {
40072
- return (fs11.existsSync(path22.join(cwd, "Gemfile")) || fs11.existsSync(path22.join(cwd, "gems.rb")) || fs11.existsSync(path22.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
40119
+ return (fs11.existsSync(path23.join(cwd, "Gemfile")) || fs11.existsSync(path23.join(cwd, "gems.rb")) || fs11.existsSync(path23.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
40073
40120
  }
40074
40121
  function detectAdditionalLinter(cwd) {
40075
40122
  if (detectRuff(cwd))
@@ -40097,10 +40144,10 @@ function detectAdditionalLinter(cwd) {
40097
40144
  function findBinInAncestors(startDir, binName) {
40098
40145
  let dir = startDir;
40099
40146
  while (true) {
40100
- const candidate = path22.join(dir, "node_modules", ".bin", binName);
40147
+ const candidate = path23.join(dir, "node_modules", ".bin", binName);
40101
40148
  if (fs11.existsSync(candidate))
40102
40149
  return candidate;
40103
- const parent = path22.dirname(dir);
40150
+ const parent = path23.dirname(dir);
40104
40151
  if (parent === dir)
40105
40152
  break;
40106
40153
  dir = parent;
@@ -40109,10 +40156,10 @@ function findBinInAncestors(startDir, binName) {
40109
40156
  }
40110
40157
  function findBinInEnvPath(binName) {
40111
40158
  const searchPath = process.env.PATH ?? "";
40112
- for (const dir of searchPath.split(path22.delimiter)) {
40159
+ for (const dir of searchPath.split(path23.delimiter)) {
40113
40160
  if (!dir)
40114
40161
  continue;
40115
- const candidate = path22.join(dir, binName);
40162
+ const candidate = path23.join(dir, binName);
40116
40163
  if (fs11.existsSync(candidate))
40117
40164
  return candidate;
40118
40165
  }
@@ -40125,13 +40172,13 @@ async function detectAvailableLinter(directory) {
40125
40172
  return null;
40126
40173
  const projectDir = directory;
40127
40174
  const isWindows = process.platform === "win32";
40128
- const biomeBin = isWindows ? path22.join(projectDir, "node_modules", ".bin", "biome.EXE") : path22.join(projectDir, "node_modules", ".bin", "biome");
40129
- const eslintBin = isWindows ? path22.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path22.join(projectDir, "node_modules", ".bin", "eslint");
40175
+ const biomeBin = isWindows ? path23.join(projectDir, "node_modules", ".bin", "biome.EXE") : path23.join(projectDir, "node_modules", ".bin", "biome");
40176
+ const eslintBin = isWindows ? path23.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path23.join(projectDir, "node_modules", ".bin", "eslint");
40130
40177
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
40131
40178
  if (localResult)
40132
40179
  return localResult;
40133
- const biomeAncestor = findBinInAncestors(path22.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
40134
- const eslintAncestor = findBinInAncestors(path22.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
40180
+ const biomeAncestor = findBinInAncestors(path23.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
40181
+ const eslintAncestor = findBinInAncestors(path23.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
40135
40182
  if (biomeAncestor || eslintAncestor) {
40136
40183
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
40137
40184
  }
@@ -40340,7 +40387,7 @@ For Rust: rustup component add clippy`
40340
40387
  // src/tools/secretscan.ts
40341
40388
  init_zod();
40342
40389
  import * as fs12 from "fs";
40343
- import * as path23 from "path";
40390
+ import * as path24 from "path";
40344
40391
  var MAX_FILE_PATH_LENGTH = 500;
40345
40392
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
40346
40393
  var MAX_FILES_SCANNED = 1000;
@@ -40567,7 +40614,7 @@ function isGlobOrPathPattern(pattern) {
40567
40614
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
40568
40615
  }
40569
40616
  function loadSecretScanIgnore(scanDir) {
40570
- const ignorePath = path23.join(scanDir, ".secretscanignore");
40617
+ const ignorePath = path24.join(scanDir, ".secretscanignore");
40571
40618
  try {
40572
40619
  if (!fs12.existsSync(ignorePath))
40573
40620
  return [];
@@ -40590,7 +40637,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
40590
40637
  if (exactNames.has(entry))
40591
40638
  return true;
40592
40639
  for (const pattern of globPatterns) {
40593
- if (path23.matchesGlob(relPath, pattern))
40640
+ if (path24.matchesGlob(relPath, pattern))
40594
40641
  return true;
40595
40642
  }
40596
40643
  return false;
@@ -40611,7 +40658,7 @@ function validateDirectoryInput(dir) {
40611
40658
  return null;
40612
40659
  }
40613
40660
  function isBinaryFile(filePath, buffer) {
40614
- const ext = path23.extname(filePath).toLowerCase();
40661
+ const ext = path24.extname(filePath).toLowerCase();
40615
40662
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
40616
40663
  return true;
40617
40664
  }
@@ -40748,9 +40795,9 @@ function isSymlinkLoop(realPath, visited) {
40748
40795
  return false;
40749
40796
  }
40750
40797
  function isPathWithinScope(realPath, scanDir) {
40751
- const resolvedScanDir = path23.resolve(scanDir);
40752
- const resolvedRealPath = path23.resolve(realPath);
40753
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path23.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
40798
+ const resolvedScanDir = path24.resolve(scanDir);
40799
+ const resolvedRealPath = path24.resolve(realPath);
40800
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path24.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
40754
40801
  }
40755
40802
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
40756
40803
  skippedDirs: 0,
@@ -40776,8 +40823,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
40776
40823
  return a.localeCompare(b);
40777
40824
  });
40778
40825
  for (const entry of entries) {
40779
- const fullPath = path23.join(dir, entry);
40780
- const relPath = path23.relative(scanDir, fullPath).replace(/\\/g, "/");
40826
+ const fullPath = path24.join(dir, entry);
40827
+ const relPath = path24.relative(scanDir, fullPath).replace(/\\/g, "/");
40781
40828
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
40782
40829
  stats.skippedDirs++;
40783
40830
  continue;
@@ -40812,7 +40859,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
40812
40859
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
40813
40860
  files.push(...subFiles);
40814
40861
  } else if (lstat.isFile()) {
40815
- const ext = path23.extname(fullPath).toLowerCase();
40862
+ const ext = path24.extname(fullPath).toLowerCase();
40816
40863
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
40817
40864
  files.push(fullPath);
40818
40865
  } else {
@@ -40878,7 +40925,7 @@ var secretscan = createSwarmTool({
40878
40925
  }
40879
40926
  }
40880
40927
  try {
40881
- const _scanDirRaw = path23.resolve(directory);
40928
+ const _scanDirRaw = path24.resolve(directory);
40882
40929
  const scanDir = (() => {
40883
40930
  try {
40884
40931
  return fs12.realpathSync(_scanDirRaw);
@@ -41038,11 +41085,11 @@ async function runSecretscan(directory) {
41038
41085
  // src/tools/test-runner.ts
41039
41086
  init_zod();
41040
41087
  import * as fs16 from "fs";
41041
- import * as path27 from "path";
41088
+ import * as path28 from "path";
41042
41089
 
41043
41090
  // src/test-impact/analyzer.ts
41044
41091
  import fs13 from "fs";
41045
- import path24 from "path";
41092
+ import path25 from "path";
41046
41093
  var IMPORT_REGEX_ES = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
41047
41094
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
41048
41095
  var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
@@ -41067,8 +41114,8 @@ function resolveRelativeImport(fromDir, importPath) {
41067
41114
  if (!importPath.startsWith(".")) {
41068
41115
  return null;
41069
41116
  }
41070
- const resolved = path24.resolve(fromDir, importPath);
41071
- if (path24.extname(resolved)) {
41117
+ const resolved = path25.resolve(fromDir, importPath);
41118
+ if (path25.extname(resolved)) {
41072
41119
  if (fs13.existsSync(resolved) && fs13.statSync(resolved).isFile()) {
41073
41120
  return normalizePath(resolved);
41074
41121
  }
@@ -41113,12 +41160,12 @@ function findTestFilesSync(cwd) {
41113
41160
  for (const entry of entries) {
41114
41161
  if (entry.isDirectory()) {
41115
41162
  if (!skipDirs.has(entry.name)) {
41116
- walk(path24.join(dir, entry.name), visitedInodes);
41163
+ walk(path25.join(dir, entry.name), visitedInodes);
41117
41164
  }
41118
41165
  } else if (entry.isFile()) {
41119
41166
  const name = entry.name;
41120
41167
  if (/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name)) {
41121
- testFiles.push(normalizePath(path24.join(dir, entry.name)));
41168
+ testFiles.push(normalizePath(path25.join(dir, entry.name)));
41122
41169
  }
41123
41170
  }
41124
41171
  }
@@ -41156,7 +41203,7 @@ async function buildImpactMapInternal(cwd) {
41156
41203
  continue;
41157
41204
  }
41158
41205
  const imports = extractImports(content);
41159
- const testDir = path24.dirname(testFile);
41206
+ const testDir = path25.dirname(testFile);
41160
41207
  for (const importPath of imports) {
41161
41208
  const resolvedSource = resolveRelativeImport(testDir, importPath);
41162
41209
  if (resolvedSource === null) {
@@ -41178,7 +41225,7 @@ async function buildImpactMap(cwd) {
41178
41225
  return impactMap;
41179
41226
  }
41180
41227
  async function loadImpactMap(cwd) {
41181
- const cachePath = path24.join(cwd, ".swarm", "cache", "impact-map.json");
41228
+ const cachePath = path25.join(cwd, ".swarm", "cache", "impact-map.json");
41182
41229
  if (fs13.existsSync(cachePath)) {
41183
41230
  try {
41184
41231
  const content = fs13.readFileSync(cachePath, "utf-8");
@@ -41193,8 +41240,8 @@ async function loadImpactMap(cwd) {
41193
41240
  return buildImpactMap(cwd);
41194
41241
  }
41195
41242
  async function saveImpactMap(cwd, impactMap) {
41196
- const cacheDir2 = path24.join(cwd, ".swarm", "cache");
41197
- const cachePath = path24.join(cacheDir2, "impact-map.json");
41243
+ const cacheDir2 = path25.join(cwd, ".swarm", "cache");
41244
+ const cachePath = path25.join(cacheDir2, "impact-map.json");
41198
41245
  if (!fs13.existsSync(cacheDir2)) {
41199
41246
  fs13.mkdirSync(cacheDir2, { recursive: true });
41200
41247
  }
@@ -41220,7 +41267,7 @@ async function analyzeImpact(changedFiles, cwd) {
41220
41267
  const impactedTestsSet = new Set;
41221
41268
  const untestedFiles = [];
41222
41269
  for (const changedFile of validFiles) {
41223
- const normalizedChanged = normalizePath(path24.resolve(changedFile));
41270
+ const normalizedChanged = normalizePath(path25.resolve(changedFile));
41224
41271
  const tests = impactMap[normalizedChanged];
41225
41272
  if (tests && tests.length > 0) {
41226
41273
  for (const test of tests) {
@@ -41467,13 +41514,13 @@ function detectFlakyTests(allHistory) {
41467
41514
 
41468
41515
  // src/test-impact/history-store.ts
41469
41516
  import fs14 from "fs";
41470
- import path25 from "path";
41517
+ import path26 from "path";
41471
41518
  var MAX_HISTORY_PER_TEST = 20;
41472
41519
  var MAX_ERROR_LENGTH = 500;
41473
41520
  var MAX_STACK_LENGTH = 200;
41474
41521
  var MAX_CHANGED_FILES = 50;
41475
41522
  function getHistoryPath(workingDir) {
41476
- return path25.join(workingDir || process.cwd(), ".swarm", "cache", "test-history.jsonl");
41523
+ return path26.join(workingDir || process.cwd(), ".swarm", "cache", "test-history.jsonl");
41477
41524
  }
41478
41525
  function sanitizeErrorMessage(errorMessage) {
41479
41526
  if (errorMessage === undefined) {
@@ -41533,7 +41580,7 @@ function appendTestRun(record3, workingDir) {
41533
41580
  changedFiles: sanitizeChangedFiles(record3.changedFiles || [])
41534
41581
  };
41535
41582
  const historyPath = getHistoryPath(workingDir);
41536
- const historyDir = path25.dirname(historyPath);
41583
+ const historyDir = path26.dirname(historyPath);
41537
41584
  if (!fs14.existsSync(historyDir)) {
41538
41585
  fs14.mkdirSync(historyDir, { recursive: true });
41539
41586
  }
@@ -41607,7 +41654,7 @@ function getAllHistory(workingDir) {
41607
41654
 
41608
41655
  // src/tools/resolve-working-directory.ts
41609
41656
  import * as fs15 from "fs";
41610
- import * as path26 from "path";
41657
+ import * as path27 from "path";
41611
41658
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
41612
41659
  if (workingDirectory == null || workingDirectory === "") {
41613
41660
  return { success: true, directory: fallbackDirectory };
@@ -41627,15 +41674,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
41627
41674
  };
41628
41675
  }
41629
41676
  }
41630
- const normalizedDir = path26.normalize(workingDirectory);
41631
- const pathParts = normalizedDir.split(path26.sep);
41677
+ const normalizedDir = path27.normalize(workingDirectory);
41678
+ const pathParts = normalizedDir.split(path27.sep);
41632
41679
  if (pathParts.includes("..")) {
41633
41680
  return {
41634
41681
  success: false,
41635
41682
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
41636
41683
  };
41637
41684
  }
41638
- const resolvedDir = path26.resolve(normalizedDir);
41685
+ const resolvedDir = path27.resolve(normalizedDir);
41639
41686
  let statResult;
41640
41687
  try {
41641
41688
  statResult = fs15.statSync(resolvedDir);
@@ -41651,7 +41698,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
41651
41698
  message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
41652
41699
  };
41653
41700
  }
41654
- const resolvedFallback = path26.resolve(fallbackDirectory);
41701
+ const resolvedFallback = path27.resolve(fallbackDirectory);
41655
41702
  let fallbackExists = false;
41656
41703
  try {
41657
41704
  fs15.statSync(resolvedFallback);
@@ -41661,7 +41708,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
41661
41708
  }
41662
41709
  if (workingDirectory != null && workingDirectory !== "") {
41663
41710
  if (fallbackExists) {
41664
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path26.sep);
41711
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path27.sep);
41665
41712
  if (isSubdirectory) {
41666
41713
  return {
41667
41714
  success: false,
@@ -41751,14 +41798,14 @@ function hasDevDependency(devDeps, ...patterns) {
41751
41798
  return hasPackageJsonDependency(devDeps, ...patterns);
41752
41799
  }
41753
41800
  function detectGoTest(cwd) {
41754
- return fs16.existsSync(path27.join(cwd, "go.mod")) && isCommandAvailable("go");
41801
+ return fs16.existsSync(path28.join(cwd, "go.mod")) && isCommandAvailable("go");
41755
41802
  }
41756
41803
  function detectJavaMaven(cwd) {
41757
- return fs16.existsSync(path27.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
41804
+ return fs16.existsSync(path28.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
41758
41805
  }
41759
41806
  function detectGradle(cwd) {
41760
- const hasBuildFile = fs16.existsSync(path27.join(cwd, "build.gradle")) || fs16.existsSync(path27.join(cwd, "build.gradle.kts"));
41761
- const hasGradlew = fs16.existsSync(path27.join(cwd, "gradlew")) || fs16.existsSync(path27.join(cwd, "gradlew.bat"));
41807
+ const hasBuildFile = fs16.existsSync(path28.join(cwd, "build.gradle")) || fs16.existsSync(path28.join(cwd, "build.gradle.kts"));
41808
+ const hasGradlew = fs16.existsSync(path28.join(cwd, "gradlew")) || fs16.existsSync(path28.join(cwd, "gradlew.bat"));
41762
41809
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
41763
41810
  }
41764
41811
  function detectDotnetTest(cwd) {
@@ -41771,30 +41818,30 @@ function detectDotnetTest(cwd) {
41771
41818
  }
41772
41819
  }
41773
41820
  function detectCTest(cwd) {
41774
- const hasSource = fs16.existsSync(path27.join(cwd, "CMakeLists.txt"));
41775
- const hasBuildCache = fs16.existsSync(path27.join(cwd, "CMakeCache.txt")) || fs16.existsSync(path27.join(cwd, "build", "CMakeCache.txt"));
41821
+ const hasSource = fs16.existsSync(path28.join(cwd, "CMakeLists.txt"));
41822
+ const hasBuildCache = fs16.existsSync(path28.join(cwd, "CMakeCache.txt")) || fs16.existsSync(path28.join(cwd, "build", "CMakeCache.txt"));
41776
41823
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
41777
41824
  }
41778
41825
  function detectSwiftTest(cwd) {
41779
- return fs16.existsSync(path27.join(cwd, "Package.swift")) && isCommandAvailable("swift");
41826
+ return fs16.existsSync(path28.join(cwd, "Package.swift")) && isCommandAvailable("swift");
41780
41827
  }
41781
41828
  function detectDartTest(cwd) {
41782
- return fs16.existsSync(path27.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
41829
+ return fs16.existsSync(path28.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
41783
41830
  }
41784
41831
  function detectRSpec(cwd) {
41785
- const hasRSpecFile = fs16.existsSync(path27.join(cwd, ".rspec"));
41786
- const hasGemfile = fs16.existsSync(path27.join(cwd, "Gemfile"));
41787
- const hasSpecDir = fs16.existsSync(path27.join(cwd, "spec"));
41832
+ const hasRSpecFile = fs16.existsSync(path28.join(cwd, ".rspec"));
41833
+ const hasGemfile = fs16.existsSync(path28.join(cwd, "Gemfile"));
41834
+ const hasSpecDir = fs16.existsSync(path28.join(cwd, "spec"));
41788
41835
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
41789
41836
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
41790
41837
  }
41791
41838
  function detectMinitest(cwd) {
41792
- return fs16.existsSync(path27.join(cwd, "test")) && (fs16.existsSync(path27.join(cwd, "Gemfile")) || fs16.existsSync(path27.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
41839
+ return fs16.existsSync(path28.join(cwd, "test")) && (fs16.existsSync(path28.join(cwd, "Gemfile")) || fs16.existsSync(path28.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
41793
41840
  }
41794
41841
  async function detectTestFramework(cwd) {
41795
41842
  const baseDir = cwd;
41796
41843
  try {
41797
- const packageJsonPath = path27.join(baseDir, "package.json");
41844
+ const packageJsonPath = path28.join(baseDir, "package.json");
41798
41845
  if (fs16.existsSync(packageJsonPath)) {
41799
41846
  const content = fs16.readFileSync(packageJsonPath, "utf-8");
41800
41847
  const pkg = JSON.parse(content);
@@ -41815,16 +41862,16 @@ async function detectTestFramework(cwd) {
41815
41862
  return "jest";
41816
41863
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
41817
41864
  return "mocha";
41818
- if (fs16.existsSync(path27.join(baseDir, "bun.lockb")) || fs16.existsSync(path27.join(baseDir, "bun.lock"))) {
41865
+ if (fs16.existsSync(path28.join(baseDir, "bun.lockb")) || fs16.existsSync(path28.join(baseDir, "bun.lock"))) {
41819
41866
  if (scripts.test?.includes("bun"))
41820
41867
  return "bun";
41821
41868
  }
41822
41869
  }
41823
41870
  } catch {}
41824
41871
  try {
41825
- const pyprojectTomlPath = path27.join(baseDir, "pyproject.toml");
41826
- const setupCfgPath = path27.join(baseDir, "setup.cfg");
41827
- const requirementsTxtPath = path27.join(baseDir, "requirements.txt");
41872
+ const pyprojectTomlPath = path28.join(baseDir, "pyproject.toml");
41873
+ const setupCfgPath = path28.join(baseDir, "setup.cfg");
41874
+ const requirementsTxtPath = path28.join(baseDir, "requirements.txt");
41828
41875
  if (fs16.existsSync(pyprojectTomlPath)) {
41829
41876
  const content = fs16.readFileSync(pyprojectTomlPath, "utf-8");
41830
41877
  if (content.includes("[tool.pytest"))
@@ -41844,7 +41891,7 @@ async function detectTestFramework(cwd) {
41844
41891
  }
41845
41892
  } catch {}
41846
41893
  try {
41847
- const cargoTomlPath = path27.join(baseDir, "Cargo.toml");
41894
+ const cargoTomlPath = path28.join(baseDir, "Cargo.toml");
41848
41895
  if (fs16.existsSync(cargoTomlPath)) {
41849
41896
  const content = fs16.readFileSync(cargoTomlPath, "utf-8");
41850
41897
  if (content.includes("[dev-dependencies]")) {
@@ -41855,9 +41902,9 @@ async function detectTestFramework(cwd) {
41855
41902
  }
41856
41903
  } catch {}
41857
41904
  try {
41858
- const pesterConfigPath = path27.join(baseDir, "pester.config.ps1");
41859
- const pesterConfigJsonPath = path27.join(baseDir, "pester.config.ps1.json");
41860
- const pesterPs1Path = path27.join(baseDir, "tests.ps1");
41905
+ const pesterConfigPath = path28.join(baseDir, "pester.config.ps1");
41906
+ const pesterConfigJsonPath = path28.join(baseDir, "pester.config.ps1.json");
41907
+ const pesterPs1Path = path28.join(baseDir, "tests.ps1");
41861
41908
  if (fs16.existsSync(pesterConfigPath) || fs16.existsSync(pesterConfigJsonPath) || fs16.existsSync(pesterPs1Path)) {
41862
41909
  return "pester";
41863
41910
  }
@@ -41900,12 +41947,12 @@ function isTestDirectoryPath(normalizedPath) {
41900
41947
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
41901
41948
  }
41902
41949
  function resolveWorkspacePath(file3, workingDir) {
41903
- return path27.isAbsolute(file3) ? path27.resolve(file3) : path27.resolve(workingDir, file3);
41950
+ return path28.isAbsolute(file3) ? path28.resolve(file3) : path28.resolve(workingDir, file3);
41904
41951
  }
41905
41952
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
41906
41953
  if (!preferRelative)
41907
41954
  return absolutePath;
41908
- return path27.relative(workingDir, absolutePath);
41955
+ return path28.relative(workingDir, absolutePath);
41909
41956
  }
41910
41957
  function dedupePush(target, value) {
41911
41958
  if (!target.includes(value)) {
@@ -41942,18 +41989,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
41942
41989
  }
41943
41990
  }
41944
41991
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
41945
- const relativeDir = path27.dirname(relativePath);
41992
+ const relativeDir = path28.dirname(relativePath);
41946
41993
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
41947
41994
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
41948
- const rootDir = path27.join(workingDir, dirName);
41949
- return nestedRelativeDir ? [rootDir, path27.join(rootDir, nestedRelativeDir)] : [rootDir];
41995
+ const rootDir = path28.join(workingDir, dirName);
41996
+ return nestedRelativeDir ? [rootDir, path28.join(rootDir, nestedRelativeDir)] : [rootDir];
41950
41997
  });
41951
41998
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
41952
41999
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
41953
- directories.push(path27.join(workingDir, "src/test/java", path27.dirname(normalizedRelativePath.slice("src/main/java/".length))));
42000
+ directories.push(path28.join(workingDir, "src/test/java", path28.dirname(normalizedRelativePath.slice("src/main/java/".length))));
41954
42001
  }
41955
42002
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
41956
- directories.push(path27.join(workingDir, "src/test/kotlin", path27.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
42003
+ directories.push(path28.join(workingDir, "src/test/kotlin", path28.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
41957
42004
  }
41958
42005
  return [...new Set(directories)];
41959
42006
  }
@@ -41981,23 +42028,23 @@ function isLanguageSpecificTestFile(basename4) {
41981
42028
  }
41982
42029
  function isConventionTestFilePath(filePath) {
41983
42030
  const normalizedPath = filePath.replace(/\\/g, "/");
41984
- const basename4 = path27.basename(filePath);
42031
+ const basename4 = path28.basename(filePath);
41985
42032
  return hasCompoundTestExtension(basename4) || basename4.includes(".spec.") || basename4.includes(".test.") || isLanguageSpecificTestFile(basename4) || isTestDirectoryPath(normalizedPath);
41986
42033
  }
41987
42034
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
41988
42035
  const testFiles = [];
41989
42036
  for (const file3 of sourceFiles) {
41990
42037
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
41991
- const relativeFile = path27.relative(workingDir, absoluteFile);
41992
- const basename4 = path27.basename(absoluteFile);
41993
- const dirname11 = path27.dirname(absoluteFile);
41994
- const preferRelativeOutput = !path27.isAbsolute(file3);
42038
+ const relativeFile = path28.relative(workingDir, absoluteFile);
42039
+ const basename4 = path28.basename(absoluteFile);
42040
+ const dirname11 = path28.dirname(absoluteFile);
42041
+ const preferRelativeOutput = !path28.isAbsolute(file3);
41995
42042
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
41996
42043
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
41997
42044
  continue;
41998
42045
  }
41999
42046
  const nameWithoutExt = basename4.replace(/\.[^.]+$/, "");
42000
- const ext = path27.extname(basename4);
42047
+ const ext = path28.extname(basename4);
42001
42048
  const genericTestNames = [
42002
42049
  `${nameWithoutExt}.spec${ext}`,
42003
42050
  `${nameWithoutExt}.test${ext}`
@@ -42006,7 +42053,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
42006
42053
  const colocatedCandidates = [
42007
42054
  ...genericTestNames,
42008
42055
  ...languageSpecificTestNames
42009
- ].map((candidateName) => path27.join(dirname11, candidateName));
42056
+ ].map((candidateName) => path28.join(dirname11, candidateName));
42010
42057
  const testDirectoryNames = [
42011
42058
  basename4,
42012
42059
  ...genericTestNames,
@@ -42015,8 +42062,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
42015
42062
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
42016
42063
  const possibleTestFiles = [
42017
42064
  ...colocatedCandidates,
42018
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path27.join(dirname11, dirName, candidateName))),
42019
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path27.join(candidateDir, candidateName)))
42065
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path28.join(dirname11, dirName, candidateName))),
42066
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path28.join(candidateDir, candidateName)))
42020
42067
  ];
42021
42068
  for (const testFile of possibleTestFiles) {
42022
42069
  if (fs16.existsSync(testFile)) {
@@ -42037,7 +42084,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
42037
42084
  try {
42038
42085
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
42039
42086
  const content = fs16.readFileSync(absoluteTestFile, "utf-8");
42040
- const testDir = path27.dirname(absoluteTestFile);
42087
+ const testDir = path28.dirname(absoluteTestFile);
42041
42088
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
42042
42089
  let match;
42043
42090
  match = importRegex.exec(content);
@@ -42045,8 +42092,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
42045
42092
  const importPath = match[1];
42046
42093
  let resolvedImport;
42047
42094
  if (importPath.startsWith(".")) {
42048
- resolvedImport = path27.resolve(testDir, importPath);
42049
- const existingExt = path27.extname(resolvedImport);
42095
+ resolvedImport = path28.resolve(testDir, importPath);
42096
+ const existingExt = path28.extname(resolvedImport);
42050
42097
  if (!existingExt) {
42051
42098
  for (const extToTry of [
42052
42099
  ".ts",
@@ -42066,12 +42113,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
42066
42113
  } else {
42067
42114
  continue;
42068
42115
  }
42069
- const importBasename = path27.basename(resolvedImport, path27.extname(resolvedImport));
42070
- const importDir = path27.dirname(resolvedImport);
42116
+ const importBasename = path28.basename(resolvedImport, path28.extname(resolvedImport));
42117
+ const importDir = path28.dirname(resolvedImport);
42071
42118
  for (const sourceFile of absoluteSourceFiles) {
42072
- const sourceDir = path27.dirname(sourceFile);
42073
- const sourceBasename = path27.basename(sourceFile, path27.extname(sourceFile));
42074
- const isRelatedDir = importDir === sourceDir || importDir === path27.join(sourceDir, "__tests__") || importDir === path27.join(sourceDir, "tests") || importDir === path27.join(sourceDir, "test") || importDir === path27.join(sourceDir, "spec");
42119
+ const sourceDir = path28.dirname(sourceFile);
42120
+ const sourceBasename = path28.basename(sourceFile, path28.extname(sourceFile));
42121
+ const isRelatedDir = importDir === sourceDir || importDir === path28.join(sourceDir, "__tests__") || importDir === path28.join(sourceDir, "tests") || importDir === path28.join(sourceDir, "test") || importDir === path28.join(sourceDir, "spec");
42075
42122
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
42076
42123
  dedupePush(testFiles, testFile);
42077
42124
  break;
@@ -42084,8 +42131,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
42084
42131
  while (match !== null) {
42085
42132
  const importPath = match[1];
42086
42133
  if (importPath.startsWith(".")) {
42087
- let resolvedImport = path27.resolve(testDir, importPath);
42088
- const existingExt = path27.extname(resolvedImport);
42134
+ let resolvedImport = path28.resolve(testDir, importPath);
42135
+ const existingExt = path28.extname(resolvedImport);
42089
42136
  if (!existingExt) {
42090
42137
  for (const extToTry of [
42091
42138
  ".ts",
@@ -42102,12 +42149,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
42102
42149
  }
42103
42150
  }
42104
42151
  }
42105
- const importDir = path27.dirname(resolvedImport);
42106
- const importBasename = path27.basename(resolvedImport, path27.extname(resolvedImport));
42152
+ const importDir = path28.dirname(resolvedImport);
42153
+ const importBasename = path28.basename(resolvedImport, path28.extname(resolvedImport));
42107
42154
  for (const sourceFile of absoluteSourceFiles) {
42108
- const sourceDir = path27.dirname(sourceFile);
42109
- const sourceBasename = path27.basename(sourceFile, path27.extname(sourceFile));
42110
- const isRelatedDir = importDir === sourceDir || importDir === path27.join(sourceDir, "__tests__") || importDir === path27.join(sourceDir, "tests") || importDir === path27.join(sourceDir, "test") || importDir === path27.join(sourceDir, "spec");
42155
+ const sourceDir = path28.dirname(sourceFile);
42156
+ const sourceBasename = path28.basename(sourceFile, path28.extname(sourceFile));
42157
+ const isRelatedDir = importDir === sourceDir || importDir === path28.join(sourceDir, "__tests__") || importDir === path28.join(sourceDir, "tests") || importDir === path28.join(sourceDir, "test") || importDir === path28.join(sourceDir, "spec");
42111
42158
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
42112
42159
  dedupePush(testFiles, testFile);
42113
42160
  break;
@@ -42210,8 +42257,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
42210
42257
  return ["mvn", "test"];
42211
42258
  case "gradle": {
42212
42259
  const isWindows = process.platform === "win32";
42213
- const hasGradlewBat = fs16.existsSync(path27.join(baseDir, "gradlew.bat"));
42214
- const hasGradlew = fs16.existsSync(path27.join(baseDir, "gradlew"));
42260
+ const hasGradlewBat = fs16.existsSync(path28.join(baseDir, "gradlew.bat"));
42261
+ const hasGradlew = fs16.existsSync(path28.join(baseDir, "gradlew"));
42215
42262
  if (hasGradlewBat && isWindows)
42216
42263
  return ["gradlew.bat", "test"];
42217
42264
  if (hasGradlew)
@@ -42228,7 +42275,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
42228
42275
  "cmake-build-release",
42229
42276
  "out"
42230
42277
  ];
42231
- const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path27.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
42278
+ const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path28.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
42232
42279
  return ["ctest", "--test-dir", actualBuildDir];
42233
42280
  }
42234
42281
  case "swift-test":
@@ -42856,7 +42903,7 @@ var test_runner = createSwarmTool({
42856
42903
  const sourceFiles = args.files.filter((file3) => {
42857
42904
  if (directTestFiles.includes(file3))
42858
42905
  return false;
42859
- const ext = path27.extname(file3).toLowerCase();
42906
+ const ext = path28.extname(file3).toLowerCase();
42860
42907
  return SOURCE_EXTENSIONS.has(ext);
42861
42908
  });
42862
42909
  const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
@@ -42891,7 +42938,7 @@ var test_runner = createSwarmTool({
42891
42938
  if (isConventionTestFilePath(f)) {
42892
42939
  return false;
42893
42940
  }
42894
- const ext = path27.extname(f).toLowerCase();
42941
+ const ext = path28.extname(f).toLowerCase();
42895
42942
  return SOURCE_EXTENSIONS.has(ext);
42896
42943
  });
42897
42944
  if (sourceFiles.length === 0) {
@@ -42918,7 +42965,7 @@ var test_runner = createSwarmTool({
42918
42965
  if (isConventionTestFilePath(f)) {
42919
42966
  return false;
42920
42967
  }
42921
- const ext = path27.extname(f).toLowerCase();
42968
+ const ext = path28.extname(f).toLowerCase();
42922
42969
  return SOURCE_EXTENSIONS.has(ext);
42923
42970
  });
42924
42971
  if (sourceFiles.length === 0) {
@@ -42936,8 +42983,8 @@ var test_runner = createSwarmTool({
42936
42983
  const impactResult = await analyzeImpact(sourceFiles, workingDir);
42937
42984
  if (impactResult.impactedTests.length > 0) {
42938
42985
  testFiles = impactResult.impactedTests.map((absPath) => {
42939
- const relativePath = path27.relative(workingDir, absPath);
42940
- return path27.isAbsolute(relativePath) ? absPath : relativePath;
42986
+ const relativePath = path28.relative(workingDir, absPath);
42987
+ return path28.isAbsolute(relativePath) ? absPath : relativePath;
42941
42988
  });
42942
42989
  } else {
42943
42990
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -43030,8 +43077,8 @@ function validateDirectoryPath(dir) {
43030
43077
  if (dir.includes("..")) {
43031
43078
  throw new Error("Directory path must not contain path traversal sequences");
43032
43079
  }
43033
- const normalized = path28.normalize(dir);
43034
- const absolutePath = path28.isAbsolute(normalized) ? normalized : path28.resolve(normalized);
43080
+ const normalized = path29.normalize(dir);
43081
+ const absolutePath = path29.isAbsolute(normalized) ? normalized : path29.resolve(normalized);
43035
43082
  return absolutePath;
43036
43083
  }
43037
43084
  function validateTimeout(timeoutMs, defaultValue) {
@@ -43054,7 +43101,7 @@ function validateTimeout(timeoutMs, defaultValue) {
43054
43101
  }
43055
43102
  function getPackageVersion(dir) {
43056
43103
  try {
43057
- const packagePath = path28.join(dir, "package.json");
43104
+ const packagePath = path29.join(dir, "package.json");
43058
43105
  if (fs17.existsSync(packagePath)) {
43059
43106
  const content = fs17.readFileSync(packagePath, "utf-8");
43060
43107
  const pkg = JSON.parse(content);
@@ -43065,7 +43112,7 @@ function getPackageVersion(dir) {
43065
43112
  }
43066
43113
  function getChangelogVersion(dir) {
43067
43114
  try {
43068
- const changelogPath = path28.join(dir, "CHANGELOG.md");
43115
+ const changelogPath = path29.join(dir, "CHANGELOG.md");
43069
43116
  if (fs17.existsSync(changelogPath)) {
43070
43117
  const content = fs17.readFileSync(changelogPath, "utf-8");
43071
43118
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
@@ -43079,7 +43126,7 @@ function getChangelogVersion(dir) {
43079
43126
  function getVersionFileVersion(dir) {
43080
43127
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
43081
43128
  for (const file3 of possibleFiles) {
43082
- const filePath = path28.join(dir, file3);
43129
+ const filePath = path29.join(dir, file3);
43083
43130
  if (fs17.existsSync(filePath)) {
43084
43131
  try {
43085
43132
  const content = fs17.readFileSync(filePath, "utf-8").trim();
@@ -43406,7 +43453,7 @@ async function runEvidenceCheck(dir) {
43406
43453
  async function runRequirementCoverageCheck(dir, currentPhase) {
43407
43454
  const startTime = Date.now();
43408
43455
  try {
43409
- const specPath = path28.join(dir, ".swarm", "spec.md");
43456
+ const specPath = path29.join(dir, ".swarm", "spec.md");
43410
43457
  if (!fs17.existsSync(specPath)) {
43411
43458
  return {
43412
43459
  type: "req_coverage",
@@ -44529,7 +44576,7 @@ async function handleResetCommand(directory, args) {
44529
44576
  // src/commands/reset-session.ts
44530
44577
  init_utils2();
44531
44578
  import * as fs19 from "fs";
44532
- import * as path29 from "path";
44579
+ import * as path30 from "path";
44533
44580
  async function handleResetSessionCommand(directory, _args) {
44534
44581
  const results = [];
44535
44582
  try {
@@ -44544,13 +44591,13 @@ async function handleResetSessionCommand(directory, _args) {
44544
44591
  results.push("\u274C Failed to delete state.json");
44545
44592
  }
44546
44593
  try {
44547
- const sessionDir = path29.dirname(validateSwarmPath(directory, "session/state.json"));
44594
+ const sessionDir = path30.dirname(validateSwarmPath(directory, "session/state.json"));
44548
44595
  if (fs19.existsSync(sessionDir)) {
44549
44596
  const files = fs19.readdirSync(sessionDir);
44550
44597
  const otherFiles = files.filter((f) => f !== "state.json");
44551
44598
  let deletedCount = 0;
44552
44599
  for (const file3 of otherFiles) {
44553
- const filePath = path29.join(sessionDir, file3);
44600
+ const filePath = path30.join(sessionDir, file3);
44554
44601
  if (fs19.lstatSync(filePath).isFile()) {
44555
44602
  fs19.unlinkSync(filePath);
44556
44603
  deletedCount++;
@@ -44580,7 +44627,7 @@ async function handleResetSessionCommand(directory, _args) {
44580
44627
  // src/summaries/manager.ts
44581
44628
  init_utils2();
44582
44629
  init_utils();
44583
- import * as path30 from "path";
44630
+ import * as path31 from "path";
44584
44631
  var SUMMARY_ID_REGEX = /^S\d+$/;
44585
44632
  function sanitizeSummaryId(id) {
44586
44633
  if (!id || id.length === 0) {
@@ -44604,7 +44651,7 @@ function sanitizeSummaryId(id) {
44604
44651
  }
44605
44652
  async function loadFullOutput(directory, id) {
44606
44653
  const sanitizedId = sanitizeSummaryId(id);
44607
- const relativePath = path30.join("summaries", `${sanitizedId}.json`);
44654
+ const relativePath = path31.join("summaries", `${sanitizedId}.json`);
44608
44655
  validateSwarmPath(directory, relativePath);
44609
44656
  const content = await readSwarmFileAsync(directory, relativePath);
44610
44657
  if (content === null) {
@@ -44660,7 +44707,7 @@ init_plan_schema();
44660
44707
  init_utils2();
44661
44708
  init_ledger();
44662
44709
  import * as fs20 from "fs";
44663
- import * as path31 from "path";
44710
+ import * as path32 from "path";
44664
44711
  async function handleRollbackCommand(directory, args) {
44665
44712
  const phaseArg = args[0];
44666
44713
  if (!phaseArg) {
@@ -44725,8 +44772,8 @@ async function handleRollbackCommand(directory, args) {
44725
44772
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
44726
44773
  continue;
44727
44774
  }
44728
- const src = path31.join(checkpointDir, file3);
44729
- const dest = path31.join(swarmDir, file3);
44775
+ const src = path32.join(checkpointDir, file3);
44776
+ const dest = path32.join(swarmDir, file3);
44730
44777
  try {
44731
44778
  fs20.cpSync(src, dest, { recursive: true, force: true });
44732
44779
  successes.push(file3);
@@ -44745,12 +44792,12 @@ async function handleRollbackCommand(directory, args) {
44745
44792
  ].join(`
44746
44793
  `);
44747
44794
  }
44748
- const existingLedgerPath = path31.join(swarmDir, "plan-ledger.jsonl");
44795
+ const existingLedgerPath = path32.join(swarmDir, "plan-ledger.jsonl");
44749
44796
  if (fs20.existsSync(existingLedgerPath)) {
44750
44797
  fs20.unlinkSync(existingLedgerPath);
44751
44798
  }
44752
44799
  try {
44753
- const planJsonPath = path31.join(swarmDir, "plan.json");
44800
+ const planJsonPath = path32.join(swarmDir, "plan.json");
44754
44801
  if (fs20.existsSync(planJsonPath)) {
44755
44802
  const planRaw = fs20.readFileSync(planJsonPath, "utf-8");
44756
44803
  const plan = PlanSchema.parse(JSON.parse(planRaw));
@@ -44823,9 +44870,9 @@ async function handleSimulateCommand(directory, args) {
44823
44870
  const report = reportLines.filter(Boolean).join(`
44824
44871
  `);
44825
44872
  const fs21 = await import("fs/promises");
44826
- const path32 = await import("path");
44827
- const reportPath = path32.join(directory, ".swarm", "simulate-report.md");
44828
- await fs21.mkdir(path32.dirname(reportPath), { recursive: true });
44873
+ const path33 = await import("path");
44874
+ const reportPath = path33.join(directory, ".swarm", "simulate-report.md");
44875
+ await fs21.mkdir(path33.dirname(reportPath), { recursive: true });
44829
44876
  await fs21.writeFile(reportPath, report, "utf-8");
44830
44877
  return `${darkMatterPairs.length} hidden coupling pairs detected`;
44831
44878
  }
@@ -45360,21 +45407,34 @@ function resolveCommand(tokens) {
45360
45407
 
45361
45408
  // src/cli/index.ts
45362
45409
  var { version: version4 } = package_default;
45363
- var CONFIG_DIR = path32.join(process.env.XDG_CONFIG_HOME || path32.join(os6.homedir(), ".config"), "opencode");
45364
- var OPENCODE_CONFIG_PATH = path32.join(CONFIG_DIR, "opencode.json");
45365
- var PLUGIN_CONFIG_PATH = path32.join(CONFIG_DIR, "opencode-swarm.json");
45366
- var PROMPTS_DIR = path32.join(CONFIG_DIR, "opencode-swarm");
45367
- var OPENCODE_PLUGIN_CACHE_PATHS = [
45368
- path32.join(process.env.XDG_CACHE_HOME || path32.join(os6.homedir(), ".cache"), "opencode", "packages", "opencode-swarm@latest"),
45369
- path32.join(CONFIG_DIR, "node_modules", "opencode-swarm")
45370
- ];
45410
+ var CONFIG_DIR = getPluginConfigDir();
45411
+ var OPENCODE_CONFIG_PATH = path33.join(CONFIG_DIR, "opencode.json");
45412
+ var PLUGIN_CONFIG_PATH = path33.join(CONFIG_DIR, "opencode-swarm.json");
45413
+ var PROMPTS_DIR = path33.join(CONFIG_DIR, "opencode-swarm");
45414
+ var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
45371
45415
  function isSafeCachePath(p) {
45372
- const resolved = path32.resolve(p);
45373
- const home = path32.resolve(os6.homedir());
45374
- if (resolved === "/" || resolved === home || resolved.length <= home.length)
45416
+ const resolved = path33.resolve(p);
45417
+ const home = path33.resolve(os7.homedir());
45418
+ if (resolved === "/" || resolved === home || resolved.length <= home.length) {
45419
+ return false;
45420
+ }
45421
+ const segments = resolved.split(path33.sep).filter((s) => s.length > 0);
45422
+ if (segments.length < 4) {
45423
+ return false;
45424
+ }
45425
+ const leaf = path33.basename(resolved);
45426
+ if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
45427
+ return false;
45428
+ }
45429
+ const parent = path33.basename(path33.dirname(resolved));
45430
+ if (parent !== "packages" && parent !== "node_modules") {
45375
45431
  return false;
45376
- const leaf = path32.basename(resolved);
45377
- return leaf === "opencode-swarm@latest" || leaf === "opencode-swarm";
45432
+ }
45433
+ const grandparent = path33.basename(path33.dirname(path33.dirname(resolved)));
45434
+ if (grandparent !== "opencode") {
45435
+ return false;
45436
+ }
45437
+ return true;
45378
45438
  }
45379
45439
  function ensureDir(dir) {
45380
45440
  if (!fs21.existsSync(dir)) {
@@ -45396,8 +45456,8 @@ function saveJson(filepath, data) {
45396
45456
  }
45397
45457
  function writeProjectConfigIfMissing(cwd) {
45398
45458
  try {
45399
- const opencodeDir = path32.join(cwd, ".opencode");
45400
- const projectConfigPath = path32.join(opencodeDir, "opencode-swarm.json");
45459
+ const opencodeDir = path33.join(cwd, ".opencode");
45460
+ const projectConfigPath = path33.join(opencodeDir, "opencode-swarm.json");
45401
45461
  if (fs21.existsSync(projectConfigPath)) {
45402
45462
  return;
45403
45463
  }
@@ -45415,7 +45475,7 @@ async function install() {
45415
45475
  `);
45416
45476
  ensureDir(CONFIG_DIR);
45417
45477
  ensureDir(PROMPTS_DIR);
45418
- const LEGACY_CONFIG_PATH = path32.join(CONFIG_DIR, "config.json");
45478
+ const LEGACY_CONFIG_PATH = path33.join(CONFIG_DIR, "config.json");
45419
45479
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
45420
45480
  if (!opencodeConfig) {
45421
45481
  const legacyConfig = loadJson(LEGACY_CONFIG_PATH);