opencode-swarm 7.56.0 → 7.56.2

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
@@ -52,7 +52,7 @@ var package_default;
52
52
  var init_package = __esm(() => {
53
53
  package_default = {
54
54
  name: "opencode-swarm",
55
- version: "7.56.0",
55
+ version: "7.56.2",
56
56
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
57
57
  main: "dist/index.js",
58
58
  types: "dist/index.d.ts",
@@ -39569,7 +39569,7 @@ async function handleCloseCommand(directory, args, options = {}) {
39569
39569
  swarmPlanFilesRemoved++;
39570
39570
  } catch (err) {
39571
39571
  if (err?.code !== "ENOENT") {
39572
- warnings.push(`Failed to remove ${path19.basename(candidate)}: ${err instanceof Error ? err.message : String(err)}`);
39572
+ warnings.push(`Failed to remove ${candidate}: ${err instanceof Error ? err.message : String(err)}`);
39573
39573
  }
39574
39574
  }
39575
39575
  }
@@ -42920,7 +42920,7 @@ var init_profiles = __esm(() => {
42920
42920
  detectFiles: ["Cargo.toml"],
42921
42921
  frameworks: [
42922
42922
  {
42923
- name: "cargo test",
42923
+ name: "cargo",
42924
42924
  detect: "Cargo.toml",
42925
42925
  cmd: "cargo test",
42926
42926
  priority: 10
@@ -42992,7 +42992,7 @@ var init_profiles = __esm(() => {
42992
42992
  test: {
42993
42993
  detectFiles: ["go.mod"],
42994
42994
  frameworks: [
42995
- { name: "go test", detect: "go.mod", cmd: "go test ./...", priority: 10 }
42995
+ { name: "go-test", detect: "go.mod", cmd: "go test ./...", priority: 10 }
42996
42996
  ]
42997
42997
  },
42998
42998
  lint: {
@@ -43067,13 +43067,13 @@ var init_profiles = __esm(() => {
43067
43067
  detectFiles: ["pom.xml", "build.gradle", "build.gradle.kts"],
43068
43068
  frameworks: [
43069
43069
  {
43070
- name: "maven-test",
43070
+ name: "maven",
43071
43071
  detect: "pom.xml",
43072
43072
  cmd: "mvn test -q",
43073
43073
  priority: 10
43074
43074
  },
43075
43075
  {
43076
- name: "gradle-test",
43076
+ name: "gradle",
43077
43077
  detect: "build.gradle",
43078
43078
  cmd: "gradle test -q",
43079
43079
  priority: 9
@@ -43151,13 +43151,13 @@ var init_profiles = __esm(() => {
43151
43151
  detectFiles: ["build.gradle.kts", "build.gradle"],
43152
43152
  frameworks: [
43153
43153
  {
43154
- name: "gradle-test",
43154
+ name: "gradle",
43155
43155
  detect: "build.gradle.kts",
43156
43156
  cmd: "gradle test -q",
43157
43157
  priority: 10
43158
43158
  },
43159
43159
  {
43160
- name: "gradle-test-groovy",
43160
+ name: "gradle",
43161
43161
  detect: "build.gradle",
43162
43162
  cmd: "gradle test -q",
43163
43163
  priority: 9
@@ -43165,11 +43165,11 @@ var init_profiles = __esm(() => {
43165
43165
  ]
43166
43166
  },
43167
43167
  lint: {
43168
- detectFiles: [".editorconfig", "build.gradle.kts"],
43168
+ detectFiles: ["build.gradle.kts", "build.gradle"],
43169
43169
  linters: [
43170
43170
  {
43171
43171
  name: "ktlint",
43172
- detect: ".editorconfig",
43172
+ detect: "build.gradle.kts",
43173
43173
  cmd: "ktlint --format",
43174
43174
  priority: 10
43175
43175
  }
@@ -43229,7 +43229,7 @@ var init_profiles = __esm(() => {
43229
43229
  detectFiles: ["*.csproj", "*.sln"],
43230
43230
  frameworks: [
43231
43231
  {
43232
- name: "dotnet test",
43232
+ name: "dotnet-test",
43233
43233
  detect: "*.csproj",
43234
43234
  cmd: "dotnet test",
43235
43235
  priority: 10
@@ -43380,7 +43380,7 @@ var init_profiles = __esm(() => {
43380
43380
  detectFiles: ["Package.swift", "*.xcodeproj"],
43381
43381
  frameworks: [
43382
43382
  {
43383
- name: "swift test",
43383
+ name: "swift-test",
43384
43384
  detect: "Package.swift",
43385
43385
  cmd: "swift test",
43386
43386
  priority: 10
@@ -43707,8 +43707,14 @@ async function detectProjectLanguages(projectDir) {
43707
43707
  }
43708
43708
  for (const profile of LANGUAGE_REGISTRY.getAll()) {
43709
43709
  for (const detectFile of profile.build.detectFiles) {
43710
- if (detectFile.includes("*") || detectFile.includes("?"))
43710
+ if (detectFile.includes("*") || detectFile.includes("?")) {
43711
+ const regex = new RegExp(`^${detectFile.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".")}$`);
43712
+ if (entries.some((name) => regex.test(name))) {
43713
+ detected.add(profile.id);
43714
+ break;
43715
+ }
43711
43716
  continue;
43717
+ }
43712
43718
  try {
43713
43719
  await access3(join24(dir, detectFile));
43714
43720
  detected.add(profile.id);
@@ -53161,12 +53167,85 @@ var init_registry_backend = __esm(() => {
53161
53167
  LANGUAGE_BACKEND_REGISTRY = new LanguageBackendRegistry;
53162
53168
  });
53163
53169
 
53164
- // src/lang/backends/typescript.ts
53170
+ // src/lang/framework-detector.ts
53165
53171
  import * as fs21 from "fs";
53166
53172
  import * as path43 from "path";
53173
+ function detectLaravelProject(directory) {
53174
+ const signals = getLaravelSignals(directory);
53175
+ const signalCount = [
53176
+ signals.hasArtisanFile,
53177
+ signals.hasLaravelFrameworkDep,
53178
+ signals.hasConfigApp
53179
+ ].filter(Boolean).length;
53180
+ return signalCount >= 2;
53181
+ }
53182
+ function getLaravelSignals(directory) {
53183
+ const hasArtisanFile = checkArtisanFile(directory);
53184
+ const hasLaravelFrameworkDep = checkLaravelFrameworkDep(directory);
53185
+ const hasConfigApp = checkConfigApp(directory);
53186
+ return { hasArtisanFile, hasLaravelFrameworkDep, hasConfigApp };
53187
+ }
53188
+ function checkArtisanFile(directory) {
53189
+ const artisanPath = path43.join(directory, "artisan");
53190
+ if (!fs21.existsSync(artisanPath))
53191
+ return false;
53192
+ try {
53193
+ return fs21.statSync(artisanPath).isFile();
53194
+ } catch {
53195
+ return false;
53196
+ }
53197
+ }
53198
+ function checkLaravelFrameworkDep(directory) {
53199
+ const composerPath = path43.join(directory, "composer.json");
53200
+ if (!fs21.existsSync(composerPath))
53201
+ return false;
53202
+ try {
53203
+ const content = fs21.readFileSync(composerPath, "utf-8");
53204
+ const parsed = JSON.parse(content);
53205
+ const require2 = parsed?.require ?? {};
53206
+ return typeof require2["laravel/framework"] === "string";
53207
+ } catch {
53208
+ return false;
53209
+ }
53210
+ }
53211
+ function checkConfigApp(directory) {
53212
+ return fs21.existsSync(path43.join(directory, "config", "app.php"));
53213
+ }
53214
+ var init_framework_detector = () => {};
53215
+
53216
+ // src/lang/backends/php.ts
53217
+ async function selectFramework3(dir) {
53218
+ if (detectLaravelProject(dir)) {
53219
+ return {
53220
+ name: "laravel",
53221
+ detectedVia: "Laravel signals (artisan / composer.json / config/app.php)"
53222
+ };
53223
+ }
53224
+ return null;
53225
+ }
53226
+ function buildPhpBackend() {
53227
+ const profile = LANGUAGE_REGISTRY.get(PROFILE_ID3);
53228
+ if (!profile) {
53229
+ throw new Error("buildPhpBackend: php profile not in LANGUAGE_REGISTRY. " + "profiles.ts must be imported before this backend.");
53230
+ }
53231
+ return {
53232
+ ...defaultBackendFor(profile),
53233
+ selectFramework: selectFramework3
53234
+ };
53235
+ }
53236
+ var PROFILE_ID3 = "php";
53237
+ var init_php = __esm(() => {
53238
+ init_default_backend();
53239
+ init_framework_detector();
53240
+ init_profiles();
53241
+ });
53242
+
53243
+ // src/lang/backends/typescript.ts
53244
+ import * as fs22 from "fs";
53245
+ import * as path44 from "path";
53167
53246
  function readPackageJsonRaw(dir) {
53168
53247
  try {
53169
- const content = fs21.readFileSync(path43.join(dir, "package.json"), "utf-8");
53248
+ const content = fs22.readFileSync(path44.join(dir, "package.json"), "utf-8");
53170
53249
  return JSON.parse(content);
53171
53250
  } catch {
53172
53251
  return null;
@@ -53216,7 +53295,7 @@ function selectionFromFramework(profile, fwName, dir, detectedVia) {
53216
53295
  };
53217
53296
  }
53218
53297
  async function selectTestFramework(dir) {
53219
- const profile = LANGUAGE_REGISTRY.get(PROFILE_ID3);
53298
+ const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
53220
53299
  if (!profile)
53221
53300
  return null;
53222
53301
  const pkg = readPackageJson(dir);
@@ -53238,7 +53317,7 @@ async function selectTestFramework(dir) {
53238
53317
  return defaultSelectTestFramework(profile, dir);
53239
53318
  }
53240
53319
  function buildTestCommand(framework, files, dir, opts) {
53241
- const profile = LANGUAGE_REGISTRY.get(PROFILE_ID3);
53320
+ const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
53242
53321
  if (!profile)
53243
53322
  return null;
53244
53323
  return defaultBuildTestCommand(profile, framework, files, dir, opts);
@@ -53246,7 +53325,7 @@ function buildTestCommand(framework, files, dir, opts) {
53246
53325
  function parseTestOutput(framework, stdout, stderr, exitCode) {
53247
53326
  return defaultParseTestOutput(framework, stdout, stderr, exitCode);
53248
53327
  }
53249
- async function selectFramework3(dir) {
53328
+ async function selectFramework4(dir) {
53250
53329
  const pkg = readPackageJson(dir);
53251
53330
  if (!pkg)
53252
53331
  return null;
@@ -53315,19 +53394,19 @@ function extractImports4(_sourceFile, source) {
53315
53394
  return [...out];
53316
53395
  }
53317
53396
  async function selectBuildCommand(dir) {
53318
- const profile = LANGUAGE_REGISTRY.get(PROFILE_ID3);
53397
+ const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
53319
53398
  if (!profile)
53320
53399
  return null;
53321
53400
  return defaultSelectBuildCommand(profile, dir);
53322
53401
  }
53323
53402
  async function testFilesFor(sourceFile, dir) {
53324
- const profile = LANGUAGE_REGISTRY.get(PROFILE_ID3);
53403
+ const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
53325
53404
  if (!profile)
53326
53405
  return [];
53327
53406
  return defaultTestFilesFor(profile, sourceFile, dir);
53328
53407
  }
53329
53408
  function buildTypescriptBackend() {
53330
- const profile = LANGUAGE_REGISTRY.get(PROFILE_ID3);
53409
+ const profile = LANGUAGE_REGISTRY.get(PROFILE_ID4);
53331
53410
  if (!profile) {
53332
53411
  throw new Error("buildTypescriptBackend: typescript profile not in LANGUAGE_REGISTRY. " + "profiles.ts must be imported before this backend.");
53333
53412
  }
@@ -53339,11 +53418,11 @@ function buildTypescriptBackend() {
53339
53418
  extractImports: extractImports4,
53340
53419
  selectBuildCommand,
53341
53420
  testFilesFor,
53342
- selectFramework: selectFramework3,
53421
+ selectFramework: selectFramework4,
53343
53422
  selectEntryPoints: selectEntryPoints3
53344
53423
  };
53345
53424
  }
53346
- var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals28;
53425
+ var PROFILE_ID4 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals28;
53347
53426
  var init_typescript = __esm(() => {
53348
53427
  init_default_backend();
53349
53428
  init_profiles();
@@ -53366,12 +53445,14 @@ function registerAllBackends() {
53366
53445
  LANGUAGE_BACKEND_REGISTRY.register(buildTypescriptBackend());
53367
53446
  LANGUAGE_BACKEND_REGISTRY.register(buildPythonBackend());
53368
53447
  LANGUAGE_BACKEND_REGISTRY.register(buildGoBackend());
53448
+ LANGUAGE_BACKEND_REGISTRY.register(buildPhpBackend());
53369
53449
  registered = true;
53370
53450
  }
53371
53451
  var registered = false;
53372
53452
  var init_backends = __esm(() => {
53373
53453
  init_registry_backend();
53374
53454
  init_go();
53455
+ init_php();
53375
53456
  init_python();
53376
53457
  init_typescript();
53377
53458
  registerAllBackends();
@@ -53385,11 +53466,11 @@ __export(exports_dispatch, {
53385
53466
  clearDispatchCache: () => clearDispatchCache,
53386
53467
  _internals: () => _internals29
53387
53468
  });
53388
- import * as fs22 from "fs";
53389
- import * as path44 from "path";
53469
+ import * as fs23 from "fs";
53470
+ import * as path45 from "path";
53390
53471
  function safeReaddirSet(dir) {
53391
53472
  try {
53392
- return new Set(fs22.readdirSync(dir));
53473
+ return new Set(fs23.readdirSync(dir));
53393
53474
  } catch {
53394
53475
  return new Set;
53395
53476
  }
@@ -53403,14 +53484,14 @@ function manifestHash(dir) {
53403
53484
  if (!entries.has(name))
53404
53485
  continue;
53405
53486
  try {
53406
- const stat4 = fs22.statSync(path44.join(dir, name));
53487
+ const stat4 = fs23.statSync(path45.join(dir, name));
53407
53488
  parts.push(`${name}:${stat4.size}:${stat4.mtimeMs}:${stat4.ino}`);
53408
53489
  } catch {}
53409
53490
  }
53410
53491
  return parts.join("|");
53411
53492
  }
53412
53493
  function findManifestRoot(start) {
53413
- const resolved = path44.resolve(start);
53494
+ const resolved = path45.resolve(start);
53414
53495
  const cached3 = manifestRootCache.get(resolved);
53415
53496
  if (cached3 !== undefined)
53416
53497
  return cached3;
@@ -53429,7 +53510,7 @@ function findManifestRoot(start) {
53429
53510
  return cur;
53430
53511
  }
53431
53512
  }
53432
- const parent = path44.dirname(cur);
53513
+ const parent = path45.dirname(cur);
53433
53514
  if (parent === cur)
53434
53515
  break;
53435
53516
  cur = parent;
@@ -53538,14 +53619,14 @@ var init_dispatch = __esm(() => {
53538
53619
  });
53539
53620
 
53540
53621
  // src/tools/test-runner.ts
53541
- import * as fs23 from "fs";
53542
- import * as path45 from "path";
53622
+ import * as fs24 from "fs";
53623
+ import * as path46 from "path";
53543
53624
  async function estimateFanOut(sourceFiles, cwd) {
53544
53625
  try {
53545
53626
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
53546
53627
  const uniqueTestFiles = new Set;
53547
53628
  for (const sourceFile of sourceFiles) {
53548
- const resolvedPath = path45.resolve(cwd, sourceFile);
53629
+ const resolvedPath = path46.resolve(cwd, sourceFile);
53549
53630
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
53550
53631
  const testFiles = impactMap[normalizedPath];
53551
53632
  if (testFiles) {
@@ -53627,19 +53708,19 @@ function hasDevDependency(devDeps, ...patterns) {
53627
53708
  return hasPackageJsonDependency(devDeps, ...patterns);
53628
53709
  }
53629
53710
  function detectGoTest(cwd) {
53630
- return fs23.existsSync(path45.join(cwd, "go.mod")) && isCommandAvailable("go");
53711
+ return fs24.existsSync(path46.join(cwd, "go.mod")) && isCommandAvailable("go");
53631
53712
  }
53632
53713
  function detectJavaMaven(cwd) {
53633
- return fs23.existsSync(path45.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
53714
+ return fs24.existsSync(path46.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
53634
53715
  }
53635
53716
  function detectGradle(cwd) {
53636
- const hasBuildFile = fs23.existsSync(path45.join(cwd, "build.gradle")) || fs23.existsSync(path45.join(cwd, "build.gradle.kts"));
53637
- const hasGradlew = fs23.existsSync(path45.join(cwd, "gradlew")) || fs23.existsSync(path45.join(cwd, "gradlew.bat"));
53717
+ const hasBuildFile = fs24.existsSync(path46.join(cwd, "build.gradle")) || fs24.existsSync(path46.join(cwd, "build.gradle.kts"));
53718
+ const hasGradlew = fs24.existsSync(path46.join(cwd, "gradlew")) || fs24.existsSync(path46.join(cwd, "gradlew.bat"));
53638
53719
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
53639
53720
  }
53640
53721
  function detectDotnetTest(cwd) {
53641
53722
  try {
53642
- const files = fs23.readdirSync(cwd);
53723
+ const files = fs24.readdirSync(cwd);
53643
53724
  const hasCsproj = files.some((f) => f.endsWith(".csproj"));
53644
53725
  return hasCsproj && isCommandAvailable("dotnet");
53645
53726
  } catch {
@@ -53647,25 +53728,25 @@ function detectDotnetTest(cwd) {
53647
53728
  }
53648
53729
  }
53649
53730
  function detectCTest(cwd) {
53650
- const hasSource = fs23.existsSync(path45.join(cwd, "CMakeLists.txt"));
53651
- const hasBuildCache = fs23.existsSync(path45.join(cwd, "CMakeCache.txt")) || fs23.existsSync(path45.join(cwd, "build", "CMakeCache.txt"));
53731
+ const hasSource = fs24.existsSync(path46.join(cwd, "CMakeLists.txt"));
53732
+ const hasBuildCache = fs24.existsSync(path46.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path46.join(cwd, "build", "CMakeCache.txt"));
53652
53733
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
53653
53734
  }
53654
53735
  function detectSwiftTest(cwd) {
53655
- return fs23.existsSync(path45.join(cwd, "Package.swift")) && isCommandAvailable("swift");
53736
+ return fs24.existsSync(path46.join(cwd, "Package.swift")) && isCommandAvailable("swift");
53656
53737
  }
53657
53738
  function detectDartTest(cwd) {
53658
- return fs23.existsSync(path45.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
53739
+ return fs24.existsSync(path46.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
53659
53740
  }
53660
53741
  function detectRSpec(cwd) {
53661
- const hasRSpecFile = fs23.existsSync(path45.join(cwd, ".rspec"));
53662
- const hasGemfile = fs23.existsSync(path45.join(cwd, "Gemfile"));
53663
- const hasSpecDir = fs23.existsSync(path45.join(cwd, "spec"));
53742
+ const hasRSpecFile = fs24.existsSync(path46.join(cwd, ".rspec"));
53743
+ const hasGemfile = fs24.existsSync(path46.join(cwd, "Gemfile"));
53744
+ const hasSpecDir = fs24.existsSync(path46.join(cwd, "spec"));
53664
53745
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
53665
53746
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
53666
53747
  }
53667
53748
  function detectMinitest(cwd) {
53668
- return fs23.existsSync(path45.join(cwd, "test")) && (fs23.existsSync(path45.join(cwd, "Gemfile")) || fs23.existsSync(path45.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
53749
+ return fs24.existsSync(path46.join(cwd, "test")) && (fs24.existsSync(path46.join(cwd, "Gemfile")) || fs24.existsSync(path46.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
53669
53750
  }
53670
53751
  async function detectTestFrameworkViaDispatch(cwd) {
53671
53752
  try {
@@ -53728,9 +53809,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
53728
53809
  async function detectTestFramework(cwd) {
53729
53810
  const baseDir = cwd;
53730
53811
  try {
53731
- const packageJsonPath = path45.join(baseDir, "package.json");
53732
- if (fs23.existsSync(packageJsonPath)) {
53733
- const content = fs23.readFileSync(packageJsonPath, "utf-8");
53812
+ const packageJsonPath = path46.join(baseDir, "package.json");
53813
+ if (fs24.existsSync(packageJsonPath)) {
53814
+ const content = fs24.readFileSync(packageJsonPath, "utf-8");
53734
53815
  const pkg = JSON.parse(content);
53735
53816
  const _deps = pkg.dependencies || {};
53736
53817
  const devDeps = pkg.devDependencies || {};
@@ -53749,38 +53830,38 @@ async function detectTestFramework(cwd) {
53749
53830
  return "jest";
53750
53831
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
53751
53832
  return "mocha";
53752
- if (fs23.existsSync(path45.join(baseDir, "bun.lockb")) || fs23.existsSync(path45.join(baseDir, "bun.lock"))) {
53833
+ if (fs24.existsSync(path46.join(baseDir, "bun.lockb")) || fs24.existsSync(path46.join(baseDir, "bun.lock"))) {
53753
53834
  if (scripts.test?.includes("bun"))
53754
53835
  return "bun";
53755
53836
  }
53756
53837
  }
53757
53838
  } catch {}
53758
53839
  try {
53759
- const pyprojectTomlPath = path45.join(baseDir, "pyproject.toml");
53760
- const setupCfgPath = path45.join(baseDir, "setup.cfg");
53761
- const requirementsTxtPath = path45.join(baseDir, "requirements.txt");
53762
- if (fs23.existsSync(pyprojectTomlPath)) {
53763
- const content = fs23.readFileSync(pyprojectTomlPath, "utf-8");
53840
+ const pyprojectTomlPath = path46.join(baseDir, "pyproject.toml");
53841
+ const setupCfgPath = path46.join(baseDir, "setup.cfg");
53842
+ const requirementsTxtPath = path46.join(baseDir, "requirements.txt");
53843
+ if (fs24.existsSync(pyprojectTomlPath)) {
53844
+ const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
53764
53845
  if (content.includes("[tool.pytest"))
53765
53846
  return "pytest";
53766
53847
  if (content.includes("pytest"))
53767
53848
  return "pytest";
53768
53849
  }
53769
- if (fs23.existsSync(setupCfgPath)) {
53770
- const content = fs23.readFileSync(setupCfgPath, "utf-8");
53850
+ if (fs24.existsSync(setupCfgPath)) {
53851
+ const content = fs24.readFileSync(setupCfgPath, "utf-8");
53771
53852
  if (content.includes("[pytest]"))
53772
53853
  return "pytest";
53773
53854
  }
53774
- if (fs23.existsSync(requirementsTxtPath)) {
53775
- const content = fs23.readFileSync(requirementsTxtPath, "utf-8");
53855
+ if (fs24.existsSync(requirementsTxtPath)) {
53856
+ const content = fs24.readFileSync(requirementsTxtPath, "utf-8");
53776
53857
  if (content.includes("pytest"))
53777
53858
  return "pytest";
53778
53859
  }
53779
53860
  } catch {}
53780
53861
  try {
53781
- const cargoTomlPath = path45.join(baseDir, "Cargo.toml");
53782
- if (fs23.existsSync(cargoTomlPath)) {
53783
- const content = fs23.readFileSync(cargoTomlPath, "utf-8");
53862
+ const cargoTomlPath = path46.join(baseDir, "Cargo.toml");
53863
+ if (fs24.existsSync(cargoTomlPath)) {
53864
+ const content = fs24.readFileSync(cargoTomlPath, "utf-8");
53784
53865
  if (content.includes("[dev-dependencies]")) {
53785
53866
  if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
53786
53867
  return "cargo";
@@ -53789,10 +53870,10 @@ async function detectTestFramework(cwd) {
53789
53870
  }
53790
53871
  } catch {}
53791
53872
  try {
53792
- const pesterConfigPath = path45.join(baseDir, "pester.config.ps1");
53793
- const pesterConfigJsonPath = path45.join(baseDir, "pester.config.ps1.json");
53794
- const pesterPs1Path = path45.join(baseDir, "tests.ps1");
53795
- if (fs23.existsSync(pesterConfigPath) || fs23.existsSync(pesterConfigJsonPath) || fs23.existsSync(pesterPs1Path)) {
53873
+ const pesterConfigPath = path46.join(baseDir, "pester.config.ps1");
53874
+ const pesterConfigJsonPath = path46.join(baseDir, "pester.config.ps1.json");
53875
+ const pesterPs1Path = path46.join(baseDir, "tests.ps1");
53876
+ if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
53796
53877
  return "pester";
53797
53878
  }
53798
53879
  } catch {}
@@ -53820,12 +53901,12 @@ function isTestDirectoryPath(normalizedPath) {
53820
53901
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
53821
53902
  }
53822
53903
  function resolveWorkspacePath(file3, workingDir) {
53823
- return path45.isAbsolute(file3) ? path45.resolve(file3) : path45.resolve(workingDir, file3);
53904
+ return path46.isAbsolute(file3) ? path46.resolve(file3) : path46.resolve(workingDir, file3);
53824
53905
  }
53825
53906
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
53826
53907
  if (!preferRelative)
53827
53908
  return absolutePath;
53828
- return path45.relative(workingDir, absolutePath);
53909
+ return path46.relative(workingDir, absolutePath);
53829
53910
  }
53830
53911
  function dedupePush(target, value) {
53831
53912
  if (!target.includes(value)) {
@@ -53862,18 +53943,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
53862
53943
  }
53863
53944
  }
53864
53945
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
53865
- const relativeDir = path45.dirname(relativePath);
53946
+ const relativeDir = path46.dirname(relativePath);
53866
53947
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
53867
53948
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
53868
- const rootDir = path45.join(workingDir, dirName);
53869
- return nestedRelativeDir ? [rootDir, path45.join(rootDir, nestedRelativeDir)] : [rootDir];
53949
+ const rootDir = path46.join(workingDir, dirName);
53950
+ return nestedRelativeDir ? [rootDir, path46.join(rootDir, nestedRelativeDir)] : [rootDir];
53870
53951
  });
53871
53952
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
53872
53953
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
53873
- directories.push(path45.join(workingDir, "src/test/java", path45.dirname(normalizedRelativePath.slice("src/main/java/".length))));
53954
+ directories.push(path46.join(workingDir, "src/test/java", path46.dirname(normalizedRelativePath.slice("src/main/java/".length))));
53874
53955
  }
53875
53956
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
53876
- directories.push(path45.join(workingDir, "src/test/kotlin", path45.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
53957
+ directories.push(path46.join(workingDir, "src/test/kotlin", path46.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
53877
53958
  }
53878
53959
  return [...new Set(directories)];
53879
53960
  }
@@ -53901,23 +53982,23 @@ function isLanguageSpecificTestFile(basename7) {
53901
53982
  }
53902
53983
  function isConventionTestFilePath(filePath) {
53903
53984
  const normalizedPath = filePath.replace(/\\/g, "/");
53904
- const basename7 = path45.basename(filePath);
53985
+ const basename7 = path46.basename(filePath);
53905
53986
  return hasCompoundTestExtension(basename7) || basename7.includes(".spec.") || basename7.includes(".test.") || isLanguageSpecificTestFile(basename7) || isTestDirectoryPath(normalizedPath);
53906
53987
  }
53907
53988
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53908
53989
  const testFiles = [];
53909
53990
  for (const file3 of sourceFiles) {
53910
53991
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
53911
- const relativeFile = path45.relative(workingDir, absoluteFile);
53912
- const basename7 = path45.basename(absoluteFile);
53913
- const dirname23 = path45.dirname(absoluteFile);
53914
- const preferRelativeOutput = !path45.isAbsolute(file3);
53992
+ const relativeFile = path46.relative(workingDir, absoluteFile);
53993
+ const basename7 = path46.basename(absoluteFile);
53994
+ const dirname23 = path46.dirname(absoluteFile);
53995
+ const preferRelativeOutput = !path46.isAbsolute(file3);
53915
53996
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
53916
53997
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
53917
53998
  continue;
53918
53999
  }
53919
54000
  const nameWithoutExt = basename7.replace(/\.[^.]+$/, "");
53920
- const ext = path45.extname(basename7);
54001
+ const ext = path46.extname(basename7);
53921
54002
  const genericTestNames = [
53922
54003
  `${nameWithoutExt}.spec${ext}`,
53923
54004
  `${nameWithoutExt}.test${ext}`
@@ -53926,7 +54007,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53926
54007
  const colocatedCandidates = [
53927
54008
  ...genericTestNames,
53928
54009
  ...languageSpecificTestNames
53929
- ].map((candidateName) => path45.join(dirname23, candidateName));
54010
+ ].map((candidateName) => path46.join(dirname23, candidateName));
53930
54011
  const testDirectoryNames = [
53931
54012
  basename7,
53932
54013
  ...genericTestNames,
@@ -53935,11 +54016,11 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53935
54016
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
53936
54017
  const possibleTestFiles = [
53937
54018
  ...colocatedCandidates,
53938
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path45.join(dirname23, dirName, candidateName))),
53939
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path45.join(candidateDir, candidateName)))
54019
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path46.join(dirname23, dirName, candidateName))),
54020
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path46.join(candidateDir, candidateName)))
53940
54021
  ];
53941
54022
  for (const testFile of possibleTestFiles) {
53942
- if (fs23.existsSync(testFile)) {
54023
+ if (fs24.existsSync(testFile)) {
53943
54024
  dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
53944
54025
  }
53945
54026
  }
@@ -53956,8 +54037,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53956
54037
  for (const testFile of candidateTestFiles) {
53957
54038
  try {
53958
54039
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
53959
- const content = fs23.readFileSync(absoluteTestFile, "utf-8");
53960
- const testDir = path45.dirname(absoluteTestFile);
54040
+ const content = fs24.readFileSync(absoluteTestFile, "utf-8");
54041
+ const testDir = path46.dirname(absoluteTestFile);
53961
54042
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
53962
54043
  let match;
53963
54044
  match = importRegex.exec(content);
@@ -53965,8 +54046,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53965
54046
  const importPath = match[1];
53966
54047
  let resolvedImport;
53967
54048
  if (importPath.startsWith(".")) {
53968
- resolvedImport = path45.resolve(testDir, importPath);
53969
- const existingExt = path45.extname(resolvedImport);
54049
+ resolvedImport = path46.resolve(testDir, importPath);
54050
+ const existingExt = path46.extname(resolvedImport);
53970
54051
  if (!existingExt) {
53971
54052
  for (const extToTry of [
53972
54053
  ".ts",
@@ -53977,7 +54058,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53977
54058
  ".cjs"
53978
54059
  ]) {
53979
54060
  const withExt = resolvedImport + extToTry;
53980
- if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
54061
+ if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
53981
54062
  resolvedImport = withExt;
53982
54063
  break;
53983
54064
  }
@@ -53986,12 +54067,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53986
54067
  } else {
53987
54068
  continue;
53988
54069
  }
53989
- const importBasename = path45.basename(resolvedImport, path45.extname(resolvedImport));
53990
- const importDir = path45.dirname(resolvedImport);
54070
+ const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
54071
+ const importDir = path46.dirname(resolvedImport);
53991
54072
  for (const sourceFile of absoluteSourceFiles) {
53992
- const sourceDir = path45.dirname(sourceFile);
53993
- const sourceBasename = path45.basename(sourceFile, path45.extname(sourceFile));
53994
- const isRelatedDir = importDir === sourceDir || importDir === path45.join(sourceDir, "__tests__") || importDir === path45.join(sourceDir, "tests") || importDir === path45.join(sourceDir, "test") || importDir === path45.join(sourceDir, "spec");
54073
+ const sourceDir = path46.dirname(sourceFile);
54074
+ const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
54075
+ const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
53995
54076
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
53996
54077
  dedupePush(testFiles, testFile);
53997
54078
  break;
@@ -54004,8 +54085,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
54004
54085
  while (match !== null) {
54005
54086
  const importPath = match[1];
54006
54087
  if (importPath.startsWith(".")) {
54007
- let resolvedImport = path45.resolve(testDir, importPath);
54008
- const existingExt = path45.extname(resolvedImport);
54088
+ let resolvedImport = path46.resolve(testDir, importPath);
54089
+ const existingExt = path46.extname(resolvedImport);
54009
54090
  if (!existingExt) {
54010
54091
  for (const extToTry of [
54011
54092
  ".ts",
@@ -54016,18 +54097,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
54016
54097
  ".cjs"
54017
54098
  ]) {
54018
54099
  const withExt = resolvedImport + extToTry;
54019
- if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
54100
+ if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
54020
54101
  resolvedImport = withExt;
54021
54102
  break;
54022
54103
  }
54023
54104
  }
54024
54105
  }
54025
- const importDir = path45.dirname(resolvedImport);
54026
- const importBasename = path45.basename(resolvedImport, path45.extname(resolvedImport));
54106
+ const importDir = path46.dirname(resolvedImport);
54107
+ const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
54027
54108
  for (const sourceFile of absoluteSourceFiles) {
54028
- const sourceDir = path45.dirname(sourceFile);
54029
- const sourceBasename = path45.basename(sourceFile, path45.extname(sourceFile));
54030
- const isRelatedDir = importDir === sourceDir || importDir === path45.join(sourceDir, "__tests__") || importDir === path45.join(sourceDir, "tests") || importDir === path45.join(sourceDir, "test") || importDir === path45.join(sourceDir, "spec");
54109
+ const sourceDir = path46.dirname(sourceFile);
54110
+ const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
54111
+ const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
54031
54112
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
54032
54113
  dedupePush(testFiles, testFile);
54033
54114
  break;
@@ -54147,8 +54228,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir, bail) {
54147
54228
  return ["mvn", "test"];
54148
54229
  case "gradle": {
54149
54230
  const isWindows = process.platform === "win32";
54150
- const hasGradlewBat = fs23.existsSync(path45.join(baseDir, "gradlew.bat"));
54151
- const hasGradlew = fs23.existsSync(path45.join(baseDir, "gradlew"));
54231
+ const hasGradlewBat = fs24.existsSync(path46.join(baseDir, "gradlew.bat"));
54232
+ const hasGradlew = fs24.existsSync(path46.join(baseDir, "gradlew"));
54152
54233
  if (hasGradlewBat && isWindows)
54153
54234
  return ["gradlew.bat", "test"];
54154
54235
  if (hasGradlew)
@@ -54165,7 +54246,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir, bail) {
54165
54246
  "cmake-build-release",
54166
54247
  "out"
54167
54248
  ];
54168
- const actualBuildDir = buildDirCandidates.find((d) => fs23.existsSync(path45.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
54249
+ const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path46.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
54169
54250
  return ["ctest", "--test-dir", actualBuildDir];
54170
54251
  }
54171
54252
  case "swift-test":
@@ -54599,13 +54680,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
54599
54680
  };
54600
54681
  }
54601
54682
  const startTime = Date.now();
54602
- const vitestJsonOutputPath = framework === "vitest" ? path45.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
54683
+ const vitestJsonOutputPath = framework === "vitest" ? path46.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
54603
54684
  try {
54604
54685
  if (vitestJsonOutputPath) {
54605
54686
  try {
54606
- fs23.mkdirSync(path45.dirname(vitestJsonOutputPath), { recursive: true });
54607
- if (fs23.existsSync(vitestJsonOutputPath)) {
54608
- fs23.unlinkSync(vitestJsonOutputPath);
54687
+ fs24.mkdirSync(path46.dirname(vitestJsonOutputPath), { recursive: true });
54688
+ if (fs24.existsSync(vitestJsonOutputPath)) {
54689
+ fs24.unlinkSync(vitestJsonOutputPath);
54609
54690
  }
54610
54691
  } catch {}
54611
54692
  }
@@ -54631,8 +54712,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
54631
54712
  }
54632
54713
  if (vitestJsonOutputPath) {
54633
54714
  try {
54634
- if (fs23.existsSync(vitestJsonOutputPath)) {
54635
- const vitestJsonOutput = fs23.readFileSync(vitestJsonOutputPath, "utf-8");
54715
+ if (fs24.existsSync(vitestJsonOutputPath)) {
54716
+ const vitestJsonOutput = fs24.readFileSync(vitestJsonOutputPath, "utf-8");
54636
54717
  if (vitestJsonOutput.trim().length > 0) {
54637
54718
  output += (output ? `
54638
54719
  ` : "") + vitestJsonOutput;
@@ -54719,10 +54800,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
54719
54800
  }
54720
54801
  function normalizeHistoryTestFile(testFile, workingDir) {
54721
54802
  const normalized = testFile.replace(/\\/g, "/");
54722
- if (!path45.isAbsolute(testFile))
54803
+ if (!path46.isAbsolute(testFile))
54723
54804
  return normalized;
54724
- const relative9 = path45.relative(workingDir, testFile);
54725
- if (relative9.startsWith("..") || path45.isAbsolute(relative9)) {
54805
+ const relative9 = path46.relative(workingDir, testFile);
54806
+ if (relative9.startsWith("..") || path46.isAbsolute(relative9)) {
54726
54807
  return normalized;
54727
54808
  }
54728
54809
  return relative9.replace(/\\/g, "/");
@@ -54829,28 +54910,26 @@ var init_test_runner = __esm(() => {
54829
54910
  init_resolve_working_directory();
54830
54911
  POWERSHELL_METACHARACTERS = /[|;&`$(){}[\]<>"'#*?\x00-\x1f]/;
54831
54912
  DISPATCH_FRAMEWORK_MAP = {
54832
- "bun:test": "bun",
54833
54913
  bun: "bun",
54834
54914
  vitest: "vitest",
54835
54915
  jest: "jest",
54836
54916
  mocha: "mocha",
54837
54917
  pytest: "pytest",
54838
- "cargo test": "cargo",
54839
54918
  cargo: "cargo",
54840
54919
  pester: "pester",
54841
- "go test": "go-test",
54842
- "maven-test": "maven",
54843
- "gradle-test": "gradle",
54844
- "gradle-test-groovy": "gradle",
54845
- "gradle-kts": "gradle",
54846
- "dotnet test": "dotnet-test",
54920
+ "go-test": "go-test",
54921
+ maven: "maven",
54922
+ gradle: "gradle",
54923
+ "dotnet-test": "dotnet-test",
54847
54924
  ctest: "ctest",
54848
- "swift test": "swift-test",
54925
+ "swift-test": "swift-test",
54926
+ "dart-test": "dart-test",
54927
+ rspec: "rspec",
54928
+ minitest: "minitest",
54929
+ "bun:test": "bun",
54849
54930
  "xcodebuild-test": "swift-test",
54850
54931
  "flutter test": "dart-test",
54851
- "dart test": "dart-test",
54852
- rspec: "rspec",
54853
- minitest: "minitest"
54932
+ "dart test": "dart-test"
54854
54933
  };
54855
54934
  COMPOUND_TEST_EXTENSIONS = [
54856
54935
  ".test.ts",
@@ -55062,7 +55141,7 @@ var init_test_runner = __esm(() => {
55062
55141
  const sourceFiles = args.files.filter((file3) => {
55063
55142
  if (directTestFiles.includes(file3))
55064
55143
  return false;
55065
- const ext = path45.extname(file3).toLowerCase();
55144
+ const ext = path46.extname(file3).toLowerCase();
55066
55145
  return SOURCE_EXTENSIONS.has(ext);
55067
55146
  });
55068
55147
  const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
@@ -55108,7 +55187,7 @@ var init_test_runner = __esm(() => {
55108
55187
  if (isConventionTestFilePath(f)) {
55109
55188
  return false;
55110
55189
  }
55111
- const ext = path45.extname(f).toLowerCase();
55190
+ const ext = path46.extname(f).toLowerCase();
55112
55191
  return SOURCE_EXTENSIONS.has(ext);
55113
55192
  });
55114
55193
  if (sourceFiles.length === 0) {
@@ -55158,7 +55237,7 @@ var init_test_runner = __esm(() => {
55158
55237
  if (isConventionTestFilePath(f)) {
55159
55238
  return false;
55160
55239
  }
55161
- const ext = path45.extname(f).toLowerCase();
55240
+ const ext = path46.extname(f).toLowerCase();
55162
55241
  return SOURCE_EXTENSIONS.has(ext);
55163
55242
  });
55164
55243
  if (sourceFiles.length === 0) {
@@ -55210,8 +55289,8 @@ var init_test_runner = __esm(() => {
55210
55289
  }
55211
55290
  if (impactResult.impactedTests.length > 0) {
55212
55291
  testFiles = impactResult.impactedTests.map((absPath) => {
55213
- const relativePath = path45.relative(workingDir, absPath);
55214
- return path45.isAbsolute(relativePath) ? absPath : relativePath;
55292
+ const relativePath = path46.relative(workingDir, absPath);
55293
+ return path46.isAbsolute(relativePath) ? absPath : relativePath;
55215
55294
  });
55216
55295
  } else {
55217
55296
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -55289,8 +55368,8 @@ var init_test_runner = __esm(() => {
55289
55368
  });
55290
55369
 
55291
55370
  // src/services/preflight-service.ts
55292
- import * as fs24 from "fs";
55293
- import * as path46 from "path";
55371
+ import * as fs25 from "fs";
55372
+ import * as path47 from "path";
55294
55373
  function validateDirectoryPath(dir) {
55295
55374
  if (!dir || typeof dir !== "string") {
55296
55375
  throw new Error("Directory path is required");
@@ -55298,8 +55377,8 @@ function validateDirectoryPath(dir) {
55298
55377
  if (dir.includes("..")) {
55299
55378
  throw new Error("Directory path must not contain path traversal sequences");
55300
55379
  }
55301
- const normalized = path46.normalize(dir);
55302
- const absolutePath = path46.isAbsolute(normalized) ? normalized : path46.resolve(normalized);
55380
+ const normalized = path47.normalize(dir);
55381
+ const absolutePath = path47.isAbsolute(normalized) ? normalized : path47.resolve(normalized);
55303
55382
  return absolutePath;
55304
55383
  }
55305
55384
  function validateTimeout(timeoutMs, defaultValue) {
@@ -55322,9 +55401,9 @@ function validateTimeout(timeoutMs, defaultValue) {
55322
55401
  }
55323
55402
  function getPackageVersion(dir) {
55324
55403
  try {
55325
- const packagePath = path46.join(dir, "package.json");
55326
- if (fs24.existsSync(packagePath)) {
55327
- const content = fs24.readFileSync(packagePath, "utf-8");
55404
+ const packagePath = path47.join(dir, "package.json");
55405
+ if (fs25.existsSync(packagePath)) {
55406
+ const content = fs25.readFileSync(packagePath, "utf-8");
55328
55407
  const pkg = JSON.parse(content);
55329
55408
  return pkg.version ?? null;
55330
55409
  }
@@ -55333,9 +55412,9 @@ function getPackageVersion(dir) {
55333
55412
  }
55334
55413
  function getChangelogVersion(dir) {
55335
55414
  try {
55336
- const changelogPath = path46.join(dir, "CHANGELOG.md");
55337
- if (fs24.existsSync(changelogPath)) {
55338
- const content = fs24.readFileSync(changelogPath, "utf-8");
55415
+ const changelogPath = path47.join(dir, "CHANGELOG.md");
55416
+ if (fs25.existsSync(changelogPath)) {
55417
+ const content = fs25.readFileSync(changelogPath, "utf-8");
55339
55418
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
55340
55419
  if (match) {
55341
55420
  return match[1];
@@ -55347,10 +55426,10 @@ function getChangelogVersion(dir) {
55347
55426
  function getVersionFileVersion(dir) {
55348
55427
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
55349
55428
  for (const file3 of possibleFiles) {
55350
- const filePath = path46.join(dir, file3);
55351
- if (fs24.existsSync(filePath)) {
55429
+ const filePath = path47.join(dir, file3);
55430
+ if (fs25.existsSync(filePath)) {
55352
55431
  try {
55353
- const content = fs24.readFileSync(filePath, "utf-8").trim();
55432
+ const content = fs25.readFileSync(filePath, "utf-8").trim();
55354
55433
  const match = content.match(/(\d+\.\d+\.\d+)/);
55355
55434
  if (match) {
55356
55435
  return match[1];
@@ -55689,8 +55768,8 @@ async function runEvidenceCheck(dir) {
55689
55768
  async function runRequirementCoverageCheck(dir, currentPhase) {
55690
55769
  const startTime = Date.now();
55691
55770
  try {
55692
- const specPath = path46.join(dir, ".swarm", "spec.md");
55693
- if (!fs24.existsSync(specPath)) {
55771
+ const specPath = path47.join(dir, ".swarm", "spec.md");
55772
+ if (!fs25.existsSync(specPath)) {
55694
55773
  return {
55695
55774
  type: "req_coverage",
55696
55775
  status: "skip",
@@ -56806,8 +56885,8 @@ var init_manager3 = __esm(() => {
56806
56885
  });
56807
56886
 
56808
56887
  // src/commands/reset.ts
56809
- import * as fs25 from "fs";
56810
- import * as path47 from "path";
56888
+ import * as fs26 from "fs";
56889
+ import * as path48 from "path";
56811
56890
  async function handleResetCommand(directory, args) {
56812
56891
  const hasConfirm = args.includes("--confirm");
56813
56892
  if (!hasConfirm) {
@@ -56835,8 +56914,8 @@ async function handleResetCommand(directory, args) {
56835
56914
  for (const filename of filesToReset) {
56836
56915
  try {
56837
56916
  const resolvedPath = validateSwarmPath(directory, filename);
56838
- if (fs25.existsSync(resolvedPath)) {
56839
- fs25.unlinkSync(resolvedPath);
56917
+ if (fs26.existsSync(resolvedPath)) {
56918
+ fs26.unlinkSync(resolvedPath);
56840
56919
  results.push(`- \u2705 Deleted ${filename}`);
56841
56920
  } else {
56842
56921
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -56847,9 +56926,9 @@ async function handleResetCommand(directory, args) {
56847
56926
  }
56848
56927
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
56849
56928
  try {
56850
- const rootPath = path47.join(directory, filename);
56851
- if (fs25.existsSync(rootPath)) {
56852
- fs25.unlinkSync(rootPath);
56929
+ const rootPath = path48.join(directory, filename);
56930
+ if (fs26.existsSync(rootPath)) {
56931
+ fs26.unlinkSync(rootPath);
56853
56932
  results.push(`- \u2705 Deleted ${filename} (root)`);
56854
56933
  }
56855
56934
  } catch {}
@@ -56862,8 +56941,8 @@ async function handleResetCommand(directory, args) {
56862
56941
  }
56863
56942
  try {
56864
56943
  const summariesPath = validateSwarmPath(directory, "summaries");
56865
- if (fs25.existsSync(summariesPath)) {
56866
- fs25.rmSync(summariesPath, { recursive: true, force: true });
56944
+ if (fs26.existsSync(summariesPath)) {
56945
+ fs26.rmSync(summariesPath, { recursive: true, force: true });
56867
56946
  results.push("- \u2705 Deleted summaries/ directory");
56868
56947
  } else {
56869
56948
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -56886,14 +56965,14 @@ var init_reset = __esm(() => {
56886
56965
  });
56887
56966
 
56888
56967
  // src/commands/reset-session.ts
56889
- import * as fs26 from "fs";
56890
- import * as path48 from "path";
56968
+ import * as fs27 from "fs";
56969
+ import * as path49 from "path";
56891
56970
  async function handleResetSessionCommand(directory, _args) {
56892
56971
  const results = [];
56893
56972
  try {
56894
56973
  const statePath = validateSwarmPath(directory, "session/state.json");
56895
- if (fs26.existsSync(statePath)) {
56896
- fs26.unlinkSync(statePath);
56974
+ if (fs27.existsSync(statePath)) {
56975
+ fs27.unlinkSync(statePath);
56897
56976
  results.push("\u2705 Deleted .swarm/session/state.json");
56898
56977
  } else {
56899
56978
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -56902,15 +56981,15 @@ async function handleResetSessionCommand(directory, _args) {
56902
56981
  results.push("\u274C Failed to delete state.json");
56903
56982
  }
56904
56983
  try {
56905
- const sessionDir = path48.dirname(validateSwarmPath(directory, "session/state.json"));
56906
- if (fs26.existsSync(sessionDir)) {
56907
- const files = fs26.readdirSync(sessionDir);
56984
+ const sessionDir = path49.dirname(validateSwarmPath(directory, "session/state.json"));
56985
+ if (fs27.existsSync(sessionDir)) {
56986
+ const files = fs27.readdirSync(sessionDir);
56908
56987
  const otherFiles = files.filter((f) => f !== "state.json");
56909
56988
  let deletedCount = 0;
56910
56989
  for (const file3 of otherFiles) {
56911
- const filePath = path48.join(sessionDir, file3);
56912
- if (fs26.lstatSync(filePath).isFile()) {
56913
- fs26.unlinkSync(filePath);
56990
+ const filePath = path49.join(sessionDir, file3);
56991
+ if (fs27.lstatSync(filePath).isFile()) {
56992
+ fs27.unlinkSync(filePath);
56914
56993
  deletedCount++;
56915
56994
  }
56916
56995
  }
@@ -56940,7 +57019,7 @@ var init_reset_session = __esm(() => {
56940
57019
  });
56941
57020
 
56942
57021
  // src/summaries/manager.ts
56943
- import * as path49 from "path";
57022
+ import * as path50 from "path";
56944
57023
  function sanitizeSummaryId(id) {
56945
57024
  if (!id || id.length === 0) {
56946
57025
  throw new Error("Invalid summary ID: empty string");
@@ -56963,7 +57042,7 @@ function sanitizeSummaryId(id) {
56963
57042
  }
56964
57043
  async function loadFullOutput(directory, id) {
56965
57044
  const sanitizedId = sanitizeSummaryId(id);
56966
- const relativePath = path49.join("summaries", `${sanitizedId}.json`);
57045
+ const relativePath = path50.join("summaries", `${sanitizedId}.json`);
56967
57046
  validateSwarmPath(directory, relativePath);
56968
57047
  const content = await readSwarmFileAsync(directory, relativePath);
56969
57048
  if (content === null) {
@@ -57025,18 +57104,18 @@ var init_retrieve = __esm(() => {
57025
57104
  });
57026
57105
 
57027
57106
  // src/commands/rollback.ts
57028
- import * as fs27 from "fs";
57029
- import * as path50 from "path";
57107
+ import * as fs28 from "fs";
57108
+ import * as path51 from "path";
57030
57109
  async function handleRollbackCommand(directory, args) {
57031
57110
  const phaseArg = args[0];
57032
57111
  if (!phaseArg) {
57033
57112
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
57034
- if (!fs27.existsSync(manifestPath2)) {
57113
+ if (!fs28.existsSync(manifestPath2)) {
57035
57114
  return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
57036
57115
  }
57037
57116
  let manifest2;
57038
57117
  try {
57039
- manifest2 = JSON.parse(fs27.readFileSync(manifestPath2, "utf-8"));
57118
+ manifest2 = JSON.parse(fs28.readFileSync(manifestPath2, "utf-8"));
57040
57119
  } catch {
57041
57120
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
57042
57121
  }
@@ -57058,12 +57137,12 @@ async function handleRollbackCommand(directory, args) {
57058
57137
  return "Error: Phase number must be a positive integer.";
57059
57138
  }
57060
57139
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
57061
- if (!fs27.existsSync(manifestPath)) {
57140
+ if (!fs28.existsSync(manifestPath)) {
57062
57141
  return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
57063
57142
  }
57064
57143
  let manifest;
57065
57144
  try {
57066
- manifest = JSON.parse(fs27.readFileSync(manifestPath, "utf-8"));
57145
+ manifest = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
57067
57146
  } catch {
57068
57147
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
57069
57148
  }
@@ -57073,10 +57152,10 @@ async function handleRollbackCommand(directory, args) {
57073
57152
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
57074
57153
  }
57075
57154
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
57076
- if (!fs27.existsSync(checkpointDir)) {
57155
+ if (!fs28.existsSync(checkpointDir)) {
57077
57156
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
57078
57157
  }
57079
- const checkpointFiles = fs27.readdirSync(checkpointDir);
57158
+ const checkpointFiles = fs28.readdirSync(checkpointDir);
57080
57159
  if (checkpointFiles.length === 0) {
57081
57160
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
57082
57161
  }
@@ -57091,10 +57170,10 @@ async function handleRollbackCommand(directory, args) {
57091
57170
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
57092
57171
  continue;
57093
57172
  }
57094
- const src = path50.join(checkpointDir, file3);
57095
- const dest = path50.join(swarmDir, file3);
57173
+ const src = path51.join(checkpointDir, file3);
57174
+ const dest = path51.join(swarmDir, file3);
57096
57175
  try {
57097
- fs27.cpSync(src, dest, { recursive: true, force: true });
57176
+ fs28.cpSync(src, dest, { recursive: true, force: true });
57098
57177
  successes.push(file3);
57099
57178
  } catch (error93) {
57100
57179
  failures.push({ file: file3, error: error93.message });
@@ -57111,14 +57190,14 @@ async function handleRollbackCommand(directory, args) {
57111
57190
  ].join(`
57112
57191
  `);
57113
57192
  }
57114
- const existingLedgerPath = path50.join(swarmDir, "plan-ledger.jsonl");
57115
- if (fs27.existsSync(existingLedgerPath)) {
57116
- fs27.unlinkSync(existingLedgerPath);
57193
+ const existingLedgerPath = path51.join(swarmDir, "plan-ledger.jsonl");
57194
+ if (fs28.existsSync(existingLedgerPath)) {
57195
+ fs28.unlinkSync(existingLedgerPath);
57117
57196
  }
57118
57197
  try {
57119
- const planJsonPath = path50.join(swarmDir, "plan.json");
57120
- if (fs27.existsSync(planJsonPath)) {
57121
- const planRaw = fs27.readFileSync(planJsonPath, "utf-8");
57198
+ const planJsonPath = path51.join(swarmDir, "plan.json");
57199
+ if (fs28.existsSync(planJsonPath)) {
57200
+ const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
57122
57201
  const plan = PlanSchema.parse(JSON.parse(planRaw));
57123
57202
  const planId = derivePlanId(plan);
57124
57203
  const planHash = computePlanHash(plan);
@@ -57145,7 +57224,7 @@ async function handleRollbackCommand(directory, args) {
57145
57224
  timestamp: new Date().toISOString()
57146
57225
  };
57147
57226
  try {
57148
- fs27.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
57227
+ fs28.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
57149
57228
  `);
57150
57229
  } catch (error93) {
57151
57230
  console.error("Failed to write rollback event:", error93 instanceof Error ? error93.message : String(error93));
@@ -57206,11 +57285,11 @@ Ensure this is a git repository with commit history.`;
57206
57285
  const report = reportLines.filter(Boolean).join(`
57207
57286
  `);
57208
57287
  try {
57209
- const fs28 = await import("fs/promises");
57210
- const path51 = await import("path");
57211
- const reportPath = path51.join(directory, ".swarm", "simulate-report.md");
57212
- await fs28.mkdir(path51.dirname(reportPath), { recursive: true });
57213
- await fs28.writeFile(reportPath, report, "utf-8");
57288
+ const fs29 = await import("fs/promises");
57289
+ const path52 = await import("path");
57290
+ const reportPath = path52.join(directory, ".swarm", "simulate-report.md");
57291
+ await fs29.mkdir(path52.dirname(reportPath), { recursive: true });
57292
+ await fs29.writeFile(reportPath, report, "utf-8");
57214
57293
  } catch (err) {
57215
57294
  const writeErr = err instanceof Error ? err.message : String(err);
57216
57295
  warn(`simulate: failed to write report to ${directory}/.swarm/simulate-report.md`, writeErr);
@@ -57232,15 +57311,15 @@ async function handleSpecifyCommand(_directory, args) {
57232
57311
  }
57233
57312
 
57234
57313
  // src/turbo/lean/state.ts
57235
- import * as fs28 from "fs";
57236
- import * as path51 from "path";
57314
+ import * as fs29 from "fs";
57315
+ import * as path52 from "path";
57237
57316
  function nowISO2() {
57238
57317
  return new Date().toISOString();
57239
57318
  }
57240
57319
  function ensureSwarmDir2(directory) {
57241
- const swarmDir = path51.resolve(directory, ".swarm");
57242
- if (!fs28.existsSync(swarmDir)) {
57243
- fs28.mkdirSync(swarmDir, { recursive: true });
57320
+ const swarmDir = path52.resolve(directory, ".swarm");
57321
+ if (!fs29.existsSync(swarmDir)) {
57322
+ fs29.mkdirSync(swarmDir, { recursive: true });
57244
57323
  }
57245
57324
  return swarmDir;
57246
57325
  }
@@ -57282,17 +57361,17 @@ function markStateUnreadable2(directory, reason) {
57282
57361
  }
57283
57362
  function readPersisted2(directory) {
57284
57363
  try {
57285
- const filePath = path51.join(directory, ".swarm", STATE_FILE2);
57286
- if (!fs28.existsSync(filePath)) {
57364
+ const filePath = path52.join(directory, ".swarm", STATE_FILE2);
57365
+ if (!fs29.existsSync(filePath)) {
57287
57366
  const seed = emptyPersisted2();
57288
57367
  try {
57289
57368
  ensureSwarmDir2(directory);
57290
- fs28.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
57369
+ fs29.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
57291
57370
  `, "utf-8");
57292
57371
  } catch {}
57293
57372
  return seed;
57294
57373
  }
57295
- const raw = fs28.readFileSync(filePath, "utf-8");
57374
+ const raw = fs29.readFileSync(filePath, "utf-8");
57296
57375
  const parsed = JSON.parse(raw);
57297
57376
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
57298
57377
  markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -57318,7 +57397,7 @@ function writePersisted2(directory, persisted) {
57318
57397
  let payload;
57319
57398
  try {
57320
57399
  ensureSwarmDir2(directory);
57321
- filePath = path51.join(directory, ".swarm", STATE_FILE2);
57400
+ filePath = path52.join(directory, ".swarm", STATE_FILE2);
57322
57401
  tmpPath = `${filePath}.tmp.${Date.now()}`;
57323
57402
  persisted.updatedAt = nowISO2();
57324
57403
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -57329,14 +57408,14 @@ function writePersisted2(directory, persisted) {
57329
57408
  throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
57330
57409
  }
57331
57410
  try {
57332
- fs28.writeFileSync(tmpPath, payload, "utf-8");
57333
- fs28.renameSync(tmpPath, filePath);
57411
+ fs29.writeFileSync(tmpPath, payload, "utf-8");
57412
+ fs29.renameSync(tmpPath, filePath);
57334
57413
  } catch (error93) {
57335
57414
  const msg = error93 instanceof Error ? error93.message : String(error93);
57336
57415
  error(`[turbo/lean/state] Failed to persist ${STATE_FILE2} atomically: ${msg}`);
57337
57416
  try {
57338
- if (fs28.existsSync(tmpPath)) {
57339
- fs28.unlinkSync(tmpPath);
57417
+ if (fs29.existsSync(tmpPath)) {
57418
+ fs29.unlinkSync(tmpPath);
57340
57419
  }
57341
57420
  } catch {}
57342
57421
  throw new Error(`Lean Turbo state persistence failed: ${msg}`);
@@ -57445,10 +57524,10 @@ var init_context_budget_service = __esm(() => {
57445
57524
 
57446
57525
  // src/services/status-service.ts
57447
57526
  import * as fsSync2 from "fs";
57448
- import * as path52 from "path";
57527
+ import * as path53 from "path";
57449
57528
  function readSpecStalenessSnapshot(directory) {
57450
57529
  try {
57451
- const p = path52.join(directory, ".swarm", "spec-staleness.json");
57530
+ const p = path53.join(directory, ".swarm", "spec-staleness.json");
57452
57531
  if (!fsSync2.existsSync(p))
57453
57532
  return { stale: false };
57454
57533
  const raw = fsSync2.readFileSync(p, "utf-8");
@@ -57973,8 +58052,8 @@ var init_write_retro2 = __esm(() => {
57973
58052
  });
57974
58053
 
57975
58054
  // src/commands/command-dispatch.ts
57976
- import fs29 from "fs";
57977
- import path53 from "path";
58055
+ import fs30 from "fs";
58056
+ import path54 from "path";
57978
58057
  function normalizeSwarmCommandInput(command, argumentText) {
57979
58058
  if (command !== "swarm" && !command.startsWith("swarm-")) {
57980
58059
  return { isSwarmCommand: false, tokens: [] };
@@ -58010,11 +58089,11 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
58010
58089
  `);
58011
58090
  }
58012
58091
  function maybeMarkFirstRun(directory) {
58013
- const sentinelPath = path53.join(directory, ".swarm", ".first-run-complete");
58092
+ const sentinelPath = path54.join(directory, ".swarm", ".first-run-complete");
58014
58093
  try {
58015
- const swarmDir = path53.join(directory, ".swarm");
58016
- fs29.mkdirSync(swarmDir, { recursive: true });
58017
- fs29.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
58094
+ const swarmDir = path54.join(directory, ".swarm");
58095
+ fs30.mkdirSync(swarmDir, { recursive: true });
58096
+ fs30.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
58018
58097
  `, { flag: "wx" });
58019
58098
  return true;
58020
58099
  } catch {
@@ -58762,24 +58841,24 @@ function validateAliases() {
58762
58841
  }
58763
58842
  aliasTargets.get(target).push(name);
58764
58843
  const visited = new Set;
58765
- const path54 = [];
58844
+ const path55 = [];
58766
58845
  let current = target;
58767
58846
  while (current) {
58768
58847
  const currentEntry = COMMAND_REGISTRY[current];
58769
58848
  if (!currentEntry)
58770
58849
  break;
58771
58850
  if (visited.has(current)) {
58772
- const cycleStart = path54.indexOf(current);
58851
+ const cycleStart = path55.indexOf(current);
58773
58852
  const fullChain = [
58774
58853
  name,
58775
- ...path54.slice(0, cycleStart > 0 ? cycleStart : path54.length),
58854
+ ...path55.slice(0, cycleStart > 0 ? cycleStart : path55.length),
58776
58855
  current
58777
58856
  ].join(" \u2192 ");
58778
58857
  errors5.push(`Circular alias detected: ${fullChain}`);
58779
58858
  break;
58780
58859
  }
58781
58860
  visited.add(current);
58782
- path54.push(current);
58861
+ path55.push(current);
58783
58862
  current = currentEntry.aliasOf || "";
58784
58863
  }
58785
58864
  }
@@ -59398,68 +59477,72 @@ init_package();
59398
59477
  init_registry();
59399
59478
  init_cache_paths();
59400
59479
  init_constants();
59401
- import * as fs30 from "fs";
59480
+ import * as fs31 from "fs";
59402
59481
  import * as os8 from "os";
59403
- import * as path54 from "path";
59482
+ import * as path55 from "path";
59404
59483
  var { version: version5 } = package_default;
59405
59484
  var CONFIG_DIR = getPluginConfigDir();
59406
- var OPENCODE_CONFIG_PATH = path54.join(CONFIG_DIR, "opencode.json");
59407
- var PLUGIN_CONFIG_PATH = path54.join(CONFIG_DIR, "opencode-swarm.json");
59408
- var PROMPTS_DIR = path54.join(CONFIG_DIR, "opencode-swarm");
59485
+ var OPENCODE_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode.json");
59486
+ var PLUGIN_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode-swarm.json");
59487
+ var PROMPTS_DIR = path55.join(CONFIG_DIR, "opencode-swarm");
59409
59488
  var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
59410
59489
  var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
59411
59490
  function isSafeCachePath(p) {
59412
- const resolved = path54.resolve(p);
59413
- const home = path54.resolve(os8.homedir());
59491
+ const resolved = path55.resolve(p);
59492
+ const home = path55.resolve(os8.homedir());
59414
59493
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
59415
59494
  return false;
59416
59495
  }
59417
- const segments = resolved.split(path54.sep).filter((s) => s.length > 0);
59496
+ const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
59418
59497
  if (segments.length < 4) {
59419
59498
  return false;
59420
59499
  }
59421
- const leaf = path54.basename(resolved);
59500
+ const leaf = path55.basename(resolved);
59422
59501
  if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
59423
59502
  return false;
59424
59503
  }
59425
- const parent = path54.basename(path54.dirname(resolved));
59504
+ const parent = path55.basename(path55.dirname(resolved));
59426
59505
  if (parent !== "packages" && parent !== "node_modules") {
59427
59506
  return false;
59428
59507
  }
59429
- const grandparent = path54.basename(path54.dirname(path54.dirname(resolved)));
59508
+ const grandparent = path55.basename(path55.dirname(path55.dirname(resolved)));
59430
59509
  if (grandparent !== "opencode") {
59431
59510
  return false;
59432
59511
  }
59433
59512
  return true;
59434
59513
  }
59435
59514
  function isSafeLockFilePath(p) {
59436
- const resolved = path54.resolve(p);
59437
- const home = path54.resolve(os8.homedir());
59515
+ const resolved = path55.resolve(p);
59516
+ const home = path55.resolve(os8.homedir());
59438
59517
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
59439
59518
  return false;
59440
59519
  }
59441
- const segments = resolved.split(path54.sep).filter((s) => s.length > 0);
59520
+ const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
59442
59521
  if (segments.length < 4) {
59443
59522
  return false;
59444
59523
  }
59445
- const leaf = path54.basename(resolved);
59524
+ const leaf = path55.basename(resolved);
59446
59525
  if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
59447
59526
  return false;
59448
59527
  }
59449
- const parent = path54.basename(path54.dirname(resolved));
59528
+ const parent = path55.basename(path55.dirname(resolved));
59450
59529
  if (parent !== "opencode") {
59451
59530
  return false;
59452
59531
  }
59532
+ const grandparent = path55.basename(path55.dirname(path55.dirname(resolved)));
59533
+ if (grandparent === "opencode") {
59534
+ return false;
59535
+ }
59453
59536
  return true;
59454
59537
  }
59455
59538
  function ensureDir(dir) {
59456
- if (!fs30.existsSync(dir)) {
59457
- fs30.mkdirSync(dir, { recursive: true });
59539
+ if (!fs31.existsSync(dir)) {
59540
+ fs31.mkdirSync(dir, { recursive: true });
59458
59541
  }
59459
59542
  }
59460
59543
  function loadJson(filepath) {
59461
59544
  try {
59462
- const content = fs30.readFileSync(filepath, "utf-8");
59545
+ const content = fs31.readFileSync(filepath, "utf-8");
59463
59546
  const stripped = content.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (match, comment) => comment ? "" : match).replace(/,(\s*[}\]])/g, "$1");
59464
59547
  return JSON.parse(stripped);
59465
59548
  } catch {
@@ -59467,14 +59550,14 @@ function loadJson(filepath) {
59467
59550
  }
59468
59551
  }
59469
59552
  function saveJson(filepath, data) {
59470
- fs30.writeFileSync(filepath, `${JSON.stringify(data, null, 2)}
59553
+ fs31.writeFileSync(filepath, `${JSON.stringify(data, null, 2)}
59471
59554
  `, "utf-8");
59472
59555
  }
59473
59556
  function writeProjectConfigIfMissing(cwd) {
59474
59557
  try {
59475
- const opencodeDir = path54.join(cwd, ".opencode");
59476
- const projectConfigPath = path54.join(opencodeDir, "opencode-swarm.json");
59477
- if (fs30.existsSync(projectConfigPath)) {
59558
+ const opencodeDir = path55.join(cwd, ".opencode");
59559
+ const projectConfigPath = path55.join(opencodeDir, "opencode-swarm.json");
59560
+ if (fs31.existsSync(projectConfigPath)) {
59478
59561
  return;
59479
59562
  }
59480
59563
  ensureDir(opencodeDir);
@@ -59490,7 +59573,7 @@ async function install() {
59490
59573
  `);
59491
59574
  ensureDir(CONFIG_DIR);
59492
59575
  ensureDir(PROMPTS_DIR);
59493
- const LEGACY_CONFIG_PATH = path54.join(CONFIG_DIR, "config.json");
59576
+ const LEGACY_CONFIG_PATH = path55.join(CONFIG_DIR, "config.json");
59494
59577
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
59495
59578
  if (!opencodeConfig) {
59496
59579
  const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
@@ -59537,7 +59620,7 @@ async function install() {
59537
59620
  console.warn(`\u26A0 Could not clear opencode lock file \u2014 you may need to delete it manually:
59538
59621
  ${failed}`);
59539
59622
  }
59540
- if (!fs30.existsSync(PLUGIN_CONFIG_PATH)) {
59623
+ if (!fs31.existsSync(PLUGIN_CONFIG_PATH)) {
59541
59624
  const defaultConfig = {
59542
59625
  agents: { ...DEFAULT_AGENT_CONFIGS },
59543
59626
  max_iterations: 5
@@ -59616,14 +59699,14 @@ function evictPluginCaches() {
59616
59699
  const cleared = [];
59617
59700
  const failed = [];
59618
59701
  for (const cachePath of OPENCODE_PLUGIN_CACHE_PATHS) {
59619
- if (!fs30.existsSync(cachePath))
59702
+ if (!fs31.existsSync(cachePath))
59620
59703
  continue;
59621
59704
  if (!isSafeCachePath(cachePath)) {
59622
59705
  failed.push(`${cachePath} (refused: failed safety check)`);
59623
59706
  continue;
59624
59707
  }
59625
59708
  try {
59626
- fs30.rmSync(cachePath, { recursive: true, force: true });
59709
+ fs31.rmSync(cachePath, { recursive: true, force: true });
59627
59710
  cleared.push(cachePath);
59628
59711
  } catch (err) {
59629
59712
  failed.push(`${cachePath} (${err instanceof Error ? err.message : String(err)})`);
@@ -59635,14 +59718,14 @@ function evictLockFiles() {
59635
59718
  const cleared = [];
59636
59719
  const failed = [];
59637
59720
  for (const lockPath of OPENCODE_PLUGIN_LOCK_FILE_PATHS) {
59638
- if (!fs30.existsSync(lockPath))
59721
+ if (!fs31.existsSync(lockPath))
59639
59722
  continue;
59640
59723
  if (!isSafeLockFilePath(lockPath)) {
59641
59724
  failed.push(`${lockPath} (refused: failed safety check)`);
59642
59725
  continue;
59643
59726
  }
59644
59727
  try {
59645
- fs30.unlinkSync(lockPath);
59728
+ fs31.unlinkSync(lockPath);
59646
59729
  cleared.push(lockPath);
59647
59730
  } catch (err) {
59648
59731
  const code = err?.code;
@@ -59661,7 +59744,7 @@ async function uninstall() {
59661
59744
  `);
59662
59745
  const opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
59663
59746
  if (!opencodeConfig) {
59664
- if (fs30.existsSync(OPENCODE_CONFIG_PATH)) {
59747
+ if (fs31.existsSync(OPENCODE_CONFIG_PATH)) {
59665
59748
  console.log(`\u2717 Could not parse opencode config at: ${OPENCODE_CONFIG_PATH}`);
59666
59749
  return 1;
59667
59750
  } else {
@@ -59693,13 +59776,13 @@ async function uninstall() {
59693
59776
  console.log("\u2713 Re-enabled default OpenCode agents (explore, general)");
59694
59777
  if (process.argv.includes("--clean")) {
59695
59778
  let cleaned = false;
59696
- if (fs30.existsSync(PLUGIN_CONFIG_PATH)) {
59697
- fs30.unlinkSync(PLUGIN_CONFIG_PATH);
59779
+ if (fs31.existsSync(PLUGIN_CONFIG_PATH)) {
59780
+ fs31.unlinkSync(PLUGIN_CONFIG_PATH);
59698
59781
  console.log(`\u2713 Removed plugin config: ${PLUGIN_CONFIG_PATH}`);
59699
59782
  cleaned = true;
59700
59783
  }
59701
- if (fs30.existsSync(PROMPTS_DIR)) {
59702
- fs30.rmSync(PROMPTS_DIR, { recursive: true });
59784
+ if (fs31.existsSync(PROMPTS_DIR)) {
59785
+ fs31.rmSync(PROMPTS_DIR, { recursive: true });
59703
59786
  console.log(`\u2713 Removed custom prompts: ${PROMPTS_DIR}`);
59704
59787
  cleaned = true;
59705
59788
  }