opencode-swarm 7.58.1 → 7.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.58.1",
72
+ version: "7.59.0",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -1044,7 +1044,9 @@ var init_constants = __esm(() => {
1044
1044
  phase_critic: true,
1045
1045
  integrated_diff_required: true,
1046
1046
  allow_docs_only_without_reviewer: false,
1047
- worktree_isolation: false
1047
+ worktree_isolation: false,
1048
+ merge_strategy: "merge",
1049
+ worktree_dir: undefined
1048
1050
  };
1049
1051
  });
1050
1052
 
@@ -15917,9 +15919,9 @@ var init_schema = __esm(() => {
15917
15919
  phase_critic: exports_external.boolean().default(true),
15918
15920
  integrated_diff_required: exports_external.boolean().default(true),
15919
15921
  allow_docs_only_without_reviewer: exports_external.boolean().default(false),
15920
- worktree_isolation: exports_external.boolean().default(false).refine((val) => val === false, {
15921
- message: "worktree_isolation: true is not yet implemented. Use false (the default) for in-repo parallel execution. Full worktree isolation will be available in a future release."
15922
- })
15922
+ worktree_isolation: exports_external.boolean().default(false),
15923
+ merge_strategy: exports_external.enum(["merge", "rebase", "cherry-pick"]).default("merge").optional(),
15924
+ worktree_dir: exports_external.string().optional()
15923
15925
  });
