opencode-swarm 7.107.1 → 7.107.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -44,7 +44,7 @@ import {
44
44
  savePlan,
45
45
  transientBackoff,
46
46
  validateProjectRoot
47
- } from "./index-jjp5qrjv.js";
47
+ } from "./index-f12bmedv.js";
48
48
  import {
49
49
  _internals as _internals2,
50
50
  _internals1 as _internals3,
@@ -724,7 +724,7 @@ var init_restricted_environment_executor = __esm(() => {
724
724
 
725
725
  // src/sandbox/win32/native-sandbox-executor.ts
726
726
  import * as crypto3 from "crypto";
727
- import * as fs13 from "fs";
727
+ import * as fs12 from "fs";
728
728
  import * as os10 from "os";
729
729
  import * as path36 from "path";
730
730
 
@@ -790,10 +790,10 @@ class NativeWindowsSandboxExecutor {
790
790
  const policyJson = JSON.stringify(policy);
791
791
  const policyDir = path36.join(os10.tmpdir(), "swarm-sandbox-policies");
792
792
  try {
793
- fs13.mkdirSync(policyDir, { recursive: true });
793
+ fs12.mkdirSync(policyDir, { recursive: true });
794
794
  } catch {}
795
795
  const policyFile = path36.join(policyDir, `${runId}.json`);
796
- fs13.writeFileSync(policyFile, policyJson, "utf-8");
796
+ fs12.writeFileSync(policyFile, policyJson, "utf-8");
797
797
  const mode = this._probeResult.mode === "none" ? "auto" : this._probeResult.mode;
798
798
  const escapedBinary = binary.includes(" ") ? `"${binary}"` : binary;
799
799
  const escapedPolicyFile = policyFile.includes(" ") ? `"${policyFile}"` : policyFile;
@@ -924,7 +924,7 @@ var init_executor = __esm(() => {
924
924
  });
925
925
 
926
926
  // src/state.ts
927
- import * as fs33 from "fs/promises";
927
+ import * as fs32 from "fs/promises";
928
928
  import * as path68 from "path";
929
929
 
930
930
  // src/db/qa-gate-profile.ts
@@ -5646,7 +5646,7 @@ function getDeferredWarnings() {
5646
5646
  }
5647
5647
 
5648
5648
  // src/config/bundled-skills.ts
5649
- import * as fs2 from "fs";
5649
+ import { randomUUID as randomUUID3 } from "crypto";
5650
5650
  import * as fsp from "fs/promises";
5651
5651
  import * as path8 from "path";
5652
5652
  var BUNDLED_PROJECT_SKILLS = [
@@ -5679,10 +5679,6 @@ var BUNDLED_PROJECT_SKILLS = [
5679
5679
  ];
5680
5680
  var MAX_SKILL_FILES = 64;
5681
5681
  var MAX_SKILL_BYTES = 512000;
5682
- var syncedProjectSkillTargets = new Set;
5683
- function getSyncCacheKey(projectDirectory, packageRoot) {
5684
- return `${path8.resolve(projectDirectory)}\x00${path8.resolve(packageRoot)}`;
5685
- }
5686
5682
  function warnBundledSkillSyncFailure(err) {
5687
5683
  const message = err instanceof Error ? err.message : String(err);
5688
5684
  console.warn(`[opencode-swarm] Could not install bundled project skills; continuing without sync: ${message}`);
@@ -5737,7 +5733,7 @@ async function collectBundledSkillFilesBoundedAsync(sourceDir, state, relativeDi
5737
5733
  }
5738
5734
  return files;
5739
5735
  }
5740
- async function rollbackCopiedFilesAsync(copiedFiles, destDir) {
5736
+ async function rollbackCopiedFilesAsync(copiedFiles, destDir, overwrittenFiles = []) {
5741
5737
  const safeDestDir = path8.resolve(destDir);
5742
5738
  const dirs = new Set;
5743
5739
  for (const copiedFile of copiedFiles) {
@@ -5750,6 +5746,15 @@ async function rollbackCopiedFilesAsync(copiedFiles, destDir) {
5750
5746
  } catch {}
5751
5747
  dirs.add(path8.dirname(resolvedFile));
5752
5748
  }
5749
+ for (const overwritten of overwrittenFiles.reverse()) {
5750
+ const resolvedFile = path8.resolve(overwritten.path);
5751
+ const relative2 = path8.relative(safeDestDir, resolvedFile);
5752
+ if (relative2.startsWith("..") || path8.isAbsolute(relative2))
5753
+ continue;
5754
+ try {
5755
+ await fsp.writeFile(resolvedFile, overwritten.contents);
5756
+ } catch {}
5757
+ }
5753
5758
  for (const dir of [...dirs].sort((a, b) => b.length - a.length)) {
5754
5759
  const relative2 = path8.relative(safeDestDir, path8.resolve(dir));
5755
5760
  if (relative2.startsWith("..") || path8.isAbsolute(relative2))
@@ -5759,39 +5764,58 @@ async function rollbackCopiedFilesAsync(copiedFiles, destDir) {
5759
5764
  } catch {}
5760
5765
  }
5761
5766
  }
5767
+ async function copyFileAtomicAsync(sourcePath, destPath) {
5768
+ const tempPath = path8.join(path8.dirname(destPath), `.${path8.basename(destPath)}.tmp.${randomUUID3()}`);
5769
+ try {
5770
+ await fsp.copyFile(sourcePath, tempPath);
5771
+ await fsp.rename(tempPath, destPath);
5772
+ } catch (err) {
5773
+ try {
5774
+ await fsp.rm(tempPath, { force: true });
5775
+ } catch {}
5776
+ throw err;
5777
+ }
5778
+ }
5762
5779
  async function copyBundledDirectoryBoundedAsync(sourceDir, destDir) {
5763
5780
  const files = await collectBundledSkillFilesBoundedAsync(sourceDir, {
5764
5781
  files: 0,
5765
5782
  bytes: 0
5766
5783
  });
5767
5784
  const copiedFiles = [];
5785
+ const overwrittenFiles = [];
5768
5786
  try {
5769
5787
  for (const file of files) {
5770
5788
  const sourcePath = path8.join(sourceDir, file.relativePath);
5771
5789
  const destPath = path8.join(destDir, file.relativePath);
5772
5790
  await fsp.mkdir(path8.dirname(destPath), { recursive: true });
5773
- try {
5774
- await fsp.copyFile(sourcePath, destPath, fs2.constants.COPYFILE_EXCL);
5791
+ if (await pathExistsAsync(destPath)) {
5792
+ if (await isSymbolicLinkAsync(destPath)) {
5793
+ throw new Error("refusing to overwrite symlinked bundled skill file");
5794
+ }
5795
+ const [sourceContents, destContents] = await Promise.all([
5796
+ fsp.readFile(sourcePath),
5797
+ fsp.readFile(destPath)
5798
+ ]);
5799
+ if (sourceContents.equals(destContents)) {
5800
+ continue;
5801
+ }
5802
+ overwrittenFiles.push({ path: destPath, contents: destContents });
5803
+ await copyFileAtomicAsync(sourcePath, destPath);
5804
+ } else {
5805
+ await copyFileAtomicAsync(sourcePath, destPath);
5775
5806
  copiedFiles.push(destPath);
5776
- } catch (err) {
5777
- if (err.code !== "EEXIST")
5778
- throw err;
5779
5807
  }
5780
5808
  }
5781
5809
  } catch (err) {
5782
- await rollbackCopiedFilesAsync(copiedFiles, destDir);
5810
+ await rollbackCopiedFilesAsync(copiedFiles, destDir, overwrittenFiles);
5783
5811
  throw err;
5784
5812
  }
5785
5813
  }
5786
5814
  async function syncBundledProjectSkillsIfMissingAsync(projectDirectory, packageRoot, quiet = false) {
5787
5815
  try {
5788
- const cacheKey = getSyncCacheKey(projectDirectory, packageRoot);
5789
- if (syncedProjectSkillTargets.has(cacheKey))
5790
- return;
5791
5816
  const sourceRoot = path8.join(packageRoot, ".opencode", "skills");
5792
5817
  const opencodeDir = path8.join(projectDirectory, ".opencode");
5793
5818
  const skillsDir = path8.join(opencodeDir, "skills");
5794
- let sawBundledSource = false;
5795
5819
  if (!await ensureNotSymlinkedDirectoryAsync(opencodeDir))
5796
5820
  return;
5797
5821
  if (!await ensureNotSymlinkedDirectoryAsync(skillsDir))
@@ -5800,21 +5824,15 @@ async function syncBundledProjectSkillsIfMissingAsync(projectDirectory, packageR
5800
5824
  const sourceDir = path8.join(sourceRoot, slug);
5801
5825
  const sourceSkill = path8.join(sourceDir, "SKILL.md");
5802
5826
  const destDir = path8.join(skillsDir, slug);
5803
- const destSkill = path8.join(destDir, "SKILL.md");
5804
5827
  if (!await pathExistsAsync(sourceSkill))
5805
5828
  continue;
5806
- sawBundledSource = true;
5807
- if (await pathExistsAsync(destSkill))
5808
- continue;
5809
5829
  if (!await ensureNotSymlinkedDirectoryAsync(destDir))
5810
5830
  continue;
5811
5831
  await copyBundledDirectoryBoundedAsync(sourceDir, destDir);
5812
5832
  if (!quiet) {
5813
- console.warn(`[opencode-swarm] Installed bundled skill .opencode/skills/${slug}/SKILL.md for first-class /swarm command support`);
5833
+ console.warn(`[opencode-swarm] Synchronized bundled skill .opencode/skills/${slug}/SKILL.md for first-class /swarm command support`);
5814
5834
  }
5815
5835
  }
5816
- if (sawBundledSource)
5817
- syncedProjectSkillTargets.add(cacheKey);
5818
5836
  } catch (err) {
5819
5837
  if (!quiet)
5820
5838
  warnBundledSkillSyncFailure(err);
@@ -6092,7 +6110,7 @@ async function handleAutoProceedCommand(_directory, args, sessionID) {
6092
6110
  }
6093
6111
 
6094
6112
  // src/services/cost-accounting.ts
6095
- import * as fs3 from "fs";
6113
+ import * as fs2 from "fs";
6096
6114
  import * as os5 from "os";
6097
6115
  import * as path10 from "path";
6098
6116
  function summarizeTelemetryCosts(directory) {
@@ -6110,15 +6128,15 @@ function readTelemetryEvents(directory) {
6110
6128
  path10.join(swarmDir, "telemetry.jsonl.1"),
6111
6129
  path10.join(swarmDir, "telemetry.jsonl")
6112
6130
  ];
6113
- const tmpDir = fs3.mkdtempSync(path10.join(os5.tmpdir(), "telemetry-snapshot-"));
6131
+ const tmpDir = fs2.mkdtempSync(path10.join(os5.tmpdir(), "telemetry-snapshot-"));
6114
6132
  const snapshotFiles = [];
6115
6133
  try {
6116
6134
  for (const file of files) {
6117
- if (!fs3.existsSync(file))
6135
+ if (!fs2.existsSync(file))
6118
6136
  continue;
6119
6137
  const snap = path10.join(tmpDir, path10.basename(file));
6120
6138
  try {
6121
- fs3.copyFileSync(file, snap);
6139
+ fs2.copyFileSync(file, snap);
6122
6140
  snapshotFiles.push(snap);
6123
6141
  } catch {}
6124
6142
  }
@@ -6127,7 +6145,7 @@ function readTelemetryEvents(directory) {
6127
6145
  for (const file of snapshotFiles) {
6128
6146
  let content = "";
6129
6147
  try {
6130
- content = fs3.readFileSync(file, "utf-8");
6148
+ content = fs2.readFileSync(file, "utf-8");
6131
6149
  } catch {
6132
6150
  continue;
6133
6151
  }
@@ -6145,10 +6163,10 @@ function readTelemetryEvents(directory) {
6145
6163
  try {
6146
6164
  for (const f of snapshotFiles) {
6147
6165
  try {
6148
- fs3.unlinkSync(f);
6166
+ fs2.unlinkSync(f);
6149
6167
  } catch {}
6150
6168
  }
6151
- fs3.rmdirSync(tmpDir);
6169
+ fs2.rmdirSync(tmpDir);
6152
6170
  } catch {}
6153
6171
  return events;
6154
6172
  }
@@ -6672,7 +6690,7 @@ async function handleBrainstormCommand(_directory, args) {
6672
6690
 
6673
6691
  // src/tools/checkpoint.ts
6674
6692
  import * as child_process from "child_process";
6675
- import * as fs4 from "fs";
6693
+ import * as fs3 from "fs";
6676
6694
  import * as path11 from "path";
6677
6695
 
6678
6696
  // src/tools/create-tool.ts
@@ -6765,8 +6783,8 @@ function getCheckpointLogPath(directory) {
6765
6783
  function readCheckpointLog(directory) {
6766
6784
  const logPath = getCheckpointLogPath(directory);
6767
6785
  try {
6768
- if (fs4.existsSync(logPath)) {
6769
- const content = fs4.readFileSync(logPath, "utf-8");
6786
+ if (fs3.existsSync(logPath)) {
6787
+ const content = fs3.readFileSync(logPath, "utf-8");
6770
6788
  const parsed = JSON.parse(content);
6771
6789
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
6772
6790
  return { version: 1, checkpoints: [] };
@@ -6779,12 +6797,12 @@ function readCheckpointLog(directory) {
6779
6797
  function writeCheckpointLog(log2, directory) {
6780
6798
  const logPath = getCheckpointLogPath(directory);
6781
6799
  const dir = path11.dirname(logPath);
6782
- if (!fs4.existsSync(dir)) {
6783
- fs4.mkdirSync(dir, { recursive: true });
6800
+ if (!fs3.existsSync(dir)) {
6801
+ fs3.mkdirSync(dir, { recursive: true });
6784
6802
  }
6785
6803
  const tempPath = `${logPath}.tmp`;
6786
- fs4.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
6787
- fs4.renameSync(tempPath, logPath);
6804
+ fs3.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
6805
+ fs3.renameSync(tempPath, logPath);
6788
6806
  }
6789
6807
  function gitExec(args, cwd) {
6790
6808
  for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
@@ -6818,7 +6836,7 @@ function appendRetentionEvent(directory, event) {
6818
6836
  const eventsPath = path11.join(directory, ".swarm", "events.jsonl");
6819
6837
  const line = `${JSON.stringify({ ...event, timestamp: new Date().toISOString() })}
6820
6838
  `;
6821
- fs4.appendFileSync(eventsPath, line);
6839
+ fs3.appendFileSync(eventsPath, line);
6822
6840
  } catch {}
6823
6841
  }
6824
6842
  function getCurrentSha(directory) {
@@ -6922,13 +6940,13 @@ function handleRestore(label, directory) {
6922
6940
  error: `checkpoint not found: "${label}"`
6923
6941
  }, null, 2);
6924
6942
  }
6925
- gitExec(["reset", "--soft", checkpoint.sha], directory);
6943
+ gitExec(["reset", "--hard", checkpoint.sha], directory);
6926
6944
  return JSON.stringify({
6927
6945
  action: "restore",
6928
6946
  success: true,
6929
6947
  label,
6930
6948
  sha: checkpoint.sha,
6931
- message: `Restored to checkpoint: "${label}" (soft reset)`
6949
+ message: `Restored to checkpoint: "${label}" (hard reset)`
6932
6950
  }, null, 2);
6933
6951
  } catch (e) {
6934
6952
  const errorMessage = e instanceof Error ? `restore failed: ${e.message}` : "restore failed: unknown error";
@@ -6978,7 +6996,7 @@ function handleDelete(label, directory) {
6978
6996
  }
6979
6997
  }
6980
6998
  var checkpoint = createSwarmTool({
6981
- description: "Save, restore, list, and delete git checkpoints. " + "Use save to create a named snapshot, restore to return to a checkpoint (soft reset), " + "list to see all checkpoints, and delete to remove a checkpoint from the log. " + "Git commits are preserved on delete.",
6999
+ description: "Save, restore, list, and delete git checkpoints. " + "Use save to create a named snapshot, restore to return tracked files to a checkpoint, " + "list to see all checkpoints, and delete to remove a checkpoint from the log. " + "Git commits are preserved on delete.",
6982
7000
  args: {
6983
7001
  action: exports_external.string().describe("Action to perform: save, restore, list, or delete"),
6984
7002
  label: exports_external.string().optional().describe("Checkpoint label (required for save, restore, delete)")
@@ -7180,7 +7198,7 @@ async function handleClarifyCommand(_directory, args) {
7180
7198
  // src/commands/close.ts
7181
7199
  import { spawnSync as spawnSync2 } from "child_process";
7182
7200
  import * as fsSync from "fs";
7183
- import { promises as fs11 } from "fs";
7201
+ import { promises as fs10 } from "fs";
7184
7202
  import path27 from "path";
7185
7203
 
7186
7204
  // src/hooks/curator-postmortem.ts
@@ -7900,11 +7918,11 @@ var _internals8 = {
7900
7918
  return KnowledgeConfigSchema2.parse({});
7901
7919
  },
7902
7920
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig) => {
7903
- const { applyCuratorKnowledgeUpdates } = await import("./curator-np2ky29t.js");
7921
+ const { applyCuratorKnowledgeUpdates } = await import("./curator-6zvpn7fs.js");
7904
7922
  return applyCuratorKnowledgeUpdates(directory, recommendations, knowledgeConfig);
7905
7923
  },
7906
7924
  checkHivePromotions: async (entries, knowledgeConfig) => {
7907
- const { checkHivePromotions } = await import("./hive-promoter-y9r8d315.js");
7925
+ const { checkHivePromotions } = await import("./hive-promoter-nwcsha2j.js");
7908
7926
  return checkHivePromotions(entries, knowledgeConfig);
7909
7927
  },
7910
7928
  applyProposalTriage: async (directory, triage) => {
@@ -7964,8 +7982,8 @@ var _internals8 = {
7964
7982
  import path16 from "path";
7965
7983
 
7966
7984
  // src/hooks/curator.ts
7967
- import { randomUUID as randomUUID4 } from "crypto";
7968
- import * as fs6 from "fs";
7985
+ import { randomUUID as randomUUID5 } from "crypto";
7986
+ import * as fs5 from "fs";
7969
7987
  import * as path15 from "path";
7970
7988
 
7971
7989
  // src/hooks/knowledge-escalator.ts
@@ -8403,12 +8421,12 @@ function formatLearningSummary(metrics) {
8403
8421
 
8404
8422
  // src/services/skill-reviser.ts
8405
8423
  init_logger();
8406
- import { readFile as readFile4, rename as rename3, writeFile as writeFile4 } from "fs/promises";
8424
+ import { readFile as readFile5, rename as rename4, writeFile as writeFile5 } from "fs/promises";
8407
8425
 
8408
8426
  // src/services/skill-improver-quota.ts
8409
8427
  var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
8410
8428
  import { existsSync as existsSync8 } from "fs";
8411
- import { mkdir as mkdir4, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
8429
+ import { mkdir as mkdir4, readFile as readFile4, rename as rename3, writeFile as writeFile4 } from "fs/promises";
8412
8430
  import * as path13 from "path";
8413
8431
  var LOCK_ACQUIRE_TIMEOUT_MS = 1e4;
8414
8432
  var LOCK_RETRY_OPTS = {
@@ -8453,7 +8471,7 @@ async function readState(filePath) {
8453
8471
  if (!existsSync8(filePath))
8454
8472
  return null;
8455
8473
  try {
8456
- const raw = await readFile3(filePath, "utf-8");
8474
+ const raw = await readFile4(filePath, "utf-8");
8457
8475
  const parsed = JSON.parse(raw);
8458
8476
  if (typeof parsed.date !== "string" || typeof parsed.calls_used !== "number" || typeof parsed.max_calls !== "number" || parsed.window !== "utc" && parsed.window !== "local") {
8459
8477
  return null;
@@ -8466,8 +8484,8 @@ async function readState(filePath) {
8466
8484
  async function writeState(filePath, state) {
8467
8485
  await mkdir4(path13.dirname(filePath), { recursive: true });
8468
8486
  const tmp = `${filePath}.tmp-${process.pid}`;
8469
- await writeFile3(tmp, JSON.stringify(state, null, 2), "utf-8");
8470
- await rename2(tmp, filePath);
8487
+ await writeFile4(tmp, JSON.stringify(state, null, 2), "utf-8");
8488
+ await rename3(tmp, filePath);
8471
8489
  }
8472
8490
  async function getQuotaState(directory, opts) {
8473
8491
  const filePath = resolveQuotaPath(directory, opts.scope);
@@ -8544,7 +8562,7 @@ var MAX_REVISION_CALLS_PER_PHASE = 3;
8544
8562
  var DEFAULT_MAX_CALLS = 10;
8545
8563
  async function getSkillVersion(skillPath) {
8546
8564
  try {
8547
- const content = await readFile4(skillPath, "utf-8");
8565
+ const content = await readFile5(skillPath, "utf-8");
8548
8566
  const match = content.match(/^version:\s*(\d+)\s*$/m);
8549
8567
  return match ? parseInt(match[1], 10) : 1;
8550
8568
  } catch {
@@ -8681,8 +8699,8 @@ async function reviseSkill(params) {
8681
8699
  };
8682
8700
  }
8683
8701
  const tmpPath = `${params.skillPath}.tmp-${process.pid}-${Date.now()}`;
8684
- await writeFile4(tmpPath, revised, "utf-8");
8685
- await rename3(tmpPath, params.skillPath);
8702
+ await writeFile5(tmpPath, revised, "utf-8");
8703
+ await rename4(tmpPath, params.skillPath);
8686
8704
  const newVersion = params.currentVersion + 1;
8687
8705
  const entry = {
8688
8706
  version: newVersion,
@@ -8758,9 +8776,9 @@ async function reviseSkill(params) {
8758
8776
  };
8759
8777
  }
8760
8778
  const tmpPath = `${params.skillPath}.tmp-${process.pid}-${Date.now()}`;
8761
- await writeFile4(tmpPath, `${finalOutput}
8779
+ await writeFile5(tmpPath, `${finalOutput}
8762
8780
  `, "utf-8");
8763
- await rename3(tmpPath, params.skillPath);
8781
+ await rename4(tmpPath, params.skillPath);
8764
8782
  const newVersion = expectedVersion;
8765
8783
  const entry = {
8766
8784
  version: newVersion,
@@ -8814,7 +8832,7 @@ init_logger();
8814
8832
 
8815
8833
  // src/hooks/skill-usage-log.ts
8816
8834
  import * as crypto2 from "crypto";
8817
- import * as fs5 from "fs";
8835
+ import * as fs4 from "fs";
8818
8836
  import * as path14 from "path";
8819
8837
  function resolveLogPath(directory) {
8820
8838
  return validateSwarmPath(directory, "skill-usage.jsonl");
@@ -8824,16 +8842,16 @@ function normalizeComplianceVerdict(verdict) {
8824
8842
  }
8825
8843
  var _internals10 = {
8826
8844
  generateId: () => crypto2.randomUUID(),
8827
- appendFileSync: fs5.appendFileSync.bind(fs5),
8828
- readFileSync: fs5.readFileSync.bind(fs5),
8829
- writeFileSync: fs5.writeFileSync.bind(fs5),
8830
- renameSync: fs5.renameSync.bind(fs5),
8831
- mkdirSync: fs5.mkdirSync.bind(fs5),
8832
- existsSync: fs5.existsSync.bind(fs5),
8833
- statSync: fs5.statSync.bind(fs5),
8834
- openSync: fs5.openSync.bind(fs5),
8835
- readSync: fs5.readSync.bind(fs5),
8836
- closeSync: fs5.closeSync.bind(fs5),
8845
+ appendFileSync: fs4.appendFileSync.bind(fs4),
8846
+ readFileSync: fs4.readFileSync.bind(fs4),
8847
+ writeFileSync: fs4.writeFileSync.bind(fs4),
8848
+ renameSync: fs4.renameSync.bind(fs4),
8849
+ mkdirSync: fs4.mkdirSync.bind(fs4),
8850
+ existsSync: fs4.existsSync.bind(fs4),
8851
+ statSync: fs4.statSync.bind(fs4),
8852
+ openSync: fs4.openSync.bind(fs4),
8853
+ readSync: fs4.readSync.bind(fs4),
8854
+ closeSync: fs4.closeSync.bind(fs4),
8837
8855
  pruneSkillUsageLog,
8838
8856
  resolveSourceKnowledgeIds,
8839
8857
  applySkillUsageFeedback,
@@ -9340,7 +9358,7 @@ var _internals11 = {
9340
9358
  retireOrMarkStale,
9341
9359
  retireSkill,
9342
9360
  getArchivedKnowledgeIds,
9343
- readFileAsync: (filePath, encoding) => import("fs/promises").then((fs7) => fs7.readFile(filePath, encoding)),
9361
+ readFileAsync: (filePath, encoding) => import("fs/promises").then((fs6) => fs6.readFile(filePath, encoding)),
9344
9362
  readKnowledge,
9345
9363
  reviseSkill,
9346
9364
  getSkillVersion,
@@ -9567,16 +9585,16 @@ function arrayOfStrings(v) {
9567
9585
  function readLatestPostMortemDigest(directory) {
9568
9586
  try {
9569
9587
  const swarmDir = path15.join(directory, ".swarm");
9570
- if (!fs6.existsSync(swarmDir))
9588
+ if (!fs5.existsSync(swarmDir))
9571
9589
  return null;
9572
- const candidates = fs6.readdirSync(swarmDir).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name)).map((name) => {
9590
+ const candidates = fs5.readdirSync(swarmDir).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name)).map((name) => {
9573
9591
  const filePath = path15.join(swarmDir, name);
9574
- return { name, filePath, mtimeMs: fs6.statSync(filePath).mtimeMs };
9592
+ return { name, filePath, mtimeMs: fs5.statSync(filePath).mtimeMs };
9575
9593
  }).sort((a, b) => b.mtimeMs - a.mtimeMs);
9576
9594
  const latest = candidates[0];
9577
9595
  if (!latest)
9578
9596
  return null;
9579
- const content = fs6.readFileSync(latest.filePath, "utf-8");
9597
+ const content = fs5.readFileSync(latest.filePath, "utf-8");
9580
9598
  const summary = content.match(/SUMMARY:\s*\n([\s\S]*?)(?:\n[A-Z_]+:|\n##|$)/);
9581
9599
  const body = (summary?.[1]?.trim() || content.slice(0, 1500)).slice(0, 1500);
9582
9600
  return `${latest.name}
@@ -9613,7 +9631,7 @@ async function readCuratorSummary(directory) {
9613
9631
  }
9614
9632
  async function writeCuratorSummary(directory, summary) {
9615
9633
  const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
9616
- fs6.mkdirSync(path15.dirname(resolvedPath), { recursive: true });
9634
+ fs5.mkdirSync(path15.dirname(resolvedPath), { recursive: true });
9617
9635
  await bunWrite(resolvedPath, JSON.stringify(summary, null, 2));
9618
9636
  }
9619
9637
  function normalizeAgentName(name) {
@@ -10054,7 +10072,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
10054
10072
  if (knowledgeApplicationFindings.length > 0) {
10055
10073
  try {
10056
10074
  const evidenceDir = path15.join(directory, ".swarm", "evidence", String(phase));
10057
- fs6.mkdirSync(evidenceDir, { recursive: true });
10075
+ fs5.mkdirSync(evidenceDir, { recursive: true });
10058
10076
  const findingsPath = path15.join(evidenceDir, "curator-findings.json");
10059
10077
  await bunWrite(findingsPath, JSON.stringify({ findings: knowledgeApplicationFindings }, null, 2));
10060
10078
  } catch (err) {
@@ -10357,7 +10375,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
10357
10375
  }
10358
10376
  const now = new Date().toISOString();
10359
10377
  const newEntry = {
10360
- id: randomUUID4(),
10378
+ id: randomUUID5(),
10361
10379
  tier: "swarm",
10362
10380
  lesson,
10363
10381
  category: rec.category ?? "other",
@@ -10674,18 +10692,18 @@ async function promoteFromSwarm(directory, lessonId) {
10674
10692
  // src/hooks/knowledge-curator.ts
10675
10693
  import { createHash as createHash4 } from "crypto";
10676
10694
  import { existsSync as existsSync13 } from "fs";
10677
- import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
10695
+ import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile8, writeFile as writeFile8 } from "fs/promises";
10678
10696
  import * as path21 from "path";
10679
10697
 
10680
10698
  // src/services/synonym-map.ts
10681
10699
  var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
10682
10700
  import {
10683
10701
  mkdir as mkdir5,
10684
- readFile as readFile5,
10685
- rename as rename4,
10702
+ readFile as readFile6,
10703
+ rename as rename5,
10686
10704
  stat as stat3,
10687
10705
  unlink,
10688
- writeFile as writeFile5
10706
+ writeFile as writeFile6
10689
10707
  } from "fs/promises";
10690
10708
  import * as path17 from "path";
10691
10709
  var SYNONYM_MAP_FILENAME = "synonym-map.json";
@@ -10835,7 +10853,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
10835
10853
  const st = await stat3(filePath);
10836
10854
  if (st.size > ceiling)
10837
10855
  return emptySynonymMap();
10838
- const raw = await readFile5(filePath, "utf-8");
10856
+ const raw = await readFile6(filePath, "utf-8");
10839
10857
  return coerceSynonymMap(JSON.parse(raw), maxPairs);
10840
10858
  } catch {
10841
10859
  return emptySynonymMap();
@@ -10845,8 +10863,8 @@ async function writeSynonymMapAtomic(filePath, map) {
10845
10863
  await mkdir5(path17.dirname(filePath), { recursive: true });
10846
10864
  const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
10847
10865
  try {
10848
- await writeFile5(tmp, JSON.stringify(map, null, 2), "utf-8");
10849
- await rename4(tmp, filePath);
10866
+ await writeFile6(tmp, JSON.stringify(map, null, 2), "utf-8");
10867
+ await rename5(tmp, filePath);
10850
10868
  } finally {
10851
10869
  try {
10852
10870
  await unlink(tmp);
@@ -10919,17 +10937,17 @@ function reinforceSwarmKnowledgeEntry(entry, confirmation) {
10919
10937
 
10920
10938
  // src/hooks/micro-reflector.ts
10921
10939
  import { existsSync as existsSync12 } from "fs";
10922
- import { readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
10940
+ import { readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
10923
10941
  import * as path20 from "path";
10924
10942
  init_logger();
10925
10943
 
10926
10944
  // src/hooks/skill-propagation-gate.ts
10927
- import * as fs8 from "fs";
10945
+ import * as fs7 from "fs";
10928
10946
  import * as path19 from "path";
10929
10947
  init_logger();
10930
10948
 
10931
10949
  // src/hooks/skill-scoring.ts
10932
- import * as fs7 from "fs";
10950
+ import * as fs6 from "fs";
10933
10951
  import * as path18 from "path";
10934
10952
  var FREQUENCY_CAP = 10;
10935
10953
  var FREQUENCY_WEIGHT = 0.3;
@@ -11103,13 +11121,13 @@ function parseSkillFrontmatter(content, skillPath) {
11103
11121
  return meta;
11104
11122
  }
11105
11123
  function readFilePrefix(filePath) {
11106
- const fd = fs7.openSync(filePath, "r");
11124
+ const fd = fs6.openSync(filePath, "r");
11107
11125
  try {
11108
11126
  const buffer = Buffer.alloc(SKILL_FRONTMATTER_READ_BYTES);
11109
- const bytesRead = fs7.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
11127
+ const bytesRead = fs6.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
11110
11128
  return buffer.toString("utf-8", 0, bytesRead);
11111
11129
  } finally {
11112
- fs7.closeSync(fd);
11130
+ fs6.closeSync(fd);
11113
11131
  }
11114
11132
  }
11115
11133
  function readSkillMetadata(skillPath, directory) {
@@ -11258,7 +11276,7 @@ function formatSkillIndexWithContext(skills, directory) {
11258
11276
  const usageLogPath = path18.join(directory, ".swarm", "skill-usage.jsonl");
11259
11277
  let hasHistory = false;
11260
11278
  try {
11261
- const stat4 = fs7.statSync(usageLogPath);
11279
+ const stat4 = fs6.statSync(usageLogPath);
11262
11280
  hasHistory = stat4.size > 0;
11263
11281
  } catch {}
11264
11282
  if (!hasHistory) {
@@ -11421,13 +11439,13 @@ var SKILL_SEARCH_ROOTS = [
11421
11439
  ];
11422
11440
  var MAX_SCORING_SESSION_ENTRIES = 500;
11423
11441
  var _internals13 = {
11424
- readdirSync: fs8.readdirSync.bind(fs8),
11425
- existsSync: fs8.existsSync.bind(fs8),
11426
- statSync: fs8.statSync.bind(fs8),
11427
- mkdirSync: fs8.mkdirSync.bind(fs8),
11428
- appendFileSync: fs8.appendFileSync.bind(fs8),
11429
- readFileSync: fs8.readFileSync.bind(fs8),
11430
- writeFileSync: fs8.writeFileSync.bind(fs8),
11442
+ readdirSync: fs7.readdirSync.bind(fs7),
11443
+ existsSync: fs7.existsSync.bind(fs7),
11444
+ statSync: fs7.statSync.bind(fs7),
11445
+ mkdirSync: fs7.mkdirSync.bind(fs7),
11446
+ appendFileSync: fs7.appendFileSync.bind(fs7),
11447
+ readFileSync: fs7.readFileSync.bind(fs7),
11448
+ writeFileSync: fs7.writeFileSync.bind(fs7),
11431
11449
  skillPropagationGateBefore: null,
11432
11450
  skillPropagationTransformScan: null,
11433
11451
  SKILL_CAPABLE_AGENTS,
@@ -11948,7 +11966,7 @@ async function readTaskTrajectory(directory, taskId) {
11948
11966
  const filePath = validateSwarmPath(directory, rel);
11949
11967
  if (!existsSync12(filePath))
11950
11968
  return [];
11951
- const content = await readFile6(filePath, "utf-8");
11969
+ const content = await readFile7(filePath, "utf-8");
11952
11970
  const out = [];
11953
11971
  for (const line of content.split(`
11954
11972
  `)) {
@@ -12418,11 +12436,11 @@ async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BAT
12418
12436
  if (!existsSync13(filePath))
12419
12437
  return [];
12420
12438
  const consumed = [];
12421
- await transactFile(filePath, async (p) => readInsightJsonl(await readFile7(p, "utf-8").catch(() => "")), async (p, data) => {
12439
+ await transactFile(filePath, async (p) => readInsightJsonl(await readFile8(p, "utf-8").catch(() => "")), async (p, data) => {
12422
12440
  const body = data.length === 0 ? "" : `${data.map((c) => JSON.stringify(c)).join(`
12423
12441
  `)}
12424
12442
  `;
12425
- await writeFile7(p, body, "utf-8");
12443
+ await writeFile8(p, body, "utf-8");
12426
12444
  }, (all) => {
12427
12445
  if (all.length === 0)
12428
12446
  return null;
@@ -12902,7 +12920,7 @@ var _internals15 = {
12902
12920
 
12903
12921
  // src/scope/scope-persistence.ts
12904
12922
  var import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
12905
- import * as fs9 from "fs";
12923
+ import * as fs8 from "fs";
12906
12924
  import * as path22 from "path";
12907
12925
  var DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
12908
12926
  var LOCK_STALE_MS = 30 * 1000;
@@ -12938,12 +12956,12 @@ function getScopesDir(directory) {
12938
12956
  }
12939
12957
  function clearAllScopes(directory) {
12940
12958
  try {
12941
- fs9.rmSync(getScopesDir(directory), { recursive: true, force: true });
12959
+ fs8.rmSync(getScopesDir(directory), { recursive: true, force: true });
12942
12960
  } catch {}
12943
12961
  }
12944
12962
 
12945
12963
  // src/services/session-reflection.ts
12946
- import { promises as fs10 } from "fs";
12964
+ import { promises as fs9 } from "fs";
12947
12965
  import * as path23 from "path";
12948
12966
 
12949
12967
  // src/hooks/abort-utils.ts
@@ -13106,12 +13124,12 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
13106
13124
  const taxonomy = {};
13107
13125
  try {
13108
13126
  const evidenceDir = path23.join(directory, ".swarm", "evidence");
13109
- const entries = await fs10.readdir(evidenceDir);
13127
+ const entries = await fs9.readdir(evidenceDir);
13110
13128
  const retroDirs = entries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
13111
13129
  for (const retroDir of retroDirs) {
13112
13130
  const evidencePath = path23.join(evidenceDir, retroDir, "evidence.json");
13113
13131
  try {
13114
- const content = await fs10.readFile(evidencePath, "utf-8");
13132
+ const content = await fs9.readFile(evidencePath, "utf-8");
13115
13133
  const parsed = JSON.parse(content);
13116
13134
  const bundleEntries = parsed.entries ?? [parsed];
13117
13135
  for (const entry of bundleEntries) {
@@ -13139,13 +13157,13 @@ async function gatherGateFailures(directory) {
13139
13157
  const failures = new Map;
13140
13158
  try {
13141
13159
  const evidenceDir = path23.join(directory, ".swarm", "evidence");
13142
- const entries = await fs10.readdir(evidenceDir);
13160
+ const entries = await fs9.readdir(evidenceDir);
13143
13161
  for (const entry of entries) {
13144
13162
  if (entry.startsWith("retro-"))
13145
13163
  continue;
13146
13164
  const evidencePath = path23.join(evidenceDir, entry, "evidence.json");
13147
13165
  try {
13148
- const content = await fs10.readFile(evidencePath, "utf-8");
13166
+ const content = await fs9.readFile(evidencePath, "utf-8");
13149
13167
  const parsed = JSON.parse(content);
13150
13168
  const bundleEntries = parsed.entries ?? [parsed];
13151
13169
  for (const e of bundleEntries) {
@@ -13337,18 +13355,18 @@ async function writeSessionReflection(directory, result) {
13337
13355
  lines.push(result.architectReport);
13338
13356
  const content = lines.join(`
13339
13357
  `);
13340
- await fs10.writeFile(reflectionPath, content, "utf-8");
13358
+ await fs9.writeFile(reflectionPath, content, "utf-8");
13341
13359
  return reflectionPath;
13342
13360
  }
13343
13361
 
13344
13362
  // src/services/skill-improver.ts
13345
13363
  import { existsSync as existsSync15 } from "fs";
13346
- import { mkdir as mkdir8, readFile as readFile8, rename as rename5, writeFile as writeFile9 } from "fs/promises";
13364
+ import { mkdir as mkdir8, readFile as readFile9, rename as rename6, writeFile as writeFile10 } from "fs/promises";
13347
13365
  import * as path25 from "path";
13348
13366
  init_logger();
13349
13367
 
13350
13368
  // src/services/trajectory-cluster.ts
13351
- import { mkdir as mkdir7, writeFile as writeFile8 } from "fs/promises";
13369
+ import { mkdir as mkdir7, writeFile as writeFile9 } from "fs/promises";
13352
13370
  import * as path24 from "path";
13353
13371
  init_logger();
13354
13372
  var MACRO_TRAJECTORY_WINDOW = 200;
@@ -13486,7 +13504,7 @@ async function writeMotifProposals(directory, opts = {}) {
13486
13504
  for (const motif of motifs.slice(0, max)) {
13487
13505
  const slug = `motif-${slugify(motif.signature)}`;
13488
13506
  const filePath = path24.join(proposalsDir, `${slug}.md`);
13489
- await writeFile8(filePath, buildMotifProposal(motif), "utf-8");
13507
+ await writeFile9(filePath, buildMotifProposal(motif), "utf-8");
13490
13508
  result.proposalsWritten.push(filePath);
13491
13509
  }
13492
13510
  return result;
@@ -13631,7 +13649,7 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
13631
13649
  for (const motif of motifs.slice(0, max)) {
13632
13650
  const slug = workflowSlug(motif.signature);
13633
13651
  const filePath = path24.join(proposalsDir, `${slug}.md`);
13634
- await writeFile8(filePath, buildWorkflowProposal(motif), "utf-8");
13652
+ await writeFile9(filePath, buildWorkflowProposal(motif), "utf-8");
13635
13653
  result.proposalsWritten.push(filePath);
13636
13654
  }
13637
13655
  return result;
@@ -13755,8 +13773,8 @@ function timestampSlug(d) {
13755
13773
  async function atomicWrite(p, content) {
13756
13774
  await mkdir8(path25.dirname(p), { recursive: true });
13757
13775
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
13758
- await writeFile9(tmp, content, "utf-8");
13759
- await rename5(tmp, p);
13776
+ await writeFile10(tmp, content, "utf-8");
13777
+ await rename6(tmp, p);
13760
13778
  }
13761
13779
  async function gatherInventory(directory) {
13762
13780
  const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
@@ -13770,7 +13788,7 @@ async function gatherInventory(directory) {
13770
13788
  for (const skill of skills.active) {
13771
13789
  let content;
13772
13790
  try {
13773
- content = await readFile8(skill.path, "utf-8");
13791
+ content = await readFile9(skill.path, "utf-8");
13774
13792
  } catch {
13775
13793
  continue;
13776
13794
  }
@@ -13946,7 +13964,7 @@ async function reconcileStaleActiveSkills(directory, options = {}) {
13946
13964
  for (const skill of skills.active) {
13947
13965
  let content;
13948
13966
  try {
13949
- content = await readFile8(skill.path, "utf-8");
13967
+ content = await readFile9(skill.path, "utf-8");
13950
13968
  } catch {
13951
13969
  continue;
13952
13970
  }
@@ -14682,20 +14700,20 @@ function countSessionKnowledgeEntries(entries, sessionStart, fallbackCount) {
14682
14700
  async function copyDirRecursiveWithFailures(src, dest) {
14683
14701
  let count = 0;
14684
14702
  const failures = [];
14685
- const entries = await fs11.readdir(src);
14686
- await fs11.mkdir(dest, { recursive: true });
14703
+ const entries = await fs10.readdir(src);
14704
+ await fs10.mkdir(dest, { recursive: true });
14687
14705
  for (const entry of entries) {
14688
14706
  const srcEntry = path27.join(src, entry);
14689
14707
  const destEntry = path27.join(dest, entry);
14690
14708
  try {
14691
- const stat4 = await fs11.stat(srcEntry);
14709
+ const stat4 = await fs10.stat(srcEntry);
14692
14710
  if (stat4.isDirectory()) {
14693
14711
  const subResult = await copyDirRecursiveWithFailures(srcEntry, destEntry);
14694
14712
  count += subResult.copied;
14695
14713
  failures.push(...subResult.failures);
14696
14714
  } else {
14697
14715
  try {
14698
- await fs11.copyFile(srcEntry, destEntry);
14716
+ await fs10.copyFile(srcEntry, destEntry);
14699
14717
  count++;
14700
14718
  } catch (err) {
14701
14719
  const errno = err?.code;
@@ -14873,18 +14891,18 @@ async function runFinalizeStage(ctx) {
14873
14891
  }
14874
14892
  const lessonsFilePath = path27.join(ctx.swarmDir, "close-lessons.md");
14875
14893
  try {
14876
- const lessonsText = await fs11.readFile(lessonsFilePath, "utf-8");
14894
+ const lessonsText = await fs10.readFile(lessonsFilePath, "utf-8");
14877
14895
  ctx.explicitLessons = lessonsText.split(`
14878
14896
  `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
14879
14897
  } catch {}
14880
14898
  try {
14881
14899
  const evidenceDir = path27.join(ctx.swarmDir, "evidence");
14882
- const evidenceEntries = await fs11.readdir(evidenceDir);
14900
+ const evidenceEntries = await fs10.readdir(evidenceDir);
14883
14901
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
14884
14902
  for (const retroDir of retroDirs) {
14885
14903
  const evidencePath = path27.join(evidenceDir, retroDir, "evidence.json");
14886
14904
  try {
14887
- const content = await fs11.readFile(evidencePath, "utf-8");
14905
+ const content = await fs10.readFile(evidencePath, "utf-8");
14888
14906
  const parsed = JSON.parse(content);
14889
14907
  const entries = parsed.entries ?? [parsed];
14890
14908
  for (const entry of entries) {
@@ -14928,7 +14946,7 @@ async function runFinalizeStage(ctx) {
14928
14946
  console.warn("[close-command] curateAndStoreSwarm error:", error2);
14929
14947
  }
14930
14948
  if (ctx.curationSucceeded && ctx.allLessons.length > 0) {
14931
- await fs11.unlink(lessonsFilePath).catch(() => {});
14949
+ await fs10.unlink(lessonsFilePath).catch(() => {});
14932
14950
  }
14933
14951
  if (ctx.curationSucceeded) {
14934
14952
  if (ctx.config.hive_enabled === false) {} else {
@@ -15077,7 +15095,7 @@ async function copySqliteSafe(srcPath, destPath) {
15077
15095
  const code = result.error.code;
15078
15096
  if (code === "ENOENT") {
15079
15097
  try {
15080
- await fs11.copyFile(srcPath, destPath);
15098
+ await fs10.copyFile(srcPath, destPath);
15081
15099
  return {
15082
15100
  success: true,
15083
15101
  reason: "copied without WAL checkpoint (sqlite3 CLI unavailable)"
@@ -15116,7 +15134,7 @@ async function copySqliteSafe(srcPath, destPath) {
15116
15134
  };
15117
15135
  }
15118
15136
  try {
15119
- await fs11.copyFile(srcPath, destPath);
15137
+ await fs10.copyFile(srcPath, destPath);
15120
15138
  if (checkpointVerified) {
15121
15139
  return { success: true };
15122
15140
  }
@@ -15136,7 +15154,7 @@ async function runArchiveStage(ctx) {
15136
15154
  ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
15137
15155
  ctx.archiveDir = path27.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
15138
15156
  try {
15139
- await fs11.mkdir(ctx.archiveDir, { recursive: true });
15157
+ await fs10.mkdir(ctx.archiveDir, { recursive: true });
15140
15158
  const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
15141
15159
  const linkedKnowledgeShared = isLinked(ctx.directory);
15142
15160
  if (linkedKnowledgeShared) {
@@ -15166,7 +15184,7 @@ async function runArchiveStage(ctx) {
15166
15184
  }
15167
15185
  } else {
15168
15186
  try {
15169
- await fs11.copyFile(srcPath, destPath);
15187
+ await fs10.copyFile(srcPath, destPath);
15170
15188
  ctx.archivedFileCount++;
15171
15189
  if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
15172
15190
  ctx.archivedActiveStateFiles.add(artifact);
@@ -15181,12 +15199,12 @@ async function runArchiveStage(ctx) {
15181
15199
  }
15182
15200
  }
15183
15201
  }
15184
- const dynamicArchiveArtifacts = (await fs11.readdir(ctx.swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
15202
+ const dynamicArchiveArtifacts = (await fs10.readdir(ctx.swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
15185
15203
  for (const artifact of dynamicArchiveArtifacts) {
15186
15204
  const srcPath = path27.join(ctx.swarmDir, artifact);
15187
15205
  const destPath = path27.join(ctx.archiveDir, artifact);
15188
15206
  try {
15189
- await fs11.copyFile(srcPath, destPath);
15207
+ await fs10.copyFile(srcPath, destPath);
15190
15208
  ctx.archivedFileCount++;
15191
15209
  ctx.archivedActiveStateFiles.add(artifact);
15192
15210
  } catch (err) {
@@ -15279,7 +15297,7 @@ async function runCleanStage(ctx) {
15279
15297
  }
15280
15298
  const filePath = path27.join(ctx.swarmDir, artifact);
15281
15299
  try {
15282
- await fs11.unlink(filePath);
15300
+ await fs10.unlink(filePath);
15283
15301
  cleanedFiles.push(artifact);
15284
15302
  } catch (err) {
15285
15303
  const errno = err?.code;
@@ -15297,7 +15315,7 @@ async function runCleanStage(ctx) {
15297
15315
  continue;
15298
15316
  }
15299
15317
  try {
15300
- await fs11.unlink(path27.join(ctx.swarmDir, artifact));
15318
+ await fs10.unlink(path27.join(ctx.swarmDir, artifact));
15301
15319
  cleanedFiles.push(artifact);
15302
15320
  } catch (err) {
15303
15321
  const errno = err?.code;
@@ -15313,16 +15331,16 @@ async function runCleanStage(ctx) {
15313
15331
  }
15314
15332
  const dirPath = path27.join(ctx.swarmDir, dirName);
15315
15333
  try {
15316
- await fs11.rm(dirPath, { recursive: true, force: true });
15334
+ await fs10.rm(dirPath, { recursive: true, force: true });
15317
15335
  cleanedFiles.push(`${dirName}/`);
15318
15336
  } catch {}
15319
15337
  }
15320
15338
  try {
15321
- const swarmFiles = await fs11.readdir(ctx.swarmDir);
15339
+ const swarmFiles = await fs10.readdir(ctx.swarmDir);
15322
15340
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
15323
15341
  for (const backup of configBackups) {
15324
15342
  try {
15325
- await fs11.unlink(path27.join(ctx.swarmDir, backup));
15343
+ await fs10.unlink(path27.join(ctx.swarmDir, backup));
15326
15344
  configBackupsRemoved++;
15327
15345
  } catch (err) {
15328
15346
  const errno = err?.code;
@@ -15335,7 +15353,7 @@ async function runCleanStage(ctx) {
15335
15353
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
15336
15354
  for (const sibling of ledgerSiblings) {
15337
15355
  try {
15338
- await fs11.unlink(path27.join(ctx.swarmDir, sibling));
15356
+ await fs10.unlink(path27.join(ctx.swarmDir, sibling));
15339
15357
  } catch (err) {
15340
15358
  const errno = err?.code;
15341
15359
  if (errno === "ENOENT") {} else {
@@ -15362,7 +15380,7 @@ async function runCleanStage(ctx) {
15362
15380
  ];
15363
15381
  for (const candidate of candidates) {
15364
15382
  try {
15365
- await fs11.unlink(candidate);
15383
+ await fs10.unlink(candidate);
15366
15384
  swarmPlanFilesRemoved++;
15367
15385
  } catch (err) {
15368
15386
  if (err?.code !== "ENOENT") {
@@ -15372,11 +15390,11 @@ async function runCleanStage(ctx) {
15372
15390
  }
15373
15391
  let tmpFilesRemoved = 0;
15374
15392
  try {
15375
- const swarmFiles = await fs11.readdir(ctx.swarmDir);
15393
+ const swarmFiles = await fs10.readdir(ctx.swarmDir);
15376
15394
  const tmpFiles = swarmFiles.filter((f) => f.startsWith(".tmp."));
15377
15395
  for (const tmp of tmpFiles) {
15378
15396
  try {
15379
- await fs11.unlink(path27.join(ctx.swarmDir, tmp));
15397
+ await fs10.unlink(path27.join(ctx.swarmDir, tmp));
15380
15398
  tmpFilesRemoved++;
15381
15399
  } catch (err) {
15382
15400
  const errno = err?.code;
@@ -15398,7 +15416,7 @@ async function runCleanStage(ctx) {
15398
15416
  }
15399
15417
  for (const terminalFile of TERMINAL_STATE_FILES) {
15400
15418
  try {
15401
- await fs11.unlink(path27.join(ctx.swarmDir, terminalFile));
15419
+ await fs10.unlink(path27.join(ctx.swarmDir, terminalFile));
15402
15420
  if (!cleanedFiles.includes(terminalFile)) {
15403
15421
  cleanedFiles.push(terminalFile);
15404
15422
  }
@@ -15425,7 +15443,7 @@ async function runCleanStage(ctx) {
15425
15443
  `);
15426
15444
  const contextTempPath = path27.join(path27.dirname(contextPath), `${path27.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15427
15445
  try {
15428
- await fs11.writeFile(contextTempPath, contextContent, "utf-8");
15446
+ await fs10.writeFile(contextTempPath, contextContent, "utf-8");
15429
15447
  fsSync.renameSync(contextTempPath, contextPath);
15430
15448
  } catch (error2) {
15431
15449
  try {
@@ -15505,14 +15523,14 @@ async function handleCloseCommand(directory, args, options = {}) {
15505
15523
  phases: []
15506
15524
  };
15507
15525
  try {
15508
- const content = await fs11.readFile(planPath, "utf-8");
15526
+ const content = await fs10.readFile(planPath, "utf-8");
15509
15527
  planData = JSON.parse(content);
15510
15528
  planExists = true;
15511
15529
  } catch (error2) {
15512
15530
  if (error2?.code !== "ENOENT") {
15513
15531
  return `\u274C Failed to read plan.json: ${error2 instanceof Error ? error2.message : String(error2)}`;
15514
15532
  }
15515
- const swarmDirExists = await fs11.access(swarmDir).then(() => true).catch(() => false);
15533
+ const swarmDirExists = await fs10.access(swarmDir).then(() => true).catch(() => false);
15516
15534
  if (!swarmDirExists) {
15517
15535
  return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
15518
15536
  }
@@ -15528,7 +15546,7 @@ async function handleCloseCommand(directory, args, options = {}) {
15528
15546
  if (!planExists) {
15529
15547
  const archiveDir = path27.join(swarmDir, "archive");
15530
15548
  try {
15531
- const archiveEntries = await fs11.readdir(archiveDir);
15549
+ const archiveEntries = await fs10.readdir(archiveDir);
15532
15550
  const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
15533
15551
  if (hasArchiveBundle) {
15534
15552
  const hasActiveState = [
@@ -15664,7 +15682,7 @@ This project was already finalized in a previous /swarm close run. The plan has
15664
15682
  `);
15665
15683
  const closeSummaryTempPath = path27.join(path27.dirname(closeSummaryPath), `${path27.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15666
15684
  try {
15667
- await fs11.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
15685
+ await fs10.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
15668
15686
  fsSync.renameSync(closeSummaryTempPath, closeSummaryPath);
15669
15687
  } catch (error2) {
15670
15688
  try {
@@ -16032,7 +16050,7 @@ async function handleConfigCommand(directory, _args) {
16032
16050
 
16033
16051
  // src/services/skill-consolidation.ts
16034
16052
  import { existsSync as existsSync18 } from "fs";
16035
- import { mkdir as mkdir9, readFile as readFile9, rename as rename6, writeFile as writeFile10 } from "fs/promises";
16053
+ import { mkdir as mkdir9, readFile as readFile10, rename as rename7, writeFile as writeFile11 } from "fs/promises";
16036
16054
  import * as path29 from "path";
16037
16055
 
16038
16056
  // src/utils/timeout.ts
@@ -16065,7 +16083,7 @@ async function readState2(directory) {
16065
16083
  if (!existsSync18(filePath))
16066
16084
  return {};
16067
16085
  try {
16068
- const parsed = JSON.parse(await readFile9(filePath, "utf-8"));
16086
+ const parsed = JSON.parse(await readFile10(filePath, "utf-8"));
16069
16087
  if (!parsed || typeof parsed !== "object")
16070
16088
  return {};
16071
16089
  return parsed;
@@ -16076,8 +16094,8 @@ async function readState2(directory) {
16076
16094
  async function atomicWrite2(filePath, content) {
16077
16095
  await mkdir9(path29.dirname(filePath), { recursive: true });
16078
16096
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
16079
- await writeFile10(tmp, content, "utf-8");
16080
- await rename6(tmp, filePath);
16097
+ await writeFile11(tmp, content, "utf-8");
16098
+ await rename7(tmp, filePath);
16081
16099
  }
16082
16100
  async function writeState2(directory, state) {
16083
16101
  await atomicWrite2(consolidationStatePath(directory), `${JSON.stringify(state, null, 2)}
@@ -16355,7 +16373,7 @@ async function handleCouncilCommand(_directory, args) {
16355
16373
 
16356
16374
  // src/commands/coupling.ts
16357
16375
  import { randomBytes } from "crypto";
16358
- import * as fs12 from "fs";
16376
+ import * as fs11 from "fs";
16359
16377
  import * as path31 from "path";
16360
16378
 
16361
16379
  // src/turbo/epic/cochange-source.ts
@@ -16364,8 +16382,8 @@ import { promisify as promisify2 } from "util";
16364
16382
 
16365
16383
  // src/tools/co-change-analyzer.ts
16366
16384
  import * as child_process2 from "child_process";
16367
- import { randomUUID as randomUUID5 } from "crypto";
16368
- import { readdir as readdir2, readFile as readFile10, stat as stat4 } from "fs/promises";
16385
+ import { randomUUID as randomUUID6 } from "crypto";
16386
+ import { readdir as readdir2, readFile as readFile11, stat as stat4 } from "fs/promises";
16369
16387
  import * as path30 from "path";
16370
16388
  import { promisify } from "util";
16371
16389
  function getExecFileAsync() {
@@ -16492,7 +16510,7 @@ async function getStaticEdges(directory) {
16492
16510
  const sourceFiles = await scanSourceFiles(directory);
16493
16511
  for (const sourceFile of sourceFiles) {
16494
16512
  try {
16495
- const content = await readFile10(sourceFile, "utf-8");
16513
+ const content = await readFile11(sourceFile, "utf-8");
16496
16514
  const importRegex = /(?:import|require)\s*(?:\(?\s*['"`]|.*?from\s+['"`])([^'"`]+)['"`]/g;
16497
16515
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
16498
16516
  const importPath = match[1].trim();
@@ -16627,7 +16645,7 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
16627
16645
  }
16628
16646
  const confidence = Math.min(0.3 + 0.2 * Math.min(pair.coChangeCount / 10, 1), 0.5);
16629
16647
  entries.push({
16630
- id: randomUUID5(),
16648
+ id: randomUUID6(),
16631
16649
  tier: "swarm",
16632
16650
  lesson,
16633
16651
  category: "architecture",
@@ -17041,16 +17059,16 @@ function parseArgs3(args) {
17041
17059
  }
17042
17060
  function persistReportJson(directory, report) {
17043
17061
  const epicDir = path31.join(directory, ".swarm", "epic");
17044
- fs12.mkdirSync(epicDir, { recursive: true });
17062
+ fs11.mkdirSync(epicDir, { recursive: true });
17045
17063
  const filePath = path31.join(epicDir, "coupling-report.json");
17046
17064
  const tmpPath = `${filePath}.tmp.${randomBytes(8).toString("hex")}`;
17047
- fs12.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
17065
+ fs11.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
17048
17066
  `, "utf-8");
17049
17067
  try {
17050
- fs12.renameSync(tmpPath, filePath);
17068
+ fs11.renameSync(tmpPath, filePath);
17051
17069
  } catch (err) {
17052
17070
  try {
17053
- fs12.unlinkSync(tmpPath);
17071
+ fs11.unlinkSync(tmpPath);
17054
17072
  } catch {}
17055
17073
  throw err;
17056
17074
  }
@@ -17140,8 +17158,8 @@ var _internals22 = {
17140
17158
  loadCuratorDeps: async () => {
17141
17159
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
17142
17160
  import("./schema-vw2ffhe9.js"),
17143
- import("./curator-np2ky29t.js"),
17144
- import("./curator-llm-factory-gdhtm1hh.js")
17161
+ import("./curator-6zvpn7fs.js"),
17162
+ import("./curator-llm-factory-r3m5e7n8.js")
17145
17163
  ]);
17146
17164
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
17147
17165
  }
@@ -17637,7 +17655,7 @@ import { fileURLToPath } from "url";
17637
17655
  // package.json
17638
17656
  var package_default = {
17639
17657
  name: "opencode-swarm",
17640
- version: "7.107.1",
17658
+ version: "7.107.2",
17641
17659
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
17642
17660
  main: "dist/index.js",
17643
17661
  types: "dist/index.d.ts",
@@ -17793,7 +17811,7 @@ init_executor();
17793
17811
 
17794
17812
  // src/services/knowledge-diagnostics.ts
17795
17813
  import { existsSync as existsSync20 } from "fs";
17796
- import { readFile as readFile11 } from "fs/promises";
17814
+ import { readFile as readFile12 } from "fs/promises";
17797
17815
 
17798
17816
  // src/services/version-check.ts
17799
17817
  import { existsSync as existsSync19, mkdirSync as mkdirSync13, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
@@ -17869,7 +17887,7 @@ var INSIGHT_BACKLOG_WARN = 50;
17869
17887
  async function readRawLines(filePath) {
17870
17888
  if (!existsSync20(filePath))
17871
17889
  return { entries: [], corrupt: 0 };
17872
- const content = await readFile11(filePath, "utf-8");
17890
+ const content = await readFile12(filePath, "utf-8");
17873
17891
  const entries = [];
17874
17892
  let corrupt = 0;
17875
17893
  for (const line of content.split(`
@@ -17995,7 +18013,7 @@ async function safeJsonlCount(filePath) {
17995
18013
  if (!filePath || !existsSync20(filePath))
17996
18014
  return 0;
17997
18015
  try {
17998
- const content = await readFile11(filePath, "utf-8");
18016
+ const content = await readFile12(filePath, "utf-8");
17999
18017
  let n = 0;
18000
18018
  for (const line of content.split(`
18001
18019
  `)) {
@@ -19231,7 +19249,7 @@ function decideEpicActivation(tasks, cochangePairs, commitsObserved, options) {
19231
19249
 
19232
19250
  // src/turbo/epic/calibration.ts
19233
19251
  init_logger();
19234
- import * as fs14 from "fs";
19252
+ import * as fs13 from "fs";
19235
19253
  import * as path38 from "path";
19236
19254
  var STATE_FILE = "calibration.json";
19237
19255
  var STATE_REL_DIR = path38.join(".swarm", "epic");
@@ -19257,12 +19275,12 @@ function markUnreadable(directory, reason) {
19257
19275
  }
19258
19276
  function repairCalibrationUnreadable(directory) {
19259
19277
  const filePath = path38.join(directory, STATE_REL_DIR, STATE_FILE);
19260
- if (!fs14.existsSync(filePath)) {
19278
+ if (!fs13.existsSync(filePath)) {
19261
19279
  stateUnreadableMap.delete(directory);
19262
19280
  return;
19263
19281
  }
19264
19282
  try {
19265
- const raw = fs14.readFileSync(filePath, "utf-8");
19283
+ const raw = fs13.readFileSync(filePath, "utf-8");
19266
19284
  const parsed = JSON.parse(raw);
19267
19285
  if (!isValidCalibrationShape(parsed)) {
19268
19286
  stateUnreadableMap.set(directory, true);
@@ -19289,8 +19307,8 @@ function isValidCalibrationShape(candidate) {
19289
19307
  }
19290
19308
  function ensureSwarmEpicDir(directory) {
19291
19309
  const dir = path38.resolve(directory, STATE_REL_DIR);
19292
- if (!fs14.existsSync(dir)) {
19293
- fs14.mkdirSync(dir, { recursive: true });
19310
+ if (!fs13.existsSync(dir)) {
19311
+ fs13.mkdirSync(dir, { recursive: true });
19294
19312
  }
19295
19313
  return dir;
19296
19314
  }
@@ -19302,16 +19320,16 @@ function loadCalibrationState(directory) {
19302
19320
  }
19303
19321
  const filePath = path38.join(directory, STATE_REL_DIR, STATE_FILE);
19304
19322
  try {
19305
- if (!fs14.existsSync(filePath)) {
19323
+ if (!fs13.existsSync(filePath)) {
19306
19324
  const seed = emptyCalibrationState();
19307
19325
  try {
19308
19326
  ensureSwarmEpicDir(directory);
19309
- fs14.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
19327
+ fs13.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
19310
19328
  `, "utf-8");
19311
19329
  } catch {}
19312
19330
  return seed;
19313
19331
  }
19314
- const raw = fs14.readFileSync(filePath, "utf-8");
19332
+ const raw = fs13.readFileSync(filePath, "utf-8");
19315
19333
  const parsed = JSON.parse(raw);
19316
19334
  if (!isValidCalibrationShape(parsed)) {
19317
19335
  markUnreadable(directory, `malformed shape (version=${parsed?.version}, hotModuleAdditions type=${Array.isArray(parsed?.hotModuleAdditions) ? "array" : typeof parsed?.hotModuleAdditions})`);
@@ -19326,36 +19344,36 @@ function loadCalibrationState(directory) {
19326
19344
 
19327
19345
  // src/turbo/epic/divergence-recorder.ts
19328
19346
  init_logger();
19329
- import * as fs15 from "fs";
19347
+ import * as fs14 from "fs";
19330
19348
  import * as path39 from "path";
19331
19349
  var EVIDENCE_REL_DIR = path39.join(".swarm", "epic");
19332
19350
  var EVIDENCE_FILE = "divergence.jsonl";
19333
19351
  var MAX_TAIL_BYTES2 = 16 * 1024 * 1024;
19334
19352
  function readDivergenceHistory(directory, options) {
19335
19353
  const filePath = path39.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
19336
- if (!fs15.existsSync(filePath)) {
19354
+ if (!fs14.existsSync(filePath)) {
19337
19355
  return [];
19338
19356
  }
19339
19357
  const maxBytes = options?.maxBytes ?? MAX_TAIL_BYTES2;
19340
19358
  let raw;
19341
19359
  let tailTruncated = false;
19342
19360
  try {
19343
- const stat5 = fs15.statSync(filePath);
19361
+ const stat5 = fs14.statSync(filePath);
19344
19362
  if (Number.isFinite(maxBytes) && stat5.size > maxBytes) {
19345
- const fd = fs15.openSync(filePath, "r");
19363
+ const fd = fs14.openSync(filePath, "r");
19346
19364
  try {
19347
19365
  const buf = Buffer.alloc(maxBytes);
19348
19366
  const offset = stat5.size - maxBytes;
19349
- fs15.readSync(fd, buf, 0, maxBytes, offset);
19367
+ fs14.readSync(fd, buf, 0, maxBytes, offset);
19350
19368
  raw = buf.toString("utf-8");
19351
19369
  tailTruncated = true;
19352
19370
  } finally {
19353
19371
  try {
19354
- fs15.closeSync(fd);
19372
+ fs14.closeSync(fd);
19355
19373
  } catch {}
19356
19374
  }
19357
19375
  } else {
19358
- raw = fs15.readFileSync(filePath, "utf-8");
19376
+ raw = fs14.readFileSync(filePath, "utf-8");
19359
19377
  }
19360
19378
  } catch {
19361
19379
  return [];
@@ -19380,16 +19398,16 @@ function readDivergenceHistory(directory, options) {
19380
19398
  }
19381
19399
 
19382
19400
  // src/turbo/epic/promotion-evidence.ts
19383
- import * as fs16 from "fs";
19401
+ import * as fs15 from "fs";
19384
19402
  import * as path40 from "path";
19385
19403
  var EVIDENCE_REL_DIR2 = path40.join(".swarm", "evidence");
19386
19404
  var EVIDENCE_FILE2 = "epic-promotions.jsonl";
19387
19405
  function readPromotionEvidence(directory) {
19388
19406
  const filePath = path40.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
19389
- if (!fs16.existsSync(filePath)) {
19407
+ if (!fs15.existsSync(filePath)) {
19390
19408
  return [];
19391
19409
  }
19392
- const raw = fs16.readFileSync(filePath, "utf-8");
19410
+ const raw = fs15.readFileSync(filePath, "utf-8");
19393
19411
  const lines = raw.split(`
19394
19412
  `).filter((l) => l.trim().length > 0);
19395
19413
  const records = [];
@@ -19894,7 +19912,7 @@ async function handleEvidenceCommand(directory, args) {
19894
19912
  return formatTaskEvidenceMarkdown(evidenceData);
19895
19913
  }
19896
19914
  async function handleEvidenceSummaryCommand(directory) {
19897
- const { buildEvidenceSummary } = await import("./evidence-summary-service-dh44gevz.js");
19915
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-7nwhd8s4.js");
19898
19916
  const artifact = await buildEvidenceSummary(directory);
19899
19917
  if (!artifact) {
19900
19918
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -19958,7 +19976,7 @@ async function handleExportCommand(directory, _args) {
19958
19976
  }
19959
19977
  // src/full-auto/state.ts
19960
19978
  var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
19961
- import * as fs17 from "fs";
19979
+ import * as fs16 from "fs";
19962
19980
  import * as path41 from "path";
19963
19981
  init_logger();
19964
19982
  var lockfile4 = import_proper_lockfile4.default;
@@ -19968,8 +19986,8 @@ function nowISO2() {
19968
19986
  }
19969
19987
  function ensureSwarmDir(directory) {
19970
19988
  const swarmDir = path41.resolve(directory, ".swarm");
19971
- if (!fs17.existsSync(swarmDir)) {
19972
- fs17.mkdirSync(swarmDir, { recursive: true });
19989
+ if (!fs16.existsSync(swarmDir)) {
19990
+ fs16.mkdirSync(swarmDir, { recursive: true });
19973
19991
  }
19974
19992
  return swarmDir;
19975
19993
  }
@@ -20027,7 +20045,7 @@ function withStateLock(directory, fn) {
20027
20045
  let release;
20028
20046
  try {
20029
20047
  const lockTarget = validateSwarmPath(directory, STATE_FILE2);
20030
- if (!fs17.existsSync(lockTarget)) {
20048
+ if (!fs16.existsSync(lockTarget)) {
20031
20049
  ensureSwarmDir(directory);
20032
20050
  const seed = {
20033
20051
  version: 2,
@@ -20035,7 +20053,7 @@ function withStateLock(directory, fn) {
20035
20053
  oversightSequence: 0,
20036
20054
  sessions: {}
20037
20055
  };
20038
- fs17.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
20056
+ fs16.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
20039
20057
  `, "utf-8");
20040
20058
  }
20041
20059
  release = lockfile4.lockSync(lockTarget, {
@@ -20085,7 +20103,7 @@ function readPersisted(directory) {
20085
20103
  const filePath = validateSwarmPath(directory, STATE_FILE2);
20086
20104
  let stats;
20087
20105
  try {
20088
- stats = fs17.statSync(filePath);
20106
+ stats = fs16.statSync(filePath);
20089
20107
  } catch {
20090
20108
  clearStateUnreadable();
20091
20109
  readCache.delete(filePath);
@@ -20096,7 +20114,7 @@ function readPersisted(directory) {
20096
20114
  clearStateUnreadable();
20097
20115
  return structuredClone(cached.state);
20098
20116
  }
20099
- const raw = fs17.readFileSync(filePath, "utf-8");
20117
+ const raw = fs16.readFileSync(filePath, "utf-8");
20100
20118
  const parsed = JSON.parse(raw);
20101
20119
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 2 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
20102
20120
  markStateUnreadable(`malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -20121,8 +20139,8 @@ function readPersisted(directory) {
20121
20139
  error(`[full-auto/state] Failed to read ${STATE_FILE2}: ${reason} \u2014 attempting .bak recovery`);
20122
20140
  try {
20123
20141
  const bakPath = validateSwarmPath(directory, `${STATE_FILE2}.bak`);
20124
- if (fs17.existsSync(bakPath)) {
20125
- const raw = fs17.readFileSync(bakPath, "utf-8");
20142
+ if (fs16.existsSync(bakPath)) {
20143
+ const raw = fs16.readFileSync(bakPath, "utf-8");
20126
20144
  const parsed = JSON.parse(raw);
20127
20145
  if (parsed?.version === 2 && parsed.sessions && !Array.isArray(parsed.sessions)) {
20128
20146
  warn(`[full-auto/state] Recovered from ${STATE_FILE2}.bak`);
@@ -20162,23 +20180,23 @@ function writePersisted(directory, persisted) {
20162
20180
  throw new Error(`Full-Auto state persistence prepare failed: ${msg}`);
20163
20181
  }
20164
20182
  try {
20165
- if (fs17.existsSync(filePath)) {
20166
- fs17.copyFileSync(filePath, bakPath);
20183
+ if (fs16.existsSync(filePath)) {
20184
+ fs16.copyFileSync(filePath, bakPath);
20167
20185
  }
20168
20186
  } catch {}
20169
20187
  try {
20170
- fs17.writeFileSync(tmpPath, payload, "utf-8");
20188
+ fs16.writeFileSync(tmpPath, payload, "utf-8");
20171
20189
  try {
20172
- const fd = fs17.openSync(tmpPath, "r+");
20190
+ const fd = fs16.openSync(tmpPath, "r+");
20173
20191
  try {
20174
- fs17.fsyncSync(fd);
20192
+ fs16.fsyncSync(fd);
20175
20193
  } finally {
20176
- fs17.closeSync(fd);
20194
+ fs16.closeSync(fd);
20177
20195
  }
20178
20196
  } catch {}
20179
- fs17.renameSync(tmpPath, filePath);
20197
+ fs16.renameSync(tmpPath, filePath);
20180
20198
  readCache.delete(filePath);
20181
- const readback = fs17.readFileSync(filePath, "utf-8");
20199
+ const readback = fs16.readFileSync(filePath, "utf-8");
20182
20200
  const parsed = JSON.parse(readback);
20183
20201
  if (parsed?.version !== 2) {
20184
20202
  throw new Error("Round-trip readback returned wrong version");
@@ -20832,6 +20850,12 @@ function serializeAgentSession(s) {
20832
20850
  lastCoderDelegationTaskId: s.lastCoderDelegationTaskId ?? null,
20833
20851
  currentTaskId: s.currentTaskId ?? null,
20834
20852
  turboMode: s.turboMode ?? false,
20853
+ ...s.turboStrategy !== undefined && { turboStrategy: s.turboStrategy },
20854
+ leanTurboActive: s.leanTurboActive ?? false,
20855
+ ...s.leanTurboCurrentPhase !== undefined && {
20856
+ leanTurboCurrentPhase: s.leanTurboCurrentPhase
20857
+ },
20858
+ epicModeActive: s.epicModeActive ?? false,
20835
20859
  gateLog,
20836
20860
  reviewerCallCount,
20837
20861
  lastGateFailure: s.lastGateFailure ?? null,
@@ -20922,13 +20946,21 @@ var _internals30 = {
20922
20946
  };
20923
20947
 
20924
20948
  // src/commands/handoff.ts
20925
- async function handleHandoffCommand(directory, _args) {
20949
+ var HANDOFF_SOURCE_SESSION_PREFIX = "<!-- opencode-swarm-handoff-source-session:";
20950
+ function formatSessionScopedHandoffMarkdown(markdown, sessionID) {
20951
+ if (!sessionID) {
20952
+ return markdown;
20953
+ }
20954
+ return `${HANDOFF_SOURCE_SESSION_PREFIX} ${encodeURIComponent(sessionID)} -->
20955
+ ${markdown}`;
20956
+ }
20957
+ async function handleHandoffCommand(directory, _args, sessionID) {
20926
20958
  const handoffData = await getHandoffData(directory);
20927
20959
  const markdown = formatHandoffMarkdown(handoffData);
20928
20960
  try {
20929
20961
  const resolvedPath = validateSwarmPath(directory, "handoff.md");
20930
20962
  const tempPath = `${resolvedPath}.tmp.${crypto4.randomUUID()}`;
20931
- await bunWrite(tempPath, markdown);
20963
+ await bunWrite(tempPath, formatSessionScopedHandoffMarkdown(markdown, sessionID));
20932
20964
  try {
20933
20965
  renameSync10(tempPath, resolvedPath);
20934
20966
  } catch (renameErr) {
@@ -21393,9 +21425,9 @@ import { join as join37 } from "path";
21393
21425
 
21394
21426
  // src/hooks/knowledge-migrator.ts
21395
21427
  init_logger();
21396
- import { randomUUID as randomUUID7 } from "crypto";
21428
+ import { randomUUID as randomUUID8 } from "crypto";
21397
21429
  import { existsSync as existsSync26, readFileSync as readFileSync16 } from "fs";
21398
- import { mkdir as mkdir10, readFile as readFile12, writeFile as writeFile11 } from "fs/promises";
21430
+ import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile12 } from "fs/promises";
21399
21431
  import * as os11 from "os";
21400
21432
  import * as path43 from "path";
21401
21433
 
@@ -21465,9 +21497,9 @@ var _internals32 = {
21465
21497
  resolveLegacyHiveKnowledgePath,
21466
21498
  existsSync: existsSync26,
21467
21499
  readFileSync: readFileSync16,
21468
- readFile: readFile12,
21500
+ readFile: readFile13,
21469
21501
  mkdir: mkdir10,
21470
- writeFile: writeFile11
21502
+ writeFile: writeFile12
21471
21503
  };
21472
21504
  async function migrateContextToKnowledge(directory, config) {
21473
21505
  const sentinelPath = path43.join(directory, ".swarm", ".knowledge-migrated");
@@ -21491,7 +21523,7 @@ async function migrateContextToKnowledge(directory, config) {
21491
21523
  skippedReason: "no-context-file"
21492
21524
  };
21493
21525
  }
21494
- const contextContent = await readFile12(contextPath, "utf-8");
21526
+ const contextContent = await readFile13(contextPath, "utf-8");
21495
21527
  if (contextContent.trim().length === 0) {
21496
21528
  return {
21497
21529
  migrated: false,
@@ -21535,7 +21567,7 @@ async function migrateContextToKnowledge(directory, config) {
21535
21567
  }
21536
21568
  const inferredTags = inferTags(raw.text);
21537
21569
  const entry = {
21538
- id: randomUUID7(),
21570
+ id: randomUUID8(),
21539
21571
  tier: "swarm",
21540
21572
  lesson: _internals32.truncateLesson(raw.text),
21541
21573
  category: raw.categoryHint ?? _internals32.inferCategoryFromText(raw.text),
@@ -21635,7 +21667,7 @@ async function migrateHiveKnowledgeLegacy(config) {
21635
21667
  const scopeTag = legacyEntry.scope_tag || "global";
21636
21668
  const legacyId = legacyEntry.id;
21637
21669
  const existingIds = new Set(existingHiveEntries.map((e) => e.id));
21638
- const resolvedId = legacyId && existingIds.has(legacyId) ? randomUUID7() : legacyId || randomUUID7();
21670
+ const resolvedId = legacyId && existingIds.has(legacyId) ? randomUUID8() : legacyId || randomUUID8();
21639
21671
  if (legacyId && existingIds.has(legacyId)) {
21640
21672
  warn(`[knowledge-migrator] Legacy entry ID collision for "${legacyId}", generating new UUID`);
21641
21673
  }
@@ -22451,7 +22483,7 @@ import { existsSync as existsSync28 } from "fs";
22451
22483
  import * as path48 from "path";
22452
22484
  import { fileURLToPath as fileURLToPath2 } from "url";
22453
22485
  // src/memory/evaluation.ts
22454
- import * as fs18 from "fs/promises";
22486
+ import * as fs17 from "fs/promises";
22455
22487
  import * as os12 from "os";
22456
22488
  import * as path46 from "path";
22457
22489
  var DEFAULT_PROVIDERS = [
@@ -22474,7 +22506,7 @@ async function evaluateMemoryRecallFixtures(options) {
22474
22506
  for (const fixture of fixtures) {
22475
22507
  const materialized = materializeFixture(fixture);
22476
22508
  for (const providerName of providers) {
22477
- const tempRoot = await fs18.realpath(await fs18.mkdtemp(path46.join(os12.tmpdir(), "swarm-memory-eval-")));
22509
+ const tempRoot = await fs17.realpath(await fs17.mkdtemp(path46.join(os12.tmpdir(), "swarm-memory-eval-")));
22478
22510
  const provider = createEvaluationProvider(providerName, tempRoot);
22479
22511
  try {
22480
22512
  await provider.initialize?.();
@@ -22517,7 +22549,7 @@ async function evaluateMemoryRecallFixtures(options) {
22517
22549
  async function rmTempRoot(tempRoot) {
22518
22550
  for (let attempt = 0;attempt < 10; attempt++) {
22519
22551
  try {
22520
- await fs18.rm(tempRoot, { recursive: true, force: true });
22552
+ await fs17.rm(tempRoot, { recursive: true, force: true });
22521
22553
  return;
22522
22554
  } catch (err) {
22523
22555
  if (attempt === 9)
@@ -22527,11 +22559,11 @@ async function rmTempRoot(tempRoot) {
22527
22559
  }
22528
22560
  }
22529
22561
  async function loadRecallEvaluationFixtures(fixtureDirectory) {
22530
- const entries = await fs18.readdir(fixtureDirectory, { withFileTypes: true });
22562
+ const entries = await fs17.readdir(fixtureDirectory, { withFileTypes: true });
22531
22563
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
22532
22564
  const fixtures = [];
22533
22565
  for (const file of files) {
22534
- const raw = await fs18.readFile(path46.join(fixtureDirectory, file), "utf-8");
22566
+ const raw = await fs17.readFile(path46.join(fixtureDirectory, file), "utf-8");
22535
22567
  fixtures.push(validateFixture(JSON.parse(raw), file));
22536
22568
  }
22537
22569
  return fixtures;
@@ -22807,14 +22839,14 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
22807
22839
  curatorMemoryDecisions: exports_external.array(CuratorMemoryDecisionSchema).max(20).optional()
22808
22840
  }).passthrough();
22809
22841
  // src/memory/consolidation-log.ts
22810
- import { appendFile as appendFile3, mkdir as mkdir11, readFile as readFile14 } from "fs/promises";
22842
+ import { appendFile as appendFile3, mkdir as mkdir11, readFile as readFile15 } from "fs/promises";
22811
22843
  import * as path47 from "path";
22812
22844
  var LOG_RELATIVE_PATH = path47.join("memory", "consolidation-log.jsonl");
22813
22845
  async function readConsolidationLog(directory) {
22814
22846
  const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
22815
22847
  let raw;
22816
22848
  try {
22817
- raw = await readFile14(filePath, "utf-8");
22849
+ raw = await readFile15(filePath, "utf-8");
22818
22850
  } catch {
22819
22851
  return [];
22820
22852
  }
@@ -23987,11 +24019,11 @@ var _internals39 = {
23987
24019
  };
23988
24020
 
23989
24021
  // src/services/preflight-service.ts
23990
- import * as fs25 from "fs";
24022
+ import * as fs24 from "fs";
23991
24023
  import * as path55 from "path";
23992
24024
 
23993
24025
  // src/tools/lint.ts
23994
- import * as fs19 from "fs";
24026
+ import * as fs18 from "fs";
23995
24027
  import * as path49 from "path";
23996
24028
 
23997
24029
  // src/utils/path-security.ts
@@ -24066,7 +24098,7 @@ function getLinterCommand(linter, mode, projectDir) {
24066
24098
  }
24067
24099
  function getAdditionalLinterCommand(linter, mode, cwd) {
24068
24100
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
24069
- const gradlew = fs19.existsSync(path49.join(cwd, gradlewName)) ? path49.join(cwd, gradlewName) : null;
24101
+ const gradlew = fs18.existsSync(path49.join(cwd, gradlewName)) ? path49.join(cwd, gradlewName) : null;
24070
24102
  switch (linter) {
24071
24103
  case "ruff":
24072
24104
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -24100,12 +24132,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
24100
24132
  }
24101
24133
  }
24102
24134
  function detectRuff(cwd) {
24103
- if (fs19.existsSync(path49.join(cwd, "ruff.toml")))
24135
+ if (fs18.existsSync(path49.join(cwd, "ruff.toml")))
24104
24136
  return isCommandAvailable("ruff");
24105
24137
  try {
24106
24138
  const pyproject = path49.join(cwd, "pyproject.toml");
24107
- if (fs19.existsSync(pyproject)) {
24108
- const content = fs19.readFileSync(pyproject, "utf-8");
24139
+ if (fs18.existsSync(pyproject)) {
24140
+ const content = fs18.readFileSync(pyproject, "utf-8");
24109
24141
  if (content.includes("[tool.ruff]"))
24110
24142
  return isCommandAvailable("ruff");
24111
24143
  }
@@ -24113,21 +24145,21 @@ function detectRuff(cwd) {
24113
24145
  return false;
24114
24146
  }
24115
24147
  function detectClippy(cwd) {
24116
- return fs19.existsSync(path49.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
24148
+ return fs18.existsSync(path49.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
24117
24149
  }
24118
24150
  function detectGolangciLint(cwd) {
24119
- return fs19.existsSync(path49.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24151
+ return fs18.existsSync(path49.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24120
24152
  }
24121
24153
  function detectCheckstyle(cwd) {
24122
- const hasMaven = fs19.existsSync(path49.join(cwd, "pom.xml"));
24123
- const hasGradle = fs19.existsSync(path49.join(cwd, "build.gradle")) || fs19.existsSync(path49.join(cwd, "build.gradle.kts"));
24124
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs19.existsSync(path49.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
24154
+ const hasMaven = fs18.existsSync(path49.join(cwd, "pom.xml"));
24155
+ const hasGradle = fs18.existsSync(path49.join(cwd, "build.gradle")) || fs18.existsSync(path49.join(cwd, "build.gradle.kts"));
24156
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs18.existsSync(path49.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
24125
24157
  return (hasMaven || hasGradle) && hasBinary;
24126
24158
  }
24127
24159
  function detectKtlint(cwd) {
24128
- const hasKotlin = fs19.existsSync(path49.join(cwd, "build.gradle.kts")) || fs19.existsSync(path49.join(cwd, "build.gradle")) || (() => {
24160
+ const hasKotlin = fs18.existsSync(path49.join(cwd, "build.gradle.kts")) || fs18.existsSync(path49.join(cwd, "build.gradle")) || (() => {
24129
24161
  try {
24130
- return fs19.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
24162
+ return fs18.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
24131
24163
  } catch {
24132
24164
  return false;
24133
24165
  }
@@ -24136,7 +24168,7 @@ function detectKtlint(cwd) {
24136
24168
  }
24137
24169
  function detectDotnetFormat(cwd) {
24138
24170
  try {
24139
- const files = fs19.readdirSync(cwd);
24171
+ const files = fs18.readdirSync(cwd);
24140
24172
  const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
24141
24173
  return hasCsproj && isCommandAvailable("dotnet");
24142
24174
  } catch {
@@ -24144,14 +24176,14 @@ function detectDotnetFormat(cwd) {
24144
24176
  }
24145
24177
  }
24146
24178
  function detectCppcheck(cwd) {
24147
- if (fs19.existsSync(path49.join(cwd, "CMakeLists.txt"))) {
24179
+ if (fs18.existsSync(path49.join(cwd, "CMakeLists.txt"))) {
24148
24180
  return isCommandAvailable("cppcheck");
24149
24181
  }
24150
24182
  try {
24151
24183
  const dirsToCheck = [cwd, path49.join(cwd, "src")];
24152
24184
  const hasCpp = dirsToCheck.some((dir) => {
24153
24185
  try {
24154
- return fs19.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
24186
+ return fs18.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
24155
24187
  } catch {
24156
24188
  return false;
24157
24189
  }
@@ -24162,13 +24194,13 @@ function detectCppcheck(cwd) {
24162
24194
  }
24163
24195
  }
24164
24196
  function detectSwiftlint(cwd) {
24165
- return fs19.existsSync(path49.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
24197
+ return fs18.existsSync(path49.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
24166
24198
  }
24167
24199
  function detectDartAnalyze(cwd) {
24168
- return fs19.existsSync(path49.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
24200
+ return fs18.existsSync(path49.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
24169
24201
  }
24170
24202
  function detectRubocop(cwd) {
24171
- return (fs19.existsSync(path49.join(cwd, "Gemfile")) || fs19.existsSync(path49.join(cwd, "gems.rb")) || fs19.existsSync(path49.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
24203
+ return (fs18.existsSync(path49.join(cwd, "Gemfile")) || fs18.existsSync(path49.join(cwd, "gems.rb")) || fs18.existsSync(path49.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
24172
24204
  }
24173
24205
  function detectAdditionalLinter(cwd) {
24174
24206
  if (detectRuff(cwd))
@@ -24197,7 +24229,7 @@ function findBinInAncestors(startDir, binName) {
24197
24229
  let dir = startDir;
24198
24230
  while (true) {
24199
24231
  const candidate = path49.join(dir, "node_modules", ".bin", binName);
24200
- if (fs19.existsSync(candidate))
24232
+ if (fs18.existsSync(candidate))
24201
24233
  return candidate;
24202
24234
  const parent = path49.dirname(dir);
24203
24235
  if (parent === dir)
@@ -24212,7 +24244,7 @@ function findBinInEnvPath(binName) {
24212
24244
  if (!dir)
24213
24245
  continue;
24214
24246
  const candidate = path49.join(dir, binName);
24215
- if (fs19.existsSync(candidate))
24247
+ if (fs18.existsSync(candidate))
24216
24248
  return candidate;
24217
24249
  }
24218
24250
  return null;
@@ -24220,7 +24252,7 @@ function findBinInEnvPath(binName) {
24220
24252
  async function detectAvailableLinter(directory) {
24221
24253
  if (!directory)
24222
24254
  return null;
24223
- if (!fs19.existsSync(directory))
24255
+ if (!fs18.existsSync(directory))
24224
24256
  return null;
24225
24257
  const projectDir = directory;
24226
24258
  const isWindows = process.platform === "win32";
@@ -24253,7 +24285,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24253
24285
  const result = await Promise.race([biomeExit, timeout]);
24254
24286
  if (result === "timeout") {
24255
24287
  biomeProc.kill();
24256
- } else if (biomeProc.exitCode === 0 && fs19.existsSync(biomeBin)) {
24288
+ } else if (biomeProc.exitCode === 0 && fs18.existsSync(biomeBin)) {
24257
24289
  return "biome";
24258
24290
  }
24259
24291
  } catch {}
@@ -24267,7 +24299,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24267
24299
  const result = await Promise.race([eslintExit, timeout]);
24268
24300
  if (result === "timeout") {
24269
24301
  eslintProc.kill();
24270
- } else if (eslintProc.exitCode === 0 && fs19.existsSync(eslintBin)) {
24302
+ } else if (eslintProc.exitCode === 0 && fs18.existsSync(eslintBin)) {
24271
24303
  return "eslint";
24272
24304
  }
24273
24305
  } catch {}
@@ -24443,7 +24475,7 @@ var _internals40 = {
24443
24475
  };
24444
24476
 
24445
24477
  // src/tools/secretscan.ts
24446
- import * as fs20 from "fs";
24478
+ import * as fs19 from "fs";
24447
24479
  import * as path50 from "path";
24448
24480
  var MAX_FILE_PATH_LENGTH = 500;
24449
24481
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
@@ -24673,9 +24705,9 @@ function isGlobOrPathPattern(pattern) {
24673
24705
  function loadSecretScanIgnore(scanDir) {
24674
24706
  const ignorePath = path50.join(scanDir, ".secretscanignore");
24675
24707
  try {
24676
- if (!fs20.existsSync(ignorePath))
24708
+ if (!fs19.existsSync(ignorePath))
24677
24709
  return [];
24678
- const content = fs20.readFileSync(ignorePath, "utf8");
24710
+ const content = fs19.readFileSync(ignorePath, "utf8");
24679
24711
  const patterns = [];
24680
24712
  for (const rawLine of content.split(/\r?\n/)) {
24681
24713
  const line = rawLine.trim();
@@ -24790,11 +24822,11 @@ function createRedactedContext(line, findings) {
24790
24822
  result += line.slice(lastEnd);
24791
24823
  return result;
24792
24824
  }
24793
- var O_NOFOLLOW = process.platform !== "win32" ? fs20.constants.O_NOFOLLOW : undefined;
24825
+ var O_NOFOLLOW = process.platform !== "win32" ? fs19.constants.O_NOFOLLOW : undefined;
24794
24826
  function scanFileForSecrets(filePath) {
24795
24827
  const findings = [];
24796
24828
  try {
24797
- const lstat2 = fs20.lstatSync(filePath);
24829
+ const lstat2 = fs19.lstatSync(filePath);
24798
24830
  if (lstat2.isSymbolicLink()) {
24799
24831
  return findings;
24800
24832
  }
@@ -24803,14 +24835,14 @@ function scanFileForSecrets(filePath) {
24803
24835
  }
24804
24836
  let buffer;
24805
24837
  if (O_NOFOLLOW !== undefined) {
24806
- const fd = fs20.openSync(filePath, "r", O_NOFOLLOW);
24838
+ const fd = fs19.openSync(filePath, "r", O_NOFOLLOW);
24807
24839
  try {
24808
- buffer = fs20.readFileSync(fd);
24840
+ buffer = fs19.readFileSync(fd);
24809
24841
  } finally {
24810
- fs20.closeSync(fd);
24842
+ fs19.closeSync(fd);
24811
24843
  }
24812
24844
  } else {
24813
- buffer = fs20.readFileSync(filePath);
24845
+ buffer = fs19.readFileSync(filePath);
24814
24846
  }
24815
24847
  if (isBinaryFile(filePath, buffer)) {
24816
24848
  return findings;
@@ -24865,7 +24897,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24865
24897
  const files = [];
24866
24898
  let entries;
24867
24899
  try {
24868
- entries = fs20.readdirSync(dir);
24900
+ entries = fs19.readdirSync(dir);
24869
24901
  } catch {
24870
24902
  stats.fileErrors++;
24871
24903
  return files;
@@ -24888,7 +24920,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24888
24920
  }
24889
24921
  let lstat2;
24890
24922
  try {
24891
- lstat2 = fs20.lstatSync(fullPath);
24923
+ lstat2 = fs19.lstatSync(fullPath);
24892
24924
  } catch {
24893
24925
  stats.fileErrors++;
24894
24926
  continue;
@@ -24900,7 +24932,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24900
24932
  if (lstat2.isDirectory()) {
24901
24933
  let realPath;
24902
24934
  try {
24903
- realPath = fs20.realpathSync(fullPath);
24935
+ realPath = fs19.realpathSync(fullPath);
24904
24936
  } catch {
24905
24937
  stats.fileErrors++;
24906
24938
  continue;
@@ -24985,12 +25017,12 @@ var secretscan = createSwarmTool({
24985
25017
  const _scanDirRaw = path50.resolve(directory);
24986
25018
  const scanDir = (() => {
24987
25019
  try {
24988
- return fs20.realpathSync(_scanDirRaw);
25020
+ return fs19.realpathSync(_scanDirRaw);
24989
25021
  } catch {
24990
25022
  return _scanDirRaw;
24991
25023
  }
24992
25024
  })();
24993
- if (!fs20.existsSync(scanDir)) {
25025
+ if (!fs19.existsSync(scanDir)) {
24994
25026
  const errorResult = {
24995
25027
  error: "directory not found",
24996
25028
  scan_dir: directory,
@@ -25001,7 +25033,7 @@ var secretscan = createSwarmTool({
25001
25033
  };
25002
25034
  return JSON.stringify(errorResult, null, 2);
25003
25035
  }
25004
- const dirStat = fs20.statSync(scanDir);
25036
+ const dirStat = fs19.statSync(scanDir);
25005
25037
  if (!dirStat.isDirectory()) {
25006
25038
  const errorResult = {
25007
25039
  error: "target must be a directory, not a file",
@@ -25052,7 +25084,7 @@ var secretscan = createSwarmTool({
25052
25084
  break;
25053
25085
  const fileFindings = scanFileForSecrets(filePath);
25054
25086
  try {
25055
- const stat5 = fs20.statSync(filePath);
25087
+ const stat5 = fs19.statSync(filePath);
25056
25088
  if (stat5.size > MAX_FILE_SIZE_BYTES) {
25057
25089
  skippedFiles++;
25058
25090
  continue;
@@ -25144,11 +25176,11 @@ var _internals41 = {
25144
25176
  };
25145
25177
 
25146
25178
  // src/tools/test-runner.ts
25147
- import * as fs24 from "fs";
25179
+ import * as fs23 from "fs";
25148
25180
  import * as path54 from "path";
25149
25181
 
25150
25182
  // src/test-impact/analyzer.ts
25151
- import fs21 from "fs";
25183
+ import fs20 from "fs";
25152
25184
  import path51 from "path";
25153
25185
  var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
25154
25186
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
@@ -25176,7 +25208,7 @@ function sharedTrailingSegments(a, b) {
25176
25208
  function isCacheStale(impactMap, generatedAtMs) {
25177
25209
  for (const sourcePath of Object.keys(impactMap)) {
25178
25210
  try {
25179
- const stat5 = fs21.statSync(sourcePath);
25211
+ const stat5 = fs20.statSync(sourcePath);
25180
25212
  if (stat5.mtimeMs > generatedAtMs) {
25181
25213
  return true;
25182
25214
  }
@@ -25192,13 +25224,13 @@ function resolveRelativeImport(fromDir, importPath) {
25192
25224
  }
25193
25225
  const resolved = path51.resolve(fromDir, importPath);
25194
25226
  if (path51.extname(resolved)) {
25195
- if (fs21.existsSync(resolved) && fs21.statSync(resolved).isFile()) {
25227
+ if (fs20.existsSync(resolved) && fs20.statSync(resolved).isFile()) {
25196
25228
  return normalizePath2(resolved);
25197
25229
  }
25198
25230
  } else {
25199
25231
  for (const ext of EXTENSIONS_TO_TRY) {
25200
25232
  const withExt = resolved + ext;
25201
- if (fs21.existsSync(withExt) && fs21.statSync(withExt).isFile()) {
25233
+ if (fs20.existsSync(withExt) && fs20.statSync(withExt).isFile()) {
25202
25234
  return normalizePath2(withExt);
25203
25235
  }
25204
25236
  }
@@ -25216,7 +25248,7 @@ function resolvePythonImport(fromDir, module) {
25216
25248
  const rest = module.slice(leadingDots);
25217
25249
  if (rest.length === 0) {
25218
25250
  const initPath = path51.join(baseDir, "__init__.py");
25219
- if (fs21.existsSync(initPath) && fs21.statSync(initPath).isFile()) {
25251
+ if (fs20.existsSync(initPath) && fs20.statSync(initPath).isFile()) {
25220
25252
  return normalizePath2(initPath);
25221
25253
  }
25222
25254
  return null;
@@ -25227,7 +25259,7 @@ function resolvePythonImport(fromDir, module) {
25227
25259
  path51.join(baseDir, subpath, "__init__.py")
25228
25260
  ];
25229
25261
  for (const c of candidates) {
25230
- if (fs21.existsSync(c) && fs21.statSync(c).isFile())
25262
+ if (fs20.existsSync(c) && fs20.statSync(c).isFile())
25231
25263
  return normalizePath2(c);
25232
25264
  }
25233
25265
  return null;
@@ -25247,7 +25279,7 @@ function findGoModule(fromDir) {
25247
25279
  walked.push(cur);
25248
25280
  try {
25249
25281
  const goMod = path51.join(cur, "go.mod");
25250
- const content = fs21.readFileSync(goMod, "utf-8");
25282
+ const content = fs20.readFileSync(goMod, "utf-8");
25251
25283
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
25252
25284
  if (moduleMatch) {
25253
25285
  const result = { moduleRoot: cur, modulePath: moduleMatch[1] };
@@ -25257,7 +25289,7 @@ function findGoModule(fromDir) {
25257
25289
  }
25258
25290
  } catch {}
25259
25291
  try {
25260
- fs21.accessSync(path51.join(cur, ".git"));
25292
+ fs20.accessSync(path51.join(cur, ".git"));
25261
25293
  break;
25262
25294
  } catch {}
25263
25295
  const parent = path51.dirname(cur);
@@ -25282,10 +25314,10 @@ function resolveGoImport(fromDir, importPath) {
25282
25314
  }
25283
25315
  if (dir === null)
25284
25316
  return [];
25285
- if (!fs21.existsSync(dir) || !fs21.statSync(dir).isDirectory())
25317
+ if (!fs20.existsSync(dir) || !fs20.statSync(dir).isDirectory())
25286
25318
  return [];
25287
25319
  try {
25288
- return fs21.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path51.join(dir, f)));
25320
+ return fs20.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path51.join(dir, f)));
25289
25321
  } catch {
25290
25322
  return [];
25291
25323
  }
@@ -25305,13 +25337,13 @@ function findTestFilesSync(cwd) {
25305
25337
  function walk(dir, visitedInodes) {
25306
25338
  let entries;
25307
25339
  try {
25308
- entries = fs21.readdirSync(dir, { withFileTypes: true });
25340
+ entries = fs20.readdirSync(dir, { withFileTypes: true });
25309
25341
  } catch {
25310
25342
  return;
25311
25343
  }
25312
25344
  let dirInode;
25313
25345
  try {
25314
- dirInode = fs21.statSync(dir).ino;
25346
+ dirInode = fs20.statSync(dir).ino;
25315
25347
  } catch {
25316
25348
  return;
25317
25349
  }
@@ -25400,7 +25432,7 @@ async function buildImpactMapInternal(cwd) {
25400
25432
  for (const testFile of testFiles) {
25401
25433
  let content;
25402
25434
  try {
25403
- content = fs21.readFileSync(testFile, "utf-8");
25435
+ content = fs20.readFileSync(testFile, "utf-8");
25404
25436
  } catch {
25405
25437
  continue;
25406
25438
  }
@@ -25432,9 +25464,9 @@ async function buildImpactMap(cwd) {
25432
25464
  }
25433
25465
  async function loadImpactMap(cwd, options) {
25434
25466
  const cachePath = path51.join(cwd, ".swarm", "cache", "impact-map.json");
25435
- if (fs21.existsSync(cachePath)) {
25467
+ if (fs20.existsSync(cachePath)) {
25436
25468
  try {
25437
- const content = fs21.readFileSync(cachePath, "utf-8");
25469
+ const content = fs20.readFileSync(cachePath, "utf-8");
25438
25470
  const data = JSON.parse(content);
25439
25471
  if (data.map !== null && typeof data.map === "object" && !Array.isArray(data.map)) {
25440
25472
  const map = data.map;
@@ -25470,15 +25502,15 @@ async function saveImpactMap(cwd, impactMap) {
25470
25502
  _internals42.validateProjectRoot(cwd);
25471
25503
  const cacheDir2 = path51.join(cwd, ".swarm", "cache");
25472
25504
  const cachePath = path51.join(cacheDir2, "impact-map.json");
25473
- if (!fs21.existsSync(cacheDir2)) {
25474
- fs21.mkdirSync(cacheDir2, { recursive: true });
25505
+ if (!fs20.existsSync(cacheDir2)) {
25506
+ fs20.mkdirSync(cacheDir2, { recursive: true });
25475
25507
  }
25476
25508
  const data = {
25477
25509
  generatedAt: new Date().toISOString(),
25478
25510
  fileCount: Object.keys(impactMap).length,
25479
25511
  map: impactMap
25480
25512
  };
25481
- fs21.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
25513
+ fs20.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
25482
25514
  }
25483
25515
  async function analyzeImpact(changedFiles, cwd, budget) {
25484
25516
  if (!Array.isArray(changedFiles)) {
@@ -25847,7 +25879,7 @@ function detectFlakyTests(allHistory) {
25847
25879
  }
25848
25880
 
25849
25881
  // src/test-impact/history-store.ts
25850
- import fs22 from "fs";
25882
+ import fs21 from "fs";
25851
25883
  import path52 from "path";
25852
25884
  var MAX_HISTORY_PER_TEST = 20;
25853
25885
  var MAX_ERROR_LENGTH = 500;
@@ -25957,8 +25989,8 @@ function batchAppendTestRuns(records, workingDir) {
25957
25989
  const historyPath = getHistoryPath(workingDir);
25958
25990
  const historyDir = path52.dirname(historyPath);
25959
25991
  _internals43.validateProjectRoot(workingDir);
25960
- if (!fs22.existsSync(historyDir)) {
25961
- fs22.mkdirSync(historyDir, { recursive: true });
25992
+ if (!fs21.existsSync(historyDir)) {
25993
+ fs21.mkdirSync(historyDir, { recursive: true });
25962
25994
  }
25963
25995
  withHistoryWriteLock(historyPath, () => {
25964
25996
  const existingRecords = readAllRecords(historyPath);
@@ -25992,13 +26024,13 @@ function batchAppendTestRuns(records, workingDir) {
25992
26024
  `)}
25993
26025
  `;
25994
26026
  const tempPath = `${historyPath}.tmp`;
25995
- fs22.writeFileSync(tempPath, content, "utf-8");
25996
- fs22.renameSync(tempPath, historyPath);
26027
+ fs21.writeFileSync(tempPath, content, "utf-8");
26028
+ fs21.renameSync(tempPath, historyPath);
25997
26029
  } catch (err) {
25998
26030
  try {
25999
26031
  const tempPath = `${historyPath}.tmp`;
26000
- if (fs22.existsSync(tempPath)) {
26001
- fs22.unlinkSync(tempPath);
26032
+ if (fs21.existsSync(tempPath)) {
26033
+ fs21.unlinkSync(tempPath);
26002
26034
  }
26003
26035
  } catch {}
26004
26036
  throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
@@ -26010,7 +26042,7 @@ function withHistoryWriteLock(historyPath, fn) {
26010
26042
  const deadline = Date.now() + HISTORY_WRITE_LOCK_TIMEOUT_MS;
26011
26043
  while (true) {
26012
26044
  try {
26013
- fs22.mkdirSync(lockPath);
26045
+ fs21.mkdirSync(lockPath);
26014
26046
  break;
26015
26047
  } catch (error2) {
26016
26048
  const code = error2 instanceof Error && "code" in error2 ? error2.code : undefined;
@@ -26021,9 +26053,9 @@ function withHistoryWriteLock(historyPath, fn) {
26021
26053
  throw new Error(`Timed out waiting for test history lock: ${historyPath}`);
26022
26054
  }
26023
26055
  try {
26024
- const lockStat = fs22.statSync(lockPath);
26056
+ const lockStat = fs21.statSync(lockPath);
26025
26057
  if (Date.now() - lockStat.mtimeMs >= HISTORY_WRITE_LOCK_STALE_MS) {
26026
- fs22.rmSync(lockPath, { recursive: true, force: true });
26058
+ fs21.rmSync(lockPath, { recursive: true, force: true });
26027
26059
  continue;
26028
26060
  }
26029
26061
  } catch {}
@@ -26038,7 +26070,7 @@ function withHistoryWriteLock(historyPath, fn) {
26038
26070
  return fn();
26039
26071
  } finally {
26040
26072
  try {
26041
- fs22.rmSync(lockPath, { recursive: true, force: true });
26073
+ fs21.rmSync(lockPath, { recursive: true, force: true });
26042
26074
  } catch {}
26043
26075
  }
26044
26076
  function sleepSync(ms) {
@@ -26047,11 +26079,11 @@ function withHistoryWriteLock(historyPath, fn) {
26047
26079
  }
26048
26080
  }
26049
26081
  function readAllRecords(historyPath) {
26050
- if (!fs22.existsSync(historyPath)) {
26082
+ if (!fs21.existsSync(historyPath)) {
26051
26083
  return [];
26052
26084
  }
26053
26085
  try {
26054
- const content = fs22.readFileSync(historyPath, "utf-8");
26086
+ const content = fs21.readFileSync(historyPath, "utf-8");
26055
26087
  const lines = content.split(`
26056
26088
  `);
26057
26089
  const records = [];
@@ -26084,7 +26116,7 @@ var _internals43 = {
26084
26116
  };
26085
26117
 
26086
26118
  // src/tools/resolve-working-directory.ts
26087
- import * as fs23 from "fs";
26119
+ import * as fs22 from "fs";
26088
26120
  import * as path53 from "path";
26089
26121
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26090
26122
  if (workingDirectory == null || workingDirectory === "") {
@@ -26128,7 +26160,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26128
26160
  const resolvedDir = path53.resolve(normalizedDir);
26129
26161
  let statResult;
26130
26162
  try {
26131
- statResult = fs23.statSync(resolvedDir);
26163
+ statResult = fs22.statSync(resolvedDir);
26132
26164
  } catch {
26133
26165
  return {
26134
26166
  success: false,
@@ -26147,7 +26179,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26147
26179
  const resolvedFallback = path53.resolve(fallbackDirectory);
26148
26180
  let fallbackExists = false;
26149
26181
  try {
26150
- fs23.statSync(resolvedFallback);
26182
+ fs22.statSync(resolvedFallback);
26151
26183
  fallbackExists = true;
26152
26184
  } catch {
26153
26185
  fallbackExists = false;
@@ -26261,19 +26293,19 @@ function hasDevDependency(devDeps, ...patterns) {
26261
26293
  return hasPackageJsonDependency(devDeps, ...patterns);
26262
26294
  }
26263
26295
  function detectGoTest(cwd) {
26264
- return fs24.existsSync(path54.join(cwd, "go.mod")) && isCommandAvailable("go");
26296
+ return fs23.existsSync(path54.join(cwd, "go.mod")) && isCommandAvailable("go");
26265
26297
  }
26266
26298
  function detectJavaMaven(cwd) {
26267
- return fs24.existsSync(path54.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
26299
+ return fs23.existsSync(path54.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
26268
26300
  }
26269
26301
  function detectGradle(cwd) {
26270
- const hasBuildFile = fs24.existsSync(path54.join(cwd, "build.gradle")) || fs24.existsSync(path54.join(cwd, "build.gradle.kts"));
26271
- const hasGradlew = fs24.existsSync(path54.join(cwd, "gradlew")) || fs24.existsSync(path54.join(cwd, "gradlew.bat"));
26302
+ const hasBuildFile = fs23.existsSync(path54.join(cwd, "build.gradle")) || fs23.existsSync(path54.join(cwd, "build.gradle.kts"));
26303
+ const hasGradlew = fs23.existsSync(path54.join(cwd, "gradlew")) || fs23.existsSync(path54.join(cwd, "gradlew.bat"));
26272
26304
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
26273
26305
  }
26274
26306
  function detectDotnetTest(cwd) {
26275
26307
  try {
26276
- const files = fs24.readdirSync(cwd);
26308
+ const files = fs23.readdirSync(cwd);
26277
26309
  const hasCsproj = files.some((f) => f.endsWith(".csproj"));
26278
26310
  return hasCsproj && isCommandAvailable("dotnet");
26279
26311
  } catch {
@@ -26281,25 +26313,25 @@ function detectDotnetTest(cwd) {
26281
26313
  }
26282
26314
  }
26283
26315
  function detectCTest(cwd) {
26284
- const hasSource = fs24.existsSync(path54.join(cwd, "CMakeLists.txt"));
26285
- const hasBuildCache = fs24.existsSync(path54.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path54.join(cwd, "build", "CMakeCache.txt"));
26316
+ const hasSource = fs23.existsSync(path54.join(cwd, "CMakeLists.txt"));
26317
+ const hasBuildCache = fs23.existsSync(path54.join(cwd, "CMakeCache.txt")) || fs23.existsSync(path54.join(cwd, "build", "CMakeCache.txt"));
26286
26318
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
26287
26319
  }
26288
26320
  function detectSwiftTest(cwd) {
26289
- return fs24.existsSync(path54.join(cwd, "Package.swift")) && isCommandAvailable("swift");
26321
+ return fs23.existsSync(path54.join(cwd, "Package.swift")) && isCommandAvailable("swift");
26290
26322
  }
26291
26323
  function detectDartTest(cwd) {
26292
- return fs24.existsSync(path54.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
26324
+ return fs23.existsSync(path54.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
26293
26325
  }
26294
26326
  function detectRSpec(cwd) {
26295
- const hasRSpecFile = fs24.existsSync(path54.join(cwd, ".rspec"));
26296
- const hasGemfile = fs24.existsSync(path54.join(cwd, "Gemfile"));
26297
- const hasSpecDir = fs24.existsSync(path54.join(cwd, "spec"));
26327
+ const hasRSpecFile = fs23.existsSync(path54.join(cwd, ".rspec"));
26328
+ const hasGemfile = fs23.existsSync(path54.join(cwd, "Gemfile"));
26329
+ const hasSpecDir = fs23.existsSync(path54.join(cwd, "spec"));
26298
26330
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
26299
26331
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
26300
26332
  }
26301
26333
  function detectMinitest(cwd) {
26302
- return fs24.existsSync(path54.join(cwd, "test")) && (fs24.existsSync(path54.join(cwd, "Gemfile")) || fs24.existsSync(path54.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
26334
+ return fs23.existsSync(path54.join(cwd, "test")) && (fs23.existsSync(path54.join(cwd, "Gemfile")) || fs23.existsSync(path54.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
26303
26335
  }
26304
26336
  var DISPATCH_FRAMEWORK_MAP = {
26305
26337
  bun: "bun",
@@ -26385,8 +26417,8 @@ async function detectTestFramework(cwd) {
26385
26417
  const baseDir = cwd;
26386
26418
  try {
26387
26419
  const packageJsonPath = path54.join(baseDir, "package.json");
26388
- if (fs24.existsSync(packageJsonPath)) {
26389
- const content = fs24.readFileSync(packageJsonPath, "utf-8");
26420
+ if (fs23.existsSync(packageJsonPath)) {
26421
+ const content = fs23.readFileSync(packageJsonPath, "utf-8");
26390
26422
  const pkg = JSON.parse(content);
26391
26423
  const _deps = pkg.dependencies || {};
26392
26424
  const devDeps = pkg.devDependencies || {};
@@ -26405,7 +26437,7 @@ async function detectTestFramework(cwd) {
26405
26437
  return "jest";
26406
26438
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
26407
26439
  return "mocha";
26408
- if (fs24.existsSync(path54.join(baseDir, "bun.lockb")) || fs24.existsSync(path54.join(baseDir, "bun.lock"))) {
26440
+ if (fs23.existsSync(path54.join(baseDir, "bun.lockb")) || fs23.existsSync(path54.join(baseDir, "bun.lock"))) {
26409
26441
  if (scripts.test?.includes("bun"))
26410
26442
  return "bun";
26411
26443
  }
@@ -26415,28 +26447,28 @@ async function detectTestFramework(cwd) {
26415
26447
  const pyprojectTomlPath = path54.join(baseDir, "pyproject.toml");
26416
26448
  const setupCfgPath = path54.join(baseDir, "setup.cfg");
26417
26449
  const requirementsTxtPath = path54.join(baseDir, "requirements.txt");
26418
- if (fs24.existsSync(pyprojectTomlPath)) {
26419
- const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
26450
+ if (fs23.existsSync(pyprojectTomlPath)) {
26451
+ const content = fs23.readFileSync(pyprojectTomlPath, "utf-8");
26420
26452
  if (content.includes("[tool.pytest"))
26421
26453
  return "pytest";
26422
26454
  if (content.includes("pytest"))
26423
26455
  return "pytest";
26424
26456
  }
26425
- if (fs24.existsSync(setupCfgPath)) {
26426
- const content = fs24.readFileSync(setupCfgPath, "utf-8");
26457
+ if (fs23.existsSync(setupCfgPath)) {
26458
+ const content = fs23.readFileSync(setupCfgPath, "utf-8");
26427
26459
  if (content.includes("[pytest]"))
26428
26460
  return "pytest";
26429
26461
  }
26430
- if (fs24.existsSync(requirementsTxtPath)) {
26431
- const content = fs24.readFileSync(requirementsTxtPath, "utf-8");
26462
+ if (fs23.existsSync(requirementsTxtPath)) {
26463
+ const content = fs23.readFileSync(requirementsTxtPath, "utf-8");
26432
26464
  if (content.includes("pytest"))
26433
26465
  return "pytest";
26434
26466
  }
26435
26467
  } catch {}
26436
26468
  try {
26437
26469
  const cargoTomlPath = path54.join(baseDir, "Cargo.toml");
26438
- if (fs24.existsSync(cargoTomlPath)) {
26439
- const content = fs24.readFileSync(cargoTomlPath, "utf-8");
26470
+ if (fs23.existsSync(cargoTomlPath)) {
26471
+ const content = fs23.readFileSync(cargoTomlPath, "utf-8");
26440
26472
  if (content.includes("[dev-dependencies]")) {
26441
26473
  if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
26442
26474
  return "cargo";
@@ -26448,7 +26480,7 @@ async function detectTestFramework(cwd) {
26448
26480
  const pesterConfigPath = path54.join(baseDir, "pester.config.ps1");
26449
26481
  const pesterConfigJsonPath = path54.join(baseDir, "pester.config.ps1.json");
26450
26482
  const pesterPs1Path = path54.join(baseDir, "tests.ps1");
26451
- if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
26483
+ if (fs23.existsSync(pesterConfigPath) || fs23.existsSync(pesterConfigJsonPath) || fs23.existsSync(pesterPs1Path)) {
26452
26484
  return "pester";
26453
26485
  }
26454
26486
  } catch {}
@@ -26551,19 +26583,19 @@ function hasCompoundTestExtension(filename) {
26551
26583
  const lower = filename.toLowerCase();
26552
26584
  return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
26553
26585
  }
26554
- function isLanguageSpecificTestFile(basename10) {
26555
- const lower = basename10.toLowerCase();
26586
+ function isLanguageSpecificTestFile(basename11) {
26587
+ const lower = basename11.toLowerCase();
26556
26588
  if (lower.endsWith("_test.go"))
26557
26589
  return true;
26558
26590
  if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
26559
26591
  return true;
26560
26592
  if (lower.endsWith("_spec.rb"))
26561
26593
  return true;
26562
- if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename10) || basename10.endsWith("Test.java") || basename10.endsWith("Tests.java") || lower.endsWith("it.java")))
26594
+ if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename11) || basename11.endsWith("Test.java") || basename11.endsWith("Tests.java") || lower.endsWith("it.java")))
26563
26595
  return true;
26564
26596
  if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
26565
26597
  return true;
26566
- if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename10) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
26598
+ if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename11) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
26567
26599
  return true;
26568
26600
  if (lower.endsWith(".tests.ps1"))
26569
26601
  return true;
@@ -26571,23 +26603,23 @@ function isLanguageSpecificTestFile(basename10) {
26571
26603
  }
26572
26604
  function isConventionTestFilePath(filePath) {
26573
26605
  const normalizedPath = filePath.replace(/\\/g, "/");
26574
- const basename10 = path54.basename(filePath);
26575
- return hasCompoundTestExtension(basename10) || basename10.includes(".spec.") || basename10.includes(".test.") || isLanguageSpecificTestFile(basename10) || isTestDirectoryPath(normalizedPath);
26606
+ const basename11 = path54.basename(filePath);
26607
+ return hasCompoundTestExtension(basename11) || basename11.includes(".spec.") || basename11.includes(".test.") || isLanguageSpecificTestFile(basename11) || isTestDirectoryPath(normalizedPath);
26576
26608
  }
26577
26609
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
26578
26610
  const testFiles = [];
26579
26611
  for (const file of sourceFiles) {
26580
26612
  const absoluteFile = resolveWorkspacePath(file, workingDir);
26581
26613
  const relativeFile = path54.relative(workingDir, absoluteFile);
26582
- const basename10 = path54.basename(absoluteFile);
26614
+ const basename11 = path54.basename(absoluteFile);
26583
26615
  const dirname24 = path54.dirname(absoluteFile);
26584
26616
  const preferRelativeOutput = !path54.isAbsolute(file);
26585
26617
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
26586
26618
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
26587
26619
  continue;
26588
26620
  }
26589
- const nameWithoutExt = basename10.replace(/\.[^.]+$/, "");
26590
- const ext = path54.extname(basename10);
26621
+ const nameWithoutExt = basename11.replace(/\.[^.]+$/, "");
26622
+ const ext = path54.extname(basename11);
26591
26623
  const genericTestNames = [
26592
26624
  `${nameWithoutExt}.spec${ext}`,
26593
26625
  `${nameWithoutExt}.test${ext}`
@@ -26598,7 +26630,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
26598
26630
  ...languageSpecificTestNames
26599
26631
  ].map((candidateName) => path54.join(dirname24, candidateName));
26600
26632
  const testDirectoryNames = [
26601
- basename10,
26633
+ basename11,
26602
26634
  ...genericTestNames,
26603
26635
  ...languageSpecificTestNames
26604
26636
  ];
@@ -26609,7 +26641,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
26609
26641
  ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path54.join(candidateDir, candidateName)))
26610
26642
  ];
26611
26643
  for (const testFile of possibleTestFiles) {
26612
- if (fs24.existsSync(testFile)) {
26644
+ if (fs23.existsSync(testFile)) {
26613
26645
  dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
26614
26646
  }
26615
26647
  }
@@ -26626,7 +26658,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26626
26658
  for (const testFile of candidateTestFiles) {
26627
26659
  try {
26628
26660
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
26629
- const content = fs24.readFileSync(absoluteTestFile, "utf-8");
26661
+ const content = fs23.readFileSync(absoluteTestFile, "utf-8");
26630
26662
  const testDir = path54.dirname(absoluteTestFile);
26631
26663
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
26632
26664
  let match;
@@ -26647,7 +26679,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26647
26679
  ".cjs"
26648
26680
  ]) {
26649
26681
  const withExt = resolvedImport + extToTry;
26650
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
26682
+ if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
26651
26683
  resolvedImport = withExt;
26652
26684
  break;
26653
26685
  }
@@ -26686,7 +26718,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26686
26718
  ".cjs"
26687
26719
  ]) {
26688
26720
  const withExt = resolvedImport + extToTry;
26689
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
26721
+ if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
26690
26722
  resolvedImport = withExt;
26691
26723
  break;
26692
26724
  }
@@ -26817,8 +26849,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
26817
26849
  return ["mvn", "test"];
26818
26850
  case "gradle": {
26819
26851
  const isWindows = process.platform === "win32";
26820
- const hasGradlewBat = fs24.existsSync(path54.join(baseDir, "gradlew.bat"));
26821
- const hasGradlew = fs24.existsSync(path54.join(baseDir, "gradlew"));
26852
+ const hasGradlewBat = fs23.existsSync(path54.join(baseDir, "gradlew.bat"));
26853
+ const hasGradlew = fs23.existsSync(path54.join(baseDir, "gradlew"));
26822
26854
  if (hasGradlewBat && isWindows)
26823
26855
  return ["gradlew.bat", "test"];
26824
26856
  if (hasGradlew)
@@ -26835,7 +26867,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
26835
26867
  "cmake-build-release",
26836
26868
  "out"
26837
26869
  ];
26838
- const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path54.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
26870
+ const actualBuildDir = buildDirCandidates.find((d) => fs23.existsSync(path54.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
26839
26871
  return ["ctest", "--test-dir", actualBuildDir];
26840
26872
  }
26841
26873
  case "swift-test":
@@ -27273,9 +27305,9 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27273
27305
  try {
27274
27306
  if (vitestJsonOutputPath) {
27275
27307
  try {
27276
- fs24.mkdirSync(path54.dirname(vitestJsonOutputPath), { recursive: true });
27277
- if (fs24.existsSync(vitestJsonOutputPath)) {
27278
- fs24.unlinkSync(vitestJsonOutputPath);
27308
+ fs23.mkdirSync(path54.dirname(vitestJsonOutputPath), { recursive: true });
27309
+ if (fs23.existsSync(vitestJsonOutputPath)) {
27310
+ fs23.unlinkSync(vitestJsonOutputPath);
27279
27311
  }
27280
27312
  } catch {}
27281
27313
  }
@@ -27301,8 +27333,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27301
27333
  }
27302
27334
  if (vitestJsonOutputPath) {
27303
27335
  try {
27304
- if (fs24.existsSync(vitestJsonOutputPath)) {
27305
- const vitestJsonOutput = fs24.readFileSync(vitestJsonOutputPath, "utf-8");
27336
+ if (fs23.existsSync(vitestJsonOutputPath)) {
27337
+ const vitestJsonOutput = fs23.readFileSync(vitestJsonOutputPath, "utf-8");
27306
27338
  if (vitestJsonOutput.trim().length > 0) {
27307
27339
  output += (output ? `
27308
27340
  ` : "") + vitestJsonOutput;
@@ -27952,8 +27984,8 @@ function validateTimeout(timeoutMs, defaultValue) {
27952
27984
  function getPackageVersion(dir) {
27953
27985
  try {
27954
27986
  const packagePath = path55.join(dir, "package.json");
27955
- if (fs25.existsSync(packagePath)) {
27956
- const content = fs25.readFileSync(packagePath, "utf-8");
27987
+ if (fs24.existsSync(packagePath)) {
27988
+ const content = fs24.readFileSync(packagePath, "utf-8");
27957
27989
  const pkg = JSON.parse(content);
27958
27990
  return pkg.version ?? null;
27959
27991
  }
@@ -27963,8 +27995,8 @@ function getPackageVersion(dir) {
27963
27995
  function getChangelogVersion(dir) {
27964
27996
  try {
27965
27997
  const changelogPath = path55.join(dir, "CHANGELOG.md");
27966
- if (fs25.existsSync(changelogPath)) {
27967
- const content = fs25.readFileSync(changelogPath, "utf-8");
27998
+ if (fs24.existsSync(changelogPath)) {
27999
+ const content = fs24.readFileSync(changelogPath, "utf-8");
27968
28000
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
27969
28001
  if (match) {
27970
28002
  return match[1];
@@ -27977,9 +28009,9 @@ function getVersionFileVersion(dir) {
27977
28009
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
27978
28010
  for (const file of possibleFiles) {
27979
28011
  const filePath = path55.join(dir, file);
27980
- if (fs25.existsSync(filePath)) {
28012
+ if (fs24.existsSync(filePath)) {
27981
28013
  try {
27982
- const content = fs25.readFileSync(filePath, "utf-8").trim();
28014
+ const content = fs24.readFileSync(filePath, "utf-8").trim();
27983
28015
  const match = content.match(/(\d+\.\d+\.\d+)/);
27984
28016
  if (match) {
27985
28017
  return match[1];
@@ -28713,7 +28745,7 @@ async function handleQaGatesCommand(directory, args, sessionID) {
28713
28745
  }
28714
28746
 
28715
28747
  // src/commands/reset.ts
28716
- import * as fs26 from "fs";
28748
+ import * as fs25 from "fs";
28717
28749
  import * as path56 from "path";
28718
28750
 
28719
28751
  // src/background/circuit-breaker.ts
@@ -29421,8 +29453,8 @@ async function handleResetCommand(directory, args) {
29421
29453
  for (const filename of filesToReset) {
29422
29454
  try {
29423
29455
  const resolvedPath = validateSwarmPath(directory, filename);
29424
- if (fs26.existsSync(resolvedPath)) {
29425
- fs26.unlinkSync(resolvedPath);
29456
+ if (fs25.existsSync(resolvedPath)) {
29457
+ fs25.unlinkSync(resolvedPath);
29426
29458
  results.push(`- \u2705 Deleted ${filename}`);
29427
29459
  } else {
29428
29460
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -29434,8 +29466,8 @@ async function handleResetCommand(directory, args) {
29434
29466
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
29435
29467
  try {
29436
29468
  const rootPath = path56.join(directory, filename);
29437
- if (fs26.existsSync(rootPath)) {
29438
- fs26.unlinkSync(rootPath);
29469
+ if (fs25.existsSync(rootPath)) {
29470
+ fs25.unlinkSync(rootPath);
29439
29471
  results.push(`- \u2705 Deleted ${filename} (root)`);
29440
29472
  }
29441
29473
  } catch (err) {
@@ -29450,8 +29482,8 @@ async function handleResetCommand(directory, args) {
29450
29482
  }
29451
29483
  try {
29452
29484
  const summariesPath = validateSwarmPath(directory, "summaries");
29453
- if (fs26.existsSync(summariesPath)) {
29454
- fs26.rmSync(summariesPath, { recursive: true, force: true });
29485
+ if (fs25.existsSync(summariesPath)) {
29486
+ fs25.rmSync(summariesPath, { recursive: true, force: true });
29455
29487
  results.push("- \u2705 Deleted summaries/ directory");
29456
29488
  } else {
29457
29489
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -29470,11 +29502,11 @@ async function handleResetCommand(directory, args) {
29470
29502
  }
29471
29503
 
29472
29504
  // src/commands/reset-session.ts
29473
- import * as fs29 from "fs";
29505
+ import * as fs28 from "fs";
29474
29506
  import * as path59 from "path";
29475
29507
 
29476
29508
  // src/prm/trajectory-store.ts
29477
- import * as fs27 from "fs/promises";
29509
+ import * as fs26 from "fs/promises";
29478
29510
  import * as path57 from "path";
29479
29511
  var MAX_TRACKED_TRAJECTORY_SESSIONS = 500;
29480
29512
  function getTrajectoryPath(sessionId, directory) {
@@ -29508,7 +29540,7 @@ function clearTrajectoryCache(sessionId) {
29508
29540
  async function readTrajectory(sessionId, directory) {
29509
29541
  try {
29510
29542
  const trajectoryPath = getTrajectoryPath(sessionId, directory);
29511
- const content = await fs27.readFile(trajectoryPath, "utf-8");
29543
+ const content = await fs26.readFile(trajectoryPath, "utf-8");
29512
29544
  const lines = content.split(`
29513
29545
  `).filter((line) => line.trim().length > 0);
29514
29546
  const entries = [];
@@ -29533,15 +29565,15 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
29533
29565
  for (const subdir of ["trajectories", "replays"]) {
29534
29566
  try {
29535
29567
  const dirPath = validateSwarmPath(directory, subdir);
29536
- const entries = await fs27.readdir(dirPath, { withFileTypes: true });
29568
+ const entries = await fs26.readdir(dirPath, { withFileTypes: true });
29537
29569
  for (const entry of entries) {
29538
29570
  if (!entry.isFile())
29539
29571
  continue;
29540
29572
  const filePath = path57.join(dirPath, entry.name);
29541
29573
  try {
29542
- const stat6 = await fs27.stat(filePath);
29574
+ const stat6 = await fs26.stat(filePath);
29543
29575
  if (now - stat6.mtimeMs > cutoffMs) {
29544
- await fs27.unlink(filePath);
29576
+ await fs26.unlink(filePath);
29545
29577
  }
29546
29578
  } catch {}
29547
29579
  }
@@ -29963,7 +29995,7 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
29963
29995
  };
29964
29996
  }
29965
29997
  // src/prm/replay.ts
29966
- import { promises as fs28 } from "fs";
29998
+ import { promises as fs27 } from "fs";
29967
29999
  import path58 from "path";
29968
30000
  function isPathSafe(targetPath, basePath) {
29969
30001
  const resolvedTarget = path58.resolve(targetPath);
@@ -29994,7 +30026,7 @@ async function startReplayRecording(sessionID, directory) {
29994
30026
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
29995
30027
  return null;
29996
30028
  }
29997
- await fs28.mkdir(replayDir, { recursive: true });
30029
+ await fs27.mkdir(replayDir, { recursive: true });
29998
30030
  return filepath;
29999
30031
  } catch (err) {
30000
30032
  console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err}`);
@@ -30014,7 +30046,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
30014
30046
  };
30015
30047
  const line = `${JSON.stringify(fullEntry)}
30016
30048
  `;
30017
- await fs28.appendFile(artifactPath, line, "utf-8");
30049
+ await fs27.appendFile(artifactPath, line, "utf-8");
30018
30050
  } catch (err) {
30019
30051
  console.warn(`[replay] Failed to record entry: ${err}`);
30020
30052
  }
@@ -30061,8 +30093,8 @@ async function handleResetSessionCommand(directory, _args) {
30061
30093
  const results = [];
30062
30094
  try {
30063
30095
  const statePath = validateSwarmPath(directory, "session/state.json");
30064
- if (fs29.existsSync(statePath)) {
30065
- fs29.unlinkSync(statePath);
30096
+ if (fs28.existsSync(statePath)) {
30097
+ fs28.unlinkSync(statePath);
30066
30098
  results.push("\u2705 Deleted .swarm/session/state.json");
30067
30099
  } else {
30068
30100
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -30072,9 +30104,9 @@ async function handleResetSessionCommand(directory, _args) {
30072
30104
  }
30073
30105
  const sessionDir = path59.dirname(validateSwarmPath(directory, "session/state.json"));
30074
30106
  let sessionFiles = [];
30075
- if (fs29.existsSync(sessionDir)) {
30107
+ if (fs28.existsSync(sessionDir)) {
30076
30108
  try {
30077
- sessionFiles = fs29.readdirSync(sessionDir);
30109
+ sessionFiles = fs28.readdirSync(sessionDir);
30078
30110
  } catch (err) {
30079
30111
  results.push(`\u274C Failed to read session directory: ${errorMessage(err)}`);
30080
30112
  }
@@ -30084,11 +30116,11 @@ async function handleResetSessionCommand(directory, _args) {
30084
30116
  continue;
30085
30117
  const filePath = path59.join(sessionDir, file);
30086
30118
  try {
30087
- if (!fs29.existsSync(filePath))
30119
+ if (!fs28.existsSync(filePath))
30088
30120
  continue;
30089
- if (!fs29.lstatSync(filePath).isFile())
30121
+ if (!fs28.lstatSync(filePath).isFile())
30090
30122
  continue;
30091
- fs29.unlinkSync(filePath);
30123
+ fs28.unlinkSync(filePath);
30092
30124
  results.push(`\u2713 Deleted ${file}`);
30093
30125
  } catch (err) {
30094
30126
  results.push(`\u274C Failed to delete ${file}: ${errorMessage(err)}`);
@@ -30106,8 +30138,8 @@ async function handleResetSessionCommand(directory, _args) {
30106
30138
  results.push(`\u2705 Cleared ${chainCount} delegation chain(s)`);
30107
30139
  const worktreesDir = path59.resolve(path59.dirname(directory), ".swarm-worktrees");
30108
30140
  try {
30109
- if (fs29.existsSync(worktreesDir)) {
30110
- fs29.rmSync(worktreesDir, { recursive: true, force: true });
30141
+ if (fs28.existsSync(worktreesDir)) {
30142
+ fs28.rmSync(worktreesDir, { recursive: true, force: true });
30111
30143
  results.push("\u2705 Removed .swarm-worktrees/ directory");
30112
30144
  }
30113
30145
  } catch (err) {
@@ -30213,18 +30245,91 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
30213
30245
  }
30214
30246
 
30215
30247
  // src/commands/rollback.ts
30216
- import * as fs30 from "fs";
30248
+ import * as fs29 from "fs";
30217
30249
  import * as path61 from "path";
30250
+ function safeParseToolJson(result) {
30251
+ try {
30252
+ const jsonStr = typeof result === "string" ? result : result.output;
30253
+ return JSON.parse(jsonStr);
30254
+ } catch {
30255
+ return null;
30256
+ }
30257
+ }
30258
+ async function listGitCheckpoints(directory) {
30259
+ try {
30260
+ const result = await checkpoint.execute({ action: "list" }, {
30261
+ directory
30262
+ });
30263
+ const parsed = safeParseToolJson(result);
30264
+ if (!parsed)
30265
+ return null;
30266
+ if (parsed.success !== true || !Array.isArray(parsed.checkpoints)) {
30267
+ return null;
30268
+ }
30269
+ return parsed.checkpoints;
30270
+ } catch {
30271
+ return null;
30272
+ }
30273
+ }
30274
+ function formatGitCheckpointList(checkpoints) {
30275
+ if (checkpoints.length === 0) {
30276
+ return "No checkpoints found. Create one with `/swarm checkpoint save <label>`";
30277
+ }
30278
+ return [
30279
+ "## Available Checkpoints",
30280
+ "",
30281
+ ...checkpoints.map((c, index) => `- ${index + 1}. "${c.label}" - ${new Date(c.timestamp).toLocaleString()} (${c.sha.slice(0, 12)})`),
30282
+ "",
30283
+ "Run `/swarm rollback <label-or-number>` to restore to a checkpoint."
30284
+ ].join(`
30285
+ `);
30286
+ }
30287
+ function resolveGitCheckpoint(checkpoints, selector) {
30288
+ const index = Number.parseInt(selector, 10);
30289
+ if (/^\d+$/.test(selector) && index >= 1 && index <= checkpoints.length) {
30290
+ return checkpoints[index - 1] ?? null;
30291
+ }
30292
+ return checkpoints.find((c) => c.label === selector) ?? null;
30293
+ }
30294
+ async function restoreGitCheckpoint(directory, selected) {
30295
+ const result = await checkpoint.execute({ action: "restore", label: selected.label }, { directory });
30296
+ const parsed = safeParseToolJson(result);
30297
+ if (!parsed) {
30298
+ return `Error: Failed to parse checkpoint response for "${selected.label}"`;
30299
+ }
30300
+ if (parsed.success !== true) {
30301
+ return `Error: ${parsed.error || `Failed to restore checkpoint "${selected.label}"`}`;
30302
+ }
30303
+ const eventsPath = validateSwarmPath(directory, "events.jsonl");
30304
+ const rollbackEvent = {
30305
+ type: "rollback",
30306
+ label: selected.label,
30307
+ sha: selected.sha,
30308
+ timestamp: new Date().toISOString(),
30309
+ source: "checkpoints.json"
30310
+ };
30311
+ try {
30312
+ fs29.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30313
+ `);
30314
+ } catch (error2) {
30315
+ console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
30316
+ }
30317
+ return `Rolled back to checkpoint "${selected.label}" (${selected.sha.slice(0, 12)})`;
30318
+ }
30218
30319
  async function handleRollbackCommand(directory, args) {
30219
30320
  const phaseArg = args[0];
30220
30321
  if (!phaseArg) {
30221
30322
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
30222
- if (!fs30.existsSync(manifestPath2)) {
30223
- return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
30323
+ if (!fs29.existsSync(manifestPath2)) {
30324
+ const gitCheckpoints = await listGitCheckpoints(directory);
30325
+ if (gitCheckpoints) {
30326
+ return formatGitCheckpointList(gitCheckpoints);
30327
+ }
30328
+ return "No checkpoints found. Use `/swarm checkpoint save <label>` to create checkpoints.";
30224
30329
  }
30225
30330
  let manifest2;
30226
30331
  try {
30227
- manifest2 = JSON.parse(fs30.readFileSync(manifestPath2, "utf-8"));
30332
+ manifest2 = JSON.parse(fs29.readFileSync(manifestPath2, "utf-8"));
30228
30333
  } catch {
30229
30334
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
30230
30335
  }
@@ -30243,15 +30348,31 @@ async function handleRollbackCommand(directory, args) {
30243
30348
  }
30244
30349
  const targetPhase = parseInt(phaseArg, 10);
30245
30350
  if (Number.isNaN(targetPhase) || targetPhase < 1) {
30246
- return "Error: Phase number must be a positive integer.";
30351
+ const gitCheckpoints = await listGitCheckpoints(directory);
30352
+ if (!gitCheckpoints) {
30353
+ return "Error: Phase number must be a positive integer.";
30354
+ }
30355
+ const selected = resolveGitCheckpoint(gitCheckpoints, phaseArg);
30356
+ if (!selected) {
30357
+ return `Error: Checkpoint "${phaseArg}" not found. Available checkpoints: ${gitCheckpoints.map((c) => `"${c.label}"`).join(", ") || "none"}`;
30358
+ }
30359
+ return restoreGitCheckpoint(directory, selected);
30247
30360
  }
30248
30361
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
30249
- if (!fs30.existsSync(manifestPath)) {
30250
- return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
30362
+ if (!fs29.existsSync(manifestPath)) {
30363
+ const gitCheckpoints = await listGitCheckpoints(directory);
30364
+ if (!gitCheckpoints) {
30365
+ return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
30366
+ }
30367
+ const selected = resolveGitCheckpoint(gitCheckpoints, phaseArg);
30368
+ if (!selected) {
30369
+ return `Error: Checkpoint ${phaseArg} not found. Available checkpoints: ${gitCheckpoints.map((c, index) => `${index + 1}="${c.label}"`).join(", ") || "none"}`;
30370
+ }
30371
+ return restoreGitCheckpoint(directory, selected);
30251
30372
  }
30252
30373
  let manifest;
30253
30374
  try {
30254
- manifest = JSON.parse(fs30.readFileSync(manifestPath, "utf-8"));
30375
+ manifest = JSON.parse(fs29.readFileSync(manifestPath, "utf-8"));
30255
30376
  } catch {
30256
30377
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
30257
30378
  }
@@ -30261,10 +30382,10 @@ async function handleRollbackCommand(directory, args) {
30261
30382
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
30262
30383
  }
30263
30384
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
30264
- if (!fs30.existsSync(checkpointDir)) {
30385
+ if (!fs29.existsSync(checkpointDir)) {
30265
30386
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
30266
30387
  }
30267
- const checkpointFiles = fs30.readdirSync(checkpointDir);
30388
+ const checkpointFiles = fs29.readdirSync(checkpointDir);
30268
30389
  if (checkpointFiles.length === 0) {
30269
30390
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
30270
30391
  }
@@ -30283,7 +30404,7 @@ async function handleRollbackCommand(directory, args) {
30283
30404
  const src = path61.join(checkpointDir, file);
30284
30405
  const dest = path61.join(swarmDir, file);
30285
30406
  try {
30286
- fs30.cpSync(src, dest, { recursive: true, force: true });
30407
+ fs29.cpSync(src, dest, { recursive: true, force: true });
30287
30408
  successes.push(file);
30288
30409
  } catch (error2) {
30289
30410
  failures.push({ file, error: error2.message });
@@ -30302,9 +30423,9 @@ async function handleRollbackCommand(directory, args) {
30302
30423
  }
30303
30424
  const existingLedgerPath = path61.join(swarmDir, "plan-ledger.jsonl");
30304
30425
  let ledgerDeletionFailed = false;
30305
- if (fs30.existsSync(existingLedgerPath)) {
30426
+ if (fs29.existsSync(existingLedgerPath)) {
30306
30427
  try {
30307
- fs30.unlinkSync(existingLedgerPath);
30428
+ fs29.unlinkSync(existingLedgerPath);
30308
30429
  } catch (err) {
30309
30430
  ledgerDeletionFailed = true;
30310
30431
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -30314,8 +30435,8 @@ async function handleRollbackCommand(directory, args) {
30314
30435
  if (!ledgerDeletionFailed) {
30315
30436
  try {
30316
30437
  const planJsonPath = path61.join(swarmDir, "plan.json");
30317
- if (fs30.existsSync(planJsonPath)) {
30318
- const planRaw = fs30.readFileSync(planJsonPath, "utf-8");
30438
+ if (fs29.existsSync(planJsonPath)) {
30439
+ const planRaw = fs29.readFileSync(planJsonPath, "utf-8");
30319
30440
  const plan = PlanSchema.parse(JSON.parse(planRaw));
30320
30441
  const planId = derivePlanId(plan);
30321
30442
  const planHash = computePlanHash(plan);
@@ -30343,7 +30464,7 @@ async function handleRollbackCommand(directory, args) {
30343
30464
  timestamp: new Date().toISOString()
30344
30465
  };
30345
30466
  try {
30346
- fs30.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30467
+ fs29.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30347
30468
  `);
30348
30469
  } catch (error2) {
30349
30470
  console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
@@ -30360,7 +30481,7 @@ async function handleRollbackCommand(directory, args) {
30360
30481
  }
30361
30482
 
30362
30483
  // src/commands/sdd.ts
30363
- import * as fs31 from "fs";
30484
+ import * as fs30 from "fs";
30364
30485
  import * as path62 from "path";
30365
30486
  var SWARM_SPEC_REL = path62.join(".swarm", "spec.md");
30366
30487
  var USAGE9 = `Usage:
@@ -30478,7 +30599,7 @@ ${USAGE9}`;
30478
30599
  }
30479
30600
  const speckitDetection = detectSpeckit(directory);
30480
30601
  const speckitPresent = speckitDetection.features.length > 0;
30481
- const nativeSpecExists = fs31.existsSync(path62.join(directory, SWARM_SPEC_REL));
30602
+ const nativeSpecExists = fs30.existsSync(path62.join(directory, SWARM_SPEC_REL));
30482
30603
  if (speckitPresent && !parsed.source && !nativeSpecExists) {
30483
30604
  const openspecProjection = buildOpenSpecProjectionSync(directory);
30484
30605
  if (openspecProjection !== null) {
@@ -30548,7 +30669,7 @@ ${USAGE9}`;
30548
30669
  ${USAGE9}`;
30549
30670
  }
30550
30671
  let useSpeckit = false;
30551
- const nativeSpecExists = fs31.existsSync(path62.join(directory, SWARM_SPEC_REL));
30672
+ const nativeSpecExists = fs30.existsSync(path62.join(directory, SWARM_SPEC_REL));
30552
30673
  if (parsed.source === "speckit") {
30553
30674
  useSpeckit = true;
30554
30675
  } else if (!parsed.source && !nativeSpecExists) {
@@ -30859,13 +30980,13 @@ Ensure this is a git repository with commit history.`;
30859
30980
  const report = reportLines.filter(Boolean).join(`
30860
30981
  `);
30861
30982
  try {
30862
- const fs32 = await import("fs/promises");
30983
+ const fs31 = await import("fs/promises");
30863
30984
  const path63 = await import("path");
30864
30985
  const reportPath = path63.join(directory, ".swarm", "simulate-report.md");
30865
- await fs32.mkdir(path63.dirname(reportPath), { recursive: true });
30986
+ await fs31.mkdir(path63.dirname(reportPath), { recursive: true });
30866
30987
  const reportTempPath = path63.join(path63.dirname(reportPath), `${path63.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
30867
30988
  try {
30868
- await fs32.writeFile(reportTempPath, report, "utf-8");
30989
+ await fs31.writeFile(reportTempPath, report, "utf-8");
30869
30990
  renameSync11(reportTempPath, reportPath);
30870
30991
  } catch (err) {
30871
30992
  try {
@@ -30891,7 +31012,7 @@ async function handleSpecifyCommand(_directory, args) {
30891
31012
 
30892
31013
  // src/services/status-service.ts
30893
31014
  import * as fsSync2 from "fs";
30894
- import { readFile as readFile16 } from "fs/promises";
31015
+ import { readFile as readFile17 } from "fs/promises";
30895
31016
  import * as path64 from "path";
30896
31017
 
30897
31018
  // src/hooks/extractors.ts
@@ -30936,7 +31057,7 @@ function extractCurrentPhaseFromPlan2(plan) {
30936
31057
 
30937
31058
  // src/turbo/lean/state.ts
30938
31059
  init_logger();
30939
- import * as fs32 from "fs";
31060
+ import * as fs31 from "fs";
30940
31061
  import * as path63 from "path";
30941
31062
  var STATE_FILE3 = "turbo-state.json";
30942
31063
  function nowISO3() {
@@ -30944,8 +31065,8 @@ function nowISO3() {
30944
31065
  }
30945
31066
  function ensureSwarmDir2(directory) {
30946
31067
  const swarmDir = path63.resolve(directory, ".swarm");
30947
- if (!fs32.existsSync(swarmDir)) {
30948
- fs32.mkdirSync(swarmDir, { recursive: true });
31068
+ if (!fs31.existsSync(swarmDir)) {
31069
+ fs31.mkdirSync(swarmDir, { recursive: true });
30949
31070
  }
30950
31071
  return swarmDir;
30951
31072
  }
@@ -30989,16 +31110,16 @@ function markStateUnreadable2(directory, reason) {
30989
31110
  function readPersisted2(directory) {
30990
31111
  try {
30991
31112
  const filePath = path63.join(directory, ".swarm", STATE_FILE3);
30992
- if (!fs32.existsSync(filePath)) {
31113
+ if (!fs31.existsSync(filePath)) {
30993
31114
  const seed = emptyPersisted2();
30994
31115
  try {
30995
31116
  ensureSwarmDir2(directory);
30996
- fs32.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
31117
+ fs31.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
30997
31118
  `, "utf-8");
30998
31119
  } catch {}
30999
31120
  return seed;
31000
31121
  }
31001
- const raw = fs32.readFileSync(filePath, "utf-8");
31122
+ const raw = fs31.readFileSync(filePath, "utf-8");
31002
31123
  const parsed = JSON.parse(raw);
31003
31124
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
31004
31125
  markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -31035,14 +31156,14 @@ function writePersisted2(directory, persisted) {
31035
31156
  throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
31036
31157
  }
31037
31158
  try {
31038
- fs32.writeFileSync(tmpPath, payload, "utf-8");
31039
- fs32.renameSync(tmpPath, filePath);
31159
+ fs31.writeFileSync(tmpPath, payload, "utf-8");
31160
+ fs31.renameSync(tmpPath, filePath);
31040
31161
  } catch (error2) {
31041
31162
  const msg = error2 instanceof Error ? error2.message : String(error2);
31042
31163
  error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
31043
31164
  try {
31044
- if (fs32.existsSync(tmpPath)) {
31045
- fs32.unlinkSync(tmpPath);
31165
+ if (fs31.existsSync(tmpPath)) {
31166
+ fs31.unlinkSync(tmpPath);
31046
31167
  }
31047
31168
  } catch {}
31048
31169
  throw new Error(`Lean Turbo state persistence failed: ${msg}`);
@@ -31395,7 +31516,7 @@ async function safeLineCount(filePath) {
31395
31516
  try {
31396
31517
  if (!fsSync2.existsSync(filePath))
31397
31518
  return 0;
31398
- const content = await readFile16(filePath, "utf-8");
31519
+ const content = await readFile17(filePath, "utf-8");
31399
31520
  let n = 0;
31400
31521
  for (const line of content.split(`
31401
31522
  `)) {
@@ -31876,7 +31997,7 @@ function buildDetailedHelp(commandName, entry) {
31876
31997
  async function handleHelpCommand(ctx) {
31877
31998
  const targetCommand = ctx.args.join(" ");
31878
31999
  if (!targetCommand) {
31879
- const { buildHelpText } = await import("./index-87d4wsv9.js");
32000
+ const { buildHelpText } = await import("./index-r87xhtmx.js");
31880
32001
  return buildHelpText();
31881
32002
  }
31882
32003
  const tokens = targetCommand.split(/\s+/);
@@ -31885,7 +32006,7 @@ async function handleHelpCommand(ctx) {
31885
32006
  return _internals49.buildDetailedHelp(resolved.key, resolved.entry);
31886
32007
  }
31887
32008
  const similar = _internals49.findSimilarCommands(targetCommand);
31888
- const { buildHelpText: fullHelp } = await import("./index-87d4wsv9.js");
32009
+ const { buildHelpText: fullHelp } = await import("./index-r87xhtmx.js");
31889
32010
  if (similar.length > 0) {
31890
32011
  return `Command '/swarm ${targetCommand}' not found.
31891
32012
 
@@ -32018,7 +32139,7 @@ var COMMAND_REGISTRY = {
32018
32139
  },
32019
32140
  "guardrail explain": {
32020
32141
  handler: async (ctx) => {
32021
- const { handleGuardrailExplain } = await import("./guardrail-explain-414smfg4.js");
32142
+ const { handleGuardrailExplain } = await import("./guardrail-explain-zajegz3a.js");
32022
32143
  return handleGuardrailExplain(ctx.directory, ctx.args);
32023
32144
  },
32024
32145
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -32540,9 +32661,9 @@ Subcommands:
32540
32661
  },
32541
32662
  rollback: {
32542
32663
  handler: (ctx) => handleRollbackCommand(ctx.directory, ctx.args),
32543
- description: "Restore swarm state to a checkpoint <phase>",
32544
- details: "Restores .swarm/ state by directly overwriting files from a checkpoint directory (checkpoints/phase-<N>). Writes rollback event to events.jsonl. Without phase argument, lists available checkpoints. Partial failures are reported but processing continues.",
32545
- args: "<phase-number>",
32664
+ description: "Restore swarm state or project files to a checkpoint",
32665
+ details: "Restores legacy .swarm/ phase checkpoints from checkpoints/phase-<N> when present. Otherwise restores named git checkpoints from .swarm/checkpoints.json by label or list number. Writes rollback event to events.jsonl. Without an argument, lists available checkpoints.",
32666
+ args: "<phase-number|label|list-number>",
32546
32667
  category: "utility",
32547
32668
  toolPolicy: "restricted"
32548
32669
  },
@@ -32555,7 +32676,7 @@ Subcommands:
32555
32676
  toolPolicy: "agent"
32556
32677
  },
32557
32678
  handoff: {
32558
- handler: (ctx) => handleHandoffCommand(ctx.directory, ctx.args),
32679
+ handler: (ctx) => handleHandoffCommand(ctx.directory, ctx.args, ctx.sessionID),
32559
32680
  description: "Prepare state for clean model switch (new session)",
32560
32681
  args: "",
32561
32682
  details: "Generates handoff.md with full session state snapshot, including plan progress, recent decisions, and agent delegation history. Prepended to the next session prompt for seamless model switches.",
@@ -32781,7 +32902,7 @@ Subcommands:
32781
32902
  checkpoint: {
32782
32903
  handler: (ctx) => handleCheckpointCommand(ctx.directory, ctx.args),
32783
32904
  description: "Manage project checkpoints [save|restore|delete|list] <label>",
32784
- details: "save: creates named snapshot of current .swarm/ state. restore: soft-resets to checkpoint by overwriting current .swarm/ files. delete: removes named checkpoint. list: shows all checkpoints with timestamps. All subcommands require a label except list.",
32905
+ details: "save: creates named git checkpoint. restore: hard-resets tracked files to the checkpoint. delete: removes named checkpoint metadata. list: shows all checkpoints with timestamps. All subcommands require a label except list.",
32785
32906
  args: "<save|restore|delete|list> <label>",
32786
32907
  category: "utility",
32787
32908
  clashesWithNativeCcCommand: "/checkpoint",
@@ -34369,8 +34490,8 @@ function dcValidateTargets(targets, cwd) {
34369
34490
  const lstatBlock = dcLstatAncestorWalk(t, cwd);
34370
34491
  if (lstatBlock)
34371
34492
  return lstatBlock;
34372
- const basename11 = path66.basename(t);
34373
- if (t === basename11 && DC_SAFE_TARGETS.has(t)) {
34493
+ const basename12 = path66.basename(t);
34494
+ if (t === basename12 && DC_SAFE_TARGETS.has(t)) {
34374
34495
  continue;
34375
34496
  }
34376
34497
  if (DC_FS_ROOTS.has(t) || DC_FS_ROOTS.has(t.replace(/\//g, "\\"))) {
@@ -36779,7 +36900,7 @@ function evidenceToWorkflowState(evidence) {
36779
36900
  async function readPlanFromDisk(directory) {
36780
36901
  try {
36781
36902
  const planPath = path68.join(directory, ".swarm", "plan.json");
36782
- const content = await fs33.readFile(planPath, "utf-8");
36903
+ const content = await fs32.readFile(planPath, "utf-8");
36783
36904
  const parsed = JSON.parse(content);
36784
36905
  return PlanSchema.parse(parsed);
36785
36906
  } catch {
@@ -36790,7 +36911,7 @@ async function readGateEvidenceFromDisk(directory) {
36790
36911
  const evidenceMap = new Map;
36791
36912
  try {
36792
36913
  const evidenceDir = path68.join(directory, ".swarm", "evidence");
36793
- const entries = await fs33.readdir(evidenceDir, { withFileTypes: true });
36914
+ const entries = await fs32.readdir(evidenceDir, { withFileTypes: true });
36794
36915
  for (const entry of entries) {
36795
36916
  if (!entry.isFile() || !entry.name.endsWith(".json")) {
36796
36917
  continue;
@@ -36801,7 +36922,7 @@ async function readGateEvidenceFromDisk(directory) {
36801
36922
  }
36802
36923
  try {
36803
36924
  const filePath = path68.join(evidenceDir, entry.name);
36804
- const content = await fs33.readFile(filePath, "utf-8");
36925
+ const content = await fs32.readFile(filePath, "utf-8");
36805
36926
  const parsed = JSON.parse(content);
36806
36927
  if (parsed && typeof parsed.taskId === "string" && Array.isArray(parsed.required_gates)) {
36807
36928
  evidenceMap.set(taskId, parsed);