opencode-swarm 6.86.5 → 6.86.6

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
@@ -17668,15 +17668,15 @@ __export(exports_config_doctor, {
17668
17668
  applySafeAutoFixes: () => applySafeAutoFixes
17669
17669
  });
17670
17670
  import * as crypto3 from "crypto";
17671
- import * as fs9 from "fs";
17671
+ import * as fs8 from "fs";
17672
17672
  import * as os5 from "os";
17673
- import * as path19 from "path";
17673
+ import * as path18 from "path";
17674
17674
  function getUserConfigDir3() {
17675
- return process.env.XDG_CONFIG_HOME || path19.join(os5.homedir(), ".config");
17675
+ return process.env.XDG_CONFIG_HOME || path18.join(os5.homedir(), ".config");
17676
17676
  }
17677
17677
  function getConfigPaths(directory) {
17678
- const userConfigPath = path19.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
17679
- const projectConfigPath = path19.join(directory, ".opencode", "opencode-swarm.json");
17678
+ const userConfigPath = path18.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
17679
+ const projectConfigPath = path18.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 = path19.resolve(configPath);
17705
- const resolvedUser = path19.resolve(normalizedUser);
17706
- const resolvedProject = path19.resolve(normalizedProject);
17704
+ const resolvedConfig = path18.resolve(configPath);
17705
+ const resolvedUser = path18.resolve(normalizedUser);
17706
+ const resolvedProject = path18.resolve(normalizedProject);
17707
17707
  return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
17708
17708
  } catch {
17709
17709
  return false;
@@ -17713,19 +17713,19 @@ function createConfigBackup(directory) {
17713
17713
  const { userConfigPath, projectConfigPath } = getConfigPaths(directory);
17714
17714
  let configPath = projectConfigPath;
17715
17715
  let content = null;
17716
- if (fs9.existsSync(projectConfigPath)) {
17716
+ if (fs8.existsSync(projectConfigPath)) {
17717
17717
  try {
17718
- content = fs9.readFileSync(projectConfigPath, "utf-8");
17718
+ content = fs8.readFileSync(projectConfigPath, "utf-8");
17719
17719
  } catch (error93) {
17720
17720
  log("[ConfigDoctor] project config read failed", {
17721
17721
  error: error93 instanceof Error ? error93.message : String(error93)
17722
17722
  });
17723
17723
  }
17724
17724
  }
17725
- if (content === null && fs9.existsSync(userConfigPath)) {
17725
+ if (content === null && fs8.existsSync(userConfigPath)) {
17726
17726
  configPath = userConfigPath;
17727
17727
  try {
17728
- content = fs9.readFileSync(userConfigPath, "utf-8");
17728
+ content = fs8.readFileSync(userConfigPath, "utf-8");
17729
17729
  } catch (error93) {
17730
17730
  log("[ConfigDoctor] user config read failed", {
17731
17731
  error: error93 instanceof Error ? error93.message : String(error93)
@@ -17743,12 +17743,12 @@ function createConfigBackup(directory) {
17743
17743
  };
17744
17744
  }
17745
17745
  function writeBackupArtifact(directory, backup) {
17746
- const swarmDir = path19.join(directory, ".swarm");
17747
- if (!fs9.existsSync(swarmDir)) {
17748
- fs9.mkdirSync(swarmDir, { recursive: true });
17746
+ const swarmDir = path18.join(directory, ".swarm");
17747
+ if (!fs8.existsSync(swarmDir)) {
17748
+ fs8.mkdirSync(swarmDir, { recursive: true });
17749
17749
  }
17750
17750
  const backupFilename = `config-backup-${backup.createdAt}.json`;
17751
- const backupPath = path19.join(swarmDir, backupFilename);
17751
+ const backupPath = path18.join(swarmDir, backupFilename);
17752
17752
  const artifact = {
17753
17753
  createdAt: backup.createdAt,
17754
17754
  configPath: backup.configPath,
@@ -17756,15 +17756,15 @@ function writeBackupArtifact(directory, backup) {
17756
17756
  content: backup.content,
17757
17757
  preview: backup.content.substring(0, 500) + (backup.content.length > 500 ? "..." : "")
17758
17758
  };
17759
- fs9.writeFileSync(backupPath, JSON.stringify(artifact, null, 2), "utf-8");
17759
+ fs8.writeFileSync(backupPath, JSON.stringify(artifact, null, 2), "utf-8");
17760
17760
  return backupPath;
17761
17761
  }
17762
17762
  function restoreFromBackup(backupPath, directory) {
17763
- if (!fs9.existsSync(backupPath)) {
17763
+ if (!fs8.existsSync(backupPath)) {
17764
17764
  return null;
17765
17765
  }
17766
17766
  try {
17767
- const artifact = JSON.parse(fs9.readFileSync(backupPath, "utf-8"));
17767
+ const artifact = JSON.parse(fs8.readFileSync(backupPath, "utf-8"));
17768
17768
  if (!artifact.content || !artifact.configPath || !artifact.contentHash) {
17769
17769
  return null;
17770
17770
  }
@@ -17778,11 +17778,11 @@ function restoreFromBackup(backupPath, directory) {
17778
17778
  return null;
17779
17779
  }
17780
17780
  const targetPath = artifact.configPath;
17781
- const targetDir = path19.dirname(targetPath);
17782
- if (!fs9.existsSync(targetDir)) {
17783
- fs9.mkdirSync(targetDir, { recursive: true });
17781
+ const targetDir = path18.dirname(targetPath);
17782
+ if (!fs8.existsSync(targetDir)) {
17783
+ fs8.mkdirSync(targetDir, { recursive: true });
17784
17784
  }
17785
- fs9.writeFileSync(targetPath, artifact.content, "utf-8");
17785
+ fs8.writeFileSync(targetPath, artifact.content, "utf-8");
17786
17786
  return targetPath;
17787
17787
  } catch {
17788
17788
  return null;
@@ -17792,12 +17792,12 @@ function readConfigFromFile(directory) {
17792
17792
  const { userConfigPath, projectConfigPath } = getConfigPaths(directory);
17793
17793
  let configPath = projectConfigPath;
17794
17794
  let configContent = null;
17795
- if (fs9.existsSync(projectConfigPath)) {
17795
+ if (fs8.existsSync(projectConfigPath)) {
17796
17796
  configPath = projectConfigPath;
17797
- configContent = fs9.readFileSync(projectConfigPath, "utf-8");
17798
- } else if (fs9.existsSync(userConfigPath)) {
17797
+ configContent = fs8.readFileSync(projectConfigPath, "utf-8");
17798
+ } else if (fs8.existsSync(userConfigPath)) {
17799
17799
  configPath = userConfigPath;
17800
- configContent = fs9.readFileSync(userConfigPath, "utf-8");
17800
+ configContent = fs8.readFileSync(userConfigPath, "utf-8");
17801
17801
  }
17802
17802
  if (configContent === null) {
17803
17803
  return null;
@@ -17809,9 +17809,9 @@ function readConfigFromFile(directory) {
17809
17809
  return null;
17810
17810
  }
17811
17811
  }
17812
- function validateConfigKey(path20, value, _config) {
17812
+ function validateConfigKey(path19, value, _config) {
17813
17813
  const findings = [];
17814
- switch (path20) {
17814
+ switch (path19) {
17815
17815
  case "agents": {
17816
17816
  if (value !== undefined) {
17817
17817
  findings.push({
@@ -18058,27 +18058,27 @@ function validateConfigKey(path20, value, _config) {
18058
18058
  }
18059
18059
  return findings;
18060
18060
  }
18061
- function walkConfigAndValidate(obj, path20, config3, findings) {
18061
+ function walkConfigAndValidate(obj, path19, config3, findings) {
18062
18062
  if (obj === null || obj === undefined) {
18063
18063
  return;
18064
18064
  }
18065
- if (path20 && typeof obj === "object" && !Array.isArray(obj)) {
18066
- const keyFindings = validateConfigKey(path20, obj, config3);
18065
+ if (path19 && typeof obj === "object" && !Array.isArray(obj)) {
18066
+ const keyFindings = validateConfigKey(path19, obj, config3);
18067
18067
  findings.push(...keyFindings);
18068
18068
  }
18069
18069
  if (typeof obj !== "object") {
18070
- const keyFindings = validateConfigKey(path20, obj, config3);
18070
+ const keyFindings = validateConfigKey(path19, 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, `${path20}[${index}]`, config3, findings);
18076
+ walkConfigAndValidate(item, `${path19}[${index}]`, config3, findings);
18077
18077
  });
18078
18078
  return;
18079
18079
  }
18080
18080
  for (const [key, value] of Object.entries(obj)) {
18081
- const newPath = path20 ? `${path20}.${key}` : key;
18081
+ const newPath = path19 ? `${path19}.${key}` : key;
18082
18082
  walkConfigAndValidate(value, newPath, config3, findings);
18083
18083
  }
18084
18084
  }
@@ -18093,9 +18093,9 @@ function runConfigDoctor(config3, directory) {
18093
18093
  const hasAutoFixableIssues = findings.some((f) => f.autoFixable && f.proposedFix?.risk === "low");
18094
18094
  const { userConfigPath, projectConfigPath } = getConfigPaths(directory);
18095
18095
  let configSource = "defaults";
18096
- if (fs9.existsSync(projectConfigPath)) {
18096
+ if (fs8.existsSync(projectConfigPath)) {
18097
18097
  configSource = projectConfigPath;
18098
- } else if (fs9.existsSync(userConfigPath)) {
18098
+ } else if (fs8.existsSync(userConfigPath)) {
18099
18099
  configSource = userConfigPath;
18100
18100
  }
18101
18101
  return {
@@ -18124,12 +18124,12 @@ function applySafeAutoFixes(directory, result) {
18124
18124
  const { userConfigPath, projectConfigPath } = getConfigPaths(directory);
18125
18125
  let configPath = projectConfigPath;
18126
18126
  let configContent;
18127
- if (fs9.existsSync(projectConfigPath)) {
18127
+ if (fs8.existsSync(projectConfigPath)) {
18128
18128
  configPath = projectConfigPath;
18129
- configContent = fs9.readFileSync(projectConfigPath, "utf-8");
18130
- } else if (fs9.existsSync(userConfigPath)) {
18129
+ configContent = fs8.readFileSync(projectConfigPath, "utf-8");
18130
+ } else if (fs8.existsSync(userConfigPath)) {
18131
18131
  configPath = userConfigPath;
18132
- configContent = fs9.readFileSync(userConfigPath, "utf-8");
18132
+ configContent = fs8.readFileSync(userConfigPath, "utf-8");
18133
18133
  } else {
18134
18134
  return { appliedFixes, updatedConfigPath: null };
18135
18135
  }
@@ -18198,22 +18198,22 @@ function applySafeAutoFixes(directory, result) {
18198
18198
  }
18199
18199
  }
18200
18200
  if (appliedFixes.length > 0) {
18201
- const configDir = path19.dirname(configPath);
18202
- if (!fs9.existsSync(configDir)) {
18203
- fs9.mkdirSync(configDir, { recursive: true });
18201
+ const configDir = path18.dirname(configPath);
18202
+ if (!fs8.existsSync(configDir)) {
18203
+ fs8.mkdirSync(configDir, { recursive: true });
18204
18204
  }
18205
- fs9.writeFileSync(configPath, JSON.stringify(config3, null, 2), "utf-8");
18205
+ fs8.writeFileSync(configPath, JSON.stringify(config3, null, 2), "utf-8");
18206
18206
  updatedConfigPath = configPath;
18207
18207
  }
18208
18208
  return { appliedFixes, updatedConfigPath };
18209
18209
  }
18210
18210
  function writeDoctorArtifact(directory, result) {
18211
- const swarmDir = path19.join(directory, ".swarm");
18212
- if (!fs9.existsSync(swarmDir)) {
18213
- fs9.mkdirSync(swarmDir, { recursive: true });
18211
+ const swarmDir = path18.join(directory, ".swarm");
18212
+ if (!fs8.existsSync(swarmDir)) {
18213
+ fs8.mkdirSync(swarmDir, { recursive: true });
18214
18214
  }
18215
18215
  const artifactFilename = "config-doctor.json";
18216
- const artifactPath = path19.join(swarmDir, artifactFilename);
18216
+ const artifactPath = path18.join(swarmDir, artifactFilename);
18217
18217
  const guiOutput = {
18218
18218
  timestamp: result.timestamp,
18219
18219
  summary: result.summary,
@@ -18234,7 +18234,7 @@ function writeDoctorArtifact(directory, result) {
18234
18234
  } : null
18235
18235
  }))
18236
18236
  };
18237
- fs9.writeFileSync(artifactPath, JSON.stringify(guiOutput, null, 2), "utf-8");
18237
+ fs8.writeFileSync(artifactPath, JSON.stringify(guiOutput, null, 2), "utf-8");
18238
18238
  return artifactPath;
18239
18239
  }
18240
18240
  function shouldRunOnStartup(automationConfig) {
@@ -18574,9 +18574,78 @@ var init_evidence_summary_service = __esm(() => {
18574
18574
  });
18575
18575
 
18576
18576
  // src/cli/index.ts
18577
- import * as fs22 from "fs";
18577
+ import * as fs21 from "fs";
18578
18578
  import * as os6 from "os";
18579
- import * as path33 from "path";
18579
+ import * as path32 from "path";
18580
+ // package.json
18581
+ var package_default = {
18582
+ name: "opencode-swarm",
18583
+ version: "6.86.6",
18584
+ description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
18585
+ main: "dist/index.js",
18586
+ types: "dist/index.d.ts",
18587
+ bin: {
18588
+ "opencode-swarm": "./dist/cli/index.js"
18589
+ },
18590
+ type: "module",
18591
+ engines: {
18592
+ bun: ">=1.0.0"
18593
+ },
18594
+ license: "MIT",
18595
+ repository: {
18596
+ type: "git",
18597
+ url: "https://github.com/zaxbysauce/opencode-swarm.git"
18598
+ },
18599
+ publishConfig: {
18600
+ access: "public",
18601
+ registry: "https://registry.npmjs.org/"
18602
+ },
18603
+ keywords: [
18604
+ "opencode",
18605
+ "opencode-plugin",
18606
+ "ai",
18607
+ "agents",
18608
+ "orchestration",
18609
+ "swarm",
18610
+ "multi-agent",
18611
+ "llm"
18612
+ ],
18613
+ files: [
18614
+ "dist",
18615
+ "dist/lang/grammars",
18616
+ "README.md",
18617
+ "LICENSE"
18618
+ ],
18619
+ scripts: {
18620
+ clean: `bun -e "require('fs').rmSync('dist',{recursive:true,force:true})"`,
18621
+ build: "bun run clean && bun run scripts/copy-grammars.ts && bun build src/index.ts --outdir dist --target bun --format esm && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm && bun run scripts/copy-grammars.ts --to-dist && tsc --emitDeclarationOnly",
18622
+ typecheck: "tsc --noEmit",
18623
+ test: "bun test",
18624
+ lint: "biome lint .",
18625
+ format: "biome format . --write",
18626
+ check: "biome check --write .",
18627
+ dev: "bun run build && opencode",
18628
+ prepublishOnly: "bun run build"
18629
+ },
18630
+ dependencies: {
18631
+ "@opencode-ai/plugin": "^1.1.53",
18632
+ "@opencode-ai/sdk": "^1.1.53",
18633
+ "@vscode/tree-sitter-wasm": "^0.3.0",
18634
+ "p-limit": "^7.3.0",
18635
+ picomatch: "^4.0.4",
18636
+ "proper-lockfile": "^4.1.2",
18637
+ "quick-lru": "^7.3.0",
18638
+ "web-tree-sitter": "^0.25.0",
18639
+ zod: "^4.1.8"
18640
+ },
18641
+ devDependencies: {
18642
+ "@biomejs/biome": "2.3.14",
18643
+ "@types/picomatch": "^4.0.3",
18644
+ "bun-types": "1.3.8",
18645
+ "js-yaml": "^4.1.1",
18646
+ typescript: "^5.7.3"
18647
+ }
18648
+ };
18580
18649
 
18581
18650
  // src/commands/acknowledge-spec-drift.ts
18582
18651
  init_utils2();
@@ -18653,71 +18722,6 @@ ${warnings.map((w) => ` - ${w}`).join(`
18653
18722
  return baseMessage + warningMessage + cautionMessage;
18654
18723
  }
18655
18724
 
18656
- // src/commands/agents.ts
18657
- function handleAgentsCommand(agents, guardrails) {
18658
- const entries = Object.entries(agents);
18659
- if (entries.length === 0) {
18660
- return "No agents registered.";
18661
- }
18662
- const lines = [`## Registered Agents (${entries.length} total)`, ""];
18663
- for (const [key, agent] of entries) {
18664
- const model = agent.config.model || "default";
18665
- const temp = agent.config.temperature !== undefined ? agent.config.temperature.toString() : "default";
18666
- const tools = agent.config.tools || {};
18667
- const isReadOnly = tools.write === false || tools.edit === false;
18668
- const access = isReadOnly ? "\uD83D\uDD12 read-only" : "\u270F\uFE0F read-write";
18669
- const desc = agent.description || agent.config.description || "";
18670
- const hasCustomProfile = guardrails?.profiles?.[key] !== undefined;
18671
- const profileIndicator = hasCustomProfile ? " | \u26A1 custom limits" : "";
18672
- lines.push(`- **${key}** | model: \`${model}\` | temp: ${temp} | ${access}${profileIndicator}`);
18673
- if (desc) {
18674
- lines.push(` ${desc}`);
18675
- }
18676
- }
18677
- if (guardrails?.profiles && Object.keys(guardrails.profiles).length > 0) {
18678
- lines.push("", "### Guardrail Profiles", "");
18679
- for (const [profileName, profile] of Object.entries(guardrails.profiles)) {
18680
- const overrides = [];
18681
- if (profile.max_tool_calls !== undefined) {
18682
- overrides.push(`max_tool_calls=${profile.max_tool_calls}`);
18683
- }
18684
- if (profile.max_duration_minutes !== undefined) {
18685
- overrides.push(`max_duration_minutes=${profile.max_duration_minutes}`);
18686
- }
18687
- if (profile.max_repetitions !== undefined) {
18688
- overrides.push(`max_repetitions=${profile.max_repetitions}`);
18689
- }
18690
- if (profile.max_consecutive_errors !== undefined) {
18691
- overrides.push(`max_consecutive_errors=${profile.max_consecutive_errors}`);
18692
- }
18693
- if (profile.warning_threshold !== undefined) {
18694
- overrides.push(`warning_threshold=${profile.warning_threshold}`);
18695
- }
18696
- const overrideStr = overrides.length > 0 ? overrides.join(", ") : "no overrides";
18697
- lines.push(`- **${profileName}**: ${overrideStr}`);
18698
- }
18699
- }
18700
- return lines.join(`
18701
- `);
18702
- }
18703
-
18704
- // src/commands/analyze.ts
18705
- async function handleAnalyzeCommand(_directory, args) {
18706
- const description = args.join(" ").trim();
18707
- if (description) {
18708
- return `[MODE: ANALYZE] ${description}`;
18709
- }
18710
- return "[MODE: ANALYZE] Please analyze the spec against the plan using MODE: ANALYZE.";
18711
- }
18712
-
18713
- // src/config/loader.ts
18714
- import * as fs2 from "fs";
18715
- import * as os2 from "os";
18716
- import * as path4 from "path";
18717
-
18718
- // src/config/schema.ts
18719
- init_zod();
18720
-
18721
18725
  // src/tools/tool-names.ts
18722
18726
  var TOOL_NAMES = [
18723
18727
  "diff",
@@ -19030,6 +19034,57 @@ for (const [agentName, tools] of Object.entries(AGENT_TOOL_MAP)) {
19030
19034
  }
19031
19035
 
19032
19036
  // src/config/schema.ts
19037
+ init_zod();
19038
+ var KNOWN_SWARM_PREFIXES = [
19039
+ "paid",
19040
+ "local",
19041
+ "cloud",
19042
+ "enterprise",
19043
+ "mega",
19044
+ "default",
19045
+ "custom",
19046
+ "team",
19047
+ "project",
19048
+ "swarm",
19049
+ "synthetic"
19050
+ ];
19051
+ var SEPARATORS = ["_", "-", " "];
19052
+ function stripKnownSwarmPrefix(agentName) {
19053
+ if (!agentName)
19054
+ return agentName;
19055
+ const normalized = agentName.toLowerCase();
19056
+ let stripped = normalized;
19057
+ let previous = "";
19058
+ while (stripped !== previous) {
19059
+ previous = stripped;
19060
+ for (const prefix of KNOWN_SWARM_PREFIXES) {
19061
+ for (const sep2 of SEPARATORS) {
19062
+ const prefixWithSep = prefix + sep2;
19063
+ if (stripped.startsWith(prefixWithSep)) {
19064
+ stripped = stripped.slice(prefixWithSep.length);
19065
+ break;
19066
+ }
19067
+ }
19068
+ if (stripped !== previous)
19069
+ break;
19070
+ }
19071
+ }
19072
+ if (ALL_AGENT_NAMES.includes(stripped)) {
19073
+ return stripped;
19074
+ }
19075
+ for (const agent of ALL_AGENT_NAMES) {
19076
+ for (const sep2 of SEPARATORS) {
19077
+ const suffix = sep2 + agent;
19078
+ if (normalized.endsWith(suffix)) {
19079
+ return agent;
19080
+ }
19081
+ }
19082
+ if (normalized === agent) {
19083
+ return agent;
19084
+ }
19085
+ }
19086
+ return agentName;
19087
+ }
19033
19088
  var AgentOverrideConfigSchema = exports_external.object({
19034
19089
  model: exports_external.string().optional(),
19035
19090
  variant: exports_external.string().min(1).optional(),
@@ -19634,6 +19689,7 @@ var PluginConfigSchema = exports_external.object({
19634
19689
  council: CouncilConfigSchema.optional(),
19635
19690
  parallelization: ParallelizationConfigSchema.optional(),
19636
19691
  turbo_mode: exports_external.boolean().default(false).optional(),
19692
+ quiet: exports_external.boolean().default(false).optional(),
19637
19693
  full_auto: exports_external.object({
19638
19694
  enabled: exports_external.boolean().default(false),
19639
19695
  critic_model: exports_external.string().optional(),
@@ -19648,7 +19704,78 @@ var PluginConfigSchema = exports_external.object({
19648
19704
  })
19649
19705
  });
19650
19706
 
19707
+ // src/commands/agents.ts
19708
+ function handleAgentsCommand(agents, guardrails) {
19709
+ const entries = Object.entries(agents);
19710
+ if (entries.length === 0) {
19711
+ return "No agents registered.";
19712
+ }
19713
+ const allAgentKeys = entries.map(([key]) => key);
19714
+ const registeredBaseNames = allAgentKeys.map((key) => stripKnownSwarmPrefix(key)).filter((stripped) => ALL_SUBAGENT_NAMES.includes(stripped));
19715
+ const unregistered = ALL_SUBAGENT_NAMES.filter((name) => !registeredBaseNames.includes(name));
19716
+ const hasUnregistered = unregistered.length > 0;
19717
+ const headerLabel = hasUnregistered ? `${entries.length} registered + ${unregistered.length} unregistered` : `${entries.length} total`;
19718
+ const lines = [`## Registered Agents (${headerLabel})`, ""];
19719
+ for (const [key, agent] of entries) {
19720
+ const model = agent.config.model || "default";
19721
+ const temp = agent.config.temperature !== undefined ? agent.config.temperature.toString() : "default";
19722
+ const tools = agent.config.tools || {};
19723
+ const isReadOnly = tools.write === false || tools.edit === false;
19724
+ const access = isReadOnly ? "\uD83D\uDD12 read-only" : "\u270F\uFE0F read-write";
19725
+ const desc = agent.description || agent.config.description || "";
19726
+ const hasCustomProfile = guardrails?.profiles?.[key] !== undefined;
19727
+ const profileIndicator = hasCustomProfile ? " | \u26A1 custom limits" : "";
19728
+ lines.push(`- **${key}** | model: \`${model}\` | temp: ${temp} | ${access}${profileIndicator}`);
19729
+ if (desc) {
19730
+ lines.push(` ${desc}`);
19731
+ }
19732
+ }
19733
+ if (hasUnregistered) {
19734
+ lines.push("", "### Unregistered Subagents");
19735
+ for (const name of unregistered) {
19736
+ lines.push(`- **${name}** (requires configuration)`);
19737
+ }
19738
+ }
19739
+ if (guardrails?.profiles && Object.keys(guardrails.profiles).length > 0) {
19740
+ lines.push("", "### Guardrail Profiles", "");
19741
+ for (const [profileName, profile] of Object.entries(guardrails.profiles)) {
19742
+ const overrides = [];
19743
+ if (profile.max_tool_calls !== undefined) {
19744
+ overrides.push(`max_tool_calls=${profile.max_tool_calls}`);
19745
+ }
19746
+ if (profile.max_duration_minutes !== undefined) {
19747
+ overrides.push(`max_duration_minutes=${profile.max_duration_minutes}`);
19748
+ }
19749
+ if (profile.max_repetitions !== undefined) {
19750
+ overrides.push(`max_repetitions=${profile.max_repetitions}`);
19751
+ }
19752
+ if (profile.max_consecutive_errors !== undefined) {
19753
+ overrides.push(`max_consecutive_errors=${profile.max_consecutive_errors}`);
19754
+ }
19755
+ if (profile.warning_threshold !== undefined) {
19756
+ overrides.push(`warning_threshold=${profile.warning_threshold}`);
19757
+ }
19758
+ const overrideStr = overrides.length > 0 ? overrides.join(", ") : "no overrides";
19759
+ lines.push(`- **${profileName}**: ${overrideStr}`);
19760
+ }
19761
+ }
19762
+ return lines.join(`
19763
+ `);
19764
+ }
19765
+
19766
+ // src/commands/analyze.ts
19767
+ async function handleAnalyzeCommand(_directory, args) {
19768
+ const description = args.join(" ").trim();
19769
+ if (description) {
19770
+ return `[MODE: ANALYZE] ${description}`;
19771
+ }
19772
+ return "[MODE: ANALYZE] Please analyze the spec against the plan using MODE: ANALYZE.";
19773
+ }
19774
+
19651
19775
  // src/config/loader.ts
19776
+ import * as fs2 from "fs";
19777
+ import * as os2 from "os";
19778
+ import * as path4 from "path";
19652
19779
  var CONFIG_FILENAME = "opencode-swarm.json";
19653
19780
  var MAX_CONFIG_FILE_BYTES = 102400;
19654
19781
  function getUserConfigDir() {
@@ -20341,6 +20468,9 @@ var DeltaSpecSchema = exports_external.union([
20341
20468
  SwarmSpecSchema,
20342
20469
  SpecDeltaSchema
20343
20470
  ]);
20471
+ // src/services/warning-buffer.ts
20472
+ var deferredWarnings = [];
20473
+
20344
20474
  // src/agents/index.ts
20345
20475
  var warnedAgents = new Set;
20346
20476
 
@@ -33670,8 +33800,8 @@ async function handleClarifyCommand(_directory, args) {
33670
33800
 
33671
33801
  // src/commands/close.ts
33672
33802
  import { execFileSync } from "child_process";
33673
- import { promises as fs8 } from "fs";
33674
- import path13 from "path";
33803
+ import { promises as fs7 } from "fs";
33804
+ import path12 from "path";
33675
33805
  init_manager2();
33676
33806
 
33677
33807
  // src/git/branch.ts
@@ -34360,31 +34490,10 @@ async function runAutoPromotion(directory, config3) {
34360
34490
  // src/commands/close.ts
34361
34491
  init_utils2();
34362
34492
 
34363
- // src/plan/checkpoint.ts
34364
- init_plan_schema();
34365
- init_ledger();
34366
- init_manager();
34367
- import * as fs7 from "fs";
34368
- import * as path11 from "path";
34369
- async function writeCheckpoint(directory) {
34370
- try {
34371
- const plan = await loadPlan(directory);
34372
- if (!plan)
34373
- return;
34374
- const jsonPath = path11.join(directory, "SWARM_PLAN.json");
34375
- const mdPath = path11.join(directory, "SWARM_PLAN.md");
34376
- fs7.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
34377
- const md = derivePlanMarkdown(plan);
34378
- fs7.writeFileSync(mdPath, md, "utf8");
34379
- } catch (error93) {
34380
- console.warn(`[checkpoint] Failed to write SWARM_PLAN checkpoint: ${error93 instanceof Error ? error93.message : String(error93)}`);
34381
- }
34382
- }
34383
-
34384
34493
  // src/session/snapshot-writer.ts
34385
34494
  init_utils2();
34386
34495
  import { mkdirSync as mkdirSync7, renameSync as renameSync5 } from "fs";
34387
- import * as path12 from "path";
34496
+ import * as path11 from "path";
34388
34497
  init_utils();
34389
34498
  var _writeInFlight = Promise.resolve();
34390
34499
  function serializeAgentSession(s) {
@@ -34475,7 +34584,7 @@ async function writeSnapshot(directory, state) {
34475
34584
  }
34476
34585
  const content = JSON.stringify(snapshot, null, 2);
34477
34586
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
34478
- const dir = path12.dirname(resolvedPath);
34587
+ const dir = path11.dirname(resolvedPath);
34479
34588
  mkdirSync7(dir, { recursive: true });
34480
34589
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
34481
34590
  await Bun.write(tempPath, content);
@@ -34868,21 +34977,21 @@ var ACTIVE_STATE_TO_CLEAN = [
34868
34977
  ];
34869
34978
  async function handleCloseCommand(directory, args) {
34870
34979
  const planPath = validateSwarmPath(directory, "plan.json");
34871
- const swarmDir = path13.join(directory, ".swarm");
34980
+ const swarmDir = path12.join(directory, ".swarm");
34872
34981
  let planExists = false;
34873
34982
  let planData = {
34874
- title: path13.basename(directory) || "Ad-hoc session",
34983
+ title: path12.basename(directory) || "Ad-hoc session",
34875
34984
  phases: []
34876
34985
  };
34877
34986
  try {
34878
- const content = await fs8.readFile(planPath, "utf-8");
34987
+ const content = await fs7.readFile(planPath, "utf-8");
34879
34988
  planData = JSON.parse(content);
34880
34989
  planExists = true;
34881
34990
  } catch (error93) {
34882
34991
  if (error93?.code !== "ENOENT") {
34883
34992
  return `\u274C Failed to read plan.json: ${error93 instanceof Error ? error93.message : String(error93)}`;
34884
34993
  }
34885
- const swarmDirExists = await fs8.access(swarmDir).then(() => true).catch(() => false);
34994
+ const swarmDirExists = await fs7.access(swarmDir).then(() => true).catch(() => false);
34886
34995
  if (!swarmDirExists) {
34887
34996
  return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
34888
34997
  }
@@ -34976,10 +35085,10 @@ async function handleCloseCommand(directory, args) {
34976
35085
  warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
34977
35086
  }
34978
35087
  }
34979
- const lessonsFilePath = path13.join(swarmDir, "close-lessons.md");
35088
+ const lessonsFilePath = path12.join(swarmDir, "close-lessons.md");
34980
35089
  let explicitLessons = [];
34981
35090
  try {
34982
- const lessonsText = await fs8.readFile(lessonsFilePath, "utf-8");
35091
+ const lessonsText = await fs7.readFile(lessonsFilePath, "utf-8");
34983
35092
  explicitLessons = lessonsText.split(`
34984
35093
  `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
34985
35094
  } catch {}
@@ -34993,7 +35102,7 @@ async function handleCloseCommand(directory, args) {
34993
35102
  console.warn("[close-command] curateAndStoreSwarm error:", error93);
34994
35103
  }
34995
35104
  if (curationSucceeded && explicitLessons.length > 0) {
34996
- await fs8.unlink(lessonsFilePath).catch(() => {});
35105
+ await fs7.unlink(lessonsFilePath).catch(() => {});
34997
35106
  }
34998
35107
  if (planExists && !planAlreadyDone) {
34999
35108
  for (const phase of phases) {
@@ -35013,7 +35122,7 @@ async function handleCloseCommand(directory, args) {
35013
35122
  }
35014
35123
  }
35015
35124
  try {
35016
- await fs8.writeFile(planPath, JSON.stringify(planData, null, 2), "utf-8");
35125
+ await fs7.writeFile(planPath, JSON.stringify(planData, null, 2), "utf-8");
35017
35126
  } catch (error93) {
35018
35127
  const msg = error93 instanceof Error ? error93.message : String(error93);
35019
35128
  warnings.push(`Failed to persist terminal plan.json state: ${msg}`);
@@ -35022,53 +35131,53 @@ async function handleCloseCommand(directory, args) {
35022
35131
  }
35023
35132
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
35024
35133
  const suffix = Math.random().toString(36).slice(2, 8);
35025
- const archiveDir = path13.join(swarmDir, "archive", `swarm-${timestamp}-${suffix}`);
35134
+ const archiveDir = path12.join(swarmDir, "archive", `swarm-${timestamp}-${suffix}`);
35026
35135
  let archiveResult = "";
35027
35136
  let archivedFileCount = 0;
35028
35137
  const archivedActiveStateFiles = new Set;
35029
35138
  try {
35030
- await fs8.mkdir(archiveDir, { recursive: true });
35139
+ await fs7.mkdir(archiveDir, { recursive: true });
35031
35140
  for (const artifact of ARCHIVE_ARTIFACTS) {
35032
- const srcPath = path13.join(swarmDir, artifact);
35033
- const destPath = path13.join(archiveDir, artifact);
35141
+ const srcPath = path12.join(swarmDir, artifact);
35142
+ const destPath = path12.join(archiveDir, artifact);
35034
35143
  try {
35035
- await fs8.copyFile(srcPath, destPath);
35144
+ await fs7.copyFile(srcPath, destPath);
35036
35145
  archivedFileCount++;
35037
35146
  if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
35038
35147
  archivedActiveStateFiles.add(artifact);
35039
35148
  }
35040
35149
  } catch {}
35041
35150
  }
35042
- const evidenceDir = path13.join(swarmDir, "evidence");
35043
- const archiveEvidenceDir = path13.join(archiveDir, "evidence");
35151
+ const evidenceDir = path12.join(swarmDir, "evidence");
35152
+ const archiveEvidenceDir = path12.join(archiveDir, "evidence");
35044
35153
  try {
35045
- const evidenceEntries = await fs8.readdir(evidenceDir);
35154
+ const evidenceEntries = await fs7.readdir(evidenceDir);
35046
35155
  if (evidenceEntries.length > 0) {
35047
- await fs8.mkdir(archiveEvidenceDir, { recursive: true });
35156
+ await fs7.mkdir(archiveEvidenceDir, { recursive: true });
35048
35157
  for (const entry of evidenceEntries) {
35049
- const srcEntry = path13.join(evidenceDir, entry);
35050
- const destEntry = path13.join(archiveEvidenceDir, entry);
35158
+ const srcEntry = path12.join(evidenceDir, entry);
35159
+ const destEntry = path12.join(archiveEvidenceDir, entry);
35051
35160
  try {
35052
- const stat = await fs8.stat(srcEntry);
35161
+ const stat = await fs7.stat(srcEntry);
35053
35162
  if (stat.isDirectory()) {
35054
- await fs8.mkdir(destEntry, { recursive: true });
35055
- const subEntries = await fs8.readdir(srcEntry);
35163
+ await fs7.mkdir(destEntry, { recursive: true });
35164
+ const subEntries = await fs7.readdir(srcEntry);
35056
35165
  for (const sub of subEntries) {
35057
- await fs8.copyFile(path13.join(srcEntry, sub), path13.join(destEntry, sub)).catch(() => {});
35166
+ await fs7.copyFile(path12.join(srcEntry, sub), path12.join(destEntry, sub)).catch(() => {});
35058
35167
  }
35059
35168
  } else {
35060
- await fs8.copyFile(srcEntry, destEntry);
35169
+ await fs7.copyFile(srcEntry, destEntry);
35061
35170
  }
35062
35171
  archivedFileCount++;
35063
35172
  } catch {}
35064
35173
  }
35065
35174
  }
35066
35175
  } catch {}
35067
- const sessionStatePath = path13.join(swarmDir, "session", "state.json");
35176
+ const sessionStatePath = path12.join(swarmDir, "session", "state.json");
35068
35177
  try {
35069
- const archiveSessionDir = path13.join(archiveDir, "session");
35070
- await fs8.mkdir(archiveSessionDir, { recursive: true });
35071
- await fs8.copyFile(sessionStatePath, path13.join(archiveSessionDir, "state.json"));
35178
+ const archiveSessionDir = path12.join(archiveDir, "session");
35179
+ await fs7.mkdir(archiveSessionDir, { recursive: true });
35180
+ await fs7.copyFile(sessionStatePath, path12.join(archiveSessionDir, "state.json"));
35072
35181
  archivedFileCount++;
35073
35182
  } catch {}
35074
35183
  archiveResult = `Archived ${archivedFileCount} artifact(s) to .swarm/archive/swarm-${timestamp}/`;
@@ -35091,9 +35200,9 @@ async function handleCloseCommand(directory, args) {
35091
35200
  warnings.push(`Preserved ${artifact} because it was not successfully archived.`);
35092
35201
  continue;
35093
35202
  }
35094
- const filePath = path13.join(swarmDir, artifact);
35203
+ const filePath = path12.join(swarmDir, artifact);
35095
35204
  try {
35096
- await fs8.unlink(filePath);
35205
+ await fs7.unlink(filePath);
35097
35206
  cleanedFiles.push(artifact);
35098
35207
  } catch {}
35099
35208
  }
@@ -35101,23 +35210,42 @@ async function handleCloseCommand(directory, args) {
35101
35210
  warnings.push("Skipped active-state cleanup because no active-state files were archived. Files preserved to prevent data loss.");
35102
35211
  }
35103
35212
  try {
35104
- const swarmFiles = await fs8.readdir(swarmDir);
35213
+ const swarmFiles = await fs7.readdir(swarmDir);
35105
35214
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
35106
35215
  for (const backup of configBackups) {
35107
35216
  try {
35108
- await fs8.unlink(path13.join(swarmDir, backup));
35217
+ await fs7.unlink(path12.join(swarmDir, backup));
35109
35218
  configBackupsRemoved++;
35110
35219
  } catch {}
35111
35220
  }
35112
35221
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
35113
35222
  for (const sibling of ledgerSiblings) {
35114
35223
  try {
35115
- await fs8.unlink(path13.join(swarmDir, sibling));
35224
+ await fs7.unlink(path12.join(swarmDir, sibling));
35116
35225
  } catch {}
35117
35226
  }
35118
35227
  } catch {}
35228
+ let swarmPlanFilesRemoved = 0;
35229
+ const swarmPlanJsonPath = path12.join(directory, "SWARM_PLAN.json");
35230
+ const swarmPlanMdPath = path12.join(directory, "SWARM_PLAN.md");
35231
+ try {
35232
+ await fs7.unlink(swarmPlanJsonPath);
35233
+ swarmPlanFilesRemoved++;
35234
+ } catch (err) {
35235
+ if (err?.code !== "ENOENT") {
35236
+ warnings.push(`Failed to remove SWARM_PLAN.json: ${err instanceof Error ? err.message : String(err)}`);
35237
+ }
35238
+ }
35239
+ try {
35240
+ await fs7.unlink(swarmPlanMdPath);
35241
+ swarmPlanFilesRemoved++;
35242
+ } catch (err) {
35243
+ if (err?.code !== "ENOENT") {
35244
+ warnings.push(`Failed to remove SWARM_PLAN.md: ${err instanceof Error ? err.message : String(err)}`);
35245
+ }
35246
+ }
35119
35247
  clearAllScopes(directory);
35120
- const contextPath = path13.join(swarmDir, "context.md");
35248
+ const contextPath = path12.join(swarmDir, "context.md");
35121
35249
  const contextContent = [
35122
35250
  "# Context",
35123
35251
  "",
@@ -35130,7 +35258,7 @@ async function handleCloseCommand(directory, args) {
35130
35258
  ].join(`
35131
35259
  `);
35132
35260
  try {
35133
- await fs8.writeFile(contextPath, contextContent, "utf-8");
35261
+ await fs7.writeFile(contextPath, contextContent, "utf-8");
35134
35262
  } catch (error93) {
35135
35263
  const msg = error93 instanceof Error ? error93.message : String(error93);
35136
35264
  warnings.push(`Failed to reset context.md: ${msg}`);
@@ -35232,6 +35360,9 @@ async function handleCloseCommand(directory, args) {
35232
35360
  ] : [],
35233
35361
  "- Reset context.md for next session",
35234
35362
  ...configBackupsRemoved > 0 ? [`- Removed ${configBackupsRemoved} stale config backup file(s)`] : [],
35363
+ ...swarmPlanFilesRemoved > 0 ? [
35364
+ `- Removed ${swarmPlanFilesRemoved} root-level SWARM_PLAN checkpoint artifact(s)`
35365
+ ] : [],
35235
35366
  ...prunedBranches.length > 0 ? [
35236
35367
  `- Pruned ${prunedBranches.length} stale local git branch(es): ${prunedBranches.join(", ")}`
35237
35368
  ] : [],
@@ -35261,7 +35392,7 @@ async function handleCloseCommand(directory, args) {
35261
35392
  ].join(`
35262
35393
  `);
35263
35394
  try {
35264
- await fs8.writeFile(closeSummaryPath, summaryContent, "utf-8");
35395
+ await fs7.writeFile(closeSummaryPath, summaryContent, "utf-8");
35265
35396
  } catch (error93) {
35266
35397
  const msg = error93 instanceof Error ? error93.message : String(error93);
35267
35398
  warnings.push(`Failed to write close-summary.md: ${msg}`);
@@ -35274,7 +35405,6 @@ async function handleCloseCommand(directory, args) {
35274
35405
  warnings.push(`flushPendingSnapshot failed: ${msg}`);
35275
35406
  console.warn("[close-command] flushPendingSnapshot error:", error93);
35276
35407
  }
35277
- await writeCheckpoint(directory).catch(() => {});
35278
35408
  const preservedClient = swarmState.opencodeClient;
35279
35409
  const preservedFullAutoFlag = swarmState.fullAutoEnabledInConfig;
35280
35410
  const preservedCuratorInitNames = swarmState.curatorInitAgentNames;
@@ -35318,14 +35448,14 @@ ${otherWarnings.map((w) => `- ${w}`).join(`
35318
35448
 
35319
35449
  // src/commands/config.ts
35320
35450
  import * as os4 from "os";
35321
- import * as path14 from "path";
35451
+ import * as path13 from "path";
35322
35452
  function getUserConfigDir2() {
35323
- return process.env.XDG_CONFIG_HOME || path14.join(os4.homedir(), ".config");
35453
+ return process.env.XDG_CONFIG_HOME || path13.join(os4.homedir(), ".config");
35324
35454
  }
35325
35455
  async function handleConfigCommand(directory, _args) {
35326
35456
  const config3 = loadPluginConfig(directory);
35327
- const userConfigPath = path14.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
35328
- const projectConfigPath = path14.join(directory, ".opencode", "opencode-swarm.json");
35457
+ const userConfigPath = path13.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
35458
+ const projectConfigPath = path13.join(directory, ".opencode", "opencode-swarm.json");
35329
35459
  const lines = [
35330
35460
  "## Swarm Configuration",
35331
35461
  "",
@@ -35411,7 +35541,7 @@ async function handleCouncilCommand(_directory, args) {
35411
35541
  }
35412
35542
 
35413
35543
  // src/hooks/hive-promoter.ts
35414
- import path15 from "path";
35544
+ import path14 from "path";
35415
35545
 
35416
35546
  // src/background/event-bus.ts
35417
35547
  init_utils();
@@ -35666,7 +35796,7 @@ async function promoteToHive(directory, lesson, category) {
35666
35796
  schema_version: 1,
35667
35797
  created_at: new Date().toISOString(),
35668
35798
  updated_at: new Date().toISOString(),
35669
- source_project: path15.basename(directory) || "unknown",
35799
+ source_project: path14.basename(directory) || "unknown",
35670
35800
  encounter_score: 1
35671
35801
  };
35672
35802
  await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
@@ -35744,14 +35874,14 @@ function formatCurationSummary(summary) {
35744
35874
  }
35745
35875
 
35746
35876
  // src/commands/dark-matter.ts
35747
- import path17 from "path";
35877
+ import path16 from "path";
35748
35878
 
35749
35879
  // src/tools/co-change-analyzer.ts
35750
35880
  init_zod();
35751
35881
  import * as child_process3 from "child_process";
35752
35882
  import { randomUUID } from "crypto";
35753
35883
  import { readdir, readFile as readFile3, stat } from "fs/promises";
35754
- import * as path16 from "path";
35884
+ import * as path15 from "path";
35755
35885
  import { promisify } from "util";
35756
35886
  function getExecFileAsync() {
35757
35887
  return promisify(child_process3.execFile);
@@ -35853,7 +35983,7 @@ async function scanSourceFiles(dir) {
35853
35983
  try {
35854
35984
  const entries = await readdir(dir, { withFileTypes: true });
35855
35985
  for (const entry of entries) {
35856
- const fullPath = path16.join(dir, entry.name);
35986
+ const fullPath = path15.join(dir, entry.name);
35857
35987
  if (entry.isDirectory()) {
35858
35988
  if (skipDirs.has(entry.name)) {
35859
35989
  continue;
@@ -35861,7 +35991,7 @@ async function scanSourceFiles(dir) {
35861
35991
  const subFiles = await scanSourceFiles(fullPath);
35862
35992
  results.push(...subFiles);
35863
35993
  } else if (entry.isFile()) {
35864
- const ext = path16.extname(entry.name);
35994
+ const ext = path15.extname(entry.name);
35865
35995
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
35866
35996
  results.push(fullPath);
35867
35997
  }
@@ -35883,8 +36013,8 @@ async function getStaticEdges(directory) {
35883
36013
  continue;
35884
36014
  }
35885
36015
  try {
35886
- const sourceDir = path16.dirname(sourceFile);
35887
- const resolvedPath = path16.resolve(sourceDir, importPath);
36016
+ const sourceDir = path15.dirname(sourceFile);
36017
+ const resolvedPath = path15.resolve(sourceDir, importPath);
35888
36018
  const extensions = [
35889
36019
  "",
35890
36020
  ".ts",
@@ -35909,8 +36039,8 @@ async function getStaticEdges(directory) {
35909
36039
  if (!targetFile) {
35910
36040
  continue;
35911
36041
  }
35912
- const relSource = path16.relative(directory, sourceFile).replace(/\\/g, "/");
35913
- const relTarget = path16.relative(directory, targetFile).replace(/\\/g, "/");
36042
+ const relSource = path15.relative(directory, sourceFile).replace(/\\/g, "/");
36043
+ const relTarget = path15.relative(directory, targetFile).replace(/\\/g, "/");
35914
36044
  const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
35915
36045
  edges.add(key);
35916
36046
  } catch {}
@@ -35922,7 +36052,7 @@ async function getStaticEdges(directory) {
35922
36052
  function isTestImplementationPair(fileA, fileB) {
35923
36053
  const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
35924
36054
  const getBaseName = (filePath) => {
35925
- const base = path16.basename(filePath);
36055
+ const base = path15.basename(filePath);
35926
36056
  for (const pattern of testPatterns) {
35927
36057
  if (base.endsWith(pattern)) {
35928
36058
  return base.slice(0, -pattern.length);
@@ -35932,16 +36062,16 @@ function isTestImplementationPair(fileA, fileB) {
35932
36062
  };
35933
36063
  const baseA = getBaseName(fileA);
35934
36064
  const baseB = getBaseName(fileB);
35935
- return baseA === baseB && baseA !== path16.basename(fileA) && baseA !== path16.basename(fileB);
36065
+ return baseA === baseB && baseA !== path15.basename(fileA) && baseA !== path15.basename(fileB);
35936
36066
  }
35937
36067
  function hasSharedPrefix(fileA, fileB) {
35938
- const dirA = path16.dirname(fileA);
35939
- const dirB = path16.dirname(fileB);
36068
+ const dirA = path15.dirname(fileA);
36069
+ const dirB = path15.dirname(fileB);
35940
36070
  if (dirA !== dirB) {
35941
36071
  return false;
35942
36072
  }
35943
- const baseA = path16.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
35944
- const baseB = path16.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
36073
+ const baseA = path15.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
36074
+ const baseB = path15.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
35945
36075
  if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
35946
36076
  return true;
35947
36077
  }
@@ -35995,8 +36125,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
35995
36125
  const entries = [];
35996
36126
  const now = new Date().toISOString();
35997
36127
  for (const pair of pairs.slice(0, 10)) {
35998
- const baseA = path16.basename(pair.fileA);
35999
- const baseB = path16.basename(pair.fileB);
36128
+ const baseA = path15.basename(pair.fileA);
36129
+ const baseB = path15.basename(pair.fileB);
36000
36130
  let lesson = `Files ${pair.fileA} and ${pair.fileB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
36001
36131
  if (lesson.length > 280) {
36002
36132
  lesson = `Files ${baseA} and ${baseB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
@@ -36106,7 +36236,7 @@ async function handleDarkMatterCommand(directory, args) {
36106
36236
  const output = formatDarkMatterOutput(pairs);
36107
36237
  if (pairs.length > 0) {
36108
36238
  try {
36109
- const projectName = path17.basename(path17.resolve(directory));
36239
+ const projectName = path16.basename(path16.resolve(directory));
36110
36240
  const entries = darkMatterToKnowledgeEntries(pairs, projectName);
36111
36241
  if (entries.length > 0) {
36112
36242
  const knowledgePath = resolveSwarmKnowledgePath(directory);
@@ -36127,12 +36257,13 @@ async function handleDarkMatterCommand(directory, args) {
36127
36257
 
36128
36258
  // src/services/diagnose-service.ts
36129
36259
  import * as child_process4 from "child_process";
36130
- import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync5 } from "fs";
36131
- import path18 from "path";
36260
+ import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync5, statSync as statSync5 } from "fs";
36261
+ import path17 from "path";
36132
36262
  import { fileURLToPath } from "url";
36133
36263
  init_manager2();
36134
36264
  init_utils2();
36135
36265
  init_manager();
36266
+ var { version: version3 } = package_default;
36136
36267
  function validateTaskDag(plan) {
36137
36268
  const allTaskIds = new Set;
36138
36269
  for (const phase of plan.phases) {
@@ -36428,7 +36559,7 @@ async function checkSpecStaleness(directory, plan) {
36428
36559
  };
36429
36560
  }
36430
36561
  async function checkConfigParseability(directory) {
36431
- const configPath = path18.join(directory, ".opencode/opencode-swarm.json");
36562
+ const configPath = path17.join(directory, ".opencode/opencode-swarm.json");
36432
36563
  if (!existsSync8(configPath)) {
36433
36564
  return {
36434
36565
  name: "Config Parseability",
@@ -36437,7 +36568,7 @@ async function checkConfigParseability(directory) {
36437
36568
  };
36438
36569
  }
36439
36570
  try {
36440
- const content = readFileSync6(configPath, "utf-8");
36571
+ const content = readFileSync5(configPath, "utf-8");
36441
36572
  JSON.parse(content);
36442
36573
  return {
36443
36574
  name: "Config Parseability",
@@ -36457,7 +36588,7 @@ function resolveGrammarDir(thisDir) {
36457
36588
  const normalized = thisDir.replace(/\\/g, "/");
36458
36589
  const isSource = normalized.endsWith("/src/services");
36459
36590
  const isCliBundle = normalized.endsWith("/cli");
36460
- return isSource || isCliBundle ? path18.join(thisDir, "..", "lang", "grammars") : path18.join(thisDir, "lang", "grammars");
36591
+ return isSource || isCliBundle ? path17.join(thisDir, "..", "lang", "grammars") : path17.join(thisDir, "lang", "grammars");
36461
36592
  }
36462
36593
  async function checkGrammarWasmFiles() {
36463
36594
  const grammarFiles = [
@@ -36481,14 +36612,14 @@ async function checkGrammarWasmFiles() {
36481
36612
  "tree-sitter-ini.wasm",
36482
36613
  "tree-sitter-regex.wasm"
36483
36614
  ];
36484
- const thisDir = path18.dirname(fileURLToPath(import.meta.url));
36615
+ const thisDir = path17.dirname(fileURLToPath(import.meta.url));
36485
36616
  const grammarDir = resolveGrammarDir(thisDir);
36486
36617
  const missing = [];
36487
- if (!existsSync8(path18.join(grammarDir, "tree-sitter.wasm"))) {
36618
+ if (!existsSync8(path17.join(grammarDir, "tree-sitter.wasm"))) {
36488
36619
  missing.push("tree-sitter.wasm (core runtime)");
36489
36620
  }
36490
36621
  for (const file3 of grammarFiles) {
36491
- if (!existsSync8(path18.join(grammarDir, file3))) {
36622
+ if (!existsSync8(path17.join(grammarDir, file3))) {
36492
36623
  missing.push(file3);
36493
36624
  }
36494
36625
  }
@@ -36506,7 +36637,7 @@ async function checkGrammarWasmFiles() {
36506
36637
  };
36507
36638
  }
36508
36639
  async function checkCheckpointManifest(directory) {
36509
- const manifestPath = path18.join(directory, ".swarm/checkpoints.json");
36640
+ const manifestPath = path17.join(directory, ".swarm/checkpoints.json");
36510
36641
  if (!existsSync8(manifestPath)) {
36511
36642
  return {
36512
36643
  name: "Checkpoint Manifest",
@@ -36515,7 +36646,7 @@ async function checkCheckpointManifest(directory) {
36515
36646
  };
36516
36647
  }
36517
36648
  try {
36518
- const content = readFileSync6(manifestPath, "utf-8");
36649
+ const content = readFileSync5(manifestPath, "utf-8");
36519
36650
  const parsed = JSON.parse(content);
36520
36651
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
36521
36652
  return {
@@ -36558,7 +36689,7 @@ async function checkCheckpointManifest(directory) {
36558
36689
  }
36559
36690
  }
36560
36691
  async function checkEventStreamIntegrity(directory) {
36561
- const eventsPath = path18.join(directory, ".swarm/events.jsonl");
36692
+ const eventsPath = path17.join(directory, ".swarm/events.jsonl");
36562
36693
  if (!existsSync8(eventsPath)) {
36563
36694
  return {
36564
36695
  name: "Event Stream",
@@ -36567,7 +36698,7 @@ async function checkEventStreamIntegrity(directory) {
36567
36698
  };
36568
36699
  }
36569
36700
  try {
36570
- const content = readFileSync6(eventsPath, "utf-8");
36701
+ const content = readFileSync5(eventsPath, "utf-8");
36571
36702
  const lines = content.split(`
36572
36703
  `).filter((line) => line.trim() !== "");
36573
36704
  let malformedCount = 0;
@@ -36599,7 +36730,7 @@ async function checkEventStreamIntegrity(directory) {
36599
36730
  }
36600
36731
  }
36601
36732
  async function checkSteeringDirectives(directory) {
36602
- const eventsPath = path18.join(directory, ".swarm/events.jsonl");
36733
+ const eventsPath = path17.join(directory, ".swarm/events.jsonl");
36603
36734
  if (!existsSync8(eventsPath)) {
36604
36735
  return {
36605
36736
  name: "Steering Directives",
@@ -36608,7 +36739,7 @@ async function checkSteeringDirectives(directory) {
36608
36739
  };
36609
36740
  }
36610
36741
  try {
36611
- const content = readFileSync6(eventsPath, "utf-8");
36742
+ const content = readFileSync5(eventsPath, "utf-8");
36612
36743
  const lines = content.split(`
36613
36744
  `).filter((line) => line.trim() !== "");
36614
36745
  const directivesIssued = [];
@@ -36655,7 +36786,7 @@ async function checkCurator(directory) {
36655
36786
  detail: "Disabled (enable via curator.enabled)"
36656
36787
  };
36657
36788
  }
36658
- const summaryPath = path18.join(directory, ".swarm/curator-summary.json");
36789
+ const summaryPath = path17.join(directory, ".swarm/curator-summary.json");
36659
36790
  if (!existsSync8(summaryPath)) {
36660
36791
  return {
36661
36792
  name: "Curator",
@@ -36664,7 +36795,7 @@ async function checkCurator(directory) {
36664
36795
  };
36665
36796
  }
36666
36797
  try {
36667
- const content = readFileSync6(summaryPath, "utf-8");
36798
+ const content = readFileSync5(summaryPath, "utf-8");
36668
36799
  const parsed = JSON.parse(content);
36669
36800
  if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
36670
36801
  return {
@@ -36699,6 +36830,11 @@ async function checkCurator(directory) {
36699
36830
  }
36700
36831
  async function getDiagnoseData(directory) {
36701
36832
  const checks5 = [];
36833
+ checks5.push({
36834
+ name: "Version",
36835
+ status: "\u2705",
36836
+ detail: version3
36837
+ });
36702
36838
  const plan = await loadPlanJsonOnly(directory);
36703
36839
  if (plan) {
36704
36840
  checks5.push({
@@ -36803,7 +36939,7 @@ async function getDiagnoseData(directory) {
36803
36939
  checks5.push(await checkSteeringDirectives(directory));
36804
36940
  checks5.push(await checkCurator(directory));
36805
36941
  try {
36806
- const evidenceDir = path18.join(directory, ".swarm", "evidence");
36942
+ const evidenceDir = path17.join(directory, ".swarm", "evidence");
36807
36943
  const snapshotFiles = existsSync8(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
36808
36944
  if (snapshotFiles.length > 0) {
36809
36945
  const latest = snapshotFiles.sort().pop();
@@ -36826,6 +36962,13 @@ async function getDiagnoseData(directory) {
36826
36962
  detail: "No snapshots yet (snapshots written on next session start)"
36827
36963
  });
36828
36964
  }
36965
+ if (deferredWarnings.length > 0) {
36966
+ checks5.push({
36967
+ name: "Deferred Warnings",
36968
+ status: "\u26A0\uFE0F",
36969
+ detail: `${deferredWarnings.length} warning(s) deferred from init (run with verbose logs for details)`
36970
+ });
36971
+ }
36829
36972
  const passCount = checks5.filter((c) => c.status === "\u2705").length;
36830
36973
  const totalCount = checks5.length;
36831
36974
  const allPassed = passCount === totalCount;
@@ -36844,6 +36987,14 @@ function formatDiagnoseMarkdown(diagnose) {
36844
36987
  "",
36845
36988
  `**Result**: ${diagnose.allPassed ? "\u2705 All checks passed" : `\u26A0\uFE0F ${diagnose.passCount}/${diagnose.totalCount} checks passed`}`
36846
36989
  ];
36990
+ if (deferredWarnings.length > 0) {
36991
+ lines.push("");
36992
+ lines.push("## Deferred Warnings");
36993
+ lines.push("");
36994
+ for (const warning of deferredWarnings) {
36995
+ lines.push(`- ${warning}`);
36996
+ }
36997
+ }
36847
36998
  return lines.join(`
36848
36999
  `);
36849
37000
  }
@@ -36855,16 +37006,16 @@ async function handleDiagnoseCommand(directory, _args) {
36855
37006
  init_config_doctor();
36856
37007
 
36857
37008
  // src/services/tool-doctor.ts
36858
- import * as fs11 from "fs";
36859
- import * as path21 from "path";
36860
-
36861
- // src/build/discovery.ts
36862
37009
  import * as fs10 from "fs";
36863
37010
  import * as path20 from "path";
36864
37011
 
37012
+ // src/build/discovery.ts
37013
+ import * as fs9 from "fs";
37014
+ import * as path19 from "path";
37015
+
36865
37016
  // src/lang/detector.ts
36866
37017
  import { access as access2, readdir as readdir2 } from "fs/promises";
36867
- import { extname as extname2, join as join16 } from "path";
37018
+ import { extname as extname2, join as join15 } from "path";
36868
37019
 
36869
37020
  // src/lang/profiles.ts
36870
37021
  class LanguageRegistry {
@@ -37844,7 +37995,7 @@ async function detectProjectLanguages(projectDir) {
37844
37995
  if (detectFile.includes("*") || detectFile.includes("?"))
37845
37996
  continue;
37846
37997
  try {
37847
- await access2(join16(dir, detectFile));
37998
+ await access2(join15(dir, detectFile));
37848
37999
  detected.add(profile.id);
37849
38000
  break;
37850
38001
  } catch {}
@@ -37865,7 +38016,7 @@ async function detectProjectLanguages(projectDir) {
37865
38016
  const topEntries = await readdir2(projectDir, { withFileTypes: true });
37866
38017
  for (const entry of topEntries) {
37867
38018
  if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
37868
- await scanDir(join16(projectDir, entry.name));
38019
+ await scanDir(join15(projectDir, entry.name));
37869
38020
  }
37870
38021
  }
37871
38022
  } catch {}
@@ -38020,16 +38171,16 @@ function findBuildFiles(workingDir, patterns) {
38020
38171
  if (pattern.includes("*")) {
38021
38172
  const dir = workingDir;
38022
38173
  try {
38023
- const files = fs10.readdirSync(dir);
38174
+ const files = fs9.readdirSync(dir);
38024
38175
  const regex = simpleGlobToRegex(pattern);
38025
38176
  const matches = files.filter((f) => regex.test(f));
38026
38177
  if (matches.length > 0) {
38027
- return path20.join(dir, matches[0]);
38178
+ return path19.join(dir, matches[0]);
38028
38179
  }
38029
38180
  } catch {}
38030
38181
  } else {
38031
- const filePath = path20.join(workingDir, pattern);
38032
- if (fs10.existsSync(filePath)) {
38182
+ const filePath = path19.join(workingDir, pattern);
38183
+ if (fs9.existsSync(filePath)) {
38033
38184
  return filePath;
38034
38185
  }
38035
38186
  }
@@ -38037,12 +38188,12 @@ function findBuildFiles(workingDir, patterns) {
38037
38188
  return null;
38038
38189
  }
38039
38190
  function getRepoDefinedScripts(workingDir, scripts) {
38040
- const packageJsonPath = path20.join(workingDir, "package.json");
38041
- if (!fs10.existsSync(packageJsonPath)) {
38191
+ const packageJsonPath = path19.join(workingDir, "package.json");
38192
+ if (!fs9.existsSync(packageJsonPath)) {
38042
38193
  return [];
38043
38194
  }
38044
38195
  try {
38045
- const content = fs10.readFileSync(packageJsonPath, "utf-8");
38196
+ const content = fs9.readFileSync(packageJsonPath, "utf-8");
38046
38197
  const pkg = JSON.parse(content);
38047
38198
  if (!pkg.scripts || typeof pkg.scripts !== "object") {
38048
38199
  return [];
@@ -38078,8 +38229,8 @@ function findAllBuildFiles(workingDir) {
38078
38229
  const regex = simpleGlobToRegex(pattern);
38079
38230
  findFilesRecursive(workingDir, regex, allBuildFiles);
38080
38231
  } else {
38081
- const filePath = path20.join(workingDir, pattern);
38082
- if (fs10.existsSync(filePath)) {
38232
+ const filePath = path19.join(workingDir, pattern);
38233
+ if (fs9.existsSync(filePath)) {
38083
38234
  allBuildFiles.add(filePath);
38084
38235
  }
38085
38236
  }
@@ -38089,9 +38240,9 @@ function findAllBuildFiles(workingDir) {
38089
38240
  }
38090
38241
  function findFilesRecursive(dir, regex, results) {
38091
38242
  try {
38092
- const entries = fs10.readdirSync(dir, { withFileTypes: true });
38243
+ const entries = fs9.readdirSync(dir, { withFileTypes: true });
38093
38244
  for (const entry of entries) {
38094
- const fullPath = path20.join(dir, entry.name);
38245
+ const fullPath = path19.join(dir, entry.name);
38095
38246
  if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
38096
38247
  findFilesRecursive(fullPath, regex, results);
38097
38248
  } else if (entry.isFile() && regex.test(entry.name)) {
@@ -38114,8 +38265,8 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
38114
38265
  let foundCommand = false;
38115
38266
  for (const cmd of sortedCommands) {
38116
38267
  if (cmd.detectFile) {
38117
- const detectFilePath = path20.join(workingDir, cmd.detectFile);
38118
- if (!fs10.existsSync(detectFilePath)) {
38268
+ const detectFilePath = path19.join(workingDir, cmd.detectFile);
38269
+ if (!fs9.existsSync(detectFilePath)) {
38119
38270
  continue;
38120
38271
  }
38121
38272
  }
@@ -38238,7 +38389,7 @@ var BINARY_CHECKLIST = [
38238
38389
  function extractRegisteredToolKeys(indexPath) {
38239
38390
  const registeredKeys = new Set;
38240
38391
  try {
38241
- const content = fs11.readFileSync(indexPath, "utf-8");
38392
+ const content = fs10.readFileSync(indexPath, "utf-8");
38242
38393
  const toolBlockMatch = content.match(/tool:\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/s);
38243
38394
  if (!toolBlockMatch) {
38244
38395
  return registeredKeys;
@@ -38289,9 +38440,9 @@ function checkBinaryReadiness() {
38289
38440
  }
38290
38441
  function runToolDoctor(_directory, pluginRoot) {
38291
38442
  const findings = [];
38292
- const resolvedPluginRoot = pluginRoot ?? path21.resolve(import.meta.dir, "..", "..");
38293
- const indexPath = path21.join(resolvedPluginRoot, "src", "index.ts");
38294
- if (!fs11.existsSync(indexPath)) {
38443
+ const resolvedPluginRoot = pluginRoot ?? path20.resolve(import.meta.dir, "..", "..");
38444
+ const indexPath = path20.join(resolvedPluginRoot, "src", "index.ts");
38445
+ if (!fs10.existsSync(indexPath)) {
38295
38446
  return {
38296
38447
  findings: [
38297
38448
  {
@@ -39211,12 +39362,12 @@ async function handleHistoryCommand(directory, _args) {
39211
39362
  }
39212
39363
  // src/hooks/knowledge-migrator.ts
39213
39364
  import { randomUUID as randomUUID2 } from "crypto";
39214
- import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
39365
+ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
39215
39366
  import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
39216
- import * as path22 from "path";
39367
+ import * as path21 from "path";
39217
39368
  async function migrateContextToKnowledge(directory, config3) {
39218
- const sentinelPath = path22.join(directory, ".swarm", ".knowledge-migrated");
39219
- const contextPath = path22.join(directory, ".swarm", "context.md");
39369
+ const sentinelPath = path21.join(directory, ".swarm", ".knowledge-migrated");
39370
+ const contextPath = path21.join(directory, ".swarm", "context.md");
39220
39371
  const knowledgePath = resolveSwarmKnowledgePath(directory);
39221
39372
  if (existsSync12(sentinelPath)) {
39222
39373
  return {
@@ -39412,16 +39563,16 @@ function truncateLesson(text) {
39412
39563
  return `${text.slice(0, 277)}...`;
39413
39564
  }
39414
39565
  function inferProjectName(directory) {
39415
- const packageJsonPath = path22.join(directory, "package.json");
39566
+ const packageJsonPath = path21.join(directory, "package.json");
39416
39567
  if (existsSync12(packageJsonPath)) {
39417
39568
  try {
39418
- const pkg = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
39569
+ const pkg = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
39419
39570
  if (pkg.name && typeof pkg.name === "string") {
39420
39571
  return pkg.name;
39421
39572
  }
39422
39573
  } catch {}
39423
39574
  }
39424
- return path22.basename(directory);
39575
+ return path21.basename(directory);
39425
39576
  }
39426
39577
  async function writeSentinel(sentinelPath, migrated, dropped) {
39427
39578
  const sentinel = {
@@ -39433,7 +39584,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
39433
39584
  schema_version: 1,
39434
39585
  migration_tool: "knowledge-migrator.ts"
39435
39586
  };
39436
- await mkdir3(path22.dirname(sentinelPath), { recursive: true });
39587
+ await mkdir3(path21.dirname(sentinelPath), { recursive: true });
39437
39588
  await writeFile4(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
39438
39589
  }
39439
39590
 
@@ -39669,13 +39820,13 @@ async function handlePlanCommand(directory, args) {
39669
39820
  // src/services/preflight-service.ts
39670
39821
  init_manager2();
39671
39822
  init_manager();
39672
- import * as fs18 from "fs";
39673
- import * as path29 from "path";
39823
+ import * as fs17 from "fs";
39824
+ import * as path28 from "path";
39674
39825
 
39675
39826
  // src/tools/lint.ts
39676
39827
  init_zod();
39677
- import * as fs12 from "fs";
39678
- import * as path23 from "path";
39828
+ import * as fs11 from "fs";
39829
+ import * as path22 from "path";
39679
39830
  init_utils();
39680
39831
 
39681
39832
  // src/utils/path-security.ts
@@ -39721,9 +39872,9 @@ function validateArgs(args) {
39721
39872
  }
39722
39873
  function getLinterCommand(linter, mode, projectDir) {
39723
39874
  const isWindows = process.platform === "win32";
39724
- const binDir = path23.join(projectDir, "node_modules", ".bin");
39725
- const biomeBin = isWindows ? path23.join(binDir, "biome.EXE") : path23.join(binDir, "biome");
39726
- const eslintBin = isWindows ? path23.join(binDir, "eslint.cmd") : path23.join(binDir, "eslint");
39875
+ const binDir = path22.join(projectDir, "node_modules", ".bin");
39876
+ const biomeBin = isWindows ? path22.join(binDir, "biome.EXE") : path22.join(binDir, "biome");
39877
+ const eslintBin = isWindows ? path22.join(binDir, "eslint.cmd") : path22.join(binDir, "eslint");
39727
39878
  switch (linter) {
39728
39879
  case "biome":
39729
39880
  if (mode === "fix") {
@@ -39739,7 +39890,7 @@ function getLinterCommand(linter, mode, projectDir) {
39739
39890
  }
39740
39891
  function getAdditionalLinterCommand(linter, mode, cwd) {
39741
39892
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
39742
- const gradlew = fs12.existsSync(path23.join(cwd, gradlewName)) ? path23.join(cwd, gradlewName) : null;
39893
+ const gradlew = fs11.existsSync(path22.join(cwd, gradlewName)) ? path22.join(cwd, gradlewName) : null;
39743
39894
  switch (linter) {
39744
39895
  case "ruff":
39745
39896
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -39773,12 +39924,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
39773
39924
  }
39774
39925
  }
39775
39926
  function detectRuff(cwd) {
39776
- if (fs12.existsSync(path23.join(cwd, "ruff.toml")))
39927
+ if (fs11.existsSync(path22.join(cwd, "ruff.toml")))
39777
39928
  return isCommandAvailable("ruff");
39778
39929
  try {
39779
- const pyproject = path23.join(cwd, "pyproject.toml");
39780
- if (fs12.existsSync(pyproject)) {
39781
- const content = fs12.readFileSync(pyproject, "utf-8");
39930
+ const pyproject = path22.join(cwd, "pyproject.toml");
39931
+ if (fs11.existsSync(pyproject)) {
39932
+ const content = fs11.readFileSync(pyproject, "utf-8");
39782
39933
  if (content.includes("[tool.ruff]"))
39783
39934
  return isCommandAvailable("ruff");
39784
39935
  }
@@ -39786,21 +39937,21 @@ function detectRuff(cwd) {
39786
39937
  return false;
39787
39938
  }
39788
39939
  function detectClippy(cwd) {
39789
- return fs12.existsSync(path23.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
39940
+ return fs11.existsSync(path22.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
39790
39941
  }
39791
39942
  function detectGolangciLint(cwd) {
39792
- return fs12.existsSync(path23.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
39943
+ return fs11.existsSync(path22.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
39793
39944
  }
39794
39945
  function detectCheckstyle(cwd) {
39795
- const hasMaven = fs12.existsSync(path23.join(cwd, "pom.xml"));
39796
- const hasGradle = fs12.existsSync(path23.join(cwd, "build.gradle")) || fs12.existsSync(path23.join(cwd, "build.gradle.kts"));
39797
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(path23.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
39946
+ const hasMaven = fs11.existsSync(path22.join(cwd, "pom.xml"));
39947
+ const hasGradle = fs11.existsSync(path22.join(cwd, "build.gradle")) || fs11.existsSync(path22.join(cwd, "build.gradle.kts"));
39948
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs11.existsSync(path22.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
39798
39949
  return (hasMaven || hasGradle) && hasBinary;
39799
39950
  }
39800
39951
  function detectKtlint(cwd) {
39801
- const hasKotlin = fs12.existsSync(path23.join(cwd, "build.gradle.kts")) || fs12.existsSync(path23.join(cwd, "build.gradle")) || (() => {
39952
+ const hasKotlin = fs11.existsSync(path22.join(cwd, "build.gradle.kts")) || fs11.existsSync(path22.join(cwd, "build.gradle")) || (() => {
39802
39953
  try {
39803
- return fs12.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
39954
+ return fs11.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
39804
39955
  } catch {
39805
39956
  return false;
39806
39957
  }
@@ -39809,7 +39960,7 @@ function detectKtlint(cwd) {
39809
39960
  }
39810
39961
  function detectDotnetFormat(cwd) {
39811
39962
  try {
39812
- const files = fs12.readdirSync(cwd);
39963
+ const files = fs11.readdirSync(cwd);
39813
39964
  const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
39814
39965
  return hasCsproj && isCommandAvailable("dotnet");
39815
39966
  } catch {
@@ -39817,14 +39968,14 @@ function detectDotnetFormat(cwd) {
39817
39968
  }
39818
39969
  }
39819
39970
  function detectCppcheck(cwd) {
39820
- if (fs12.existsSync(path23.join(cwd, "CMakeLists.txt"))) {
39971
+ if (fs11.existsSync(path22.join(cwd, "CMakeLists.txt"))) {
39821
39972
  return isCommandAvailable("cppcheck");
39822
39973
  }
39823
39974
  try {
39824
- const dirsToCheck = [cwd, path23.join(cwd, "src")];
39975
+ const dirsToCheck = [cwd, path22.join(cwd, "src")];
39825
39976
  const hasCpp = dirsToCheck.some((dir) => {
39826
39977
  try {
39827
- return fs12.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
39978
+ return fs11.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
39828
39979
  } catch {
39829
39980
  return false;
39830
39981
  }
@@ -39835,13 +39986,13 @@ function detectCppcheck(cwd) {
39835
39986
  }
39836
39987
  }
39837
39988
  function detectSwiftlint(cwd) {
39838
- return fs12.existsSync(path23.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
39989
+ return fs11.existsSync(path22.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
39839
39990
  }
39840
39991
  function detectDartAnalyze(cwd) {
39841
- return fs12.existsSync(path23.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
39992
+ return fs11.existsSync(path22.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
39842
39993
  }
39843
39994
  function detectRubocop(cwd) {
39844
- return (fs12.existsSync(path23.join(cwd, "Gemfile")) || fs12.existsSync(path23.join(cwd, "gems.rb")) || fs12.existsSync(path23.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
39995
+ 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"));
39845
39996
  }
39846
39997
  function detectAdditionalLinter(cwd) {
39847
39998
  if (detectRuff(cwd))
@@ -39869,10 +40020,10 @@ function detectAdditionalLinter(cwd) {
39869
40020
  function findBinInAncestors(startDir, binName) {
39870
40021
  let dir = startDir;
39871
40022
  while (true) {
39872
- const candidate = path23.join(dir, "node_modules", ".bin", binName);
39873
- if (fs12.existsSync(candidate))
40023
+ const candidate = path22.join(dir, "node_modules", ".bin", binName);
40024
+ if (fs11.existsSync(candidate))
39874
40025
  return candidate;
39875
- const parent = path23.dirname(dir);
40026
+ const parent = path22.dirname(dir);
39876
40027
  if (parent === dir)
39877
40028
  break;
39878
40029
  dir = parent;
@@ -39881,11 +40032,11 @@ function findBinInAncestors(startDir, binName) {
39881
40032
  }
39882
40033
  function findBinInEnvPath(binName) {
39883
40034
  const searchPath = process.env.PATH ?? "";
39884
- for (const dir of searchPath.split(path23.delimiter)) {
40035
+ for (const dir of searchPath.split(path22.delimiter)) {
39885
40036
  if (!dir)
39886
40037
  continue;
39887
- const candidate = path23.join(dir, binName);
39888
- if (fs12.existsSync(candidate))
40038
+ const candidate = path22.join(dir, binName);
40039
+ if (fs11.existsSync(candidate))
39889
40040
  return candidate;
39890
40041
  }
39891
40042
  return null;
@@ -39893,17 +40044,17 @@ function findBinInEnvPath(binName) {
39893
40044
  async function detectAvailableLinter(directory) {
39894
40045
  if (!directory)
39895
40046
  return null;
39896
- if (!fs12.existsSync(directory))
40047
+ if (!fs11.existsSync(directory))
39897
40048
  return null;
39898
40049
  const projectDir = directory;
39899
40050
  const isWindows = process.platform === "win32";
39900
- const biomeBin = isWindows ? path23.join(projectDir, "node_modules", ".bin", "biome.EXE") : path23.join(projectDir, "node_modules", ".bin", "biome");
39901
- const eslintBin = isWindows ? path23.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path23.join(projectDir, "node_modules", ".bin", "eslint");
40051
+ const biomeBin = isWindows ? path22.join(projectDir, "node_modules", ".bin", "biome.EXE") : path22.join(projectDir, "node_modules", ".bin", "biome");
40052
+ const eslintBin = isWindows ? path22.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path22.join(projectDir, "node_modules", ".bin", "eslint");
39902
40053
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
39903
40054
  if (localResult)
39904
40055
  return localResult;
39905
- const biomeAncestor = findBinInAncestors(path23.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
39906
- const eslintAncestor = findBinInAncestors(path23.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
40056
+ const biomeAncestor = findBinInAncestors(path22.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
40057
+ const eslintAncestor = findBinInAncestors(path22.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
39907
40058
  if (biomeAncestor || eslintAncestor) {
39908
40059
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
39909
40060
  }
@@ -39926,7 +40077,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
39926
40077
  const result = await Promise.race([biomeExit, timeout]);
39927
40078
  if (result === "timeout") {
39928
40079
  biomeProc.kill();
39929
- } else if (biomeProc.exitCode === 0 && fs12.existsSync(biomeBin)) {
40080
+ } else if (biomeProc.exitCode === 0 && fs11.existsSync(biomeBin)) {
39930
40081
  return "biome";
39931
40082
  }
39932
40083
  } catch {}
@@ -39940,7 +40091,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
39940
40091
  const result = await Promise.race([eslintExit, timeout]);
39941
40092
  if (result === "timeout") {
39942
40093
  eslintProc.kill();
39943
- } else if (eslintProc.exitCode === 0 && fs12.existsSync(eslintBin)) {
40094
+ } else if (eslintProc.exitCode === 0 && fs11.existsSync(eslintBin)) {
39944
40095
  return "eslint";
39945
40096
  }
39946
40097
  } catch {}
@@ -40111,8 +40262,8 @@ For Rust: rustup component add clippy`
40111
40262
 
40112
40263
  // src/tools/secretscan.ts
40113
40264
  init_zod();
40114
- import * as fs13 from "fs";
40115
- import * as path24 from "path";
40265
+ import * as fs12 from "fs";
40266
+ import * as path23 from "path";
40116
40267
  var MAX_FILE_PATH_LENGTH = 500;
40117
40268
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
40118
40269
  var MAX_FILES_SCANNED = 1000;
@@ -40339,11 +40490,11 @@ function isGlobOrPathPattern(pattern) {
40339
40490
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
40340
40491
  }
40341
40492
  function loadSecretScanIgnore(scanDir) {
40342
- const ignorePath = path24.join(scanDir, ".secretscanignore");
40493
+ const ignorePath = path23.join(scanDir, ".secretscanignore");
40343
40494
  try {
40344
- if (!fs13.existsSync(ignorePath))
40495
+ if (!fs12.existsSync(ignorePath))
40345
40496
  return [];
40346
- const content = fs13.readFileSync(ignorePath, "utf8");
40497
+ const content = fs12.readFileSync(ignorePath, "utf8");
40347
40498
  const patterns = [];
40348
40499
  for (const rawLine of content.split(/\r?\n/)) {
40349
40500
  const line = rawLine.trim();
@@ -40362,7 +40513,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
40362
40513
  if (exactNames.has(entry))
40363
40514
  return true;
40364
40515
  for (const pattern of globPatterns) {
40365
- if (path24.matchesGlob(relPath, pattern))
40516
+ if (path23.matchesGlob(relPath, pattern))
40366
40517
  return true;
40367
40518
  }
40368
40519
  return false;
@@ -40383,7 +40534,7 @@ function validateDirectoryInput(dir) {
40383
40534
  return null;
40384
40535
  }
40385
40536
  function isBinaryFile(filePath, buffer) {
40386
- const ext = path24.extname(filePath).toLowerCase();
40537
+ const ext = path23.extname(filePath).toLowerCase();
40387
40538
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
40388
40539
  return true;
40389
40540
  }
@@ -40458,11 +40609,11 @@ function createRedactedContext(line, findings) {
40458
40609
  result += line.slice(lastEnd);
40459
40610
  return result;
40460
40611
  }
40461
- var O_NOFOLLOW = process.platform !== "win32" ? fs13.constants.O_NOFOLLOW : undefined;
40612
+ var O_NOFOLLOW = process.platform !== "win32" ? fs12.constants.O_NOFOLLOW : undefined;
40462
40613
  function scanFileForSecrets(filePath) {
40463
40614
  const findings = [];
40464
40615
  try {
40465
- const lstat = fs13.lstatSync(filePath);
40616
+ const lstat = fs12.lstatSync(filePath);
40466
40617
  if (lstat.isSymbolicLink()) {
40467
40618
  return findings;
40468
40619
  }
@@ -40471,14 +40622,14 @@ function scanFileForSecrets(filePath) {
40471
40622
  }
40472
40623
  let buffer;
40473
40624
  if (O_NOFOLLOW !== undefined) {
40474
- const fd = fs13.openSync(filePath, "r", O_NOFOLLOW);
40625
+ const fd = fs12.openSync(filePath, "r", O_NOFOLLOW);
40475
40626
  try {
40476
- buffer = fs13.readFileSync(fd);
40627
+ buffer = fs12.readFileSync(fd);
40477
40628
  } finally {
40478
- fs13.closeSync(fd);
40629
+ fs12.closeSync(fd);
40479
40630
  }
40480
40631
  } else {
40481
- buffer = fs13.readFileSync(filePath);
40632
+ buffer = fs12.readFileSync(filePath);
40482
40633
  }
40483
40634
  if (isBinaryFile(filePath, buffer)) {
40484
40635
  return findings;
@@ -40520,9 +40671,9 @@ function isSymlinkLoop(realPath, visited) {
40520
40671
  return false;
40521
40672
  }
40522
40673
  function isPathWithinScope(realPath, scanDir) {
40523
- const resolvedScanDir = path24.resolve(scanDir);
40524
- const resolvedRealPath = path24.resolve(realPath);
40525
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path24.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
40674
+ const resolvedScanDir = path23.resolve(scanDir);
40675
+ const resolvedRealPath = path23.resolve(realPath);
40676
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path23.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
40526
40677
  }
40527
40678
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
40528
40679
  skippedDirs: 0,
@@ -40533,7 +40684,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
40533
40684
  const files = [];
40534
40685
  let entries;
40535
40686
  try {
40536
- entries = fs13.readdirSync(dir);
40687
+ entries = fs12.readdirSync(dir);
40537
40688
  } catch {
40538
40689
  stats.fileErrors++;
40539
40690
  return files;
@@ -40548,15 +40699,15 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
40548
40699
  return a.localeCompare(b);
40549
40700
  });
40550
40701
  for (const entry of entries) {
40551
- const fullPath = path24.join(dir, entry);
40552
- const relPath = path24.relative(scanDir, fullPath).replace(/\\/g, "/");
40702
+ const fullPath = path23.join(dir, entry);
40703
+ const relPath = path23.relative(scanDir, fullPath).replace(/\\/g, "/");
40553
40704
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
40554
40705
  stats.skippedDirs++;
40555
40706
  continue;
40556
40707
  }
40557
40708
  let lstat;
40558
40709
  try {
40559
- lstat = fs13.lstatSync(fullPath);
40710
+ lstat = fs12.lstatSync(fullPath);
40560
40711
  } catch {
40561
40712
  stats.fileErrors++;
40562
40713
  continue;
@@ -40568,7 +40719,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
40568
40719
  if (lstat.isDirectory()) {
40569
40720
  let realPath;
40570
40721
  try {
40571
- realPath = fs13.realpathSync(fullPath);
40722
+ realPath = fs12.realpathSync(fullPath);
40572
40723
  } catch {
40573
40724
  stats.fileErrors++;
40574
40725
  continue;
@@ -40584,7 +40735,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
40584
40735
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
40585
40736
  files.push(...subFiles);
40586
40737
  } else if (lstat.isFile()) {
40587
- const ext = path24.extname(fullPath).toLowerCase();
40738
+ const ext = path23.extname(fullPath).toLowerCase();
40588
40739
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
40589
40740
  files.push(fullPath);
40590
40741
  } else {
@@ -40650,15 +40801,15 @@ var secretscan = createSwarmTool({
40650
40801
  }
40651
40802
  }
40652
40803
  try {
40653
- const _scanDirRaw = path24.resolve(directory);
40804
+ const _scanDirRaw = path23.resolve(directory);
40654
40805
  const scanDir = (() => {
40655
40806
  try {
40656
- return fs13.realpathSync(_scanDirRaw);
40807
+ return fs12.realpathSync(_scanDirRaw);
40657
40808
  } catch {
40658
40809
  return _scanDirRaw;
40659
40810
  }
40660
40811
  })();
40661
- if (!fs13.existsSync(scanDir)) {
40812
+ if (!fs12.existsSync(scanDir)) {
40662
40813
  const errorResult = {
40663
40814
  error: "directory not found",
40664
40815
  scan_dir: directory,
@@ -40669,7 +40820,7 @@ var secretscan = createSwarmTool({
40669
40820
  };
40670
40821
  return JSON.stringify(errorResult, null, 2);
40671
40822
  }
40672
- const dirStat = fs13.statSync(scanDir);
40823
+ const dirStat = fs12.statSync(scanDir);
40673
40824
  if (!dirStat.isDirectory()) {
40674
40825
  const errorResult = {
40675
40826
  error: "target must be a directory, not a file",
@@ -40720,7 +40871,7 @@ var secretscan = createSwarmTool({
40720
40871
  break;
40721
40872
  const fileFindings = scanFileForSecrets(filePath);
40722
40873
  try {
40723
- const stat2 = fs13.statSync(filePath);
40874
+ const stat2 = fs12.statSync(filePath);
40724
40875
  if (stat2.size > MAX_FILE_SIZE_BYTES) {
40725
40876
  skippedFiles++;
40726
40877
  continue;
@@ -40809,12 +40960,12 @@ async function runSecretscan(directory) {
40809
40960
 
40810
40961
  // src/tools/test-runner.ts
40811
40962
  init_zod();
40812
- import * as fs17 from "fs";
40813
- import * as path28 from "path";
40963
+ import * as fs16 from "fs";
40964
+ import * as path27 from "path";
40814
40965
 
40815
40966
  // src/test-impact/analyzer.ts
40816
- import fs14 from "fs";
40817
- import path25 from "path";
40967
+ import fs13 from "fs";
40968
+ import path24 from "path";
40818
40969
  var IMPORT_REGEX_ES = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
40819
40970
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
40820
40971
  var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
@@ -40825,7 +40976,7 @@ function normalizePath(p) {
40825
40976
  function isCacheStale(impactMap, generatedAtMs) {
40826
40977
  for (const sourcePath of Object.keys(impactMap)) {
40827
40978
  try {
40828
- const stat2 = fs14.statSync(sourcePath);
40979
+ const stat2 = fs13.statSync(sourcePath);
40829
40980
  if (stat2.mtimeMs > generatedAtMs) {
40830
40981
  return true;
40831
40982
  }
@@ -40839,15 +40990,15 @@ function resolveRelativeImport(fromDir, importPath) {
40839
40990
  if (!importPath.startsWith(".")) {
40840
40991
  return null;
40841
40992
  }
40842
- const resolved = path25.resolve(fromDir, importPath);
40843
- if (path25.extname(resolved)) {
40844
- if (fs14.existsSync(resolved) && fs14.statSync(resolved).isFile()) {
40993
+ const resolved = path24.resolve(fromDir, importPath);
40994
+ if (path24.extname(resolved)) {
40995
+ if (fs13.existsSync(resolved) && fs13.statSync(resolved).isFile()) {
40845
40996
  return normalizePath(resolved);
40846
40997
  }
40847
40998
  } else {
40848
40999
  for (const ext of EXTENSIONS_TO_TRY) {
40849
41000
  const withExt = resolved + ext;
40850
- if (fs14.existsSync(withExt) && fs14.statSync(withExt).isFile()) {
41001
+ if (fs13.existsSync(withExt) && fs13.statSync(withExt).isFile()) {
40851
41002
  return normalizePath(withExt);
40852
41003
  }
40853
41004
  }
@@ -40866,13 +41017,13 @@ function findTestFilesSync(cwd) {
40866
41017
  function walk(dir, visitedInodes) {
40867
41018
  let entries;
40868
41019
  try {
40869
- entries = fs14.readdirSync(dir, { withFileTypes: true });
41020
+ entries = fs13.readdirSync(dir, { withFileTypes: true });
40870
41021
  } catch {
40871
41022
  return;
40872
41023
  }
40873
41024
  let dirInode;
40874
41025
  try {
40875
- dirInode = fs14.statSync(dir).ino;
41026
+ dirInode = fs13.statSync(dir).ino;
40876
41027
  } catch {
40877
41028
  return;
40878
41029
  }
@@ -40885,12 +41036,12 @@ function findTestFilesSync(cwd) {
40885
41036
  for (const entry of entries) {
40886
41037
  if (entry.isDirectory()) {
40887
41038
  if (!skipDirs.has(entry.name)) {
40888
- walk(path25.join(dir, entry.name), visitedInodes);
41039
+ walk(path24.join(dir, entry.name), visitedInodes);
40889
41040
  }
40890
41041
  } else if (entry.isFile()) {
40891
41042
  const name = entry.name;
40892
41043
  if (/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name)) {
40893
- testFiles.push(normalizePath(path25.join(dir, entry.name)));
41044
+ testFiles.push(normalizePath(path24.join(dir, entry.name)));
40894
41045
  }
40895
41046
  }
40896
41047
  }
@@ -40920,7 +41071,7 @@ async function buildImpactMapInternal(cwd) {
40920
41071
  for (const testFile of testFiles) {
40921
41072
  let content;
40922
41073
  try {
40923
- content = fs14.readFileSync(testFile, "utf-8");
41074
+ content = fs13.readFileSync(testFile, "utf-8");
40924
41075
  } catch {
40925
41076
  continue;
40926
41077
  }
@@ -40928,7 +41079,7 @@ async function buildImpactMapInternal(cwd) {
40928
41079
  continue;
40929
41080
  }
40930
41081
  const imports = extractImports(content);
40931
- const testDir = path25.dirname(testFile);
41082
+ const testDir = path24.dirname(testFile);
40932
41083
  for (const importPath of imports) {
40933
41084
  const resolvedSource = resolveRelativeImport(testDir, importPath);
40934
41085
  if (resolvedSource === null) {
@@ -40950,10 +41101,10 @@ async function buildImpactMap(cwd) {
40950
41101
  return impactMap;
40951
41102
  }
40952
41103
  async function loadImpactMap(cwd) {
40953
- const cachePath = path25.join(cwd, ".swarm", "cache", "impact-map.json");
40954
- if (fs14.existsSync(cachePath)) {
41104
+ const cachePath = path24.join(cwd, ".swarm", "cache", "impact-map.json");
41105
+ if (fs13.existsSync(cachePath)) {
40955
41106
  try {
40956
- const content = fs14.readFileSync(cachePath, "utf-8");
41107
+ const content = fs13.readFileSync(cachePath, "utf-8");
40957
41108
  const data = JSON.parse(content);
40958
41109
  const map3 = data.map;
40959
41110
  const generatedAt = new Date(data.generatedAt).getTime();
@@ -40965,17 +41116,17 @@ async function loadImpactMap(cwd) {
40965
41116
  return buildImpactMap(cwd);
40966
41117
  }
40967
41118
  async function saveImpactMap(cwd, impactMap) {
40968
- const cacheDir = path25.join(cwd, ".swarm", "cache");
40969
- const cachePath = path25.join(cacheDir, "impact-map.json");
40970
- if (!fs14.existsSync(cacheDir)) {
40971
- fs14.mkdirSync(cacheDir, { recursive: true });
41119
+ const cacheDir = path24.join(cwd, ".swarm", "cache");
41120
+ const cachePath = path24.join(cacheDir, "impact-map.json");
41121
+ if (!fs13.existsSync(cacheDir)) {
41122
+ fs13.mkdirSync(cacheDir, { recursive: true });
40972
41123
  }
40973
41124
  const data = {
40974
41125
  generatedAt: new Date().toISOString(),
40975
41126
  fileCount: Object.keys(impactMap).length,
40976
41127
  map: impactMap
40977
41128
  };
40978
- fs14.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
41129
+ fs13.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
40979
41130
  }
40980
41131
  async function analyzeImpact(changedFiles, cwd) {
40981
41132
  if (!Array.isArray(changedFiles)) {
@@ -40992,7 +41143,7 @@ async function analyzeImpact(changedFiles, cwd) {
40992
41143
  const impactedTestsSet = new Set;
40993
41144
  const untestedFiles = [];
40994
41145
  for (const changedFile of validFiles) {
40995
- const normalizedChanged = normalizePath(path25.resolve(changedFile));
41146
+ const normalizedChanged = normalizePath(path24.resolve(changedFile));
40996
41147
  const tests = impactMap[normalizedChanged];
40997
41148
  if (tests && tests.length > 0) {
40998
41149
  for (const test of tests) {
@@ -41238,14 +41389,14 @@ function detectFlakyTests(allHistory) {
41238
41389
  }
41239
41390
 
41240
41391
  // src/test-impact/history-store.ts
41241
- import fs15 from "fs";
41242
- import path26 from "path";
41392
+ import fs14 from "fs";
41393
+ import path25 from "path";
41243
41394
  var MAX_HISTORY_PER_TEST = 20;
41244
41395
  var MAX_ERROR_LENGTH = 500;
41245
41396
  var MAX_STACK_LENGTH = 200;
41246
41397
  var MAX_CHANGED_FILES = 50;
41247
41398
  function getHistoryPath(workingDir) {
41248
- return path26.join(workingDir || process.cwd(), ".swarm", "cache", "test-history.jsonl");
41399
+ return path25.join(workingDir || process.cwd(), ".swarm", "cache", "test-history.jsonl");
41249
41400
  }
41250
41401
  function sanitizeErrorMessage(errorMessage) {
41251
41402
  if (errorMessage === undefined) {
@@ -41305,9 +41456,9 @@ function appendTestRun(record3, workingDir) {
41305
41456
  changedFiles: sanitizeChangedFiles(record3.changedFiles || [])
41306
41457
  };
41307
41458
  const historyPath = getHistoryPath(workingDir);
41308
- const historyDir = path26.dirname(historyPath);
41309
- if (!fs15.existsSync(historyDir)) {
41310
- fs15.mkdirSync(historyDir, { recursive: true });
41459
+ const historyDir = path25.dirname(historyPath);
41460
+ if (!fs14.existsSync(historyDir)) {
41461
+ fs14.mkdirSync(historyDir, { recursive: true });
41311
41462
  }
41312
41463
  const existingRecords = readAllRecords(historyPath);
41313
41464
  existingRecords.push(sanitizedRecord);
@@ -41332,24 +41483,24 @@ function appendTestRun(record3, workingDir) {
41332
41483
  `)}
41333
41484
  `;
41334
41485
  const tempPath = `${historyPath}.tmp`;
41335
- fs15.writeFileSync(tempPath, content, "utf-8");
41336
- fs15.renameSync(tempPath, historyPath);
41486
+ fs14.writeFileSync(tempPath, content, "utf-8");
41487
+ fs14.renameSync(tempPath, historyPath);
41337
41488
  } catch (err) {
41338
41489
  try {
41339
41490
  const tempPath = `${historyPath}.tmp`;
41340
- if (fs15.existsSync(tempPath)) {
41341
- fs15.unlinkSync(tempPath);
41491
+ if (fs14.existsSync(tempPath)) {
41492
+ fs14.unlinkSync(tempPath);
41342
41493
  }
41343
41494
  } catch {}
41344
41495
  throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
41345
41496
  }
41346
41497
  }
41347
41498
  function readAllRecords(historyPath) {
41348
- if (!fs15.existsSync(historyPath)) {
41499
+ if (!fs14.existsSync(historyPath)) {
41349
41500
  return [];
41350
41501
  }
41351
41502
  try {
41352
- const content = fs15.readFileSync(historyPath, "utf-8");
41503
+ const content = fs14.readFileSync(historyPath, "utf-8");
41353
41504
  const lines = content.split(`
41354
41505
  `);
41355
41506
  const records = [];
@@ -41378,8 +41529,8 @@ function getAllHistory(workingDir) {
41378
41529
  }
41379
41530
 
41380
41531
  // src/tools/resolve-working-directory.ts
41381
- import * as fs16 from "fs";
41382
- import * as path27 from "path";
41532
+ import * as fs15 from "fs";
41533
+ import * as path26 from "path";
41383
41534
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
41384
41535
  if (workingDirectory == null || workingDirectory === "") {
41385
41536
  return { success: true, directory: fallbackDirectory };
@@ -41399,18 +41550,18 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
41399
41550
  };
41400
41551
  }
41401
41552
  }
41402
- const normalizedDir = path27.normalize(workingDirectory);
41403
- const pathParts = normalizedDir.split(path27.sep);
41553
+ const normalizedDir = path26.normalize(workingDirectory);
41554
+ const pathParts = normalizedDir.split(path26.sep);
41404
41555
  if (pathParts.includes("..")) {
41405
41556
  return {
41406
41557
  success: false,
41407
41558
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
41408
41559
  };
41409
41560
  }
41410
- const resolvedDir = path27.resolve(normalizedDir);
41561
+ const resolvedDir = path26.resolve(normalizedDir);
41411
41562
  let statResult;
41412
41563
  try {
41413
- statResult = fs16.statSync(resolvedDir);
41564
+ statResult = fs15.statSync(resolvedDir);
41414
41565
  } catch {
41415
41566
  return {
41416
41567
  success: false,
@@ -41423,17 +41574,17 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
41423
41574
  message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
41424
41575
  };
41425
41576
  }
41426
- const resolvedFallback = path27.resolve(fallbackDirectory);
41577
+ const resolvedFallback = path26.resolve(fallbackDirectory);
41427
41578
  let fallbackExists = false;
41428
41579
  try {
41429
- fs16.statSync(resolvedFallback);
41580
+ fs15.statSync(resolvedFallback);
41430
41581
  fallbackExists = true;
41431
41582
  } catch {
41432
41583
  fallbackExists = false;
41433
41584
  }
41434
41585
  if (workingDirectory != null && workingDirectory !== "") {
41435
41586
  if (fallbackExists) {
41436
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path27.sep);
41587
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path26.sep);
41437
41588
  if (isSubdirectory) {
41438
41589
  return {
41439
41590
  success: false,
@@ -41523,19 +41674,19 @@ function hasDevDependency(devDeps, ...patterns) {
41523
41674
  return hasPackageJsonDependency(devDeps, ...patterns);
41524
41675
  }
41525
41676
  function detectGoTest(cwd) {
41526
- return fs17.existsSync(path28.join(cwd, "go.mod")) && isCommandAvailable("go");
41677
+ return fs16.existsSync(path27.join(cwd, "go.mod")) && isCommandAvailable("go");
41527
41678
  }
41528
41679
  function detectJavaMaven(cwd) {
41529
- return fs17.existsSync(path28.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
41680
+ return fs16.existsSync(path27.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
41530
41681
  }
41531
41682
  function detectGradle(cwd) {
41532
- const hasBuildFile = fs17.existsSync(path28.join(cwd, "build.gradle")) || fs17.existsSync(path28.join(cwd, "build.gradle.kts"));
41533
- const hasGradlew = fs17.existsSync(path28.join(cwd, "gradlew")) || fs17.existsSync(path28.join(cwd, "gradlew.bat"));
41683
+ const hasBuildFile = fs16.existsSync(path27.join(cwd, "build.gradle")) || fs16.existsSync(path27.join(cwd, "build.gradle.kts"));
41684
+ const hasGradlew = fs16.existsSync(path27.join(cwd, "gradlew")) || fs16.existsSync(path27.join(cwd, "gradlew.bat"));
41534
41685
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
41535
41686
  }
41536
41687
  function detectDotnetTest(cwd) {
41537
41688
  try {
41538
- const files = fs17.readdirSync(cwd);
41689
+ const files = fs16.readdirSync(cwd);
41539
41690
  const hasCsproj = files.some((f) => f.endsWith(".csproj"));
41540
41691
  return hasCsproj && isCommandAvailable("dotnet");
41541
41692
  } catch {
@@ -41543,32 +41694,32 @@ function detectDotnetTest(cwd) {
41543
41694
  }
41544
41695
  }
41545
41696
  function detectCTest(cwd) {
41546
- const hasSource = fs17.existsSync(path28.join(cwd, "CMakeLists.txt"));
41547
- const hasBuildCache = fs17.existsSync(path28.join(cwd, "CMakeCache.txt")) || fs17.existsSync(path28.join(cwd, "build", "CMakeCache.txt"));
41697
+ const hasSource = fs16.existsSync(path27.join(cwd, "CMakeLists.txt"));
41698
+ const hasBuildCache = fs16.existsSync(path27.join(cwd, "CMakeCache.txt")) || fs16.existsSync(path27.join(cwd, "build", "CMakeCache.txt"));
41548
41699
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
41549
41700
  }
41550
41701
  function detectSwiftTest(cwd) {
41551
- return fs17.existsSync(path28.join(cwd, "Package.swift")) && isCommandAvailable("swift");
41702
+ return fs16.existsSync(path27.join(cwd, "Package.swift")) && isCommandAvailable("swift");
41552
41703
  }
41553
41704
  function detectDartTest(cwd) {
41554
- return fs17.existsSync(path28.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
41705
+ return fs16.existsSync(path27.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
41555
41706
  }
41556
41707
  function detectRSpec(cwd) {
41557
- const hasRSpecFile = fs17.existsSync(path28.join(cwd, ".rspec"));
41558
- const hasGemfile = fs17.existsSync(path28.join(cwd, "Gemfile"));
41559
- const hasSpecDir = fs17.existsSync(path28.join(cwd, "spec"));
41708
+ const hasRSpecFile = fs16.existsSync(path27.join(cwd, ".rspec"));
41709
+ const hasGemfile = fs16.existsSync(path27.join(cwd, "Gemfile"));
41710
+ const hasSpecDir = fs16.existsSync(path27.join(cwd, "spec"));
41560
41711
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
41561
41712
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
41562
41713
  }
41563
41714
  function detectMinitest(cwd) {
41564
- return fs17.existsSync(path28.join(cwd, "test")) && (fs17.existsSync(path28.join(cwd, "Gemfile")) || fs17.existsSync(path28.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
41715
+ return fs16.existsSync(path27.join(cwd, "test")) && (fs16.existsSync(path27.join(cwd, "Gemfile")) || fs16.existsSync(path27.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
41565
41716
  }
41566
41717
  async function detectTestFramework(cwd) {
41567
41718
  const baseDir = cwd;
41568
41719
  try {
41569
- const packageJsonPath = path28.join(baseDir, "package.json");
41570
- if (fs17.existsSync(packageJsonPath)) {
41571
- const content = fs17.readFileSync(packageJsonPath, "utf-8");
41720
+ const packageJsonPath = path27.join(baseDir, "package.json");
41721
+ if (fs16.existsSync(packageJsonPath)) {
41722
+ const content = fs16.readFileSync(packageJsonPath, "utf-8");
41572
41723
  const pkg = JSON.parse(content);
41573
41724
  const _deps = pkg.dependencies || {};
41574
41725
  const devDeps = pkg.devDependencies || {};
@@ -41587,38 +41738,38 @@ async function detectTestFramework(cwd) {
41587
41738
  return "jest";
41588
41739
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
41589
41740
  return "mocha";
41590
- if (fs17.existsSync(path28.join(baseDir, "bun.lockb")) || fs17.existsSync(path28.join(baseDir, "bun.lock"))) {
41741
+ if (fs16.existsSync(path27.join(baseDir, "bun.lockb")) || fs16.existsSync(path27.join(baseDir, "bun.lock"))) {
41591
41742
  if (scripts.test?.includes("bun"))
41592
41743
  return "bun";
41593
41744
  }
41594
41745
  }
41595
41746
  } catch {}
41596
41747
  try {
41597
- const pyprojectTomlPath = path28.join(baseDir, "pyproject.toml");
41598
- const setupCfgPath = path28.join(baseDir, "setup.cfg");
41599
- const requirementsTxtPath = path28.join(baseDir, "requirements.txt");
41600
- if (fs17.existsSync(pyprojectTomlPath)) {
41601
- const content = fs17.readFileSync(pyprojectTomlPath, "utf-8");
41748
+ const pyprojectTomlPath = path27.join(baseDir, "pyproject.toml");
41749
+ const setupCfgPath = path27.join(baseDir, "setup.cfg");
41750
+ const requirementsTxtPath = path27.join(baseDir, "requirements.txt");
41751
+ if (fs16.existsSync(pyprojectTomlPath)) {
41752
+ const content = fs16.readFileSync(pyprojectTomlPath, "utf-8");
41602
41753
  if (content.includes("[tool.pytest"))
41603
41754
  return "pytest";
41604
41755
  if (content.includes("pytest"))
41605
41756
  return "pytest";
41606
41757
  }
41607
- if (fs17.existsSync(setupCfgPath)) {
41608
- const content = fs17.readFileSync(setupCfgPath, "utf-8");
41758
+ if (fs16.existsSync(setupCfgPath)) {
41759
+ const content = fs16.readFileSync(setupCfgPath, "utf-8");
41609
41760
  if (content.includes("[pytest]"))
41610
41761
  return "pytest";
41611
41762
  }
41612
- if (fs17.existsSync(requirementsTxtPath)) {
41613
- const content = fs17.readFileSync(requirementsTxtPath, "utf-8");
41763
+ if (fs16.existsSync(requirementsTxtPath)) {
41764
+ const content = fs16.readFileSync(requirementsTxtPath, "utf-8");
41614
41765
  if (content.includes("pytest"))
41615
41766
  return "pytest";
41616
41767
  }
41617
41768
  } catch {}
41618
41769
  try {
41619
- const cargoTomlPath = path28.join(baseDir, "Cargo.toml");
41620
- if (fs17.existsSync(cargoTomlPath)) {
41621
- const content = fs17.readFileSync(cargoTomlPath, "utf-8");
41770
+ const cargoTomlPath = path27.join(baseDir, "Cargo.toml");
41771
+ if (fs16.existsSync(cargoTomlPath)) {
41772
+ const content = fs16.readFileSync(cargoTomlPath, "utf-8");
41622
41773
  if (content.includes("[dev-dependencies]")) {
41623
41774
  if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
41624
41775
  return "cargo";
@@ -41627,10 +41778,10 @@ async function detectTestFramework(cwd) {
41627
41778
  }
41628
41779
  } catch {}
41629
41780
  try {
41630
- const pesterConfigPath = path28.join(baseDir, "pester.config.ps1");
41631
- const pesterConfigJsonPath = path28.join(baseDir, "pester.config.ps1.json");
41632
- const pesterPs1Path = path28.join(baseDir, "tests.ps1");
41633
- if (fs17.existsSync(pesterConfigPath) || fs17.existsSync(pesterConfigJsonPath) || fs17.existsSync(pesterPs1Path)) {
41781
+ const pesterConfigPath = path27.join(baseDir, "pester.config.ps1");
41782
+ const pesterConfigJsonPath = path27.join(baseDir, "pester.config.ps1.json");
41783
+ const pesterPs1Path = path27.join(baseDir, "tests.ps1");
41784
+ if (fs16.existsSync(pesterConfigPath) || fs16.existsSync(pesterConfigJsonPath) || fs16.existsSync(pesterPs1Path)) {
41634
41785
  return "pester";
41635
41786
  }
41636
41787
  } catch {}
@@ -41672,12 +41823,12 @@ function isTestDirectoryPath(normalizedPath) {
41672
41823
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
41673
41824
  }
41674
41825
  function resolveWorkspacePath(file3, workingDir) {
41675
- return path28.isAbsolute(file3) ? path28.resolve(file3) : path28.resolve(workingDir, file3);
41826
+ return path27.isAbsolute(file3) ? path27.resolve(file3) : path27.resolve(workingDir, file3);
41676
41827
  }
41677
41828
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
41678
41829
  if (!preferRelative)
41679
41830
  return absolutePath;
41680
- return path28.relative(workingDir, absolutePath);
41831
+ return path27.relative(workingDir, absolutePath);
41681
41832
  }
41682
41833
  function dedupePush(target, value) {
41683
41834
  if (!target.includes(value)) {
@@ -41714,18 +41865,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
41714
41865
  }
41715
41866
  }
41716
41867
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
41717
- const relativeDir = path28.dirname(relativePath);
41868
+ const relativeDir = path27.dirname(relativePath);
41718
41869
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
41719
41870
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
41720
- const rootDir = path28.join(workingDir, dirName);
41721
- return nestedRelativeDir ? [rootDir, path28.join(rootDir, nestedRelativeDir)] : [rootDir];
41871
+ const rootDir = path27.join(workingDir, dirName);
41872
+ return nestedRelativeDir ? [rootDir, path27.join(rootDir, nestedRelativeDir)] : [rootDir];
41722
41873
  });
41723
41874
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
41724
41875
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
41725
- directories.push(path28.join(workingDir, "src/test/java", path28.dirname(normalizedRelativePath.slice("src/main/java/".length))));
41876
+ directories.push(path27.join(workingDir, "src/test/java", path27.dirname(normalizedRelativePath.slice("src/main/java/".length))));
41726
41877
  }
41727
41878
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
41728
- directories.push(path28.join(workingDir, "src/test/kotlin", path28.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
41879
+ directories.push(path27.join(workingDir, "src/test/kotlin", path27.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
41729
41880
  }
41730
41881
  return [...new Set(directories)];
41731
41882
  }
@@ -41753,23 +41904,23 @@ function isLanguageSpecificTestFile(basename4) {
41753
41904
  }
41754
41905
  function isConventionTestFilePath(filePath) {
41755
41906
  const normalizedPath = filePath.replace(/\\/g, "/");
41756
- const basename4 = path28.basename(filePath);
41907
+ const basename4 = path27.basename(filePath);
41757
41908
  return hasCompoundTestExtension(basename4) || basename4.includes(".spec.") || basename4.includes(".test.") || isLanguageSpecificTestFile(basename4) || isTestDirectoryPath(normalizedPath);
41758
41909
  }
41759
41910
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
41760
41911
  const testFiles = [];
41761
41912
  for (const file3 of sourceFiles) {
41762
41913
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
41763
- const relativeFile = path28.relative(workingDir, absoluteFile);
41764
- const basename4 = path28.basename(absoluteFile);
41765
- const dirname11 = path28.dirname(absoluteFile);
41766
- const preferRelativeOutput = !path28.isAbsolute(file3);
41914
+ const relativeFile = path27.relative(workingDir, absoluteFile);
41915
+ const basename4 = path27.basename(absoluteFile);
41916
+ const dirname11 = path27.dirname(absoluteFile);
41917
+ const preferRelativeOutput = !path27.isAbsolute(file3);
41767
41918
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
41768
41919
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
41769
41920
  continue;
41770
41921
  }
41771
41922
  const nameWithoutExt = basename4.replace(/\.[^.]+$/, "");
41772
- const ext = path28.extname(basename4);
41923
+ const ext = path27.extname(basename4);
41773
41924
  const genericTestNames = [
41774
41925
  `${nameWithoutExt}.spec${ext}`,
41775
41926
  `${nameWithoutExt}.test${ext}`
@@ -41778,7 +41929,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
41778
41929
  const colocatedCandidates = [
41779
41930
  ...genericTestNames,
41780
41931
  ...languageSpecificTestNames
41781
- ].map((candidateName) => path28.join(dirname11, candidateName));
41932
+ ].map((candidateName) => path27.join(dirname11, candidateName));
41782
41933
  const testDirectoryNames = [
41783
41934
  basename4,
41784
41935
  ...genericTestNames,
@@ -41787,11 +41938,11 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
41787
41938
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
41788
41939
  const possibleTestFiles = [
41789
41940
  ...colocatedCandidates,
41790
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path28.join(dirname11, dirName, candidateName))),
41791
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path28.join(candidateDir, candidateName)))
41941
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path27.join(dirname11, dirName, candidateName))),
41942
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path27.join(candidateDir, candidateName)))
41792
41943
  ];
41793
41944
  for (const testFile of possibleTestFiles) {
41794
- if (fs17.existsSync(testFile)) {
41945
+ if (fs16.existsSync(testFile)) {
41795
41946
  dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
41796
41947
  }
41797
41948
  }
@@ -41808,8 +41959,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
41808
41959
  for (const testFile of candidateTestFiles) {
41809
41960
  try {
41810
41961
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
41811
- const content = fs17.readFileSync(absoluteTestFile, "utf-8");
41812
- const testDir = path28.dirname(absoluteTestFile);
41962
+ const content = fs16.readFileSync(absoluteTestFile, "utf-8");
41963
+ const testDir = path27.dirname(absoluteTestFile);
41813
41964
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
41814
41965
  let match;
41815
41966
  match = importRegex.exec(content);
@@ -41817,8 +41968,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
41817
41968
  const importPath = match[1];
41818
41969
  let resolvedImport;
41819
41970
  if (importPath.startsWith(".")) {
41820
- resolvedImport = path28.resolve(testDir, importPath);
41821
- const existingExt = path28.extname(resolvedImport);
41971
+ resolvedImport = path27.resolve(testDir, importPath);
41972
+ const existingExt = path27.extname(resolvedImport);
41822
41973
  if (!existingExt) {
41823
41974
  for (const extToTry of [
41824
41975
  ".ts",
@@ -41829,7 +41980,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
41829
41980
  ".cjs"
41830
41981
  ]) {
41831
41982
  const withExt = resolvedImport + extToTry;
41832
- if (absoluteSourceFiles.includes(withExt) || fs17.existsSync(withExt)) {
41983
+ if (absoluteSourceFiles.includes(withExt) || fs16.existsSync(withExt)) {
41833
41984
  resolvedImport = withExt;
41834
41985
  break;
41835
41986
  }
@@ -41838,12 +41989,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
41838
41989
  } else {
41839
41990
  continue;
41840
41991
  }
41841
- const importBasename = path28.basename(resolvedImport, path28.extname(resolvedImport));
41842
- const importDir = path28.dirname(resolvedImport);
41992
+ const importBasename = path27.basename(resolvedImport, path27.extname(resolvedImport));
41993
+ const importDir = path27.dirname(resolvedImport);
41843
41994
  for (const sourceFile of absoluteSourceFiles) {
41844
- const sourceDir = path28.dirname(sourceFile);
41845
- const sourceBasename = path28.basename(sourceFile, path28.extname(sourceFile));
41846
- const isRelatedDir = importDir === sourceDir || importDir === path28.join(sourceDir, "__tests__") || importDir === path28.join(sourceDir, "tests") || importDir === path28.join(sourceDir, "test") || importDir === path28.join(sourceDir, "spec");
41995
+ const sourceDir = path27.dirname(sourceFile);
41996
+ const sourceBasename = path27.basename(sourceFile, path27.extname(sourceFile));
41997
+ const isRelatedDir = importDir === sourceDir || importDir === path27.join(sourceDir, "__tests__") || importDir === path27.join(sourceDir, "tests") || importDir === path27.join(sourceDir, "test") || importDir === path27.join(sourceDir, "spec");
41847
41998
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
41848
41999
  dedupePush(testFiles, testFile);
41849
42000
  break;
@@ -41856,8 +42007,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
41856
42007
  while (match !== null) {
41857
42008
  const importPath = match[1];
41858
42009
  if (importPath.startsWith(".")) {
41859
- let resolvedImport = path28.resolve(testDir, importPath);
41860
- const existingExt = path28.extname(resolvedImport);
42010
+ let resolvedImport = path27.resolve(testDir, importPath);
42011
+ const existingExt = path27.extname(resolvedImport);
41861
42012
  if (!existingExt) {
41862
42013
  for (const extToTry of [
41863
42014
  ".ts",
@@ -41868,18 +42019,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
41868
42019
  ".cjs"
41869
42020
  ]) {
41870
42021
  const withExt = resolvedImport + extToTry;
41871
- if (absoluteSourceFiles.includes(withExt) || fs17.existsSync(withExt)) {
42022
+ if (absoluteSourceFiles.includes(withExt) || fs16.existsSync(withExt)) {
41872
42023
  resolvedImport = withExt;
41873
42024
  break;
41874
42025
  }
41875
42026
  }
41876
42027
  }
41877
- const importDir = path28.dirname(resolvedImport);
41878
- const importBasename = path28.basename(resolvedImport, path28.extname(resolvedImport));
42028
+ const importDir = path27.dirname(resolvedImport);
42029
+ const importBasename = path27.basename(resolvedImport, path27.extname(resolvedImport));
41879
42030
  for (const sourceFile of absoluteSourceFiles) {
41880
- const sourceDir = path28.dirname(sourceFile);
41881
- const sourceBasename = path28.basename(sourceFile, path28.extname(sourceFile));
41882
- const isRelatedDir = importDir === sourceDir || importDir === path28.join(sourceDir, "__tests__") || importDir === path28.join(sourceDir, "tests") || importDir === path28.join(sourceDir, "test") || importDir === path28.join(sourceDir, "spec");
42031
+ const sourceDir = path27.dirname(sourceFile);
42032
+ const sourceBasename = path27.basename(sourceFile, path27.extname(sourceFile));
42033
+ const isRelatedDir = importDir === sourceDir || importDir === path27.join(sourceDir, "__tests__") || importDir === path27.join(sourceDir, "tests") || importDir === path27.join(sourceDir, "test") || importDir === path27.join(sourceDir, "spec");
41883
42034
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
41884
42035
  dedupePush(testFiles, testFile);
41885
42036
  break;
@@ -41982,8 +42133,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
41982
42133
  return ["mvn", "test"];
41983
42134
  case "gradle": {
41984
42135
  const isWindows = process.platform === "win32";
41985
- const hasGradlewBat = fs17.existsSync(path28.join(baseDir, "gradlew.bat"));
41986
- const hasGradlew = fs17.existsSync(path28.join(baseDir, "gradlew"));
42136
+ const hasGradlewBat = fs16.existsSync(path27.join(baseDir, "gradlew.bat"));
42137
+ const hasGradlew = fs16.existsSync(path27.join(baseDir, "gradlew"));
41987
42138
  if (hasGradlewBat && isWindows)
41988
42139
  return ["gradlew.bat", "test"];
41989
42140
  if (hasGradlew)
@@ -42000,7 +42151,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
42000
42151
  "cmake-build-release",
42001
42152
  "out"
42002
42153
  ];
42003
- const actualBuildDir = buildDirCandidates.find((d) => fs17.existsSync(path28.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
42154
+ const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path27.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
42004
42155
  return ["ctest", "--test-dir", actualBuildDir];
42005
42156
  }
42006
42157
  case "swift-test":
@@ -42628,7 +42779,7 @@ var test_runner = createSwarmTool({
42628
42779
  const sourceFiles = args.files.filter((file3) => {
42629
42780
  if (directTestFiles.includes(file3))
42630
42781
  return false;
42631
- const ext = path28.extname(file3).toLowerCase();
42782
+ const ext = path27.extname(file3).toLowerCase();
42632
42783
  return SOURCE_EXTENSIONS.has(ext);
42633
42784
  });
42634
42785
  const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
@@ -42663,7 +42814,7 @@ var test_runner = createSwarmTool({
42663
42814
  if (isConventionTestFilePath(f)) {
42664
42815
  return false;
42665
42816
  }
42666
- const ext = path28.extname(f).toLowerCase();
42817
+ const ext = path27.extname(f).toLowerCase();
42667
42818
  return SOURCE_EXTENSIONS.has(ext);
42668
42819
  });
42669
42820
  if (sourceFiles.length === 0) {
@@ -42690,7 +42841,7 @@ var test_runner = createSwarmTool({
42690
42841
  if (isConventionTestFilePath(f)) {
42691
42842
  return false;
42692
42843
  }
42693
- const ext = path28.extname(f).toLowerCase();
42844
+ const ext = path27.extname(f).toLowerCase();
42694
42845
  return SOURCE_EXTENSIONS.has(ext);
42695
42846
  });
42696
42847
  if (sourceFiles.length === 0) {
@@ -42708,8 +42859,8 @@ var test_runner = createSwarmTool({
42708
42859
  const impactResult = await analyzeImpact(sourceFiles, workingDir);
42709
42860
  if (impactResult.impactedTests.length > 0) {
42710
42861
  testFiles = impactResult.impactedTests.map((absPath) => {
42711
- const relativePath = path28.relative(workingDir, absPath);
42712
- return path28.isAbsolute(relativePath) ? absPath : relativePath;
42862
+ const relativePath = path27.relative(workingDir, absPath);
42863
+ return path27.isAbsolute(relativePath) ? absPath : relativePath;
42713
42864
  });
42714
42865
  } else {
42715
42866
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -42802,8 +42953,8 @@ function validateDirectoryPath(dir) {
42802
42953
  if (dir.includes("..")) {
42803
42954
  throw new Error("Directory path must not contain path traversal sequences");
42804
42955
  }
42805
- const normalized = path29.normalize(dir);
42806
- const absolutePath = path29.isAbsolute(normalized) ? normalized : path29.resolve(normalized);
42956
+ const normalized = path28.normalize(dir);
42957
+ const absolutePath = path28.isAbsolute(normalized) ? normalized : path28.resolve(normalized);
42807
42958
  return absolutePath;
42808
42959
  }
42809
42960
  function validateTimeout(timeoutMs, defaultValue) {
@@ -42826,9 +42977,9 @@ function validateTimeout(timeoutMs, defaultValue) {
42826
42977
  }
42827
42978
  function getPackageVersion(dir) {
42828
42979
  try {
42829
- const packagePath = path29.join(dir, "package.json");
42830
- if (fs18.existsSync(packagePath)) {
42831
- const content = fs18.readFileSync(packagePath, "utf-8");
42980
+ const packagePath = path28.join(dir, "package.json");
42981
+ if (fs17.existsSync(packagePath)) {
42982
+ const content = fs17.readFileSync(packagePath, "utf-8");
42832
42983
  const pkg = JSON.parse(content);
42833
42984
  return pkg.version ?? null;
42834
42985
  }
@@ -42837,9 +42988,9 @@ function getPackageVersion(dir) {
42837
42988
  }
42838
42989
  function getChangelogVersion(dir) {
42839
42990
  try {
42840
- const changelogPath = path29.join(dir, "CHANGELOG.md");
42841
- if (fs18.existsSync(changelogPath)) {
42842
- const content = fs18.readFileSync(changelogPath, "utf-8");
42991
+ const changelogPath = path28.join(dir, "CHANGELOG.md");
42992
+ if (fs17.existsSync(changelogPath)) {
42993
+ const content = fs17.readFileSync(changelogPath, "utf-8");
42843
42994
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
42844
42995
  if (match) {
42845
42996
  return match[1];
@@ -42851,10 +43002,10 @@ function getChangelogVersion(dir) {
42851
43002
  function getVersionFileVersion(dir) {
42852
43003
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
42853
43004
  for (const file3 of possibleFiles) {
42854
- const filePath = path29.join(dir, file3);
42855
- if (fs18.existsSync(filePath)) {
43005
+ const filePath = path28.join(dir, file3);
43006
+ if (fs17.existsSync(filePath)) {
42856
43007
  try {
42857
- const content = fs18.readFileSync(filePath, "utf-8").trim();
43008
+ const content = fs17.readFileSync(filePath, "utf-8").trim();
42858
43009
  const match = content.match(/(\d+\.\d+\.\d+)/);
42859
43010
  if (match) {
42860
43011
  return match[1];
@@ -43178,8 +43329,8 @@ async function runEvidenceCheck(dir) {
43178
43329
  async function runRequirementCoverageCheck(dir, currentPhase) {
43179
43330
  const startTime = Date.now();
43180
43331
  try {
43181
- const specPath = path29.join(dir, ".swarm", "spec.md");
43182
- if (!fs18.existsSync(specPath)) {
43332
+ const specPath = path28.join(dir, ".swarm", "spec.md");
43333
+ if (!fs17.existsSync(specPath)) {
43183
43334
  return {
43184
43335
  type: "req_coverage",
43185
43336
  status: "skip",
@@ -43560,7 +43711,7 @@ async function handleQaGatesCommand(directory, args, sessionID) {
43560
43711
  }
43561
43712
 
43562
43713
  // src/commands/reset.ts
43563
- import * as fs19 from "fs";
43714
+ import * as fs18 from "fs";
43564
43715
 
43565
43716
  // src/background/manager.ts
43566
43717
  init_utils();
@@ -44261,8 +44412,8 @@ async function handleResetCommand(directory, args) {
44261
44412
  for (const filename of filesToReset) {
44262
44413
  try {
44263
44414
  const resolvedPath = validateSwarmPath(directory, filename);
44264
- if (fs19.existsSync(resolvedPath)) {
44265
- fs19.unlinkSync(resolvedPath);
44415
+ if (fs18.existsSync(resolvedPath)) {
44416
+ fs18.unlinkSync(resolvedPath);
44266
44417
  results.push(`- \u2705 Deleted ${filename}`);
44267
44418
  } else {
44268
44419
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -44279,8 +44430,8 @@ async function handleResetCommand(directory, args) {
44279
44430
  }
44280
44431
  try {
44281
44432
  const summariesPath = validateSwarmPath(directory, "summaries");
44282
- if (fs19.existsSync(summariesPath)) {
44283
- fs19.rmSync(summariesPath, { recursive: true, force: true });
44433
+ if (fs18.existsSync(summariesPath)) {
44434
+ fs18.rmSync(summariesPath, { recursive: true, force: true });
44284
44435
  results.push("- \u2705 Deleted summaries/ directory");
44285
44436
  } else {
44286
44437
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -44300,14 +44451,14 @@ async function handleResetCommand(directory, args) {
44300
44451
 
44301
44452
  // src/commands/reset-session.ts
44302
44453
  init_utils2();
44303
- import * as fs20 from "fs";
44304
- import * as path30 from "path";
44454
+ import * as fs19 from "fs";
44455
+ import * as path29 from "path";
44305
44456
  async function handleResetSessionCommand(directory, _args) {
44306
44457
  const results = [];
44307
44458
  try {
44308
44459
  const statePath = validateSwarmPath(directory, "session/state.json");
44309
- if (fs20.existsSync(statePath)) {
44310
- fs20.unlinkSync(statePath);
44460
+ if (fs19.existsSync(statePath)) {
44461
+ fs19.unlinkSync(statePath);
44311
44462
  results.push("\u2705 Deleted .swarm/session/state.json");
44312
44463
  } else {
44313
44464
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -44316,15 +44467,15 @@ async function handleResetSessionCommand(directory, _args) {
44316
44467
  results.push("\u274C Failed to delete state.json");
44317
44468
  }
44318
44469
  try {
44319
- const sessionDir = path30.dirname(validateSwarmPath(directory, "session/state.json"));
44320
- if (fs20.existsSync(sessionDir)) {
44321
- const files = fs20.readdirSync(sessionDir);
44470
+ const sessionDir = path29.dirname(validateSwarmPath(directory, "session/state.json"));
44471
+ if (fs19.existsSync(sessionDir)) {
44472
+ const files = fs19.readdirSync(sessionDir);
44322
44473
  const otherFiles = files.filter((f) => f !== "state.json");
44323
44474
  let deletedCount = 0;
44324
44475
  for (const file3 of otherFiles) {
44325
- const filePath = path30.join(sessionDir, file3);
44326
- if (fs20.lstatSync(filePath).isFile()) {
44327
- fs20.unlinkSync(filePath);
44476
+ const filePath = path29.join(sessionDir, file3);
44477
+ if (fs19.lstatSync(filePath).isFile()) {
44478
+ fs19.unlinkSync(filePath);
44328
44479
  deletedCount++;
44329
44480
  }
44330
44481
  }
@@ -44352,7 +44503,7 @@ async function handleResetSessionCommand(directory, _args) {
44352
44503
  // src/summaries/manager.ts
44353
44504
  init_utils2();
44354
44505
  init_utils();
44355
- import * as path31 from "path";
44506
+ import * as path30 from "path";
44356
44507
  var SUMMARY_ID_REGEX = /^S\d+$/;
44357
44508
  function sanitizeSummaryId(id) {
44358
44509
  if (!id || id.length === 0) {
@@ -44376,7 +44527,7 @@ function sanitizeSummaryId(id) {
44376
44527
  }
44377
44528
  async function loadFullOutput(directory, id) {
44378
44529
  const sanitizedId = sanitizeSummaryId(id);
44379
- const relativePath = path31.join("summaries", `${sanitizedId}.json`);
44530
+ const relativePath = path30.join("summaries", `${sanitizedId}.json`);
44380
44531
  validateSwarmPath(directory, relativePath);
44381
44532
  const content = await readSwarmFileAsync(directory, relativePath);
44382
44533
  if (content === null) {
@@ -44431,18 +44582,18 @@ ${error93 instanceof Error ? error93.message : String(error93)}`;
44431
44582
  init_plan_schema();
44432
44583
  init_utils2();
44433
44584
  init_ledger();
44434
- import * as fs21 from "fs";
44435
- import * as path32 from "path";
44585
+ import * as fs20 from "fs";
44586
+ import * as path31 from "path";
44436
44587
  async function handleRollbackCommand(directory, args) {
44437
44588
  const phaseArg = args[0];
44438
44589
  if (!phaseArg) {
44439
44590
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
44440
- if (!fs21.existsSync(manifestPath2)) {
44591
+ if (!fs20.existsSync(manifestPath2)) {
44441
44592
  return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
44442
44593
  }
44443
44594
  let manifest2;
44444
44595
  try {
44445
- manifest2 = JSON.parse(fs21.readFileSync(manifestPath2, "utf-8"));
44596
+ manifest2 = JSON.parse(fs20.readFileSync(manifestPath2, "utf-8"));
44446
44597
  } catch {
44447
44598
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
44448
44599
  }
@@ -44464,12 +44615,12 @@ async function handleRollbackCommand(directory, args) {
44464
44615
  return "Error: Phase number must be a positive integer.";
44465
44616
  }
44466
44617
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
44467
- if (!fs21.existsSync(manifestPath)) {
44618
+ if (!fs20.existsSync(manifestPath)) {
44468
44619
  return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
44469
44620
  }
44470
44621
  let manifest;
44471
44622
  try {
44472
- manifest = JSON.parse(fs21.readFileSync(manifestPath, "utf-8"));
44623
+ manifest = JSON.parse(fs20.readFileSync(manifestPath, "utf-8"));
44473
44624
  } catch {
44474
44625
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
44475
44626
  }
@@ -44479,10 +44630,10 @@ async function handleRollbackCommand(directory, args) {
44479
44630
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
44480
44631
  }
44481
44632
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
44482
- if (!fs21.existsSync(checkpointDir)) {
44633
+ if (!fs20.existsSync(checkpointDir)) {
44483
44634
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
44484
44635
  }
44485
- const checkpointFiles = fs21.readdirSync(checkpointDir);
44636
+ const checkpointFiles = fs20.readdirSync(checkpointDir);
44486
44637
  if (checkpointFiles.length === 0) {
44487
44638
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
44488
44639
  }
@@ -44497,10 +44648,10 @@ async function handleRollbackCommand(directory, args) {
44497
44648
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
44498
44649
  continue;
44499
44650
  }
44500
- const src = path32.join(checkpointDir, file3);
44501
- const dest = path32.join(swarmDir, file3);
44651
+ const src = path31.join(checkpointDir, file3);
44652
+ const dest = path31.join(swarmDir, file3);
44502
44653
  try {
44503
- fs21.cpSync(src, dest, { recursive: true, force: true });
44654
+ fs20.cpSync(src, dest, { recursive: true, force: true });
44504
44655
  successes.push(file3);
44505
44656
  } catch (error93) {
44506
44657
  failures.push({ file: file3, error: error93.message });
@@ -44517,14 +44668,14 @@ async function handleRollbackCommand(directory, args) {
44517
44668
  ].join(`
44518
44669
  `);
44519
44670
  }
44520
- const existingLedgerPath = path32.join(swarmDir, "plan-ledger.jsonl");
44521
- if (fs21.existsSync(existingLedgerPath)) {
44522
- fs21.unlinkSync(existingLedgerPath);
44671
+ const existingLedgerPath = path31.join(swarmDir, "plan-ledger.jsonl");
44672
+ if (fs20.existsSync(existingLedgerPath)) {
44673
+ fs20.unlinkSync(existingLedgerPath);
44523
44674
  }
44524
44675
  try {
44525
- const planJsonPath = path32.join(swarmDir, "plan.json");
44526
- if (fs21.existsSync(planJsonPath)) {
44527
- const planRaw = fs21.readFileSync(planJsonPath, "utf-8");
44676
+ const planJsonPath = path31.join(swarmDir, "plan.json");
44677
+ if (fs20.existsSync(planJsonPath)) {
44678
+ const planRaw = fs20.readFileSync(planJsonPath, "utf-8");
44528
44679
  const plan = PlanSchema.parse(JSON.parse(planRaw));
44529
44680
  const planId = `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
44530
44681
  const planHash = computePlanHash(plan);
@@ -44551,7 +44702,7 @@ async function handleRollbackCommand(directory, args) {
44551
44702
  timestamp: new Date().toISOString()
44552
44703
  };
44553
44704
  try {
44554
- fs21.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
44705
+ fs20.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
44555
44706
  `);
44556
44707
  } catch (error93) {
44557
44708
  console.error("Failed to write rollback event:", error93 instanceof Error ? error93.message : String(error93));
@@ -44594,11 +44745,11 @@ async function handleSimulateCommand(directory, args) {
44594
44745
  ];
44595
44746
  const report = reportLines.filter(Boolean).join(`
44596
44747
  `);
44597
- const fs22 = await import("fs/promises");
44598
- const path33 = await import("path");
44599
- const reportPath = path33.join(directory, ".swarm", "simulate-report.md");
44600
- await fs22.mkdir(path33.dirname(reportPath), { recursive: true });
44601
- await fs22.writeFile(reportPath, report, "utf-8");
44748
+ const fs21 = await import("fs/promises");
44749
+ const path32 = await import("path");
44750
+ const reportPath = path32.join(directory, ".swarm", "simulate-report.md");
44751
+ await fs21.mkdir(path32.dirname(reportPath), { recursive: true });
44752
+ await fs21.writeFile(reportPath, report, "utf-8");
44602
44753
  return `${darkMatterPairs.length} hidden coupling pairs detected`;
44603
44754
  }
44604
44755
 
@@ -45131,19 +45282,20 @@ function resolveCommand(tokens) {
45131
45282
  }
45132
45283
 
45133
45284
  // src/cli/index.ts
45134
- var CONFIG_DIR = path33.join(process.env.XDG_CONFIG_HOME || path33.join(os6.homedir(), ".config"), "opencode");
45135
- var OPENCODE_CONFIG_PATH = path33.join(CONFIG_DIR, "opencode.json");
45136
- var PLUGIN_CONFIG_PATH = path33.join(CONFIG_DIR, "opencode-swarm.json");
45137
- var PROMPTS_DIR = path33.join(CONFIG_DIR, "opencode-swarm");
45138
- var OPENCODE_PLUGIN_CACHE_PATH = path33.join(process.env.XDG_CACHE_HOME || path33.join(os6.homedir(), ".cache"), "opencode", "packages", "opencode-swarm@latest");
45285
+ var { version: version4 } = package_default;
45286
+ var CONFIG_DIR = path32.join(process.env.XDG_CONFIG_HOME || path32.join(os6.homedir(), ".config"), "opencode");
45287
+ var OPENCODE_CONFIG_PATH = path32.join(CONFIG_DIR, "opencode.json");
45288
+ var PLUGIN_CONFIG_PATH = path32.join(CONFIG_DIR, "opencode-swarm.json");
45289
+ var PROMPTS_DIR = path32.join(CONFIG_DIR, "opencode-swarm");
45290
+ var OPENCODE_PLUGIN_CACHE_PATH = path32.join(process.env.XDG_CACHE_HOME || path32.join(os6.homedir(), ".cache"), "opencode", "packages", "opencode-swarm@latest");
45139
45291
  function ensureDir(dir) {
45140
- if (!fs22.existsSync(dir)) {
45141
- fs22.mkdirSync(dir, { recursive: true });
45292
+ if (!fs21.existsSync(dir)) {
45293
+ fs21.mkdirSync(dir, { recursive: true });
45142
45294
  }
45143
45295
  }
45144
45296
  function loadJson(filepath) {
45145
45297
  try {
45146
- const content = fs22.readFileSync(filepath, "utf-8");
45298
+ const content = fs21.readFileSync(filepath, "utf-8");
45147
45299
  const stripped = content.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (match, comment) => comment ? "" : match).replace(/,(\s*[}\]])/g, "$1");
45148
45300
  return JSON.parse(stripped);
45149
45301
  } catch {
@@ -45151,15 +45303,31 @@ function loadJson(filepath) {
45151
45303
  }
45152
45304
  }
45153
45305
  function saveJson(filepath, data) {
45154
- fs22.writeFileSync(filepath, `${JSON.stringify(data, null, 2)}
45306
+ fs21.writeFileSync(filepath, `${JSON.stringify(data, null, 2)}
45155
45307
  `, "utf-8");
45156
45308
  }
45309
+ function writeProjectConfigIfMissing(cwd) {
45310
+ try {
45311
+ const opencodeDir = path32.join(cwd, ".opencode");
45312
+ const projectConfigPath = path32.join(opencodeDir, "opencode-swarm.json");
45313
+ if (fs21.existsSync(projectConfigPath)) {
45314
+ return;
45315
+ }
45316
+ ensureDir(opencodeDir);
45317
+ const starterConfig = { agents: {} };
45318
+ saveJson(projectConfigPath, starterConfig);
45319
+ console.log("\u2713 Created project config at:", projectConfigPath);
45320
+ } catch (error93) {
45321
+ console.warn("\u26A0 Could not create project config \u2014 installation will continue:");
45322
+ console.warn(` ${error93 instanceof Error ? error93.message : String(error93)}`);
45323
+ }
45324
+ }
45157
45325
  async function install() {
45158
45326
  console.log(`\uD83D\uDC1D Installing OpenCode Swarm...
45159
45327
  `);
45160
45328
  ensureDir(CONFIG_DIR);
45161
45329
  ensureDir(PROMPTS_DIR);
45162
- const LEGACY_CONFIG_PATH = path33.join(CONFIG_DIR, "config.json");
45330
+ const LEGACY_CONFIG_PATH = path32.join(CONFIG_DIR, "config.json");
45163
45331
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
45164
45332
  if (!opencodeConfig) {
45165
45333
  const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
@@ -45191,15 +45359,15 @@ async function install() {
45191
45359
  console.log("\u2713 Added opencode-swarm to OpenCode plugins");
45192
45360
  console.log("\u2713 Disabled default OpenCode agents (explore, general)");
45193
45361
  try {
45194
- if (fs22.existsSync(OPENCODE_PLUGIN_CACHE_PATH)) {
45195
- fs22.rmSync(OPENCODE_PLUGIN_CACHE_PATH, { recursive: true, force: true });
45362
+ if (fs21.existsSync(OPENCODE_PLUGIN_CACHE_PATH)) {
45363
+ fs21.rmSync(OPENCODE_PLUGIN_CACHE_PATH, { recursive: true, force: true });
45196
45364
  console.log("\u2713 Cleared opencode plugin cache (next start will fetch latest)");
45197
45365
  }
45198
45366
  } catch {
45199
45367
  console.warn("\u26A0 Could not clear opencode plugin cache \u2014 you may need to delete it manually:");
45200
45368
  console.warn(` ${OPENCODE_PLUGIN_CACHE_PATH}`);
45201
45369
  }
45202
- if (!fs22.existsSync(PLUGIN_CONFIG_PATH)) {
45370
+ if (!fs21.existsSync(PLUGIN_CONFIG_PATH)) {
45203
45371
  const defaultConfig = {
45204
45372
  agents: {
45205
45373
  coder: {
@@ -45274,6 +45442,7 @@ async function install() {
45274
45442
  } else {
45275
45443
  console.log("\u2713 Plugin config already exists at:", PLUGIN_CONFIG_PATH);
45276
45444
  }
45445
+ writeProjectConfigIfMissing(process.cwd());
45277
45446
  console.log(`
45278
45447
  \uD83D\uDCC1 Configuration files:`);
45279
45448
  console.log(` OpenCode config: ${OPENCODE_CONFIG_PATH}`);
@@ -45302,7 +45471,7 @@ async function uninstall() {
45302
45471
  `);
45303
45472
  const opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
45304
45473
  if (!opencodeConfig) {
45305
- if (fs22.existsSync(OPENCODE_CONFIG_PATH)) {
45474
+ if (fs21.existsSync(OPENCODE_CONFIG_PATH)) {
45306
45475
  console.log(`\u2717 Could not parse opencode config at: ${OPENCODE_CONFIG_PATH}`);
45307
45476
  return 1;
45308
45477
  } else {
@@ -45334,13 +45503,13 @@ async function uninstall() {
45334
45503
  console.log("\u2713 Re-enabled default OpenCode agents (explore, general)");
45335
45504
  if (process.argv.includes("--clean")) {
45336
45505
  let cleaned = false;
45337
- if (fs22.existsSync(PLUGIN_CONFIG_PATH)) {
45338
- fs22.unlinkSync(PLUGIN_CONFIG_PATH);
45506
+ if (fs21.existsSync(PLUGIN_CONFIG_PATH)) {
45507
+ fs21.unlinkSync(PLUGIN_CONFIG_PATH);
45339
45508
  console.log(`\u2713 Removed plugin config: ${PLUGIN_CONFIG_PATH}`);
45340
45509
  cleaned = true;
45341
45510
  }
45342
- if (fs22.existsSync(PROMPTS_DIR)) {
45343
- fs22.rmSync(PROMPTS_DIR, { recursive: true });
45511
+ if (fs21.existsSync(PROMPTS_DIR)) {
45512
+ fs21.rmSync(PROMPTS_DIR, { recursive: true });
45344
45513
  console.log(`\u2713 Removed custom prompts: ${PROMPTS_DIR}`);
45345
45514
  cleaned = true;
45346
45515
  }
@@ -45403,6 +45572,10 @@ Examples:
45403
45572
  }
45404
45573
  async function main() {
45405
45574
  const args = process.argv.slice(2);
45575
+ if (args.includes("-v") || args.includes("--version")) {
45576
+ console.log(`opencode-swarm ${version4}`);
45577
+ process.exit(0);
45578
+ }
45406
45579
  if (args.includes("-h") || args.includes("--help")) {
45407
45580
  printHelp();
45408
45581
  process.exit(0);