15924
15926
  StandardTurboConfigSchema = exports_external.object({
15925
15927
  strategy: exports_external.literal("standard"),
@@ -93513,10 +93515,10 @@ var init_curator_drift = __esm(() => {
93513
93515
  var exports_design_doc_drift = {};
93514
93516
  __export(exports_design_doc_drift, {
93515
93517
  runDesignDocDriftCheck: () => runDesignDocDriftCheck,
93516
- _internals: () => _internals67
93518
+ _internals: () => _internals69
93517
93519
  });
93518
93520
  import * as fs109 from "node:fs";
93519
- import * as path148 from "node:path";
93521
+ import * as path149 from "node:path";
93520
93522
  function mtimeMsOrNull(absPath) {
93521
93523
  try {
93522
93524
  return fs109.statSync(absPath).mtimeMs;
@@ -93527,35 +93529,35 @@ function mtimeMsOrNull(absPath) {
93527
93529
  function resolveAnchorWithin(directory, anchor) {
93528
93530
  if (!anchor || typeof anchor !== "string")
93529
93531
  return null;
93530
- const root = path148.resolve(directory);
93531
- const resolved = path148.resolve(root, anchor);
93532
- const rel = path148.relative(root, resolved);
93533
- if (rel.startsWith("..") || path148.isAbsolute(rel))
93532
+ const root = path149.resolve(directory);
93533
+ const resolved = path149.resolve(root, anchor);
93534
+ const rel = path149.relative(root, resolved);
93535
+ if (rel.startsWith("..") || path149.isAbsolute(rel))
93534
93536
  return null;
93535
93537
  return resolved;
93536
93538
  }
93537
93539
  async function runDesignDocDriftCheck(directory, phase, outDir) {
93538
93540
  try {
93539
- const root = path148.resolve(directory);
93540
- const outAbs = path148.resolve(root, outDir);
93541
- const outRel = path148.relative(root, outAbs);
93542
- if (outRel.startsWith("..") || path148.isAbsolute(outRel)) {
93541
+ const root = path149.resolve(directory);
93542
+ const outAbs = path149.resolve(root, outDir);
93543
+ const outRel = path149.relative(root, outAbs);
93544
+ if (outRel.startsWith("..") || path149.isAbsolute(outRel)) {
93543
93545
  return null;
93544
93546
  }
93545
93547
  const docMtimes = new Map;
93546
93548
  const checkedDocs = [];
93547
93549
  const missingDocs = [];
93548
93550
  for (const [docName, relFile] of Object.entries(DESIGN_DOC_FILES)) {
93549
- const abs = path148.join(outAbs, relFile);
93551
+ const abs = path149.join(outAbs, relFile);
93550
93552
  const mtime = mtimeMsOrNull(abs);
93551
93553
  docMtimes.set(docName, mtime);
93552
93554
  if (mtime === null) {
93553
- missingDocs.push(path148.join(outDir, relFile));
93555
+ missingDocs.push(path149.join(outDir, relFile));
93554
93556
  } else {
93555
- checkedDocs.push(path148.join(outDir, relFile));
93557
+ checkedDocs.push(path149.join(outDir, relFile));
93556
93558
  }
93557
93559
  }
93558
- const traceabilityAbs = path148.join(outAbs, TRACEABILITY_REL);
93560
+ const traceabilityAbs = path149.join(outAbs, TRACEABILITY_REL);
93559
93561
  let registry3 = null;
93560
93562
  try {
93561
93563
  const stat9 = await fs109.promises.stat(traceabilityAbs);
@@ -93568,7 +93570,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
93568
93570
  registry3 = null;
93569
93571
  }
93570
93572
  const noDocs = checkedDocs.length === 0 || registry3 === null;
93571
- const specMtime = mtimeMsOrNull(path148.join(root, ".swarm", "spec.md"));
93573
+ const specMtime = mtimeMsOrNull(path149.join(root, ".swarm", "spec.md"));
93572
93574
  const staleSections = [];
93573
93575
  if (!noDocs && Array.isArray(registry3?.sections)) {
93574
93576
  for (const section of registry3.sections) {
@@ -93624,7 +93626,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
93624
93626
  };
93625
93627
  const filename = `${DOC_DRIFT_REPORT_PREFIX}${phase}.json`;
93626
93628
  const filePath = validateSwarmPath(directory, filename);
93627
- await fs109.promises.mkdir(path148.dirname(filePath), { recursive: true });
93629
+ await fs109.promises.mkdir(path149.dirname(filePath), { recursive: true });
93628
93630
  await fs109.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
93629
93631
  getGlobalEventBus().publish("curator.docdrift.completed", {
93630
93632
  phase,
@@ -93645,7 +93647,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
93645
93647
  return null;
93646
93648
  }
93647
93649
  }
93648
- var DOC_DRIFT_REPORT_PREFIX = "doc-drift-phase-", MAX_TRACEABILITY_BYTES, DESIGN_DOC_FILES, TRACEABILITY_REL, _internals67;
93650
+ var DOC_DRIFT_REPORT_PREFIX = "doc-drift-phase-", MAX_TRACEABILITY_BYTES, DESIGN_DOC_FILES, TRACEABILITY_REL, _internals69;
93649
93651
  var init_design_doc_drift = __esm(() => {
93650
93652
  init_event_bus();
93651
93653
  init_logger();
@@ -93655,11 +93657,11 @@ var init_design_doc_drift = __esm(() => {
93655
93657
  domain: "domain.md",
93656
93658
  "technical-spec": "technical-spec.md",
93657
93659
  "behavior-spec": "behavior-spec.md",
93658
- "reference-impl": path148.join("reference", "reference-impl.md"),
93659
- "idiom-notes": path148.join("reference", "idiom-notes.md")
93660
+ "reference-impl": path149.join("reference", "reference-impl.md"),
93661
+ "idiom-notes": path149.join("reference", "idiom-notes.md")
93660
93662
  };
93661
- TRACEABILITY_REL = path148.join("reference", "traceability.json");
93662
- _internals67 = {
93663
+ TRACEABILITY_REL = path149.join("reference", "traceability.json");
93664
+ _internals69 = {
93663
93665
  mtimeMsOrNull,
93664
93666
  resolveAnchorWithin,
93665
93667
  DESIGN_DOC_FILES
@@ -93670,11 +93672,11 @@ var init_design_doc_drift = __esm(() => {
93670
93672
  var exports_project_context = {};
93671
93673
  __export(exports_project_context, {
93672
93674
  buildProjectContext: () => buildProjectContext,
93673
- _internals: () => _internals78,
93675
+ _internals: () => _internals80,
93674
93676
  LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
93675
93677
  });
93676
93678
  import * as fs133 from "node:fs";
93677
- import * as path177 from "node:path";
93679
+ import * as path178 from "node:path";
93678
93680
  function detectFileExists2(directory, pattern) {
93679
93681
  if (pattern.includes("*") || pattern.includes("?")) {
93680
93682
  try {
@@ -93686,7 +93688,7 @@ function detectFileExists2(directory, pattern) {
93686
93688
  }
93687
93689
  }
93688
93690
  try {
93689
- fs133.accessSync(path177.join(directory, pattern));
93691
+ fs133.accessSync(path178.join(directory, pattern));
93690
93692
  return true;
93691
93693
  } catch {
93692
93694
  return false;
@@ -93695,7 +93697,7 @@ function detectFileExists2(directory, pattern) {
93695
93697
  function selectTestCommandFromScriptsTest(backend, directory) {
93696
93698
  let pkgRaw;
93697
93699
  try {
93698
- pkgRaw = fs133.readFileSync(path177.join(directory, "package.json"), "utf-8");
93700
+ pkgRaw = fs133.readFileSync(path178.join(directory, "package.json"), "utf-8");
93699
93701
  } catch {
93700
93702
  return null;
93701
93703
  }
@@ -93754,7 +93756,7 @@ function selectLintCommand(backend, directory) {
93754
93756
  return null;
93755
93757
  }
93756
93758
  async function buildProjectContext(directory) {
93757
- const backend = await _internals78.pickBackend(directory);
93759
+ const backend = await _internals80.pickBackend(directory);
93758
93760
  if (!backend)
93759
93761
  return null;
93760
93762
  const ctx = emptyProjectContext();
@@ -93793,17 +93795,17 @@ async function buildProjectContext(directory) {
93793
93795
  if (backend.prompts.reviewerChecklist.length > 0) {
93794
93796
  ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
93795
93797
  }
93796
- const profiles = _internals78.pickedProfiles(directory);
93798
+ const profiles = _internals80.pickedProfiles(directory);
93797
93799
  if (profiles.length > 1) {
93798
93800
  ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
93799
93801
  }
93800
93802
  return ctx;
93801
93803
  }
93802
- var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals78;
93804
+ var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals80;
93803
93805
  var init_project_context = __esm(() => {
93804
93806
  init_dispatch();
93805
93807
  init_framework_detector();
93806
- _internals78 = {
93808
+ _internals80 = {
93807
93809
  pickBackend,
93808
93810
  pickedProfiles
93809
93811
  };
@@ -93813,7 +93815,7 @@ var init_project_context = __esm(() => {
93813
93815
  init_package();
93814
93816
  init_agents2();
93815
93817
  init_critic();
93816
- import * as path178 from "node:path";
93818
+ import * as path179 from "node:path";
93817
93819
  import { fileURLToPath as fileURLToPath5 } from "node:url";
93818
93820
 
93819
93821
  // src/background/index.ts
@@ -116503,7 +116505,468 @@ init_state2();
116503
116505
  init_file_locks();
116504
116506
  init_manager();
116505
116507
  init_state();
116508
+
116509
+ // src/turbo/lean/merge-back.ts
116510
+ init_bun_compat();
116511
+
116512
+ // src/turbo/lean/worktree.ts
116513
+ init_bun_compat();
116514
+ import * as os14 from "node:os";
116515
+ import * as path137 from "node:path";
116516
+ var _internals62 = {
116517
+ bunSpawn,
116518
+ platform: process.platform,
116519
+ sleep: (ms) => new Promise((resolve50) => setTimeout(resolve50, ms)),
116520
+ osTmpdir: () => os14.tmpdir(),
116521
+ getCoreLongPaths: async (directory) => {
116522
+ const result = await runGit(["config", "core.longpaths"], directory);
116523
+ if (result.exitCode !== 0) {
116524
+ return;
116525
+ }
116526
+ const value = result.stdout.trim().toLowerCase();
116527
+ return value === "" ? undefined : value;
116528
+ }
116529
+ };
116530
+ var WORKTREE_TIMEOUT_MS = 30000;
116531
+ var WIN_PATH_BUDGET = 250;
116532
+ async function runGit(args2, cwd, timeoutMs = WORKTREE_TIMEOUT_MS) {
116533
+ const proc = _internals62.bunSpawn(["git", ...args2], {
116534
+ cwd,
116535
+ timeout: timeoutMs,
116536
+ stdin: "ignore",
116537
+ stdout: "pipe",
116538
+ stderr: "pipe",
116539
+ env: { ...process.env, LC_ALL: "C" }
116540
+ });
116541
+ try {
116542
+ const exitCode = await proc.exited;
116543
+ const stdout = await proc.stdout.text();
116544
+ const stderr = await proc.stderr.text();
116545
+ return { exitCode, stdout, stderr };
116546
+ } finally {
116547
+ try {
116548
+ proc.kill();
116549
+ } catch {}
116550
+ }
116551
+ }
116552
+ async function checkPathBudget(worktreeRoot, directory) {
116553
+ if (_internals62.platform !== "win32") {
116554
+ return { ok: true };
116555
+ }
116556
+ let longPaths;
116557
+ try {
116558
+ longPaths = await _internals62.getCoreLongPaths(directory);
116559
+ } catch {}
116560
+ if (longPaths === "true") {
116561
+ return { ok: true };
116562
+ }
116563
+ const proc = _internals62.bunSpawn(["git", "ls-files"], {
116564
+ cwd: directory,
116565
+ timeout: WORKTREE_TIMEOUT_MS,
116566
+ stdin: "ignore",
116567
+ stdout: "pipe",
116568
+ stderr: "ignore",
116569
+ env: { ...process.env, LC_ALL: "C" }
116570
+ });
116571
+ try {
116572
+ const exitCode = await proc.exited;
116573
+ const stdout = await proc.stdout.text();
116574
+ if (exitCode !== 0 || stdout.trim().length === 0) {
116575
+ return { ok: true };
116576
+ }
116577
+ const files = stdout.split(/\r?\n/);
116578
+ let longest = 0;
116579
+ for (const file3 of files) {
116580
+ if (file3.length > longest) {
116581
+ longest = file3.length;
116582
+ }
116583
+ }
116584
+ const totalPathLength = worktreeRoot.length + 1 + longest;
116585
+ if (totalPathLength >= WIN_PATH_BUDGET) {
116586
+ return {
116587
+ ok: false,
116588
+ error: `Total path budget exceeded: worktree root "${worktreeRoot}" (${worktreeRoot.length} chars) + longest file "${files.find((f) => f.length === longest)}" (${longest} chars) = ${totalPathLength} chars (budget: ${WIN_PATH_BUDGET})`,
116589
+ suggestion: "Set config.worktree_dir to a shorter absolute path, or let the auto-shorten feature relocate the worktree to the system temp directory."
116590
+ };
116591
+ }
116592
+ return { ok: true };
116593
+ } finally {
116594
+ try {
116595
+ proc.kill();
116596
+ } catch {}
116597
+ }
116598
+ }
116599
+ function shortenWorktreePath(_directory, sessionId, laneId) {
116600
+ return path137.join(_internals62.osTmpdir(), "swwt", sessionId, laneId);
116601
+ }
116602
+ async function provisionWorktree(directory, laneId, sessionId, config3) {
116603
+ const branchName = `swarm-lane/${sessionId}/${laneId}`;
116604
+ let worktreePath = config3.worktree_dir ? path137.resolve(directory, config3.worktree_dir, sessionId, laneId) : path137.resolve(path137.dirname(directory), ".swarm-worktrees", sessionId, laneId);
116605
+ const budgetResult = await checkPathBudget(worktreePath, directory);
116606
+ if (budgetResult.ok === false) {
116607
+ if (config3.worktree_dir) {
116608
+ console.warn(`[swarm] Path budget warning: ${budgetResult.error} ${budgetResult.suggestion}`);
116609
+ } else {
116610
+ const shortPath = shortenWorktreePath(directory, sessionId, laneId);
116611
+ const shortBudget = await checkPathBudget(shortPath, directory);
116612
+ if (shortBudget.ok === false) {
116613
+ return { error: budgetResult.error };
116614
+ }
116615
+ worktreePath = shortPath;
116616
+ }
116617
+ }
116618
+ const checkResult = await runGit(["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`], directory);
116619
+ if (checkResult.exitCode === 0) {
116620
+ return { error: `Branch already exists: ${branchName}` };
116621
+ }
116622
+ const addResult = await runGit(["worktree", "add", "-b", branchName, worktreePath, "HEAD"], directory);
116623
+ if (addResult.exitCode !== 0) {
116624
+ return {
116625
+ error: `Failed to create worktree: ${addResult.stderr.trim() || addResult.stdout.trim()}`
116626
+ };
116627
+ }
116628
+ return { worktreePath, branchName };
116629
+ }
116630
+ async function removeWorktree(worktreePath, projectRoot) {
116631
+ const isWindows = _internals62.platform === "win32";
116632
+ const MAX_RETRIES = 4;
116633
+ const RETRY_DELAY_MS = 2000;
116634
+ let lastError = "";
116635
+ for (let attempt = 0;attempt < MAX_RETRIES; attempt++) {
116636
+ const result = await runGit(["worktree", "remove", worktreePath], projectRoot);
116637
+ if (result.exitCode === 0) {
116638
+ return { success: true };
116639
+ }
116640
+ lastError = result.stderr.trim() || result.stdout.trim();
116641
+ if (isWindows && (lastError.includes("EBUSY") || lastError.includes("EPERM")) && attempt < MAX_RETRIES - 1) {
116642
+ await _internals62.sleep(RETRY_DELAY_MS);
116643
+ continue;
116644
+ }
116645
+ return { error: lastError };
116646
+ }
116647
+ return { error: lastError };
116648
+ }
116649
+ async function autoCommitDirty(worktreePath) {
116650
+ const COMMIT_MESSAGE = "swarm-lane: auto-commit before cleanup";
116651
+ const addResult = await runGit(["add", "-A"], worktreePath);
116652
+ if (addResult.exitCode !== 0) {
116653
+ return {
116654
+ committed: false,
116655
+ reason: `git add failed: ${addResult.stderr.trim() || addResult.stdout.trim()}`
116656
+ };
116657
+ }
116658
+ const commitResult = await runGit(["commit", "-m", COMMIT_MESSAGE], worktreePath);
116659
+ if (commitResult.exitCode !== 0) {
116660
+ const stderr = commitResult.stderr.trim();
116661
+ const stdout = commitResult.stdout.trim();
116662
+ if (stderr.includes("nothing to commit") || stdout.includes("nothing to commit") || stderr.includes("nothing added to commit")) {
116663
+ return { committed: false, reason: "Nothing to commit" };
116664
+ }
116665
+ return {
116666
+ committed: false,
116667
+ reason: `git commit failed: ${stderr || stdout}`
116668
+ };
116669
+ }
116670
+ return { committed: true, message: COMMIT_MESSAGE };
116671
+ }
116672
+ var SAFE_CLEAN_PATTERNS = [
116673
+ "dist/",
116674
+ "build/",
116675
+ ".turbo/",
116676
+ "coverage/",
116677
+ "node_modules/.cache/",
116678
+ ".log",
116679
+ ".tmp",
116680
+ ".o",
116681
+ ".pyc",
116682
+ ".class"
116683
+ ];
116684
+ function isSafeToClean(candidatePath) {
116685
+ const normalized = candidatePath.replace(/\\/g, "/").toLowerCase();
116686
+ return SAFE_CLEAN_PATTERNS.some((pattern) => {
116687
+ const p = pattern.toLowerCase();
116688
+ if (p.endsWith("/")) {
116689
+ return normalized.startsWith(p) || normalized.includes("/" + p);
116690
+ }
116691
+ return normalized.endsWith(p);
116692
+ });
116693
+ }
116694
+ async function cleanUntrackedFiles(worktreePath) {
116695
+ const dryRun = await runGit(["clean", "-fdn"], worktreePath);
116696
+ if (dryRun.exitCode === 0) {
116697
+ const candidates = dryRun.stdout.trim().split(`
116698
+ `).map((line) => {
116699
+ const match = line.match(/^Would remove (.+)$/);
116700
+ return match ? match[1].trim() : "";
116701
+ }).filter((p) => p.length > 0);
116702
+ const unsafePaths = candidates.filter((p) => !isSafeToClean(p));
116703
+ if (unsafePaths.length > 0) {
116704
+ console.warn(`[swarm:cleanUntrackedFiles] Skipping clean — untracked source files detected: ${unsafePaths.join(", ")}`);
116705
+ return {
116706
+ cleaned: false,
116707
+ error: "untracked source files detected — skipping clean to prevent data loss"
116708
+ };
116709
+ }
116710
+ }
116711
+ const result = await runGit(["clean", "-fd"], worktreePath);
116712
+ if (result.exitCode !== 0) {
116713
+ return {
116714
+ cleaned: false,
116715
+ error: result.stderr.trim() || result.stdout.trim()
116716
+ };
116717
+ }
116718
+ return { cleaned: true };
116719
+ }
116720
+ async function assertCleanWorkingTree(directory) {
116721
+ const [statusResult, untrackedResult] = await Promise.all([
116722
+ runGit(["status", "--porcelain"], directory),
116723
+ runGit(["ls-files", "--others", "--exclude-standard"], directory)
116724
+ ]);
116725
+ if (statusResult.exitCode !== 0) {
116726
+ return {
116727
+ clean: false,
116728
+ error: `Unable to verify working tree cleanliness: ${statusResult.stderr.trim() || statusResult.stdout.trim()}`
116729
+ };
116730
+ }
116731
+ if (untrackedResult.exitCode !== 0) {
116732
+ return {
116733
+ clean: false,
116734
+ error: `Unable to verify working tree cleanliness: ${untrackedResult.stderr.trim() || untrackedResult.stdout.trim()}`
116735
+ };
116736
+ }
116737
+ const hasChanges = statusResult.stdout.trim().length > 0;
116738
+ const hasUntracked = untrackedResult.stdout.trim().length > 0;
116739
+ if (hasChanges || hasUntracked) {
116740
+ return {
116741
+ clean: false,
116742
+ error: "Working tree has uncommitted changes. Please commit or stash before provisioning worktrees. Run 'git status' for details."
116743
+ };
116744
+ }
116745
+ return { clean: true };
116746
+ }
116747
+
116748
+ // src/turbo/lean/merge-back.ts
116749
+ var _internals63 = {
116750
+ bunSpawn,
116751
+ platform: process.platform,
116752
+ sleep: (ms) => new Promise((resolve50) => setTimeout(resolve50, ms))
116753
+ };
116754
+ var MERGE_TIMEOUT_MS = 30000;
116755
+ async function runGit2(args2, cwd, timeoutMs = MERGE_TIMEOUT_MS) {
116756
+ const proc = _internals63.bunSpawn(["git", ...args2], {
116757
+ cwd,
116758
+ timeout: timeoutMs,
116759
+ stdin: "ignore",
116760
+ stdout: "pipe",
116761
+ stderr: "pipe",
116762
+ env: { ...process.env, LC_ALL: "C" }
116763
+ });
116764
+ try {
116765
+ const exitCode = await proc.exited;
116766
+ const stdout = await proc.stdout.text();
116767
+ const stderr = await proc.stderr.text();
116768
+ return { exitCode, stdout, stderr };
116769
+ } finally {
116770
+ try {
116771
+ proc.kill();
116772
+ } catch {}
116773
+ }
116774
+ }
116775
+ function parseConflictFiles(output) {
116776
+ const files = [];
116777
+ const lines = output.split(`
116778
+ `);
116779
+ for (const line of lines) {
116780
+ const match = line.match(/CONFLICT\b.*(?:Merge conflict in |in )(.+)/);
116781
+ if (match?.[1]) {
116782
+ files.push(match[1].trim());
116783
+ }
116784
+ }
116785
+ return files;
116786
+ }
116787
+ function getMergeStrategy(config3) {
116788
+ return config3.merge_strategy ?? "merge";
116789
+ }
116790
+ async function mergeLaneBranch(primaryDir, branchName, strategy) {
116791
+ let result;
116792
+ switch (strategy) {
116793
+ case "merge":
116794
+ result = await runGit2(["merge", "--no-edit", branchName], primaryDir);
116795
+ break;
116796
+ case "rebase":
116797
+ result = await runGit2(["rebase", branchName], primaryDir);
116798
+ break;
116799
+ case "cherry-pick": {
116800
+ const mergeBaseResult = await runGit2(["merge-base", "HEAD", branchName], primaryDir);
116801
+ if (mergeBaseResult.exitCode === 0 && mergeBaseResult.stdout.trim()) {
116802
+ const mergeBase = mergeBaseResult.stdout.trim();
116803
+ result = await runGit2(["cherry-pick", `${mergeBase}..${branchName}`], primaryDir);
116804
+ } else {
116805
+ console.warn("[lean-turbo] mergeLaneBranch: git merge-base failed for cherry-pick; falling back to tip-only cherry-pick");
116806
+ result = await runGit2(["cherry-pick", branchName], primaryDir);
116807
+ }
116808
+ break;
116809
+ }
116810
+ }
116811
+ if (result.exitCode === 0) {
116812
+ return { merged: true, strategy };
116813
+ }
116814
+ const combinedOutput = `${result.stderr}
116815
+ ${result.stdout}`;
116816
+ const hasConflict = /CONFLICT/i.test(combinedOutput) || /conflict/i.test(combinedOutput);
116817
+ if (hasConflict) {
116818
+ const files = parseConflictFiles(combinedOutput);
116819
+ const abortArgs = strategy === "rebase" ? ["rebase", "--abort"] : strategy === "cherry-pick" ? ["cherry-pick", "--abort"] : ["merge", "--abort"];
116820
+ await runGit2(abortArgs, primaryDir);
116821
+ return {
116822
+ conflict: true,
116823
+ files,
116824
+ message: result.stderr.trim()
116825
+ };
116826
+ }
116827
+ return {
116828
+ error: result.stderr.trim() || result.stdout.trim()
116829
+ };
116830
+ }
116831
+ async function postMergeCleanup(directory, branchName) {
116832
+ const deleteResult = await runGit2(["branch", "-D", branchName], directory);
116833
+ const deleteOk = deleteResult.exitCode === 0;
116834
+ const pruneResult = await runGit2(["worktree", "prune"], directory);
116835
+ const pruneOk = pruneResult.exitCode === 0;
116836
+ if (deleteOk && pruneOk) {
116837
+ return { cleaned: true };
116838
+ }
116839
+ if (!deleteOk && pruneOk) {
116840
+ return {
116841
+ error: `Branch delete failed: ${deleteResult.stderr.trim() || deleteResult.stdout.trim()}`,
116842
+ partial: true
116843
+ };
116844
+ }
116845
+ return {
116846
+ error: deleteOk ? `Worktree prune failed: ${pruneResult.stderr.trim() || pruneResult.stdout.trim()}` : `Branch delete failed: ${deleteResult.stderr.trim() || deleteResult.stdout.trim()}; worktree prune failed: ${pruneResult.stderr.trim() || pruneResult.stdout.trim()}`
116847
+ };
116848
+ }
116849
+ async function attemptMergeBackFromDirty(worktreePath, branchName, primaryDir, strategy) {
116850
+ let autoCommitted = false;
116851
+ let cleaned = false;
116852
+ let autoCommitFailed = false;
116853
+ let cleanFailed = false;
116854
+ const commitResult = await autoCommitDirty(worktreePath);
116855
+ if (commitResult.committed) {
116856
+ autoCommitted = true;
116857
+ } else if (commitResult.reason !== "Nothing to commit") {
116858
+ autoCommitFailed = true;
116859
+ console.warn(`[lean-turbo] attemptMergeBackFromDirty: auto-commit failed for worktree "${worktreePath}" branch "${branchName}": ${commitResult.reason}`);
116860
+ }
116861
+ const cleanResult = await cleanUntrackedFiles(worktreePath);
116862
+ if (cleanResult.cleaned) {
116863
+ cleaned = true;
116864
+ } else {
116865
+ cleanFailed = true;
116866
+ console.warn(`[lean-turbo] attemptMergeBackFromDirty: clean untracked failed for worktree "${worktreePath}" branch "${branchName}": ${cleanResult.error}`);
116867
+ }
116868
+ if (autoCommitFailed && cleanFailed) {
116869
+ return {
116870
+ failed: true,
116871
+ stage: "cleanup",
116872
+ message: "Auto-commit and clean both failed; abandoning worktree"
116873
+ };
116874
+ }
116875
+ const mergeResult = await mergeLaneBranch(primaryDir, branchName, strategy);
116876
+ if ("merged" in mergeResult && mergeResult.merged) {
116877
+ return { merged: true, strategy, autoCommitted, cleaned };
116878
+ }
116879
+ if ("conflict" in mergeResult) {
116880
+ return {
116881
+ partial: true,
116882
+ stage: "merge",
116883
+ autoCommitted,
116884
+ cleaned,
116885
+ message: mergeResult.message
116886
+ };
116887
+ }
116888
+ if ("error" in mergeResult) {
116889
+ return {
116890
+ failed: true,
116891
+ stage: "merge",
116892
+ message: mergeResult.error
116893
+ };
116894
+ }
116895
+ return {
116896
+ failed: true,
116897
+ stage: "merge",
116898
+ message: "Merge failed with unexpected result"
116899
+ };
116900
+ }
116901
+ function extractSessionId(branchName) {
116902
+ const segments = branchName.trim().split("/");
116903
+ if (segments.length >= 3 && segments[0] === "swarm-lane") {
116904
+ return segments[1];
116905
+ }
116906
+ return null;
116907
+ }
116908
+ async function startupOrphanRecovery(directory, activeSessionIds = []) {
116909
+ const warnings = [];
116910
+ const pruneResult = await runGit2(["worktree", "prune"], directory);
116911
+ if (pruneResult.exitCode !== 0) {
116912
+ warnings.push(`git worktree prune failed: ${pruneResult.stderr.trim() || pruneResult.stdout.trim()}`);
116913
+ }
116914
+ const listResult = await runGit2(["branch", "--format=%(refname:short)", "--list", "swarm-lane/*"], directory);
116915
+ const allBranches = listResult.stdout.split(`
116916
+ `).map((line) => line.trim()).filter((line) => line.length > 0);
116917
+ const orphanBranches = [];
116918
+ for (const branch of allBranches) {
116919
+ const sessionId = extractSessionId(branch);
116920
+ if (sessionId === null || !activeSessionIds.includes(sessionId)) {
116921
+ orphanBranches.push(branch);
116922
+ warnings.push(`Orphaned swarm-lane branch "${branch}" detected in "${directory}"`);
116923
+ }
116924
+ }
116925
+ for (const warning of warnings) {
116926
+ console.warn(warning);
116927
+ }
116928
+ return {
116929
+ prunedWorktrees: pruneResult.exitCode === 0,
116930
+ remainingBranches: orphanBranches,
116931
+ warnings
116932
+ };
116933
+ }
116934
+
116935
+ // src/turbo/lean/runner.ts
116506
116936
  init_state3();
116937
+ function isTransientProvisionError(errorMsg) {
116938
+ const lower = errorMsg.toLowerCase();
116939
+ if (lower.includes("already exists") || lower.includes("not a git repository")) {
116940
+ return false;
116941
+ }
116942
+ const transientCodes = [
116943
+ "enoent",
116944
+ "econnrefused",
116945
+ "etimedout",
116946
+ "ebusy",
116947
+ "eperm",
116948
+ "enomem"
116949
+ ];
116950
+ for (const code of transientCodes) {
116951
+ if (lower.includes(code)) {
116952
+ return true;
116953
+ }
116954
+ }
116955
+ const transientMessages = [
116956
+ "disk full",
116957
+ "no space left",
116958
+ "resource temporarily unavailable"
116959
+ ];
116960
+ for (const msg of transientMessages) {
116961
+ if (lower.includes(msg)) {
116962
+ return true;
116963
+ }
116964
+ }
116965
+ if (lower.includes("fatal:")) {
116966
+ return true;
116967
+ }
116968
+ return false;
116969
+ }
116507
116970
 
116508
116971
  class LeanTurboRunner {
116509
116972
  static _internals = {
@@ -116516,7 +116979,15 @@ class LeanTurboRunner {
116516
116979
  hasActiveFullAuto,
116517
116980
  loadFullAutoRunState,
116518
116981
  writeLaneEvidence,
116519
- laneDispatchTimeoutMs: undefined
116982
+ laneDispatchTimeoutMs: undefined,
116983
+ provisionWorktree,
116984
+ removeWorktree,
116985
+ mergeLaneBranch,
116986
+ postMergeCleanup,
116987
+ attemptMergeBackFromDirty,
116988
+ startupOrphanRecovery,
116989
+ getMergeStrategy,
116990
+ assertCleanWorkingTree
116520
116991
  };
116521
116992
  _sessionOps = null;
116522
116993
  _directory;
@@ -116575,6 +117046,22 @@ class LeanTurboRunner {
116575
117046
  }
116576
117047
  }
116577
117048
  const leanConfig = this._getLeanConfig(this._leanConfig);
117049
+ if (leanConfig.worktree_isolation) {
117050
+ await LeanTurboRunner._internals.startupOrphanRecovery(this._directory, [
117051
+ this._sessionID
117052
+ ]);
117053
+ try {
117054
+ const cleanResult = await LeanTurboRunner._internals.assertCleanWorkingTree(this._directory);
117055
+ if (!cleanResult.clean) {
117056
+ console.warn(`[lean-turbo] worktree isolation requires clean working tree: ${cleanResult.error}`);
117057
+ leanConfig.worktree_isolation = false;
117058
+ }
117059
+ } catch (assertErr) {
117060
+ const assertMsg = assertErr instanceof Error ? assertErr.message : String(assertErr);
117061
+ console.warn(`[lean-turbo] unable to verify working tree cleanliness: ${assertMsg} — degrading to shared directory`);
117062
+ leanConfig.worktree_isolation = false;
117063
+ }
117064
+ }
116578
117065
  const lanePlan = LeanTurboRunner._internals.planLeanTurboLanes(this._directory, phaseNumber, { phases: plan.phases }, leanConfig);
116579
117066
  const degradedTasks = lanePlan.degradedTasks.map((d) => d.taskId);
116580
117067
  if (lanePlan.lanes.length === 0 && degradedTasks.length === 0 && lanePlan.serializedTasks.length === 0) {
@@ -116598,21 +117085,23 @@ class LeanTurboRunner {
116598
117085
  await this._withStateLock(() => this._updateDurableState(lanePlan));
116599
117086
  this._laneStatuses = new Map(lanePlan.lanes.map((lane) => [lane.laneId, { ...lane }]));
116600
117087
  const laneResults = [];
116601
- const results = await Promise.all(lanePlan.lanes.map((lane) => this._processLane(lane)));
117088
+ const results = await Promise.all(lanePlan.lanes.map((lane) => this._processLane(lane, leanConfig)));
116602
117089
  laneResults.push(...results);
117090
+ const mergeBackFailures = await this._sequentialWorktreeCleanup(laneResults, leanConfig);
116603
117091
  return {
116604
117092
  ok: true,
116605
117093
  lanes: laneResults,
116606
117094
  degradedTasks,
116607
- serializedTasks: lanePlan.serializedTasks
117095
+ serializedTasks: lanePlan.serializedTasks,
117096
+ mergeBackFailures: mergeBackFailures.length > 0 ? mergeBackFailures : undefined
116608
117097
  };
116609
117098
  }
116610
- async dispatchLane(lane, agentName) {
117099
+ async dispatchLane(lane, agentName, worktreeDirectory) {
116611
117100
  const session = this._sessionOps ?? this._client?.session;
116612
117101
  if (!session) {
116613
117102
  return { ok: false, error: "NO_CLIENT" };
116614
117103
  }
116615
- const dispatchPromise = this._doDispatch(session, lane, agentName);
117104
+ const dispatchPromise = this._doDispatch(session, lane, agentName, worktreeDirectory);
116616
117105
  const timeoutMs = LeanTurboRunner._internals.laneDispatchTimeoutMs;
116617
117106
  if (timeoutMs !== undefined && timeoutMs > 0) {
116618
117107
  const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Lane dispatch timed out after ${timeoutMs}ms`)), timeoutMs));
@@ -116643,10 +117132,11 @@ class LeanTurboRunner {
116643
117132
  }
116644
117133
  return dispatchPromise;
116645
117134
  }
116646
- async _doDispatch(session, lane, agentName) {
117135
+ async _doDispatch(session, lane, agentName, worktreeDirectory) {
116647
117136
  try {
117137
+ const effectiveDirectory = worktreeDirectory ?? this._directory;
116648
117138
  const createResult = await session.create({
116649
- query: { directory: this._directory }
117139
+ query: { directory: effectiveDirectory }
116650
117140
  });
116651
117141
  if (!createResult.data) {
116652
117142
  return {
@@ -116698,6 +117188,13 @@ class LeanTurboRunner {
116698
117188
  } catch {}
116699
117189
  }
116700
117190
  this._laneLockMap = {};
117191
+ for (const [_laneId, lane] of this._laneStatuses) {
117192
+ if (lane.worktreePath) {
117193
+ try {
117194
+ await LeanTurboRunner._internals.removeWorktree(lane.worktreePath, this._directory);
117195
+ } catch {}
117196
+ }
117197
+ }
116701
117198
  await this._withStateLock(async () => {
116702
117199
  const runState = LeanTurboRunner._internals.loadLeanTurboRunState(this._directory, this._sessionID);
116703
117200
  if (runState) {
@@ -116745,7 +117242,7 @@ class LeanTurboRunner {
116745
117242
  }
116746
117243
  return defaults;
116747
117244
  }
116748
- async _processLane(lane) {
117245
+ async _processLane(lane, leanConfig) {
116749
117246
  const laneInState = this._laneStatuses.get(lane.laneId);
116750
117247
  if (laneInState) {
116751
117248
  laneInState.status = "running";
@@ -116782,12 +117279,85 @@ class LeanTurboRunner {
116782
117279
  };
116783
117280
  }
116784
117281
  this._laneLockMap[lane.laneId] = [...lane.files];
116785
- const dispatchResult = await this.dispatchLane(lane, agent);
117282
+ let worktreeDirectory;
117283
+ if (leanConfig.worktree_isolation) {
117284
+ let provisionError;
117285
+ try {
117286
+ const provisionResult = await LeanTurboRunner._internals.provisionWorktree(this._directory, lane.laneId, this._sessionID, leanConfig);
117287
+ if ("worktreePath" in provisionResult) {
117288
+ worktreeDirectory = provisionResult.worktreePath;
117289
+ if (laneInState) {
117290
+ laneInState.worktreePath = provisionResult.worktreePath;
117291
+ laneInState.branchName = provisionResult.branchName;
117292
+ }
117293
+ await this._persistLaneWorktreeFields(lane.laneId, provisionResult.worktreePath, provisionResult.branchName);
117294
+ } else {
117295
+ provisionError = provisionResult.error;
117296
+ }
117297
+ } catch (provisionErr) {
117298
+ provisionError = provisionErr instanceof Error ? provisionErr.message : String(provisionErr);
117299
+ }
117300
+ if (provisionError) {
117301
+ if (isTransientProvisionError(provisionError)) {
117302
+ console.warn(`[lean-turbo] worktree provision failed for lane ${lane.laneId}: ${provisionError} — retrying once...`);
117303
+ await new Promise((r) => setTimeout(r, 100));
117304
+ try {
117305
+ const retryResult = await LeanTurboRunner._internals.provisionWorktree(this._directory, lane.laneId, this._sessionID, leanConfig);
117306
+ if ("worktreePath" in retryResult) {
117307
+ worktreeDirectory = retryResult.worktreePath;
117308
+ if (laneInState) {
117309
+ laneInState.worktreePath = retryResult.worktreePath;
117310
+ laneInState.branchName = retryResult.branchName;
117311
+ }
117312
+ await this._persistLaneWorktreeFields(lane.laneId, retryResult.worktreePath, retryResult.branchName);
117313
+ console.warn(`[lean-turbo] worktree provision retry succeeded for lane ${lane.laneId}`);
117314
+ provisionError = undefined;
117315
+ } else {
117316
+ provisionError = retryResult.error;
117317
+ console.warn(`[lean-turbo] worktree provision retry failed for lane ${lane.laneId}: ${retryResult.error}`);
117318
+ }
117319
+ } catch (retryErr) {
117320
+ const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
117321
+ console.warn(`[lean-turbo] worktree provision retry threw for lane ${lane.laneId}: ${retryMsg}`);
117322
+ }
117323
+ } else {
117324
+ console.warn(`[lean-turbo] worktree provision failed for lane ${lane.laneId}: ${provisionError}`);
117325
+ }
117326
+ }
117327
+ if (!worktreeDirectory) {
117328
+ const failMsg = `worktree provision failed: ${provisionError ?? "unknown error"}`;
117329
+ try {
117330
+ await LeanTurboRunner._internals.releaseLaneLocks(this._directory, lane.laneId);
117331
+ } catch {}
117332
+ delete this._laneLockMap[lane.laneId];
117333
+ if (laneInState) {
117334
+ laneInState.status = "failed";
117335
+ laneInState.error = failMsg;
117336
+ }
117337
+ await this._updateDurableStateLaneStatus(lane.laneId, "failed");
117338
+ await this._writeLaneEvidenceSafely(lane, "failed", {
117339
+ status: "failed",
117340
+ error: failMsg,
117341
+ agent
117342
+ });
117343
+ return {
117344
+ laneId: lane.laneId,
117345
+ status: "failed",
117346
+ taskIds: lane.taskIds,
117347
+ agent,
117348
+ error: failMsg
117349
+ };
117350
+ }
117351
+ }
117352
+ const dispatchResult = await this.dispatchLane(lane, agent, worktreeDirectory);
116786
117353
  if (!dispatchResult.ok) {
116787
117354
  try {
116788
117355
  await LeanTurboRunner._internals.releaseLaneLocks(this._directory, lane.laneId);
116789
117356
  } catch {}
116790
117357
  delete this._laneLockMap[lane.laneId];
117358
+ if (worktreeDirectory && laneInState) {
117359
+ laneInState._failureCleanupPending = true;
117360
+ }
116791
117361
  if (laneInState) {
116792
117362
  laneInState.status = "failed";
116793
117363
  laneInState.error = dispatchResult.error;
@@ -116832,6 +117402,69 @@ class LeanTurboRunner {
116832
117402
  sessionId: dispatchResult.sessionId
116833
117403
  };
116834
117404
  }
117405
+ async _sequentialWorktreeCleanup(laneResults, leanConfig) {
117406
+ const mergeBackFailures = [];
117407
+ for (const lr of laneResults) {
117408
+ const laneInState = this._laneStatuses.get(lr.laneId);
117409
+ if (!laneInState?.worktreePath)
117410
+ continue;
117411
+ let needsPostMergeCleanup = false;
117412
+ if (lr.status === "completed") {
117413
+ if (!laneInState.branchName)
117414
+ continue;
117415
+ try {
117416
+ const strategy = LeanTurboRunner._internals.getMergeStrategy(leanConfig);
117417
+ const mergeResult = await LeanTurboRunner._internals.mergeLaneBranch(this._directory, laneInState.branchName, strategy);
117418
+ if ("merged" in mergeResult && mergeResult.merged) {
117419
+ needsPostMergeCleanup = true;
117420
+ } else if ("conflict" in mergeResult && mergeResult.conflict) {
117421
+ const failureInfo = {
117422
+ laneId: lr.laneId,
117423
+ reason: mergeResult.message || "merge conflict",
117424
+ conflictFiles: mergeResult.files
117425
+ };
117426
+ mergeBackFailures.push(failureInfo);
117427
+ lr.mergeBackFailure = failureInfo;
117428
+ console.warn(`[lean-turbo] merge-back CONFLICT for lane ${lr.laneId}: ${failureInfo.reason} — worktree preserved at ${laneInState.worktreePath} for manual recovery`);
117429
+ continue;
117430
+ } else if ("error" in mergeResult && mergeResult.error) {
117431
+ const failureInfo = {
117432
+ laneId: lr.laneId,
117433
+ reason: mergeResult.error
117434
+ };
117435
+ mergeBackFailures.push(failureInfo);
117436
+ lr.mergeBackFailure = failureInfo;
117437
+ console.warn(`[lean-turbo] merge-back ERROR for lane ${lr.laneId}: ${failureInfo.reason} — worktree preserved at ${laneInState.worktreePath} for manual recovery`);
117438
+ continue;
117439
+ }
117440
+ } catch (err2) {
117441
+ const errMsg = err2 instanceof Error ? err2.message : String(err2);
117442
+ const failureInfo = {
117443
+ laneId: lr.laneId,
117444
+ reason: errMsg
117445
+ };
117446
+ mergeBackFailures.push(failureInfo);
117447
+ lr.mergeBackFailure = failureInfo;
117448
+ console.warn(`[lean-turbo] merge-back EXCEPTION for lane ${lr.laneId}: ${errMsg} — worktree preserved at ${laneInState.worktreePath} for manual recovery`);
117449
+ continue;
117450
+ }
117451
+ } else if (lr.status === "failed" && laneInState._failureCleanupPending) {
117452
+ try {
117453
+ const strategy = LeanTurboRunner._internals.getMergeStrategy(leanConfig);
117454
+ await LeanTurboRunner._internals.attemptMergeBackFromDirty(laneInState.worktreePath, laneInState.branchName ?? `swarm-lane/${this._sessionID}/${lr.laneId}`, this._directory, strategy);
117455
+ } catch {}
117456
+ }
117457
+ try {
117458
+ await LeanTurboRunner._internals.removeWorktree(laneInState.worktreePath, this._directory);
117459
+ } catch {}
117460
+ if (needsPostMergeCleanup && laneInState.branchName) {
117461
+ try {
117462
+ await LeanTurboRunner._internals.postMergeCleanup(this._directory, laneInState.branchName);
117463
+ } catch {}
117464
+ }
117465
+ }
117466
+ return mergeBackFailures;
117467
+ }
116835
117468
  _selectNextAgent() {
116836
117469
  if (this._availableAgents.length === 0) {
116837
117470
  return "coder";
@@ -116925,6 +117558,21 @@ ${fileList}
116925
117558
  LeanTurboRunner._internals.saveLeanTurboRunState(this._directory, runState);
116926
117559
  } catch {}
116927
117560
  }
117561
+ async _persistLaneWorktreeFields(laneId, worktreePath, branchName) {
117562
+ await this._withStateLock(async () => {
117563
+ try {
117564
+ const runState = LeanTurboRunner._internals.loadLeanTurboRunState(this._directory, this._sessionID);
117565
+ if (!runState)
117566
+ return;
117567
+ const lane = runState.lanes.find((l) => l.laneId === laneId);
117568
+ if (lane) {
117569
+ lane.worktreePath = worktreePath;
117570
+ lane.branchName = branchName;
117571
+ LeanTurboRunner._internals.saveLeanTurboRunState(this._directory, runState);
117572
+ }
117573
+ } catch {}
117574
+ });
117575
+ }
116928
117576
  async _updateDurableStateLaneStatus(laneId, status) {
116929
117577
  await this._withStateLock(async () => {
116930
117578
  try {
@@ -116950,7 +117598,7 @@ ${fileList}
116950
117598
 
116951
117599
  // src/tools/lean-turbo-run-phase.ts
116952
117600
  init_create_tool();
116953
- var _internals62 = {
117601
+ var _internals64 = {
116954
117602
  LeanTurboRunner,
116955
117603
  loadPluginConfigWithMeta
116956
117604
  };
@@ -116960,9 +117608,9 @@ async function executeLeanTurboRunPhase(args2) {
116960
117608
  let runError = null;
116961
117609
  let runner = null;
116962
117610
  try {
116963
- const { config: config3 } = _internals62.loadPluginConfigWithMeta(directory);
117611
+ const { config: config3 } = _internals64.loadPluginConfigWithMeta(directory);
116964
117612
  const leanConfig = config3.turbo?.strategy === "lean" ? config3.turbo.lean : undefined;
116965
- runner = new _internals62.LeanTurboRunner({
117613
+ runner = new _internals64.LeanTurboRunner({
116966
117614
  directory,
116967
117615
  sessionID,
116968
117616
  opencodeClient: swarmState.opencodeClient ?? null,
@@ -116995,6 +117643,7 @@ async function executeLeanTurboRunPhase(args2) {
116995
117643
  lanes: runResult.lanes,
116996
117644
  degradedTasks: runResult.degradedTasks,
116997
117645
  serializedTasks: runResult.serializedTasks,
117646
+ mergeBackFailures: runResult.mergeBackFailures,
116998
117647
  reason: runResult.reason
116999
117648
  };
117000
117649
  }
@@ -117121,7 +117770,7 @@ init_lint();
117121
117770
  init_spec_schema();
117122
117771
  init_create_tool();
117123
117772
  import * as fs99 from "node:fs";
117124
- import * as path137 from "node:path";
117773
+ import * as path138 from "node:path";
117125
117774
  var SPEC_FILE_NAME = "spec.md";
117126
117775
  var SWARM_DIR2 = ".swarm";
117127
117776
  var OBLIGATION_KEYWORDS = ["MUST", "SHALL", "SHOULD", "MAY"];
@@ -117174,7 +117823,7 @@ var lint_spec = createSwarmTool({
117174
117823
  async execute(_args, directory) {
117175
117824
  const errors5 = [];
117176
117825
  const warnings = [];
117177
- const specPath = path137.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
117826
+ const specPath = path138.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
117178
117827
  if (!fs99.existsSync(specPath)) {
117179
117828
  const result2 = {
117180
117829
  valid: false,
@@ -117246,12 +117895,12 @@ var lint_spec = createSwarmTool({
117246
117895
  // src/tools/mutation-test.ts
117247
117896
  init_zod();
117248
117897
  import * as fs100 from "node:fs";
117249
- import * as path139 from "node:path";
117898
+ import * as path140 from "node:path";
117250
117899
 
117251
117900
  // src/mutation/engine.ts
117252
117901
  import { spawnSync as spawnSync9 } from "node:child_process";
117253
117902
  import { unlinkSync as unlinkSync19, writeFileSync as writeFileSync26 } from "node:fs";
117254
- import * as path138 from "node:path";
117903
+ import * as path139 from "node:path";
117255
117904
 
117256
117905
  // src/mutation/equivalence.ts
117257
117906
  function isStaticallyEquivalent(originalCode, mutatedCode) {
@@ -117323,7 +117972,7 @@ function isStaticallyEquivalent(originalCode, mutatedCode) {
117323
117972
  const strippedMutated = stripCode(mutatedCode);
117324
117973
  return strippedOriginal === strippedMutated;
117325
117974
  }
117326
- var _internals63 = {
117975
+ var _internals65 = {
117327
117976
  isStaticallyEquivalent,
117328
117977
  checkEquivalence,
117329
117978
  batchCheckEquivalence
@@ -117363,7 +118012,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
117363
118012
  const results = [];
117364
118013
  for (const { patch, originalCode, mutatedCode } of patches) {
117365
118014
  try {
117366
- const result = await _internals63.checkEquivalence(patch, originalCode, mutatedCode, llmJudge);
118015
+ const result = await _internals65.checkEquivalence(patch, originalCode, mutatedCode, llmJudge);
117367
118016
  results.push(result);
117368
118017
  } catch (err2) {
117369
118018
  results.push({
@@ -117382,7 +118031,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
117382
118031
  var MUTATION_TIMEOUT_MS = 30000;
117383
118032
  var TOTAL_BUDGET_MS = 300000;
117384
118033
  var GIT_APPLY_TIMEOUT_MS = 5000;
117385
- var _internals64 = {
118034
+ var _internals66 = {
117386
118035
  executeMutation,
117387
118036
  computeReport,
117388
118037
  executeMutationSuite,
@@ -117397,7 +118046,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
117397
118046
  let patchFile;
117398
118047
  try {
117399
118048
  const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
117400
- patchFile = path138.join(workingDir, `.mutation_patch_${safeId2}.diff`);
118049
+ patchFile = path139.join(workingDir, `.mutation_patch_${safeId2}.diff`);
117401
118050
  try {
117402
118051
  writeFileSync26(patchFile, patch.patch);
117403
118052
  } catch (writeErr) {
@@ -117414,7 +118063,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
117414
118063
  };
117415
118064
  }
117416
118065
  try {
117417
- const applyResult = _internals64.spawnSync("git", ["apply", "--", patchFile], {
118066
+ const applyResult = _internals66.spawnSync("git", ["apply", "--", patchFile], {
117418
118067
  cwd: workingDir,
117419
118068
  timeout: GIT_APPLY_TIMEOUT_MS,
117420
118069
  stdio: "pipe"
@@ -117443,7 +118092,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
117443
118092
  }
117444
118093
  let testPassed = false;
117445
118094
  try {
117446
- const spawnResult = _internals64.spawnSync(testCommand[0], testCommand.slice(1), {
118095
+ const spawnResult = _internals66.spawnSync(testCommand[0], testCommand.slice(1), {
117447
118096
  cwd: workingDir,
117448
118097
  timeout: MUTATION_TIMEOUT_MS,
117449
118098
  stdio: "pipe"
@@ -117476,7 +118125,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
117476
118125
  } finally {
117477
118126
  if (patchFile) {
117478
118127
  try {
117479
- const revertResult = _internals64.spawnSync("git", ["apply", "-R", "--", patchFile], {
118128
+ const revertResult = _internals66.spawnSync("git", ["apply", "-R", "--", patchFile], {
117480
118129
  cwd: workingDir,
117481
118130
  timeout: GIT_APPLY_TIMEOUT_MS,
117482
118131
  stdio: "pipe"
@@ -117669,7 +118318,7 @@ async function executeMutationSuite(patches, testCommand, testFiles, workingDir,
117669
118318
  }
117670
118319
 
117671
118320
  // src/mutation/gate.ts
117672
- var _internals65 = {
118321
+ var _internals67 = {
117673
118322
  evaluateMutationGate,
117674
118323
  buildTestImprovementPrompt,
117675
118324
  buildMessage
@@ -117690,8 +118339,8 @@ function evaluateMutationGate(report, passThreshold = PASS_THRESHOLD, warnThresh
117690
118339
  } else {
117691
118340
  verdict = "fail";
117692
118341
  }
117693
- const testImprovementPrompt = _internals65.buildTestImprovementPrompt(report, passThreshold, verdict);
117694
- const message = _internals65.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
118342
+ const testImprovementPrompt = _internals67.buildTestImprovementPrompt(report, passThreshold, verdict);
118343
+ const message = _internals67.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
117695
118344
  return {
117696
118345
  verdict,
117697
118346
  killRate: report.killRate,
@@ -117801,7 +118450,7 @@ var mutation_test = createSwarmTool({
117801
118450
  ];
117802
118451
  for (const filePath of uniquePaths) {
117803
118452
  try {
117804
- const resolvedPath = path139.resolve(cwd, filePath);
118453
+ const resolvedPath = path140.resolve(cwd, filePath);
117805
118454
  sourceFiles.set(filePath, fs100.readFileSync(resolvedPath, "utf-8"));
117806
118455
  } catch {}
117807
118456
  }
@@ -117823,22 +118472,22 @@ init_config();
117823
118472
  init_schema();
117824
118473
  init_manager2();
117825
118474
  import * as fs110 from "node:fs";
117826
- import * as path149 from "node:path";
118475
+ import * as path150 from "node:path";
117827
118476
 
117828
118477
  // src/full-auto/phase-approval.ts
117829
118478
  init_utils2();
117830
118479
  init_logger();
117831
118480
  init_state2();
117832
118481
  import * as fs101 from "node:fs";
117833
- import * as path140 from "node:path";
118482
+ import * as path141 from "node:path";
117834
118483
  var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
117835
118484
  function readEvidenceDir(directory, phase) {
117836
118485
  try {
117837
- const dirPath = validateSwarmPath(directory, path140.posix.join("evidence", String(phase)));
118486
+ const dirPath = validateSwarmPath(directory, path141.posix.join("evidence", String(phase)));
117838
118487
  if (!fs101.existsSync(dirPath))
117839
118488
  return [];
117840
118489
  const entries = fs101.readdirSync(dirPath);
117841
- return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path140.join(dirPath, e));
118490
+ return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path141.join(dirPath, e));
117842
118491
  } catch {
117843
118492
  return [];
117844
118493
  }
@@ -117979,16 +118628,16 @@ init_plan_schema();
117979
118628
  init_ledger();
117980
118629
  init_manager();
117981
118630
  import * as fs102 from "node:fs";
117982
- import * as path141 from "node:path";
118631
+ import * as path142 from "node:path";
117983
118632
  async function writeCheckpoint(directory) {
117984
118633
  try {
117985
118634
  const plan = await loadPlan(directory);
117986
118635
  if (!plan)
117987
118636
  return;
117988
- const swarmDir = path141.join(directory, ".swarm");
118637
+ const swarmDir = path142.join(directory, ".swarm");
117989
118638
  fs102.mkdirSync(swarmDir, { recursive: true });
117990
- const jsonPath = path141.join(swarmDir, "SWARM_PLAN.json");
117991
- const mdPath = path141.join(swarmDir, "SWARM_PLAN.md");
118639
+ const jsonPath = path142.join(swarmDir, "SWARM_PLAN.json");
118640
+ const mdPath = path142.join(swarmDir, "SWARM_PLAN.md");
117992
118641
  fs102.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
117993
118642
  const md = derivePlanMarkdown(plan);
117994
118643
  fs102.writeFileSync(mdPath, md, "utf8");
@@ -118007,7 +118656,7 @@ init_telemetry();
118007
118656
  // src/turbo/lean/phase-ready.ts
118008
118657
  init_file_locks();
118009
118658
  import * as fs103 from "node:fs";
118010
- import * as path142 from "node:path";
118659
+ import * as path143 from "node:path";
118011
118660
  init_state3();
118012
118661
  var DEFAULT_CONFIG3 = {
118013
118662
  phase_reviewer: true,
@@ -118016,7 +118665,7 @@ var DEFAULT_CONFIG3 = {
118016
118665
  };
118017
118666
  function defaultReadPlanJson(dir) {
118018
118667
  try {
118019
- const planPath = path142.join(dir, ".swarm", "plan.json");
118668
+ const planPath = path143.join(dir, ".swarm", "plan.json");
118020
118669
  if (!fs103.existsSync(planPath))
118021
118670
  return null;
118022
118671
  const raw = fs103.readFileSync(planPath, "utf-8");
@@ -118031,7 +118680,7 @@ function defaultReadPlanJson(dir) {
118031
118680
  }
118032
118681
  function readReviewerEvidenceFromFile(directory, phase) {
118033
118682
  try {
118034
- const evidencePath = path142.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
118683
+ const evidencePath = path143.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
118035
118684
  if (!fs103.existsSync(evidencePath)) {
118036
118685
  return null;
118037
118686
  }
@@ -118051,7 +118700,7 @@ function readReviewerEvidenceFromFile(directory, phase) {
118051
118700
  }
118052
118701
  function readCriticEvidenceFromFile(directory, phase) {
118053
118702
  try {
118054
- const evidencePath = path142.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
118703
+ const evidencePath = path143.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
118055
118704
  if (!fs103.existsSync(evidencePath)) {
118056
118705
  return null;
118057
118706
  }
@@ -118070,7 +118719,7 @@ function readCriticEvidenceFromFile(directory, phase) {
118070
118719
  }
118071
118720
  }
118072
118721
  function listLaneEvidenceSync(directory, phase) {
118073
- const evidenceDir = path142.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
118722
+ const evidenceDir = path143.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
118074
118723
  let entries;
118075
118724
  try {
118076
118725
  entries = fs103.readdirSync(evidenceDir);
@@ -118086,7 +118735,7 @@ function listLaneEvidenceSync(directory, phase) {
118086
118735
  }
118087
118736
  return laneIds;
118088
118737
  }
118089
- var _internals66 = {
118738
+ var _internals68 = {
118090
118739
  listActiveLocks,
118091
118740
  readPersisted: readPersisted2,
118092
118741
  readPlanJson: defaultReadPlanJson,
@@ -118140,14 +118789,14 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
118140
118789
  ...DEFAULT_CONFIG3,
118141
118790
  ...actualConfig
118142
118791
  };
118143
- const statePath = path142.join(directory, ".swarm", "turbo-state.json");
118792
+ const statePath = path143.join(directory, ".swarm", "turbo-state.json");
118144
118793
  if (!fs103.existsSync(statePath)) {
118145
118794
  return {
118146
118795
  ok: false,
118147
118796
  reason: "Lean Turbo state unreadable or missing"
118148
118797
  };
118149
118798
  }
118150
- const persisted = _internals66.readPersisted(directory);
118799
+ const persisted = _internals68.readPersisted(directory);
118151
118800
  if (!persisted) {
118152
118801
  return {
118153
118802
  ok: false,
@@ -118211,7 +118860,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
118211
118860
  }
118212
118861
  }
118213
118862
  if (runState.lanes.length > 0) {
118214
- const evidenceLaneIds = new Set(_internals66.listLaneEvidenceSync(directory, phase));
118863
+ const evidenceLaneIds = new Set(_internals68.listLaneEvidenceSync(directory, phase));
118215
118864
  for (const lane of runState.lanes) {
118216
118865
  if ((lane.status === "completed" || lane.status === "failed") && !evidenceLaneIds.has(lane.laneId)) {
118217
118866
  return {
@@ -118221,7 +118870,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
118221
118870
  }
118222
118871
  }
118223
118872
  }
118224
- const activeLocks = _internals66.listActiveLocks(directory);
118873
+ const activeLocks = _internals68.listActiveLocks(directory);
118225
118874
  const phaseLaneIds = new Set(laneIds);
118226
118875
  for (const lock of activeLocks) {
118227
118876
  if (lock.laneId && phaseLaneIds.has(lock.laneId)) {
@@ -118241,7 +118890,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
118241
118890
  }
118242
118891
  const serialDegradedTasks = runState.degradedTasks.filter((dt) => !laneTaskIds.has(dt.taskId));
118243
118892
  if (serialDegradedTasks.length > 0) {
118244
- const plan = _internals66.readPlanJson(directory);
118893
+ const plan = _internals68.readPlanJson(directory);
118245
118894
  if (!plan) {
118246
118895
  return {
118247
118896
  ok: false,
@@ -118285,7 +118934,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
118285
118934
  }
118286
118935
  const serializedTasks = runState.serializedTasks;
118287
118936
  if (Array.isArray(serializedTasks) && serializedTasks.length > 0) {
118288
- const plan = _internals66.readPlanJson(directory);
118937
+ const plan = _internals68.readPlanJson(directory);
118289
118938
  if (!plan) {
118290
118939
  return {
118291
118940
  ok: false,
@@ -118328,7 +118977,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
118328
118977
  }
118329
118978
  }
118330
118979
  if (mergedConfig.integrated_diff_required) {
118331
- const evidencePath = path142.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
118980
+ const evidencePath = path143.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
118332
118981
  let hasDiff = false;
118333
118982
  try {
118334
118983
  const content = fs103.readFileSync(evidencePath, "utf-8");
@@ -118344,7 +118993,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
118344
118993
  }
118345
118994
  let reviewerVerdict = runState.lastReviewerVerdict;
118346
118995
  if (!reviewerVerdict) {
118347
- const evidence = _internals66.readReviewerEvidence(directory, phase);
118996
+ const evidence = _internals68.readReviewerEvidence(directory, phase);
118348
118997
  reviewerVerdict = evidence?.verdict ?? undefined;
118349
118998
  }
118350
118999
  if (mergedConfig.phase_reviewer) {
@@ -118357,7 +119006,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
118357
119006
  }
118358
119007
  let criticVerdict = runState.lastCriticVerdict;
118359
119008
  if (!criticVerdict) {
118360
- const evidence = _internals66.readCriticEvidence(directory, phase);
119009
+ const evidence = _internals68.readCriticEvidence(directory, phase);
118361
119010
  criticVerdict = evidence?.verdict ?? undefined;
118362
119011
  }
118363
119012
  if (mergedConfig.phase_critic) {
@@ -118480,13 +119129,13 @@ init_qa_gate_profile();
118480
119129
  init_manager();
118481
119130
  init_state();
118482
119131
  import * as fs104 from "node:fs";
118483
- import * as path143 from "node:path";
119132
+ import * as path144 from "node:path";
118484
119133
  async function runDriftGate(ctx) {
118485
119134
  const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
118486
119135
  let driftCheckEnabled = true;
118487
119136
  let driftHasSpecMd = false;
118488
119137
  try {
118489
- const specMdPath = path143.join(dir, ".swarm", "spec.md");
119138
+ const specMdPath = path144.join(dir, ".swarm", "spec.md");
118490
119139
  driftHasSpecMd = fs104.existsSync(specMdPath);
118491
119140
  const gatePlan = await loadPlan(dir);
118492
119141
  if (gatePlan) {
@@ -118514,7 +119163,7 @@ async function runDriftGate(ctx) {
118514
119163
  }
118515
119164
  let phaseType;
118516
119165
  try {
118517
- const planPath = path143.join(dir, ".swarm", "plan.json");
119166
+ const planPath = path144.join(dir, ".swarm", "plan.json");
118518
119167
  if (fs104.existsSync(planPath)) {
118519
119168
  const planRaw = fs104.readFileSync(planPath, "utf-8");
118520
119169
  const plan = JSON.parse(planRaw);
@@ -118533,7 +119182,7 @@ async function runDriftGate(ctx) {
118533
119182
  };
118534
119183
  }
118535
119184
  try {
118536
- const driftEvidencePath = path143.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
119185
+ const driftEvidencePath = path144.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
118537
119186
  let driftVerdictFound = false;
118538
119187
  let driftVerdictApproved = false;
118539
119188
  try {
@@ -118569,7 +119218,7 @@ async function runDriftGate(ctx) {
118569
119218
  let incompleteTaskCount = 0;
118570
119219
  let planParseable = false;
118571
119220
  try {
118572
- const planPath = path143.join(dir, ".swarm", "plan.json");
119221
+ const planPath = path144.join(dir, ".swarm", "plan.json");
118573
119222
  if (fs104.existsSync(planPath)) {
118574
119223
  const planRaw = fs104.readFileSync(planPath, "utf-8");
118575
119224
  const plan = JSON.parse(planRaw);
@@ -118651,7 +119300,7 @@ init_qa_gate_profile();
118651
119300
  init_manager();
118652
119301
  init_state();
118653
119302
  import * as fs105 from "node:fs";
118654
- import * as path144 from "node:path";
119303
+ import * as path145 from "node:path";
118655
119304
  async function runFinalCouncilGate(ctx) {
118656
119305
  const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
118657
119306
  let finalCouncilEnabled = false;
@@ -118669,7 +119318,7 @@ async function runFinalCouncilGate(ctx) {
118669
119318
  const effective = getEffectiveGates(profile, overrides);
118670
119319
  if (effective.final_council === true) {
118671
119320
  finalCouncilEnabled = true;
118672
- const fcPath = path144.join(dir, ".swarm", "evidence", "final-council.json");
119321
+ const fcPath = path145.join(dir, ".swarm", "evidence", "final-council.json");
118673
119322
  let fcVerdictFound = false;
118674
119323
  let _fcVerdict;
118675
119324
  try {
@@ -118810,7 +119459,7 @@ init_qa_gate_profile();
118810
119459
  init_manager();
118811
119460
  init_state();
118812
119461
  import * as fs106 from "node:fs";
118813
- import * as path145 from "node:path";
119462
+ import * as path146 from "node:path";
118814
119463
  async function runHallucinationGate(ctx) {
118815
119464
  const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
118816
119465
  try {
@@ -118823,7 +119472,7 @@ async function runHallucinationGate(ctx) {
118823
119472
  const overrides = session?.qaGateSessionOverrides ?? {};
118824
119473
  const effective = getEffectiveGates(profile, overrides);
118825
119474
  if (effective.hallucination_guard === true) {
118826
- const hgPath = path145.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
119475
+ const hgPath = path146.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
118827
119476
  let hgVerdictFound = false;
118828
119477
  let hgVerdictApproved = false;
118829
119478
  try {
@@ -118886,7 +119535,7 @@ init_qa_gate_profile();
118886
119535
  init_manager();
118887
119536
  init_state();
118888
119537
  import * as fs107 from "node:fs";
118889
- import * as path146 from "node:path";
119538
+ import * as path147 from "node:path";
118890
119539
  async function runMutationGate(ctx) {
118891
119540
  const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
118892
119541
  try {
@@ -118899,7 +119548,7 @@ async function runMutationGate(ctx) {
118899
119548
  const overrides = session?.qaGateSessionOverrides ?? {};
118900
119549
  const effective = getEffectiveGates(profile, overrides);
118901
119550
  if (effective.mutation_test === true) {
118902
- const mgPath = path146.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
119551
+ const mgPath = path147.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
118903
119552
  let mgVerdictFound = false;
118904
119553
  let mgVerdict;
118905
119554
  try {
@@ -118962,7 +119611,7 @@ init_qa_gate_profile();
118962
119611
  init_manager();
118963
119612
  init_state();
118964
119613
  import * as fs108 from "node:fs";
118965
- import * as path147 from "node:path";
119614
+ import * as path148 from "node:path";
118966
119615
  async function runPhaseCouncilGate(ctx) {
118967
119616
  const { phase, dir, sessionID, pluginConfig, agentsDispatched, safeWarn } = ctx;
118968
119617
  let councilModeEnabled = false;
@@ -118977,7 +119626,7 @@ async function runPhaseCouncilGate(ctx) {
118977
119626
  const effective = getEffectiveGates(profile, overrides);
118978
119627
  if (effective.council_mode === true) {
118979
119628
  councilModeEnabled = true;
118980
- const pcPath = path147.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
119629
+ const pcPath = path148.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
118981
119630
  let pcVerdictFound = false;
118982
119631
  let _pcVerdict;
118983
119632
  let pcQuorumSize;
@@ -119469,7 +120118,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
119469
120118
  phase_critic: leanConfig.phase_critic,
119470
120119
  integrated_diff_required: leanConfig.integrated_diff_required
119471
120120
  } : undefined;
119472
- const leanCheck = _internals66.verifyLeanTurboPhaseReady(dir, phase, sessionID, leanPhaseReadyConfig);
120121
+ const leanCheck = _internals68.verifyLeanTurboPhaseReady(dir, phase, sessionID, leanPhaseReadyConfig);
119473
120122
  if (!leanCheck.ok) {
119474
120123
  return JSON.stringify({
119475
120124
  success: false,
@@ -119492,7 +120141,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
119492
120141
  }
119493
120142
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
119494
120143
  try {
119495
- const projectName = path149.basename(dir);
120144
+ const projectName = path150.basename(dir);
119496
120145
  const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
119497
120146
  if (curationResult) {
119498
120147
  const sessionState = swarmState.agentSessions.get(sessionID);
@@ -119935,7 +120584,7 @@ init_utils();
119935
120584
  init_bun_compat();
119936
120585
  init_create_tool();
119937
120586
  import * as fs111 from "node:fs";
119938
- import * as path150 from "node:path";
120587
+ import * as path151 from "node:path";
119939
120588
  var MAX_OUTPUT_BYTES6 = 52428800;
119940
120589
  var AUDIT_TIMEOUT_MS = 120000;
119941
120590
  function isValidEcosystem(value) {
@@ -119963,16 +120612,16 @@ function validateArgs3(args2) {
119963
120612
  function detectEcosystems(directory) {
119964
120613
  const ecosystems = [];
119965
120614
  const cwd = directory;
119966
- if (fs111.existsSync(path150.join(cwd, "package.json"))) {
120615
+ if (fs111.existsSync(path151.join(cwd, "package.json"))) {
119967
120616
  ecosystems.push("npm");
119968
120617
  }
119969
- if (fs111.existsSync(path150.join(cwd, "pyproject.toml")) || fs111.existsSync(path150.join(cwd, "requirements.txt"))) {
120618
+ if (fs111.existsSync(path151.join(cwd, "pyproject.toml")) || fs111.existsSync(path151.join(cwd, "requirements.txt"))) {
119970
120619
  ecosystems.push("pip");
119971
120620
  }
119972
- if (fs111.existsSync(path150.join(cwd, "Cargo.toml"))) {
120621
+ if (fs111.existsSync(path151.join(cwd, "Cargo.toml"))) {
119973
120622
  ecosystems.push("cargo");
119974
120623
  }
119975
- if (fs111.existsSync(path150.join(cwd, "go.mod"))) {
120624
+ if (fs111.existsSync(path151.join(cwd, "go.mod"))) {
119976
120625
  ecosystems.push("go");
119977
120626
  }
119978
120627
  try {
@@ -119981,13 +120630,13 @@ function detectEcosystems(directory) {
119981
120630
  ecosystems.push("dotnet");
119982
120631
  }
119983
120632
  } catch {}
119984
- if (fs111.existsSync(path150.join(cwd, "Gemfile")) || fs111.existsSync(path150.join(cwd, "Gemfile.lock"))) {
120633
+ if (fs111.existsSync(path151.join(cwd, "Gemfile")) || fs111.existsSync(path151.join(cwd, "Gemfile.lock"))) {
119985
120634
  ecosystems.push("ruby");
119986
120635
  }
119987
- if (fs111.existsSync(path150.join(cwd, "pubspec.yaml"))) {
120636
+ if (fs111.existsSync(path151.join(cwd, "pubspec.yaml"))) {
119988
120637
  ecosystems.push("dart");
119989
120638
  }
119990
- if (fs111.existsSync(path150.join(cwd, "composer.lock"))) {
120639
+ if (fs111.existsSync(path151.join(cwd, "composer.lock"))) {
119991
120640
  ecosystems.push("composer");
119992
120641
  }
119993
120642
  return ecosystems;
@@ -120000,7 +120649,7 @@ async function runNpmAudit(directory) {
120000
120649
  stderr: "pipe",
120001
120650
  cwd: directory
120002
120651
  });
120003
- const timeoutPromise = new Promise((resolve51) => setTimeout(() => resolve51("timeout"), AUDIT_TIMEOUT_MS));
120652
+ const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
120004
120653
  const result = await Promise.race([
120005
120654
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
120006
120655
  timeoutPromise
@@ -120120,7 +120769,7 @@ async function runPipAudit(directory) {
120120
120769
  stderr: "pipe",
120121
120770
  cwd: directory
120122
120771
  });
120123
- const timeoutPromise = new Promise((resolve51) => setTimeout(() => resolve51("timeout"), AUDIT_TIMEOUT_MS));
120772
+ const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
120124
120773
  const result = await Promise.race([
120125
120774
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
120126
120775
  timeoutPromise
@@ -120248,7 +120897,7 @@ async function runCargoAudit(directory) {
120248
120897
  stderr: "pipe",
120249
120898
  cwd: directory
120250
120899
  });
120251
- const timeoutPromise = new Promise((resolve51) => setTimeout(() => resolve51("timeout"), AUDIT_TIMEOUT_MS));
120900
+ const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
120252
120901
  const result = await Promise.race([
120253
120902
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
120254
120903
  timeoutPromise
@@ -120372,7 +121021,7 @@ async function runGoAudit(directory) {
120372
121021
  stderr: "pipe",
120373
121022
  cwd: directory
120374
121023
  });
120375
- const timeoutPromise = new Promise((resolve51) => setTimeout(() => resolve51("timeout"), AUDIT_TIMEOUT_MS));
121024
+ const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
120376
121025
  const result = await Promise.race([
120377
121026
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
120378
121027
  timeoutPromise
@@ -120505,7 +121154,7 @@ async function runDotnetAudit(directory) {
120505
121154
  stderr: "pipe",
120506
121155
  cwd: directory
120507
121156
  });
120508
- const timeoutPromise = new Promise((resolve51) => setTimeout(() => resolve51("timeout"), AUDIT_TIMEOUT_MS));
121157
+ const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
120509
121158
  const result = await Promise.race([
120510
121159
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
120511
121160
  timeoutPromise
@@ -120621,7 +121270,7 @@ async function runBundleAudit(directory) {
120621
121270
  stderr: "pipe",
120622
121271
  cwd: directory
120623
121272
  });
120624
- const timeoutPromise = new Promise((resolve51) => setTimeout(() => resolve51("timeout"), AUDIT_TIMEOUT_MS));
121273
+ const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
120625
121274
  const result = await Promise.race([
120626
121275
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
120627
121276
  timeoutPromise
@@ -120766,7 +121415,7 @@ async function runDartAudit(directory) {
120766
121415
  stderr: "pipe",
120767
121416
  cwd: directory
120768
121417
  });
120769
- const timeoutPromise = new Promise((resolve51) => setTimeout(() => resolve51("timeout"), AUDIT_TIMEOUT_MS));
121418
+ const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
120770
121419
  const result = await Promise.race([
120771
121420
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
120772
121421
  timeoutPromise
@@ -120881,7 +121530,7 @@ async function runComposerAudit(directory) {
120881
121530
  stderr: "pipe",
120882
121531
  cwd: directory
120883
121532
  });
120884
- const timeoutPromise = new Promise((resolve51) => setTimeout(() => resolve51("timeout"), AUDIT_TIMEOUT_MS));
121533
+ const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
120885
121534
  const result = await Promise.race([
120886
121535
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
120887
121536
  timeoutPromise
@@ -121124,7 +121773,7 @@ var pkg_audit = createSwarmTool({
121124
121773
  init_zod();
121125
121774
  init_manager2();
121126
121775
  import * as fs112 from "node:fs";
121127
- import * as path151 from "node:path";
121776
+ import * as path152 from "node:path";
121128
121777
  init_utils();
121129
121778
  init_create_tool();
121130
121779
  var MAX_FILE_SIZE = 1024 * 1024;
@@ -121247,7 +121896,7 @@ function isScaffoldFile(filePath) {
121247
121896
  if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
121248
121897
  return true;
121249
121898
  }
121250
- const filename = path151.basename(filePath);
121899
+ const filename = path152.basename(filePath);
121251
121900
  if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
121252
121901
  return true;
121253
121902
  }
@@ -121264,7 +121913,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
121264
121913
  if (regex.test(normalizedPath)) {
121265
121914
  return true;
121266
121915
  }
121267
- const filename = path151.basename(filePath);
121916
+ const filename = path152.basename(filePath);
121268
121917
  const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
121269
121918
  if (filenameRegex.test(filename)) {
121270
121919
  return true;
@@ -121273,7 +121922,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
121273
121922
  return false;
121274
121923
  }
121275
121924
  function isParserSupported(filePath) {
121276
- const ext = path151.extname(filePath).toLowerCase();
121925
+ const ext = path152.extname(filePath).toLowerCase();
121277
121926
  return SUPPORTED_PARSER_EXTENSIONS.has(ext);
121278
121927
  }
121279
121928
  function isPlanFile(filePath) {
@@ -121520,9 +122169,9 @@ async function placeholderScan(input, directory) {
121520
122169
  let filesScanned = 0;
121521
122170
  const filesWithFindings = new Set;
121522
122171
  for (const filePath of changed_files) {
121523
- const fullPath = path151.isAbsolute(filePath) ? filePath : path151.resolve(directory, filePath);
121524
- const resolvedDirectory = path151.resolve(directory);
121525
- if (!fullPath.startsWith(resolvedDirectory + path151.sep) && fullPath !== resolvedDirectory) {
122172
+ const fullPath = path152.isAbsolute(filePath) ? filePath : path152.resolve(directory, filePath);
122173
+ const resolvedDirectory = path152.resolve(directory);
122174
+ if (!fullPath.startsWith(resolvedDirectory + path152.sep) && fullPath !== resolvedDirectory) {
121526
122175
  continue;
121527
122176
  }
121528
122177
  if (!fs112.existsSync(fullPath)) {
@@ -121531,7 +122180,7 @@ async function placeholderScan(input, directory) {
121531
122180
  if (isAllowedByGlobs(filePath, allow_globs)) {
121532
122181
  continue;
121533
122182
  }
121534
- const relativeFilePath = path151.relative(directory, fullPath).replace(/\\/g, "/");
122183
+ const relativeFilePath = path152.relative(directory, fullPath).replace(/\\/g, "/");
121535
122184
  if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
121536
122185
  continue;
121537
122186
  }
@@ -121604,7 +122253,7 @@ var placeholder_scan = createSwarmTool({
121604
122253
 
121605
122254
  // src/tools/pre-check-batch.ts
121606
122255
  import * as fs116 from "node:fs";
121607
- import * as path155 from "node:path";
122256
+ import * as path156 from "node:path";
121608
122257
  init_zod();
121609
122258
  init_manager2();
121610
122259
  init_utils();
@@ -121732,11 +122381,11 @@ var quality_budget = createSwarmTool({
121732
122381
  }).optional().describe("Quality budget thresholds")
121733
122382
  },
121734
122383
  async execute(args2, directory) {
121735
- const result = await _internals68.qualityBudget(args2, directory);
122384
+ const result = await _internals70.qualityBudget(args2, directory);
121736
122385
  return JSON.stringify(result);
121737
122386
  }
121738
122387
  });
121739
- var _internals68 = {
122388
+ var _internals70 = {
121740
122389
  qualityBudget
121741
122390
  };
121742
122391
 
@@ -121745,7 +122394,7 @@ init_zod();
121745
122394
  init_manager2();
121746
122395
  init_detector();
121747
122396
  import * as fs115 from "node:fs";
121748
- import * as path154 from "node:path";
122397
+ import * as path155 from "node:path";
121749
122398
  import { extname as extname22 } from "node:path";
121750
122399
 
121751
122400
  // src/sast/rules/c.ts
@@ -122455,13 +123104,13 @@ function executeRulesSync(filePath, content, language) {
122455
123104
  // src/sast/semgrep.ts
122456
123105
  import * as child_process10 from "node:child_process";
122457
123106
  import * as fs113 from "node:fs";
122458
- import * as path152 from "node:path";
123107
+ import * as path153 from "node:path";
122459
123108
  var semgrepAvailableCache = null;
122460
123109
  var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
122461
123110
  var DEFAULT_TIMEOUT_MS3 = 30000;
122462
123111
  var MAX_OUTPUT_BYTES7 = 10 * 1024 * 1024;
122463
123112
  var KILL_GRACE_MS = 2000;
122464
- var _internals69 = {
123113
+ var _internals71 = {
122465
123114
  isSemgrepAvailable,
122466
123115
  checkSemgrepAvailable,
122467
123116
  resetSemgrepCache,
@@ -122487,7 +123136,7 @@ function isSemgrepAvailable() {
122487
123136
  }
122488
123137
  }
122489
123138
  async function checkSemgrepAvailable() {
122490
- return _internals69.isSemgrepAvailable();
123139
+ return _internals71.isSemgrepAvailable();
122491
123140
  }
122492
123141
  function resetSemgrepCache() {
122493
123142
  semgrepAvailableCache = null;
@@ -122540,7 +123189,7 @@ function mapSemgrepSeverity(severity) {
122540
123189
  }
122541
123190
  async function executeWithTimeout(command, args2, options) {
122542
123191
  const maxOutputBytes = options.maxOutputBytes ?? MAX_OUTPUT_BYTES7;
122543
- return new Promise((resolve53) => {
123192
+ return new Promise((resolve54) => {
122544
123193
  const child = child_process10.spawn(command, args2, {
122545
123194
  shell: false,
122546
123195
  cwd: options.cwd,
@@ -122572,7 +123221,7 @@ async function executeWithTimeout(command, args2, options) {
122572
123221
  escalation.unref();
122573
123222
  }
122574
123223
  }
122575
- resolve53({ ...result, truncated });
123224
+ resolve54({ ...result, truncated });
122576
123225
  };
122577
123226
  timeout = setTimeout(() => {
122578
123227
  settle({
@@ -122631,12 +123280,12 @@ async function runSemgrep(options) {
122631
123280
  const timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS3;
122632
123281
  if (files.length === 0) {
122633
123282
  return {
122634
- available: _internals69.isSemgrepAvailable(),
123283
+ available: _internals71.isSemgrepAvailable(),
122635
123284
  findings: [],
122636
123285
  engine: "tier_a"
122637
123286
  };
122638
123287
  }
122639
- if (!_internals69.isSemgrepAvailable()) {
123288
+ if (!_internals71.isSemgrepAvailable()) {
122640
123289
  return {
122641
123290
  available: false,
122642
123291
  findings: [],
@@ -122700,7 +123349,7 @@ async function runSemgrep(options) {
122700
123349
  }
122701
123350
  function getRulesDirectory(projectRoot) {
122702
123351
  if (projectRoot) {
122703
- return path152.resolve(projectRoot, DEFAULT_RULES_DIR);
123352
+ return path153.resolve(projectRoot, DEFAULT_RULES_DIR);
122704
123353
  }
122705
123354
  return DEFAULT_RULES_DIR;
122706
123355
  }
@@ -122721,24 +123370,24 @@ init_create_tool();
122721
123370
  init_utils2();
122722
123371
  import * as crypto12 from "node:crypto";
122723
123372
  import * as fs114 from "node:fs";
122724
- import * as path153 from "node:path";
123373
+ import * as path154 from "node:path";
122725
123374
  var BASELINE_SCHEMA_VERSION = "1.0.0";
122726
123375
  var MAX_BASELINE_FINDINGS = 2000;
122727
123376
  var MAX_BASELINE_BYTES = 2 * 1048576;
122728
123377
  var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
122729
123378
  function normalizeFindingPath(directory, file3) {
122730
- const resolved = path153.isAbsolute(file3) ? file3 : path153.resolve(directory, file3);
122731
- const rel = path153.relative(path153.resolve(directory), resolved);
123379
+ const resolved = path154.isAbsolute(file3) ? file3 : path154.resolve(directory, file3);
123380
+ const rel = path154.relative(path154.resolve(directory), resolved);
122732
123381
  return rel.replace(/\\/g, "/");
122733
123382
  }
122734
123383
  function baselineRelPath(phase) {
122735
- return path153.join("evidence", String(phase), "sast-baseline.json");
123384
+ return path154.join("evidence", String(phase), "sast-baseline.json");
122736
123385
  }
122737
123386
  function tempRelPath(phase) {
122738
- return path153.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
123387
+ return path154.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
122739
123388
  }
122740
123389
  function lockRelPath(phase) {
122741
- return path153.join("evidence", String(phase), "sast-baseline.json.lock");
123390
+ return path154.join("evidence", String(phase), "sast-baseline.json.lock");
122742
123391
  }
122743
123392
  function getLine(lines, idx) {
122744
123393
  if (idx < 0 || idx >= lines.length)
@@ -122803,7 +123452,7 @@ function assignOccurrenceIndices(findings, directory) {
122803
123452
  }
122804
123453
  const occIdx = countMap.get(baseKey) ?? 0;
122805
123454
  countMap.set(baseKey, occIdx + 1);
122806
- const fp = _internals70.fingerprintFinding(finding, directory, occIdx);
123455
+ const fp = _internals72.fingerprintFinding(finding, directory, occIdx);
122807
123456
  return {
122808
123457
  finding,
122809
123458
  index: occIdx,
@@ -122824,7 +123473,7 @@ async function acquireLock2(lockPath) {
122824
123473
  };
122825
123474
  } catch {
122826
123475
  if (attempt < LOCK_RETRY_DELAYS_MS.length) {
122827
- await new Promise((resolve54) => setTimeout(resolve54, LOCK_RETRY_DELAYS_MS[attempt]));
123476
+ await new Promise((resolve55) => setTimeout(resolve55, LOCK_RETRY_DELAYS_MS[attempt]));
122828
123477
  }
122829
123478
  }
122830
123479
  }
@@ -122859,8 +123508,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
122859
123508
  message: e instanceof Error ? e.message : "Path validation failed"
122860
123509
  };
122861
123510
  }
122862
- fs114.mkdirSync(path153.dirname(baselinePath), { recursive: true });
122863
- fs114.mkdirSync(path153.dirname(tempPath), { recursive: true });
123511
+ fs114.mkdirSync(path154.dirname(baselinePath), { recursive: true });
123512
+ fs114.mkdirSync(path154.dirname(tempPath), { recursive: true });
122864
123513
  const releaseLock = await acquireLock2(lockPath);
122865
123514
  try {
122866
123515
  let existing = null;
@@ -122872,7 +123521,7 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
122872
123521
  }
122873
123522
  } catch {}
122874
123523
  const scannedRelFiles = new Set(scannedFiles.map((f) => normalizeFindingPath(directory, f)));
122875
- const indexed = _internals70.assignOccurrenceIndices(findings, directory);
123524
+ const indexed = _internals72.assignOccurrenceIndices(findings, directory);
122876
123525
  if (existing && !opts?.force) {
122877
123526
  const prunedFingerprints = existing.fingerprints.filter((fp) => {
122878
123527
  const relFile = fp.slice(0, fp.indexOf("|"));
@@ -123012,7 +123661,7 @@ function loadBaseline(directory, phase) {
123012
123661
  };
123013
123662
  }
123014
123663
  }
123015
- var _internals70 = {
123664
+ var _internals72 = {
123016
123665
  fingerprintFinding,
123017
123666
  assignOccurrenceIndices,
123018
123667
  captureOrMergeBaseline,
@@ -123133,9 +123782,9 @@ async function sastScan(input, directory, config3) {
123133
123782
  _filesSkipped++;
123134
123783
  continue;
123135
123784
  }
123136
- const resolvedPath = path154.isAbsolute(filePath) ? filePath : path154.resolve(directory, filePath);
123137
- const resolvedDirectory = path154.resolve(directory);
123138
- if (!resolvedPath.startsWith(resolvedDirectory + path154.sep) && resolvedPath !== resolvedDirectory) {
123785
+ const resolvedPath = path155.isAbsolute(filePath) ? filePath : path155.resolve(directory, filePath);
123786
+ const resolvedDirectory = path155.resolve(directory);
123787
+ if (!resolvedPath.startsWith(resolvedDirectory + path155.sep) && resolvedPath !== resolvedDirectory) {
123139
123788
  _filesSkipped++;
123140
123789
  continue;
123141
123790
  }
@@ -123422,11 +124071,11 @@ var sast_scan = createSwarmTool({
123422
124071
  capture_baseline: safeArgs.capture_baseline,
123423
124072
  phase: safeArgs.phase
123424
124073
  };
123425
- const result = await _internals71.sastScan(input, directory);
124074
+ const result = await _internals73.sastScan(input, directory);
123426
124075
  return JSON.stringify(result, null, 2);
123427
124076
  }
123428
124077
  });
123429
- var _internals71 = {
124078
+ var _internals73 = {
123430
124079
  sastScan,
123431
124080
  sast_scan
123432
124081
  };
@@ -123450,18 +124099,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
123450
124099
  let resolved;
123451
124100
  const isWinAbs = isWindowsAbsolutePath(inputPath);
123452
124101
  if (isWinAbs) {
123453
- resolved = path155.win32.resolve(inputPath);
123454
- } else if (path155.isAbsolute(inputPath)) {
123455
- resolved = path155.resolve(inputPath);
124102
+ resolved = path156.win32.resolve(inputPath);
124103
+ } else if (path156.isAbsolute(inputPath)) {
124104
+ resolved = path156.resolve(inputPath);
123456
124105
  } else {
123457
- resolved = path155.resolve(baseDir, inputPath);
124106
+ resolved = path156.resolve(baseDir, inputPath);
123458
124107
  }
123459
- const workspaceResolved = path155.resolve(workspaceDir);
124108
+ const workspaceResolved = path156.resolve(workspaceDir);
123460
124109
  let relative31;
123461
124110
  if (isWinAbs) {
123462
- relative31 = path155.win32.relative(workspaceResolved, resolved);
124111
+ relative31 = path156.win32.relative(workspaceResolved, resolved);
123463
124112
  } else {
123464
- relative31 = path155.relative(workspaceResolved, resolved);
124113
+ relative31 = path156.relative(workspaceResolved, resolved);
123465
124114
  }
123466
124115
  if (relative31.startsWith("..")) {
123467
124116
  return "path traversal detected";
@@ -123526,7 +124175,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
123526
124175
  if (typeof file3 !== "string") {
123527
124176
  continue;
123528
124177
  }
123529
- const resolvedPath = path155.resolve(file3);
124178
+ const resolvedPath = path156.resolve(file3);
123530
124179
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
123531
124180
  if (validationError) {
123532
124181
  continue;
@@ -123683,7 +124332,7 @@ async function runSecretscanWithFiles(files, directory) {
123683
124332
  skippedFiles++;
123684
124333
  continue;
123685
124334
  }
123686
- const resolvedPath = path155.resolve(file3);
124335
+ const resolvedPath = path156.resolve(file3);
123687
124336
  const validationError = validatePath(resolvedPath, directory, directory);
123688
124337
  if (validationError) {
123689
124338
  skippedFiles++;
@@ -123701,7 +124350,7 @@ async function runSecretscanWithFiles(files, directory) {
123701
124350
  };
123702
124351
  }
123703
124352
  for (const file3 of validatedFiles) {
123704
- const ext = path155.extname(file3).toLowerCase();
124353
+ const ext = path156.extname(file3).toLowerCase();
123705
124354
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
123706
124355
  skippedFiles++;
123707
124356
  continue;
@@ -123920,7 +124569,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
123920
124569
  const preexistingFindings = [];
123921
124570
  for (const finding of findings) {
123922
124571
  const filePath = finding.location.file;
123923
- const normalised = path155.relative(directory, filePath).replace(/\\/g, "/");
124572
+ const normalised = path156.relative(directory, filePath).replace(/\\/g, "/");
123924
124573
  const changedLines = changedLineRanges.get(normalised);
123925
124574
  if (changedLines?.has(finding.location.line)) {
123926
124575
  newFindings.push(finding);
@@ -123971,7 +124620,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
123971
124620
  warn(`pre_check_batch: Invalid file path: ${file3}`);
123972
124621
  continue;
123973
124622
  }
123974
- changedFiles.push(path155.resolve(directory, file3));
124623
+ changedFiles.push(path156.resolve(directory, file3));
123975
124624
  }
123976
124625
  if (changedFiles.length === 0) {
123977
124626
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -124172,9 +124821,9 @@ var pre_check_batch = createSwarmTool({
124172
124821
  };
124173
124822
  return JSON.stringify(errorResult, null, 2);
124174
124823
  }
124175
- const resolvedDirectory = path155.resolve(typedArgs.directory);
124176
- const workspaceAnchor = path155.resolve(directory);
124177
- if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path155.sep)) {
124824
+ const resolvedDirectory = path156.resolve(typedArgs.directory);
124825
+ const workspaceAnchor = path156.resolve(directory);
124826
+ if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path156.sep)) {
124178
124827
  const subDirError = `directory "${typedArgs.directory}" is a subdirectory of the project root — pre_check_batch requires the project root directory "${workspaceAnchor}"`;
124179
124828
  const subDirResult = {
124180
124829
  gates_passed: false,
@@ -124226,7 +124875,7 @@ var pre_check_batch = createSwarmTool({
124226
124875
 
124227
124876
  // src/tools/repo-map.ts
124228
124877
  init_zod();
124229
- import * as path156 from "node:path";
124878
+ import * as path157 from "node:path";
124230
124879
  init_path_security();
124231
124880
  init_create_tool();
124232
124881
  var VALID_ACTIONS = [
@@ -124251,7 +124900,7 @@ function validateFile(p) {
124251
124900
  return "file contains control characters";
124252
124901
  if (containsPathTraversal(p))
124253
124902
  return "file contains path traversal";
124254
- if (path156.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
124903
+ if (path157.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
124255
124904
  return "file must be a workspace-relative path, not absolute";
124256
124905
  }
124257
124906
  return null;
@@ -124274,8 +124923,8 @@ function ok(action, payload) {
124274
124923
  }
124275
124924
  function toRelativeGraphPath(input, workspaceRoot) {
124276
124925
  const normalized = input.replace(/\\/g, "/");
124277
- if (path156.isAbsolute(normalized)) {
124278
- const rel = path156.relative(workspaceRoot, normalized).replace(/\\/g, "/");
124926
+ if (path157.isAbsolute(normalized)) {
124927
+ const rel = path157.relative(workspaceRoot, normalized).replace(/\\/g, "/");
124279
124928
  return normalizeGraphPath2(rel);
124280
124929
  }
124281
124930
  return normalizeGraphPath2(normalized);
@@ -124421,7 +125070,7 @@ var repo_map = createSwarmTool({
124421
125070
  init_zod();
124422
125071
  init_create_tool();
124423
125072
  import * as fs117 from "node:fs";
124424
- import * as path157 from "node:path";
125073
+ import * as path158 from "node:path";
124425
125074
  var SPEC_FILE = ".swarm/spec.md";
124426
125075
  var EVIDENCE_DIR4 = ".swarm/evidence";
124427
125076
  var OBLIGATION_KEYWORDS2 = ["MUST", "SHOULD", "SHALL"];
@@ -124490,7 +125139,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
124490
125139
  return [];
124491
125140
  }
124492
125141
  for (const entry of entries) {
124493
- const entryPath = path157.join(evidenceDir, entry);
125142
+ const entryPath = path158.join(evidenceDir, entry);
124494
125143
  try {
124495
125144
  const stat9 = fs117.statSync(entryPath);
124496
125145
  if (!stat9.isDirectory()) {
@@ -124506,11 +125155,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
124506
125155
  if (entryPhase !== String(phase)) {
124507
125156
  continue;
124508
125157
  }
124509
- const evidenceFilePath = path157.join(entryPath, "evidence.json");
125158
+ const evidenceFilePath = path158.join(entryPath, "evidence.json");
124510
125159
  try {
124511
- const resolvedPath = path157.resolve(evidenceFilePath);
124512
- const evidenceDirResolved = path157.resolve(evidenceDir);
124513
- if (!resolvedPath.startsWith(evidenceDirResolved + path157.sep)) {
125160
+ const resolvedPath = path158.resolve(evidenceFilePath);
125161
+ const evidenceDirResolved = path158.resolve(evidenceDir);
125162
+ if (!resolvedPath.startsWith(evidenceDirResolved + path158.sep)) {
124514
125163
  continue;
124515
125164
  }
124516
125165
  const stat9 = fs117.lstatSync(evidenceFilePath);
@@ -124544,7 +125193,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
124544
125193
  if (Array.isArray(diffEntry.files_changed)) {
124545
125194
  for (const file3 of diffEntry.files_changed) {
124546
125195
  if (typeof file3 === "string") {
124547
- touchedFiles.add(path157.resolve(cwd, file3));
125196
+ touchedFiles.add(path158.resolve(cwd, file3));
124548
125197
  }
124549
125198
  }
124550
125199
  }
@@ -124557,8 +125206,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
124557
125206
  }
124558
125207
  function searchFileForKeywords(filePath, keywords, cwd) {
124559
125208
  try {
124560
- const resolvedPath = path157.resolve(filePath);
124561
- const cwdResolved = path157.resolve(cwd);
125209
+ const resolvedPath = path158.resolve(filePath);
125210
+ const cwdResolved = path158.resolve(cwd);
124562
125211
  if (!resolvedPath.startsWith(cwdResolved)) {
124563
125212
  return false;
124564
125213
  }
@@ -124692,7 +125341,7 @@ var req_coverage = createSwarmTool({
124692
125341
  }, null, 2);
124693
125342
  }
124694
125343
  const cwd = inputDirectory || directory;
124695
- const specPath = path157.join(cwd, SPEC_FILE);
125344
+ const specPath = path158.join(cwd, SPEC_FILE);
124696
125345
  let specContent;
124697
125346
  try {
124698
125347
  specContent = fs117.readFileSync(specPath, "utf-8");
@@ -124719,7 +125368,7 @@ var req_coverage = createSwarmTool({
124719
125368
  message: "No FR requirements found in spec.md"
124720
125369
  }, null, 2);
124721
125370
  }
124722
- const evidenceDir = path157.join(cwd, EVIDENCE_DIR4);
125371
+ const evidenceDir = path158.join(cwd, EVIDENCE_DIR4);
124723
125372
  const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
124724
125373
  const analyzedRequirements = [];
124725
125374
  let coveredCount = 0;
@@ -124745,7 +125394,7 @@ var req_coverage = createSwarmTool({
124745
125394
  requirements: analyzedRequirements
124746
125395
  };
124747
125396
  const reportFilename = `req-coverage-phase-${phase}.json`;
124748
- const reportPath = path157.join(evidenceDir, reportFilename);
125397
+ const reportPath = path158.join(evidenceDir, reportFilename);
124749
125398
  try {
124750
125399
  if (!fs117.existsSync(evidenceDir)) {
124751
125400
  fs117.mkdirSync(evidenceDir, { recursive: true });
@@ -124835,7 +125484,7 @@ init_qa_gate_profile();
124835
125484
  init_file_locks();
124836
125485
  import * as crypto13 from "node:crypto";
124837
125486
  import * as fs118 from "node:fs";
124838
- import * as path158 from "node:path";
125487
+ import * as path159 from "node:path";
124839
125488
  init_ledger();
124840
125489
  init_manager();
124841
125490
  init_state();
@@ -124916,8 +125565,8 @@ async function executeSavePlan(args2, fallbackDir) {
124916
125565
  };
124917
125566
  }
124918
125567
  if (args2.working_directory && fallbackDir) {
124919
- const resolvedTarget = path158.resolve(args2.working_directory);
124920
- const resolvedRoot = path158.resolve(fallbackDir);
125568
+ const resolvedTarget = path159.resolve(args2.working_directory);
125569
+ const resolvedRoot = path159.resolve(fallbackDir);
124921
125570
  let fallbackExists = false;
124922
125571
  try {
124923
125572
  fs118.accessSync(resolvedRoot, fs118.constants.F_OK);
@@ -124926,7 +125575,7 @@ async function executeSavePlan(args2, fallbackDir) {
124926
125575
  fallbackExists = false;
124927
125576
  }
124928
125577
  if (fallbackExists) {
124929
- const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path158.sep);
125578
+ const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path159.sep);
124930
125579
  if (isSubdirectory) {
124931
125580
  return {
124932
125581
  success: false,
@@ -124942,7 +125591,7 @@ async function executeSavePlan(args2, fallbackDir) {
124942
125591
  let specMtime;
124943
125592
  let specHash;
124944
125593
  if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
124945
- const specPath = path158.join(targetWorkspace, ".swarm", "spec.md");
125594
+ const specPath = path159.join(targetWorkspace, ".swarm", "spec.md");
124946
125595
  try {
124947
125596
  const stat9 = await fs118.promises.stat(specPath);
124948
125597
  specMtime = stat9.mtime.toISOString();
@@ -124958,7 +125607,7 @@ async function executeSavePlan(args2, fallbackDir) {
124958
125607
  }
124959
125608
  }
124960
125609
  if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
124961
- const contextPath = path158.join(targetWorkspace, ".swarm", "context.md");
125610
+ const contextPath = path159.join(targetWorkspace, ".swarm", "context.md");
124962
125611
  let contextContent = "";
124963
125612
  try {
124964
125613
  contextContent = await fs118.promises.readFile(contextPath, "utf8");
@@ -125248,7 +125897,7 @@ async function executeSavePlan(args2, fallbackDir) {
125248
125897
  }
125249
125898
  await writeCheckpoint(dir).catch(() => {});
125250
125899
  try {
125251
- const markerPath = path158.join(dir, ".swarm", ".plan-write-marker");
125900
+ const markerPath = path159.join(dir, ".swarm", ".plan-write-marker");
125252
125901
  const marker = JSON.stringify({
125253
125902
  source: "save_plan",
125254
125903
  timestamp: new Date().toISOString(),
@@ -125271,7 +125920,7 @@ async function executeSavePlan(args2, fallbackDir) {
125271
125920
  return {
125272
125921
  success: true,
125273
125922
  message: "Plan saved successfully",
125274
- plan_path: path158.join(dir, ".swarm", "plan.json"),
125923
+ plan_path: path159.join(dir, ".swarm", "plan.json"),
125275
125924
  phases_count: plan.phases.length,
125276
125925
  tasks_count: tasksCount,
125277
125926
  ...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
@@ -125338,7 +125987,7 @@ var save_plan = createSwarmTool({
125338
125987
  init_zod();
125339
125988
  init_manager2();
125340
125989
  import * as fs119 from "node:fs";
125341
- import * as path159 from "node:path";
125990
+ import * as path160 from "node:path";
125342
125991
 
125343
125992
  // src/sbom/detectors/index.ts
125344
125993
  init_utils();
@@ -126188,7 +126837,7 @@ function findManifestFiles(rootDir) {
126188
126837
  try {
126189
126838
  const entries = fs119.readdirSync(dir, { withFileTypes: true });
126190
126839
  for (const entry of entries) {
126191
- const fullPath = path159.join(dir, entry.name);
126840
+ const fullPath = path160.join(dir, entry.name);
126192
126841
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
126193
126842
  continue;
126194
126843
  }
@@ -126197,7 +126846,7 @@ function findManifestFiles(rootDir) {
126197
126846
  } else if (entry.isFile()) {
126198
126847
  for (const pattern of patterns) {
126199
126848
  if (simpleGlobToRegex(pattern).test(entry.name)) {
126200
- manifestFiles.push(path159.relative(rootDir, fullPath));
126849
+ manifestFiles.push(path160.relative(rootDir, fullPath));
126201
126850
  break;
126202
126851
  }
126203
126852
  }
@@ -126215,11 +126864,11 @@ function findManifestFilesInDirs(directories, workingDir) {
126215
126864
  try {
126216
126865
  const entries = fs119.readdirSync(dir, { withFileTypes: true });
126217
126866
  for (const entry of entries) {
126218
- const fullPath = path159.join(dir, entry.name);
126867
+ const fullPath = path160.join(dir, entry.name);
126219
126868
  if (entry.isFile()) {
126220
126869
  for (const pattern of patterns) {
126221
126870
  if (simpleGlobToRegex(pattern).test(entry.name)) {
126222
- found.push(path159.relative(workingDir, fullPath));
126871
+ found.push(path160.relative(workingDir, fullPath));
126223
126872
  break;
126224
126873
  }
126225
126874
  }
@@ -126232,11 +126881,11 @@ function findManifestFilesInDirs(directories, workingDir) {
126232
126881
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
126233
126882
  const dirs = new Set;
126234
126883
  for (const file3 of changedFiles) {
126235
- let currentDir = path159.dirname(file3);
126884
+ let currentDir = path160.dirname(file3);
126236
126885
  while (true) {
126237
- if (currentDir && currentDir !== "." && currentDir !== path159.sep) {
126238
- dirs.add(path159.join(workingDir, currentDir));
126239
- const parent = path159.dirname(currentDir);
126886
+ if (currentDir && currentDir !== "." && currentDir !== path160.sep) {
126887
+ dirs.add(path160.join(workingDir, currentDir));
126888
+ const parent = path160.dirname(currentDir);
126240
126889
  if (parent === currentDir)
126241
126890
  break;
126242
126891
  currentDir = parent;
@@ -126320,7 +126969,7 @@ var sbom_generate = createSwarmTool({
126320
126969
  const changedFiles = obj.changed_files;
126321
126970
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
126322
126971
  const workingDir = directory;
126323
- const outputDir = path159.isAbsolute(relativeOutputDir) ? relativeOutputDir : path159.join(workingDir, relativeOutputDir);
126972
+ const outputDir = path160.isAbsolute(relativeOutputDir) ? relativeOutputDir : path160.join(workingDir, relativeOutputDir);
126324
126973
  let manifestFiles = [];
126325
126974
  if (scope === "all") {
126326
126975
  manifestFiles = findManifestFiles(workingDir);
@@ -126343,7 +126992,7 @@ var sbom_generate = createSwarmTool({
126343
126992
  const processedFiles = [];
126344
126993
  for (const manifestFile of manifestFiles) {
126345
126994
  try {
126346
- const fullPath = path159.isAbsolute(manifestFile) ? manifestFile : path159.join(workingDir, manifestFile);
126995
+ const fullPath = path160.isAbsolute(manifestFile) ? manifestFile : path160.join(workingDir, manifestFile);
126347
126996
  if (!fs119.existsSync(fullPath)) {
126348
126997
  continue;
126349
126998
  }
@@ -126360,7 +127009,7 @@ var sbom_generate = createSwarmTool({
126360
127009
  const bom = generateCycloneDX(allComponents);
126361
127010
  const bomJson = serializeCycloneDX(bom);
126362
127011
  const filename = generateSbomFilename();
126363
- const outputPath = path159.join(outputDir, filename);
127012
+ const outputPath = path160.join(outputDir, filename);
126364
127013
  fs119.writeFileSync(outputPath, bomJson, "utf-8");
126365
127014
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
126366
127015
  try {
@@ -126405,7 +127054,7 @@ var sbom_generate = createSwarmTool({
126405
127054
  init_zod();
126406
127055
  init_create_tool();
126407
127056
  import * as fs120 from "node:fs";
126408
- import * as path160 from "node:path";
127057
+ import * as path161 from "node:path";
126409
127058
  var SPEC_CANDIDATES = [
126410
127059
  "openapi.json",
126411
127060
  "openapi.yaml",
@@ -126437,12 +127086,12 @@ function normalizePath5(p) {
126437
127086
  }
126438
127087
  function discoverSpecFile(cwd, specFileArg) {
126439
127088
  if (specFileArg) {
126440
- const resolvedPath = path160.resolve(cwd, specFileArg);
126441
- const normalizedCwd = cwd.endsWith(path160.sep) ? cwd : cwd + path160.sep;
127089
+ const resolvedPath = path161.resolve(cwd, specFileArg);
127090
+ const normalizedCwd = cwd.endsWith(path161.sep) ? cwd : cwd + path161.sep;
126442
127091
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
126443
127092
  throw new Error("Invalid spec_file: path traversal detected");
126444
127093
  }
126445
- const ext = path160.extname(resolvedPath).toLowerCase();
127094
+ const ext = path161.extname(resolvedPath).toLowerCase();
126446
127095
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
126447
127096
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
126448
127097
  }
@@ -126456,7 +127105,7 @@ function discoverSpecFile(cwd, specFileArg) {
126456
127105
  return resolvedPath;
126457
127106
  }
126458
127107
  for (const candidate of SPEC_CANDIDATES) {
126459
- const candidatePath = path160.resolve(cwd, candidate);
127108
+ const candidatePath = path161.resolve(cwd, candidate);
126460
127109
  if (fs120.existsSync(candidatePath)) {
126461
127110
  const stats = fs120.statSync(candidatePath);
126462
127111
  if (stats.size <= MAX_SPEC_SIZE) {
@@ -126468,7 +127117,7 @@ function discoverSpecFile(cwd, specFileArg) {
126468
127117
  }
126469
127118
  function parseSpec(specFile) {
126470
127119
  const content = fs120.readFileSync(specFile, "utf-8");
126471
- const ext = path160.extname(specFile).toLowerCase();
127120
+ const ext = path161.extname(specFile).toLowerCase();
126472
127121
  if (ext === ".json") {
126473
127122
  return parseJsonSpec(content);
126474
127123
  }
@@ -126544,7 +127193,7 @@ function extractRoutes(cwd) {
126544
127193
  return;
126545
127194
  }
126546
127195
  for (const entry of entries) {
126547
- const fullPath = path160.join(dir, entry.name);
127196
+ const fullPath = path161.join(dir, entry.name);
126548
127197
  if (entry.isSymbolicLink()) {
126549
127198
  continue;
126550
127199
  }
@@ -126554,7 +127203,7 @@ function extractRoutes(cwd) {
126554
127203
  }
126555
127204
  walkDir2(fullPath);
126556
127205
  } else if (entry.isFile()) {
126557
- const ext = path160.extname(entry.name).toLowerCase();
127206
+ const ext = path161.extname(entry.name).toLowerCase();
126558
127207
  const baseName = entry.name.toLowerCase();
126559
127208
  if (![".ts", ".js", ".mjs"].includes(ext)) {
126560
127209
  continue;
@@ -126723,7 +127372,7 @@ init_bun_compat();
126723
127372
  init_path_security();
126724
127373
  init_create_tool();
126725
127374
  import * as fs121 from "node:fs";
126726
- import * as path161 from "node:path";
127375
+ import * as path162 from "node:path";
126727
127376
  var DEFAULT_MAX_RESULTS = 100;
126728
127377
  var DEFAULT_MAX_LINES = 200;
126729
127378
  var REGEX_TIMEOUT_MS = 5000;
@@ -126759,11 +127408,11 @@ function containsWindowsAttacks4(str) {
126759
127408
  }
126760
127409
  function isPathInWorkspace3(filePath, workspace) {
126761
127410
  try {
126762
- const resolvedPath = path161.resolve(workspace, filePath);
127411
+ const resolvedPath = path162.resolve(workspace, filePath);
126763
127412
  const realWorkspace = fs121.realpathSync(workspace);
126764
127413
  const realResolvedPath = fs121.realpathSync(resolvedPath);
126765
- const relativePath = path161.relative(realWorkspace, realResolvedPath);
126766
- if (relativePath.startsWith("..") || path161.isAbsolute(relativePath)) {
127414
+ const relativePath = path162.relative(realWorkspace, realResolvedPath);
127415
+ if (relativePath.startsWith("..") || path162.isAbsolute(relativePath)) {
126767
127416
  return false;
126768
127417
  }
126769
127418
  return true;
@@ -126776,11 +127425,11 @@ function validatePathForRead2(filePath, workspace) {
126776
127425
  }
126777
127426
  function findRgInEnvPath() {
126778
127427
  const searchPath = process.env.PATH ?? "";
126779
- for (const dir of searchPath.split(path161.delimiter)) {
127428
+ for (const dir of searchPath.split(path162.delimiter)) {
126780
127429
  if (!dir)
126781
127430
  continue;
126782
127431
  const isWindows = process.platform === "win32";
126783
- const candidate = path161.join(dir, isWindows ? "rg.exe" : "rg");
127432
+ const candidate = path162.join(dir, isWindows ? "rg.exe" : "rg");
126784
127433
  if (fs121.existsSync(candidate))
126785
127434
  return candidate;
126786
127435
  }
@@ -126835,7 +127484,7 @@ async function ripgrepSearch(opts) {
126835
127484
  stderr: "pipe",
126836
127485
  cwd: opts.workspace
126837
127486
  });
126838
- const timeout = new Promise((resolve60) => setTimeout(() => resolve60("timeout"), REGEX_TIMEOUT_MS));
127487
+ const timeout = new Promise((resolve61) => setTimeout(() => resolve61("timeout"), REGEX_TIMEOUT_MS));
126839
127488
  const exitPromise = proc.exited;
126840
127489
  const result = await Promise.race([exitPromise, timeout]);
126841
127490
  if (result === "timeout") {
@@ -126910,8 +127559,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
126910
127559
  try {
126911
127560
  const entries = fs121.readdirSync(dir, { withFileTypes: true });
126912
127561
  for (const entry of entries) {
126913
- const fullPath = path161.join(dir, entry.name);
126914
- const relativePath = path161.relative(workspace, fullPath);
127562
+ const fullPath = path162.join(dir, entry.name);
127563
+ const relativePath = path162.relative(workspace, fullPath);
126915
127564
  if (!validatePathForRead2(fullPath, workspace)) {
126916
127565
  continue;
126917
127566
  }
@@ -126952,7 +127601,7 @@ async function fallbackSearch(opts) {
126952
127601
  const matches = [];
126953
127602
  let total = 0;
126954
127603
  for (const file3 of files) {
126955
- const fullPath = path161.join(opts.workspace, file3);
127604
+ const fullPath = path162.join(opts.workspace, file3);
126956
127605
  if (!validatePathForRead2(fullPath, opts.workspace)) {
126957
127606
  continue;
126958
127607
  }
@@ -127365,7 +128014,7 @@ init_config();
127365
128014
  init_schema();
127366
128015
  init_create_tool();
127367
128016
  import { mkdir as mkdir23, rename as rename10, writeFile as writeFile16 } from "node:fs/promises";
127368
- import * as path162 from "node:path";
128017
+ import * as path163 from "node:path";
127369
128018
  var MAX_SPEC_BYTES = 256 * 1024;
127370
128019
  var spec_write = createSwarmTool({
127371
128020
  description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
@@ -127406,8 +128055,8 @@ var spec_write = createSwarmTool({
127406
128055
  reason: 'spec must contain at least one top-level "# Heading"'
127407
128056
  }, null, 2);
127408
128057
  }
127409
- const target = path162.join(directory, ".swarm", "spec.md");
127410
- await mkdir23(path162.dirname(target), { recursive: true });
128058
+ const target = path163.join(directory, ".swarm", "spec.md");
128059
+ await mkdir23(path163.dirname(target), { recursive: true });
127411
128060
  const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
127412
128061
  let finalContent = content;
127413
128062
  if (mode === "append") {
@@ -127443,7 +128092,7 @@ import {
127443
128092
  unlinkSync as unlinkSync21,
127444
128093
  writeFileSync as writeFileSync32
127445
128094
  } from "node:fs";
127446
- import path163 from "node:path";
128095
+ import path164 from "node:path";
127447
128096
  init_create_tool();
127448
128097
  init_resolve_working_directory();
127449
128098
  var VerdictSchema2 = exports_external.object({
@@ -127587,7 +128236,7 @@ var submit_phase_council_verdicts = createSwarmTool({
127587
128236
  }
127588
128237
  });
127589
128238
  function getPhaseMutationGapFinding(phaseNumber, workingDir) {
127590
- const mutationGatePath = path163.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
128239
+ const mutationGatePath = path164.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
127591
128240
  try {
127592
128241
  const raw = readFileSync81(mutationGatePath, "utf-8");
127593
128242
  const parsed = JSON.parse(raw);
@@ -127649,9 +128298,9 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
127649
128298
  }
127650
128299
  }
127651
128300
  function writePhaseCouncilEvidence(workingDir, synthesis) {
127652
- const evidenceDir = path163.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
128301
+ const evidenceDir = path164.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
127653
128302
  mkdirSync41(evidenceDir, { recursive: true });
127654
- const evidenceFile = path163.join(evidenceDir, "phase-council.json");
128303
+ const evidenceFile = path164.join(evidenceDir, "phase-council.json");
127655
128304
  const evidenceBundle = {
127656
128305
  entries: [
127657
128306
  {
@@ -127713,7 +128362,7 @@ init_zod();
127713
128362
  init_path_security();
127714
128363
  init_create_tool();
127715
128364
  import * as fs122 from "node:fs";
127716
- import * as path164 from "node:path";
128365
+ import * as path165 from "node:path";
127717
128366
  var BINARY_EXTENSIONS2 = new Set([
127718
128367
  ".png",
127719
128368
  ".jpg",
@@ -127749,14 +128398,14 @@ function containsWindowsAttacks5(str) {
127749
128398
  }
127750
128399
  function isPathInWorkspace4(filePath, workspace) {
127751
128400
  try {
127752
- const resolvedPath = path164.resolve(workspace, filePath);
128401
+ const resolvedPath = path165.resolve(workspace, filePath);
127753
128402
  if (!fs122.existsSync(resolvedPath)) {
127754
128403
  return true;
127755
128404
  }
127756
128405
  const realWorkspace = fs122.realpathSync(workspace);
127757
128406
  const realResolvedPath = fs122.realpathSync(resolvedPath);
127758
- const relativePath = path164.relative(realWorkspace, realResolvedPath);
127759
- if (relativePath.startsWith("..") || path164.isAbsolute(relativePath)) {
128407
+ const relativePath = path165.relative(realWorkspace, realResolvedPath);
128408
+ if (relativePath.startsWith("..") || path165.isAbsolute(relativePath)) {
127760
128409
  return false;
127761
128410
  }
127762
128411
  return true;
@@ -127871,7 +128520,7 @@ function arraysEqual2(a, b) {
127871
128520
  return true;
127872
128521
  }
127873
128522
  function isBinaryFile4(filePath) {
127874
- const ext = path164.extname(filePath).toLowerCase();
128523
+ const ext = path165.extname(filePath).toLowerCase();
127875
128524
  return BINARY_EXTENSIONS2.has(ext);
127876
128525
  }
127877
128526
  function splitDiffLines(content) {
@@ -128076,7 +128725,7 @@ var suggestPatch = createSwarmTool({
128076
128725
  });
128077
128726
  continue;
128078
128727
  }
128079
- const fullPath = path164.resolve(directory, change.file);
128728
+ const fullPath = path165.resolve(directory, change.file);
128080
128729
  if (!fs122.existsSync(fullPath)) {
128081
128730
  errors5.push({
128082
128731
  success: false,
@@ -128171,7 +128820,7 @@ var suggestPatch = createSwarmTool({
128171
128820
  const unifiedParts = [];
128172
128821
  for (const [file3, entries] of fileGroups) {
128173
128822
  entries.sort((a, b) => a.contextMatch.startLineIndex - b.contextMatch.startLineIndex);
128174
- const entryFullPath = path164.resolve(directory, file3);
128823
+ const entryFullPath = path165.resolve(directory, file3);
128175
128824
  let entryContent;
128176
128825
  try {
128177
128826
  entryContent = fs122.readFileSync(entryFullPath, "utf-8");
@@ -128372,7 +129021,7 @@ var swarm_memory_propose = createSwarmTool({
128372
129021
  evidenceRefs: exports_external.array(exports_external.string().min(1).max(500)).max(20).optional().describe("Evidence refs such as files, commits, test outputs, or URLs")
128373
129022
  },
128374
129023
  execute: async (args2, directory, ctx) => {
128375
- const { config: config3 } = _internals72.loadPluginConfigWithMeta(directory);
129024
+ const { config: config3 } = _internals74.loadPluginConfigWithMeta(directory);
128376
129025
  if (config3.memory?.enabled !== true) {
128377
129026
  return JSON.stringify({
128378
129027
  success: false,
@@ -128388,7 +129037,7 @@ var swarm_memory_propose = createSwarmTool({
128388
129037
  });
128389
129038
  }
128390
129039
  const agent = getContextAgent2(ctx);
128391
- const gateway = _internals72.createMemoryGateway({
129040
+ const gateway = _internals74.createMemoryGateway({
128392
129041
  directory,
128393
129042
  sessionID: ctx?.sessionID,
128394
129043
  agentRole: agent,
@@ -128413,7 +129062,7 @@ var swarm_memory_propose = createSwarmTool({
128413
129062
  }
128414
129063
  }
128415
129064
  });
128416
- var _internals72 = {
129065
+ var _internals74 = {
128417
129066
  loadPluginConfigWithMeta,
128418
129067
  createMemoryGateway
128419
129068
  };
@@ -128451,7 +129100,7 @@ var swarm_memory_recall = createSwarmTool({
128451
129100
  maxItems: exports_external.number().int().min(1).max(20).optional().describe("Maximum memories to return")
128452
129101
  },
128453
129102
  execute: async (args2, directory, ctx) => {
128454
- const { config: config3 } = _internals73.loadPluginConfigWithMeta(directory);
129103
+ const { config: config3 } = _internals75.loadPluginConfigWithMeta(directory);
128455
129104
  if (config3.memory?.enabled !== true) {
128456
129105
  return JSON.stringify({
128457
129106
  success: false,
@@ -128467,7 +129116,7 @@ var swarm_memory_recall = createSwarmTool({
128467
129116
  });
128468
129117
  }
128469
129118
  const agent = getContextAgent3(ctx);
128470
- const gateway = _internals73.createMemoryGateway({
129119
+ const gateway = _internals75.createMemoryGateway({
128471
129120
  directory,
128472
129121
  sessionID: ctx?.sessionID,
128473
129122
  agentRole: agent,
@@ -128500,7 +129149,7 @@ var RecallArgsSchema = exports_external.object({
128500
129149
  kinds: exports_external.array(exports_external.enum(MEMORY_KINDS2)).optional(),
128501
129150
  maxItems: exports_external.number().int().min(1).max(20).optional()
128502
129151
  });
128503
- var _internals73 = {
129152
+ var _internals75 = {
128504
129153
  loadPluginConfigWithMeta,
128505
129154
  createMemoryGateway
128506
129155
  };
@@ -128513,7 +129162,7 @@ function getContextAgent3(ctx) {
128513
129162
 
128514
129163
  // src/tools/syntax-check.ts
128515
129164
  import * as fs123 from "node:fs";
128516
- import * as path165 from "node:path";
129165
+ import * as path166 from "node:path";
128517
129166
  init_zod();
128518
129167
  init_manager2();
128519
129168
  init_detector();
@@ -128585,7 +129234,7 @@ async function syntaxCheck(input, directory, config3) {
128585
129234
  if (languages?.length) {
128586
129235
  const lowerLangs = languages.map((l) => l.toLowerCase());
128587
129236
  filesToCheck = filesToCheck.filter((file3) => {
128588
- const ext = path165.extname(file3.path).toLowerCase();
129237
+ const ext = path166.extname(file3.path).toLowerCase();
128589
129238
  const langDef = getLanguageForExtension(ext);
128590
129239
  const fileProfile = getProfileForFile(file3.path);
128591
129240
  const langId = fileProfile?.id || langDef?.id;
@@ -128595,7 +129244,7 @@ async function syntaxCheck(input, directory, config3) {
128595
129244
  const { loadGrammar: loadGrammar2 } = await Promise.resolve().then(() => (init_runtime(), exports_runtime));
128596
129245
  async function checkOneFile(fileInfo) {
128597
129246
  const { path: filePath } = fileInfo;
128598
- const fullPath = path165.isAbsolute(filePath) ? filePath : path165.join(directory, filePath);
129247
+ const fullPath = path166.isAbsolute(filePath) ? filePath : path166.join(directory, filePath);
128599
129248
  const result = {
128600
129249
  path: filePath,
128601
129250
  language: "",
@@ -128642,7 +129291,7 @@ async function syntaxCheck(input, directory, config3) {
128642
129291
  result.skipped_reason = "binary_file";
128643
129292
  return { result, counted: false, failed: false, skipped: true };
128644
129293
  }
128645
- const ext = path165.extname(filePath).toLowerCase();
129294
+ const ext = path166.extname(filePath).toLowerCase();
128646
129295
  const langDef = getLanguageForExtension(ext);
128647
129296
  result.language = profile?.id || langDef?.id || "unknown";
128648
129297
  const errors5 = extractSyntaxErrors(parser, content);
@@ -128754,7 +129403,7 @@ init_utils();
128754
129403
  init_create_tool();
128755
129404
  init_path_security();
128756
129405
  import * as fs124 from "node:fs";
128757
- import * as path166 from "node:path";
129406
+ import * as path167 from "node:path";
128758
129407
  var MAX_TEXT_LENGTH = 200;
128759
129408
  var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
128760
129409
  var SUPPORTED_EXTENSIONS4 = new Set([
@@ -128820,9 +129469,9 @@ function validatePathsInput(paths, cwd) {
128820
129469
  return { error: "paths contains path traversal", resolvedPath: null };
128821
129470
  }
128822
129471
  try {
128823
- const resolvedPath = path166.resolve(paths);
128824
- const normalizedCwd = path166.resolve(cwd);
128825
- const normalizedResolved = path166.resolve(resolvedPath);
129472
+ const resolvedPath = path167.resolve(paths);
129473
+ const normalizedCwd = path167.resolve(cwd);
129474
+ const normalizedResolved = path167.resolve(resolvedPath);
128826
129475
  if (!normalizedResolved.startsWith(normalizedCwd)) {
128827
129476
  return {
128828
129477
  error: "paths must be within the current working directory",
@@ -128838,7 +129487,7 @@ function validatePathsInput(paths, cwd) {
128838
129487
  }
128839
129488
  }
128840
129489
  function isSupportedExtension(filePath) {
128841
- const ext = path166.extname(filePath).toLowerCase();
129490
+ const ext = path167.extname(filePath).toLowerCase();
128842
129491
  return SUPPORTED_EXTENSIONS4.has(ext);
128843
129492
  }
128844
129493
  function findSourceFiles4(dir, files = []) {
@@ -128853,7 +129502,7 @@ function findSourceFiles4(dir, files = []) {
128853
129502
  if (SKIP_DIRECTORIES6.has(entry)) {
128854
129503
  continue;
128855
129504
  }
128856
- const fullPath = path166.join(dir, entry);
129505
+ const fullPath = path167.join(dir, entry);
128857
129506
  let stat9;
128858
129507
  try {
128859
129508
  stat9 = fs124.statSync(fullPath);
@@ -128965,7 +129614,7 @@ var todo_extract = createSwarmTool({
128965
129614
  filesToScan.push(scanPath);
128966
129615
  } else {
128967
129616
  const errorResult = {
128968
- error: `unsupported file extension: ${path166.extname(scanPath)}`,
129617
+ error: `unsupported file extension: ${path167.extname(scanPath)}`,
128969
129618
  total: 0,
128970
129619
  byPriority: { high: 0, medium: 0, low: 0 },
128971
129620
  entries: []
@@ -129015,18 +129664,18 @@ init_schema();
129015
129664
  init_qa_gate_profile();
129016
129665
  init_gate_evidence();
129017
129666
  import * as fs128 from "node:fs";
129018
- import * as path170 from "node:path";
129667
+ import * as path171 from "node:path";
129019
129668
 
129020
129669
  // src/hooks/diff-scope.ts
129021
129670
  init_bun_compat();
129022
129671
  import * as fs126 from "node:fs";
129023
- import * as path168 from "node:path";
129672
+ import * as path169 from "node:path";
129024
129673
 
129025
129674
  // src/utils/gitignore-warning.ts
129026
129675
  init_bun_compat();
129027
129676
  import * as fs125 from "node:fs";
129028
- import * as path167 from "node:path";
129029
- var _internals74 = { bunSpawn };
129677
+ import * as path168 from "node:path";
129678
+ var _internals76 = { bunSpawn };
129030
129679
  var _swarmGitExcludedChecked = false;
129031
129680
  function fileCoversSwarm(content) {
129032
129681
  for (const rawLine of content.split(`
@@ -129059,7 +129708,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
129059
129708
  checkIgnoreExitCode
129060
129709
  ] = await Promise.all([
129061
129710
  (async () => {
129062
- const proc = _internals74.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
129711
+ const proc = _internals76.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
129063
129712
  try {
129064
129713
  return await Promise.all([proc.exited, proc.stdout.text()]);
129065
129714
  } finally {
@@ -129069,7 +129718,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
129069
129718
  }
129070
129719
  })(),
129071
129720
  (async () => {
129072
- const proc = _internals74.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
129721
+ const proc = _internals76.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
129073
129722
  try {
129074
129723
  return await Promise.all([proc.exited, proc.stdout.text()]);
129075
129724
  } finally {
@@ -129079,7 +129728,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
129079
129728
  }
129080
129729
  })(),
129081
129730
  (async () => {
129082
- const proc = _internals74.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
129731
+ const proc = _internals76.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
129083
129732
  try {
129084
129733
  return await proc.exited;
129085
129734
  } finally {
@@ -129099,10 +129748,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
129099
129748
  const excludeRelPath = excludePathRaw.trim();
129100
129749
  if (!excludeRelPath)
129101
129750
  return;
129102
- const excludePath = path167.isAbsolute(excludeRelPath) ? excludeRelPath : path167.join(directory, excludeRelPath);
129751
+ const excludePath = path168.isAbsolute(excludeRelPath) ? excludeRelPath : path168.join(directory, excludeRelPath);
129103
129752
  if (checkIgnoreExitCode !== 0) {
129104
129753
  try {
129105
- fs125.mkdirSync(path167.dirname(excludePath), { recursive: true });
129754
+ fs125.mkdirSync(path168.dirname(excludePath), { recursive: true });
129106
129755
  let existing = "";
129107
129756
  try {
129108
129757
  existing = fs125.readFileSync(excludePath, "utf8");
@@ -129118,7 +129767,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
129118
129767
  }
129119
129768
  } catch {}
129120
129769
  }
129121
- const trackedProc = _internals74.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
129770
+ const trackedProc = _internals76.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
129122
129771
  let trackedExitCode;
129123
129772
  let trackedOutput;
129124
129773
  try {
@@ -129143,10 +129792,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
129143
129792
  }
129144
129793
 
129145
129794
  // src/hooks/diff-scope.ts
129146
- var _internals75 = { bunSpawn };
129795
+ var _internals77 = { bunSpawn };
129147
129796
  function getDeclaredScope(taskId, directory) {
129148
129797
  try {
129149
- const planPath = path168.join(directory, ".swarm", "plan.json");
129798
+ const planPath = path169.join(directory, ".swarm", "plan.json");
129150
129799
  if (!fs126.existsSync(planPath))
129151
129800
  return null;
129152
129801
  const raw = fs126.readFileSync(planPath, "utf-8");
@@ -129178,7 +129827,7 @@ var GIT_DIFF_SPAWN_OPTIONS = {
129178
129827
  };
129179
129828
  async function getChangedFiles(directory) {
129180
129829
  try {
129181
- const proc = _internals75.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
129830
+ const proc = _internals77.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
129182
129831
  cwd: directory,
129183
129832
  ...GIT_DIFF_SPAWN_OPTIONS
129184
129833
  });
@@ -129195,7 +129844,7 @@ async function getChangedFiles(directory) {
129195
129844
  return stdout.trim().split(`
129196
129845
  `).map((f) => f.trim()).filter((f) => f.length > 0);
129197
129846
  }
129198
- const proc2 = _internals75.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
129847
+ const proc2 = _internals77.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
129199
129848
  cwd: directory,
129200
129849
  ...GIT_DIFF_SPAWN_OPTIONS
129201
129850
  });
@@ -129252,8 +129901,8 @@ init_telemetry();
129252
129901
  // src/turbo/lean/task-completion.ts
129253
129902
  init_file_locks();
129254
129903
  import * as fs127 from "node:fs";
129255
- import * as path169 from "node:path";
129256
- var _internals76 = {
129904
+ import * as path170 from "node:path";
129905
+ var _internals78 = {
129257
129906
  listActiveLocks,
129258
129907
  verifyLeanTurboTaskCompletion
129259
129908
  };
@@ -129271,7 +129920,7 @@ var TIER_3_PATTERNS = [
129271
129920
  ];
129272
129921
  function matchesTier3Pattern(files) {
129273
129922
  for (const file3 of files) {
129274
- const fileName = path169.basename(file3);
129923
+ const fileName = path170.basename(file3);
129275
129924
  for (const pattern of TIER_3_PATTERNS) {
129276
129925
  if (pattern.test(fileName)) {
129277
129926
  return true;
@@ -129283,7 +129932,7 @@ function matchesTier3Pattern(files) {
129283
129932
  function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
129284
129933
  let persisted = null;
129285
129934
  try {
129286
- const statePath = path169.join(directory, ".swarm", "turbo-state.json");
129935
+ const statePath = path170.join(directory, ".swarm", "turbo-state.json");
129287
129936
  if (!fs127.existsSync(statePath)) {
129288
129937
  return {
129289
129938
  ok: false,
@@ -129367,11 +130016,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
129367
130016
  };
129368
130017
  }
129369
130018
  const phase = runState.phase ?? 0;
129370
- const evidencePath = path169.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
129371
- const expectedDir = path169.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
129372
- const resolvedPath = path169.resolve(evidencePath);
129373
- const resolvedDir = path169.resolve(expectedDir);
129374
- if (!resolvedPath.startsWith(resolvedDir + path169.sep) && resolvedPath !== resolvedDir) {
130019
+ const evidencePath = path170.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
130020
+ const expectedDir = path170.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
130021
+ const resolvedPath = path170.resolve(evidencePath);
130022
+ const resolvedDir = path170.resolve(expectedDir);
130023
+ if (!resolvedPath.startsWith(resolvedDir + path170.sep) && resolvedPath !== resolvedDir) {
129375
130024
  return {
129376
130025
  ok: false,
129377
130026
  reason: `Lane ID causes path traversal: ${lane.laneId}`,
@@ -129395,7 +130044,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
129395
130044
  }
129396
130045
  };
129397
130046
  }
129398
- const activeLocks = _internals76.listActiveLocks(directory);
130047
+ const activeLocks = _internals78.listActiveLocks(directory);
129399
130048
  const laneLocks = activeLocks.filter((lock) => lock.laneId === lane.laneId);
129400
130049
  if (laneLocks.length > 0) {
129401
130050
  return {
@@ -129411,7 +130060,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
129411
130060
  }
129412
130061
  let filesTouched = [];
129413
130062
  try {
129414
- const planPath = path169.join(directory, ".swarm", "plan.json");
130063
+ const planPath = path170.join(directory, ".swarm", "plan.json");
129415
130064
  const planRaw = fs127.readFileSync(planPath, "utf-8");
129416
130065
  const plan = JSON.parse(planRaw);
129417
130066
  for (const planPhase of plan.phases ?? []) {
@@ -129495,7 +130144,7 @@ var TIER_3_PATTERNS2 = [
129495
130144
  ];
129496
130145
  function matchesTier3Pattern2(files) {
129497
130146
  for (const file3 of files) {
129498
- const fileName = path170.basename(file3);
130147
+ const fileName = path171.basename(file3);
129499
130148
  for (const pattern of TIER_3_PATTERNS2) {
129500
130149
  if (pattern.test(fileName)) {
129501
130150
  return true;
@@ -129534,7 +130183,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
129534
130183
  if (!skipStandardTurboBypass && hasActiveTurboMode()) {
129535
130184
  const resolvedDir2 = workingDirectory;
129536
130185
  try {
129537
- const planPath = path170.join(resolvedDir2, ".swarm", "plan.json");
130186
+ const planPath = path171.join(resolvedDir2, ".swarm", "plan.json");
129538
130187
  const planRaw = fs128.readFileSync(planPath, "utf-8");
129539
130188
  const plan = JSON.parse(planRaw);
129540
130189
  for (const planPhase of plan.phases ?? []) {
@@ -129612,7 +130261,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
129612
130261
  }
129613
130262
  if (resolvedDir) {
129614
130263
  try {
129615
- const planPath = path170.join(resolvedDir, ".swarm", "plan.json");
130264
+ const planPath = path171.join(resolvedDir, ".swarm", "plan.json");
129616
130265
  const planRaw = fs128.readFileSync(planPath, "utf-8");
129617
130266
  const plan = JSON.parse(planRaw);
129618
130267
  for (const planPhase of plan.phases ?? []) {
@@ -129854,7 +130503,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
129854
130503
  };
129855
130504
  }
129856
130505
  directory = resolveResult.directory;
129857
- const planPath = path170.join(directory, ".swarm", "plan.json");
130506
+ const planPath = path171.join(directory, ".swarm", "plan.json");
129858
130507
  if (!fs128.existsSync(planPath)) {
129859
130508
  return {
129860
130509
  success: false,
@@ -129863,9 +130512,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
129863
130512
  };
129864
130513
  }
129865
130514
  if (fallbackDir && directory !== fallbackDir) {
129866
- const canonicalDir = fs128.realpathSync(path170.resolve(directory));
129867
- const canonicalRoot = fs128.realpathSync(path170.resolve(fallbackDir));
129868
- if (canonicalDir.startsWith(canonicalRoot + path170.sep)) {
130515
+ const canonicalDir = fs128.realpathSync(path171.resolve(directory));
130516
+ const canonicalRoot = fs128.realpathSync(path171.resolve(fallbackDir));
130517
+ if (canonicalDir.startsWith(canonicalRoot + path171.sep)) {
129869
130518
  return {
129870
130519
  success: false,
129871
130520
  message: `Invalid working_directory: "${directory}" is a subdirectory of ` + `the project root "${fallbackDir}". Pass the project root path or ` + `omit working_directory entirely.`,
@@ -129877,8 +130526,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
129877
130526
  }
129878
130527
  if (args2.status === "in_progress") {
129879
130528
  try {
129880
- const evidencePath = path170.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
129881
- fs128.mkdirSync(path170.dirname(evidencePath), { recursive: true });
130529
+ const evidencePath = path171.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
130530
+ fs128.mkdirSync(path171.dirname(evidencePath), { recursive: true });
129882
130531
  const fd = fs128.openSync(evidencePath, "wx");
129883
130532
  let writeOk = false;
129884
130533
  try {
@@ -129902,7 +130551,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
129902
130551
  recoverTaskStateFromDelegations(args2.task_id, directory);
129903
130552
  let phaseRequiresReviewer = true;
129904
130553
  try {
129905
- const planPath2 = path170.join(directory, ".swarm", "plan.json");
130554
+ const planPath2 = path171.join(directory, ".swarm", "plan.json");
129906
130555
  const planRaw = fs128.readFileSync(planPath2, "utf-8");
129907
130556
  const plan = JSON.parse(planRaw);
129908
130557
  const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
@@ -130199,7 +130848,7 @@ init_utils2();
130199
130848
  init_redaction();
130200
130849
  import { createHash as createHash13 } from "node:crypto";
130201
130850
  import { appendFile as appendFile14, mkdir as mkdir24 } from "node:fs/promises";
130202
- import * as path171 from "node:path";
130851
+ import * as path172 from "node:path";
130203
130852
  var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
130204
130853
  var MAX_EVIDENCE_TEXT_LENGTH = 4000;
130205
130854
  async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
@@ -130207,7 +130856,7 @@ async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
130207
130856
  const capturedAt = now().toISOString();
130208
130857
  const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
130209
130858
  if (records.length > 0) {
130210
- await mkdir24(path171.dirname(filePath), { recursive: true });
130859
+ await mkdir24(path172.dirname(filePath), { recursive: true });
130211
130860
  await appendFile14(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
130212
130861
  `)}
130213
130862
  `, "utf-8");
@@ -130373,7 +131022,7 @@ var web_search = createSwarmTool({
130373
131022
  });
130374
131023
  async function captureSearchEvidence(directory, query, results) {
130375
131024
  try {
130376
- const written = await _internals77.writeEvidenceDocuments(directory, results.map((result) => ({
131025
+ const written = await _internals79.writeEvidenceDocuments(directory, results.map((result) => ({
130377
131026
  sourceType: "web_search",
130378
131027
  query,
130379
131028
  title: result.title,
@@ -130401,7 +131050,7 @@ async function captureSearchEvidence(directory, query, results) {
130401
131050
  };
130402
131051
  }
130403
131052
  }
130404
- var _internals77 = {
131053
+ var _internals79 = {
130405
131054
  writeEvidenceDocuments
130406
131055
  };
130407
131056
 
@@ -130415,7 +131064,7 @@ init_schema3();
130415
131064
  init_store();
130416
131065
  init_create_tool();
130417
131066
  init_resolve_working_directory();
130418
- import * as path172 from "node:path";
131067
+ import * as path173 from "node:path";
130419
131068
  var FindingSchema2 = exports_external.object({
130420
131069
  severity: exports_external.enum(["low", "medium", "high", "critical"]),
130421
131070
  category: exports_external.string().min(1),
@@ -130479,7 +131128,7 @@ var write_architecture_supervisor_evidence = createSwarmTool({
130479
131128
  if (config3.architectural_supervision?.persist_knowledge_recommendations && args2.knowledge_recommendations.length > 0) {
130480
131129
  const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
130481
131130
  const lessons = args2.knowledge_recommendations.map((r) => r.lesson);
130482
- const result = await curateAndStoreSwarm(lessons, path172.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, { skipAutoPromotion: true });
131131
+ const result = await curateAndStoreSwarm(lessons, path173.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, { skipAutoPromotion: true });
130483
131132
  knowledgeProposed = result.stored;
130484
131133
  }
130485
131134
  } catch {}
@@ -130515,7 +131164,7 @@ init_ledger();
130515
131164
  init_manager();
130516
131165
  init_create_tool();
130517
131166
  import fs129 from "node:fs";
130518
- import path173 from "node:path";
131167
+ import path174 from "node:path";
130519
131168
  function normalizeVerdict(verdict) {
130520
131169
  switch (verdict) {
130521
131170
  case "APPROVED":
@@ -130563,7 +131212,7 @@ async function executeWriteDriftEvidence(args2, directory) {
130563
131212
  entries: [evidenceEntry]
130564
131213
  };
130565
131214
  const filename = "drift-verifier.json";
130566
- const relativePath = path173.join("evidence", String(phase), filename);
131215
+ const relativePath = path174.join("evidence", String(phase), filename);
130567
131216
  let validatedPath;
130568
131217
  try {
130569
131218
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -130574,10 +131223,10 @@ async function executeWriteDriftEvidence(args2, directory) {
130574
131223
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
130575
131224
  }, null, 2);
130576
131225
  }
130577
- const evidenceDir = path173.dirname(validatedPath);
131226
+ const evidenceDir = path174.dirname(validatedPath);
130578
131227
  try {
130579
131228
  await fs129.promises.mkdir(evidenceDir, { recursive: true });
130580
- const tempPath = path173.join(evidenceDir, `.${filename}.tmp`);
131229
+ const tempPath = path174.join(evidenceDir, `.${filename}.tmp`);
130581
131230
  await fs129.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
130582
131231
  await fs129.promises.rename(tempPath, validatedPath);
130583
131232
  let snapshotInfo;
@@ -130674,7 +131323,7 @@ var write_drift_evidence = createSwarmTool({
130674
131323
  init_zod();
130675
131324
  init_loader();
130676
131325
  import fs130 from "node:fs";
130677
- import path174 from "node:path";
131326
+ import path175 from "node:path";
130678
131327
  init_utils2();
130679
131328
  init_manager();
130680
131329
  init_create_tool();
@@ -130768,7 +131417,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
130768
131417
  timestamp: synthesis.timestamp
130769
131418
  };
130770
131419
  const filename = "final-council.json";
130771
- const relativePath = path174.join("evidence", filename);
131420
+ const relativePath = path175.join("evidence", filename);
130772
131421
  let validatedPath;
130773
131422
  try {
130774
131423
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -130782,10 +131431,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
130782
131431
  const evidenceContent = {
130783
131432
  entries: [evidenceEntry]
130784
131433
  };
130785
- const evidenceDir = path174.dirname(validatedPath);
131434
+ const evidenceDir = path175.dirname(validatedPath);
130786
131435
  try {
130787
131436
  await fs130.promises.mkdir(evidenceDir, { recursive: true });
130788
- const tempPath = path174.join(evidenceDir, `.${filename}.tmp`);
131437
+ const tempPath = path175.join(evidenceDir, `.${filename}.tmp`);
130789
131438
  await fs130.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
130790
131439
  await fs130.promises.rename(tempPath, validatedPath);
130791
131440
  return JSON.stringify({
@@ -130845,7 +131494,7 @@ init_zod();
130845
131494
  init_utils2();
130846
131495
  init_create_tool();
130847
131496
  import fs131 from "node:fs";
130848
- import path175 from "node:path";
131497
+ import path176 from "node:path";
130849
131498
  function normalizeVerdict2(verdict) {
130850
131499
  switch (verdict) {
130851
131500
  case "APPROVED":
@@ -130893,7 +131542,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
130893
131542
  entries: [evidenceEntry]
130894
131543
  };
130895
131544
  const filename = "hallucination-guard.json";
130896
- const relativePath = path175.join("evidence", String(phase), filename);
131545
+ const relativePath = path176.join("evidence", String(phase), filename);
130897
131546
  let validatedPath;
130898
131547
  try {
130899
131548
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -130904,10 +131553,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
130904
131553
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
130905
131554
  }, null, 2);
130906
131555
  }
130907
- const evidenceDir = path175.dirname(validatedPath);
131556
+ const evidenceDir = path176.dirname(validatedPath);
130908
131557
  try {
130909
131558
  await fs131.promises.mkdir(evidenceDir, { recursive: true });
130910
- const tempPath = path175.join(evidenceDir, `.${filename}.tmp`);
131559
+ const tempPath = path176.join(evidenceDir, `.${filename}.tmp`);
130911
131560
  await fs131.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
130912
131561
  await fs131.promises.rename(tempPath, validatedPath);
130913
131562
  return JSON.stringify({
@@ -130957,7 +131606,7 @@ init_zod();
130957
131606
  init_utils2();
130958
131607
  init_create_tool();
130959
131608
  import fs132 from "node:fs";
130960
- import path176 from "node:path";
131609
+ import path177 from "node:path";
130961
131610
  function normalizeVerdict3(verdict) {
130962
131611
  switch (verdict) {
130963
131612
  case "PASS":
@@ -131031,7 +131680,7 @@ async function executeWriteMutationEvidence(args2, directory) {
131031
131680
  entries: [evidenceEntry]
131032
131681
  };
131033
131682
  const filename = "mutation-gate.json";
131034
- const relativePath = path176.join("evidence", String(phase), filename);
131683
+ const relativePath = path177.join("evidence", String(phase), filename);
131035
131684
  let validatedPath;
131036
131685
  try {
131037
131686
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -131042,10 +131691,10 @@ async function executeWriteMutationEvidence(args2, directory) {
131042
131691
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
131043
131692
  }, null, 2);
131044
131693
  }
131045
- const evidenceDir = path176.dirname(validatedPath);
131694
+ const evidenceDir = path177.dirname(validatedPath);
131046
131695
  try {
131047
131696
  await fs132.promises.mkdir(evidenceDir, { recursive: true });
131048
- const tempPath = path176.join(evidenceDir, `.${filename}.tmp`);
131697
+ const tempPath = path177.join(evidenceDir, `.${filename}.tmp`);
131049
131698
  await fs132.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
131050
131699
  await fs132.promises.rename(tempPath, validatedPath);
131051
131700
  return JSON.stringify({
@@ -131233,7 +131882,7 @@ ${footerLines.join(`
131233
131882
  init_warning_buffer();
131234
131883
  var _heartbeatTimers = new Map;
131235
131884
  var SWARM_COMMAND_SYSTEM_RULE_TAG = "[opencode-swarm:swarm-command-rule]";
131236
- var PACKAGE_ROOT2 = path178.resolve(path178.dirname(fileURLToPath5(import.meta.url)), "..");
131885
+ var PACKAGE_ROOT2 = path179.resolve(path179.dirname(fileURLToPath5(import.meta.url)), "..");
131237
131886
  function createSwarmCommandSystemRuleHook(agentDefinitions, registeredAgents) {
131238
131887
  return async (input, output) => {
131239
131888
  const { sessionID } = input;
@@ -131503,7 +132152,7 @@ async function initializeOpenCodeSwarm(ctx) {
131503
132152
  const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
131504
132153
  preflightTriggerManager = new PTM(automationConfig);
131505
132154
  const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
131506
- const swarmDir = path178.resolve(ctx.directory, ".swarm");
132155
+ const swarmDir = path179.resolve(ctx.directory, ".swarm");
131507
132156
  statusArtifact = new ASA(swarmDir);
131508
132157
  statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
131509
132158
  if (automationConfig.capabilities?.evidence_auto_summaries === true) {
@@ -132034,7 +132683,7 @@ ${promptRaw}`;
132034
132683
  const meta3 = readSkillMetadata(s.skillPath, ctx.directory);
132035
132684
  let desc = meta3.description || "";
132036
132685
  if (!desc || desc === "No description provided") {
132037
- desc = path178.basename(path178.dirname(s.skillPath));
132686
+ desc = path179.basename(path179.dirname(s.skillPath));
132038
132687
  }
132039
132688
  desc = desc.replace(/,/g, ";");
132040
132689
  return `file:${s.skillPath} (-- ${desc})`;
@@ -132044,7 +132693,7 @@ ${promptRaw}`;
132044
132693
 
132045
132694
  ${promptRaw}`;
132046
132695
  argsRecord.prompt = newPrompt;
132047
- const skillNames = topSkills.map((s) => `${path178.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
132696
+ const skillNames = topSkills.map((s) => `${path179.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
132048
132697
  console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
132049
132698
  for (const skill of topSkills) {
132050
132699
  try {