opencode-swarm 6.86.5 → 6.86.7

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