opencode-swarm 7.107.1 → 7.107.3

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.
Files changed (39) hide show
  1. package/dist/cli/{curator-np2ky29t.js → curator-1nr4qszq.js} +6 -6
  2. package/dist/cli/{curator-drift-6ad8mxxb.js → curator-drift-ed7p5mfy.js} +2 -2
  3. package/dist/cli/{curator-llm-factory-gdhtm1hh.js → curator-llm-factory-x9tk7e6m.js} +6 -6
  4. package/dist/cli/{evidence-summary-service-dh44gevz.js → evidence-summary-service-9r28ds8t.js} +3 -3
  5. package/dist/cli/{guardrail-explain-414smfg4.js → guardrail-explain-etdrhd4d.js} +7 -7
  6. package/dist/cli/{guardrail-log-fsc85hwa.js → guardrail-log-2rns4g6d.js} +2 -2
  7. package/dist/cli/{hive-promoter-y9r8d315.js → hive-promoter-j4e6rfa6.js} +6 -6
  8. package/dist/cli/{index-87d4wsv9.js → index-502f6np6.js} +8 -8
  9. package/dist/cli/{index-mpe0yk9s.js → index-57ymmh7h.js} +5 -3
  10. package/dist/cli/{index-357p0baj.js → index-91j1sqzm.js} +14 -2
  11. package/dist/cli/{index-gt514nt1.js → index-cyzzdbvw.js} +1058 -873
  12. package/dist/cli/{index-t4hbye3v.js → index-hkpw4wwa.js} +1 -1
  13. package/dist/cli/{index-jjp5qrjv.js → index-kzfkggjx.js} +97 -39
  14. package/dist/cli/{index-w8dzxnx4.js → index-m1xjr58n.js} +1 -1
  15. package/dist/cli/{index-fxtrk7y8.js → index-tgtmbf3r.js} +1 -1
  16. package/dist/cli/{index-7v734syt.js → index-w15984gg.js} +2 -2
  17. package/dist/cli/index.js +6 -6
  18. package/dist/cli/{pending-delegations-46xf2n2e.js → pending-delegations-ws51m1e1.js} +1 -1
  19. package/dist/cli/{pr-subscriptions-3c34rnm1.js → pr-subscriptions-0dpn4epk.js} +2 -2
  20. package/dist/commands/handoff.d.ts +2 -1
  21. package/dist/commands/registry.d.ts +4 -4
  22. package/dist/config/bundled-skills.d.ts +3 -5
  23. package/dist/hooks/guardrails/file-authority.d.ts +1 -1
  24. package/dist/hooks/knowledge-injector.d.ts +3 -0
  25. package/dist/hooks/knowledge-reader.d.ts +17 -0
  26. package/dist/hooks/semantic-diff-injection.d.ts +19 -0
  27. package/dist/index.js +340 -332
  28. package/dist/services/directive-predicate-runner.d.ts +1 -1
  29. package/dist/session/snapshot-writer.d.ts +4 -0
  30. package/dist/tools/external-skill-discover.d.ts +11 -0
  31. package/dist/tools/knowledge-remove.d.ts +11 -0
  32. package/dist/tools/pre-check-batch.d.ts +4 -0
  33. package/dist/turbo/lean/evidence.d.ts +22 -0
  34. package/dist/turbo/lean/integration.d.ts +6 -1
  35. package/dist/turbo/lean/reviewer.d.ts +6 -1
  36. package/dist/turbo/lean/runner.d.ts +10 -1
  37. package/dist/utils/untrusted-markdown.d.ts +1 -0
  38. package/dist/worktree/merge.d.ts +1 -0
  39. package/package.json +1 -1
@@ -44,7 +44,7 @@ import {
44
44
  savePlan,
45
45
  transientBackoff,
46
46
  validateProjectRoot
47
- } from "./index-jjp5qrjv.js";
47
+ } from "./index-kzfkggjx.js";
48
48
  import {
49
49
  _internals as _internals2,
50
50
  _internals1 as _internals3,
@@ -136,7 +136,7 @@ import {
136
136
  resolveSpeckitProjection,
137
137
  validateSpeckit,
138
138
  writeProjectedSpecSync
139
- } from "./index-357p0baj.js";
139
+ } from "./index-91j1sqzm.js";
140
140
  import {
141
141
  SandboxCapabilityProbe,
142
142
  _internals,
@@ -154,12 +154,12 @@ import {
154
154
  listActive,
155
155
  subscribe,
156
156
  unsubscribe
157
- } from "./index-t4hbye3v.js";
157
+ } from "./index-hkpw4wwa.js";
158
158
  import {
159
159
  readSwarmFileAsync,
160
160
  safeHook,
161
161
  validateSwarmPath
162
- } from "./index-mpe0yk9s.js";
162
+ } from "./index-57ymmh7h.js";
163
163
  import {
164
164
  deepMerge
165
165
  } from "./index-p0arc26j.js";
@@ -329,7 +329,7 @@ var init_bubblewrap = __esm(() => {
329
329
  import { spawnSync as spawnSync4 } from "child_process";
330
330
  import { mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync6 } from "fs";
331
331
  import * as os8 from "os";
332
- import * as path34 from "path";
332
+ import * as path35 from "path";
333
333
  function probeSandboxExec() {
334
334
  try {
335
335
  const result = spawnSync4("sandbox-exec", ["--version"], {
@@ -357,8 +357,8 @@ function probeSandboxExec() {
357
357
  function shellEscape2(s) {
358
358
  return s.replace(/'/g, "'\\''");
359
359
  }
360
- function sbplEscapePath(path35) {
361
- const withoutControlChars = path35.split("").filter((ch) => {
360
+ function sbplEscapePath(path36) {
361
+ const withoutControlChars = path36.split("").filter((ch) => {
362
362
  const cp = ch.codePointAt(0);
363
363
  return cp >= 32 && cp !== 127;
364
364
  }).join("");
@@ -434,8 +434,8 @@ class MacOSSandboxExecutor {
434
434
  const profile = buildSandboxProfile(allScopes, temp);
435
435
  let profilePath;
436
436
  try {
437
- const profileDir = mkdtempSync2(path34.join(os8.tmpdir(), "sandbox-"));
438
- profilePath = path34.join(profileDir, `profile-${process.pid}-${Date.now()}.sb`);
437
+ const profileDir = mkdtempSync2(path35.join(os8.tmpdir(), "sandbox-"));
438
+ profilePath = path35.join(profileDir, `profile-${process.pid}-${Date.now()}.sb`);
439
439
  writeFileSync6(profilePath, profile, { mode: 384 });
440
440
  } catch (err) {
441
441
  const message = err instanceof Error ? err.message : String(err);
@@ -542,7 +542,7 @@ var init_edge_cases = () => {};
542
542
  // src/sandbox/win32/restricted-environment-executor.ts
543
543
  import { spawnSync as spawnSync5 } from "child_process";
544
544
  import * as os9 from "os";
545
- import * as path35 from "path";
545
+ import * as path36 from "path";
546
546
  function probeWindowsSandbox() {
547
547
  try {
548
548
  const result = spawnSync5("cmd", ["/c", "echo", "ok"], {
@@ -589,7 +589,7 @@ function isPathInScopes(command, scopes) {
589
589
  const paths = command.match(pathPattern) || [];
590
590
  if (paths.length === 0)
591
591
  return true;
592
- const normalizedPaths = paths.map((p) => path35.win32.resolve(p));
592
+ const normalizedPaths = paths.map((p) => path36.win32.resolve(p));
593
593
  const normalizedScopes = scopes.map((s) => s.toLowerCase().replace(/\\+$/, ""));
594
594
  return normalizedPaths.every((p) => {
595
595
  const lower = p.toLowerCase();
@@ -724,9 +724,9 @@ 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
- import * as path36 from "path";
729
+ import * as path37 from "path";
730
730
 
731
731
  class NativeWindowsSandboxExecutor {
732
732
  mechanism;
@@ -788,12 +788,12 @@ class NativeWindowsSandboxExecutor {
788
788
  policy.workspace_roots = scopePaths.length > 0 ? scopePaths : [workspaceRoot];
789
789
  policy.writable_roots = policy.workspace_roots;
790
790
  const policyJson = JSON.stringify(policy);
791
- const policyDir = path36.join(os10.tmpdir(), "swarm-sandbox-policies");
791
+ const policyDir = path37.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
- const policyFile = path36.join(policyDir, `${runId}.json`);
796
- fs13.writeFileSync(policyFile, policyJson, "utf-8");
795
+ const policyFile = path37.join(policyDir, `${runId}.json`);
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,8 +924,8 @@ var init_executor = __esm(() => {
924
924
  });
925
925
 
926
926
  // src/state.ts
927
- import * as fs33 from "fs/promises";
928
- import * as path68 from "path";
927
+ import * as fs32 from "fs/promises";
928
+ import * as path69 from "path";
929
929
 
930
930
  // src/db/qa-gate-profile.ts
931
931
  import { createHash } from "crypto";
@@ -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,15 @@ 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
+ const logBeforeReset = log2;
6944
+ gitExec(["reset", "--hard", checkpoint.sha], directory);
6945
+ writeCheckpointLog(logBeforeReset, directory);
6926
6946
  return JSON.stringify({
6927
6947
  action: "restore",
6928
6948
  success: true,
6929
6949
  label,
6930
6950
  sha: checkpoint.sha,
6931
- message: `Restored to checkpoint: "${label}" (soft reset)`
6951
+ message: `Restored to checkpoint: "${label}" (hard reset)`
6932
6952
  }, null, 2);
6933
6953
  } catch (e) {
6934
6954
  const errorMessage = e instanceof Error ? `restore failed: ${e.message}` : "restore failed: unknown error";
@@ -6978,7 +6998,7 @@ function handleDelete(label, directory) {
6978
6998
  }
6979
6999
  }
6980
7000
  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.",
7001
+ 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
7002
  args: {
6983
7003
  action: exports_external.string().describe("Action to perform: save, restore, list, or delete"),
6984
7004
  label: exports_external.string().optional().describe("Checkpoint label (required for save, restore, delete)")
@@ -7180,8 +7200,8 @@ async function handleClarifyCommand(_directory, args) {
7180
7200
  // src/commands/close.ts
7181
7201
  import { spawnSync as spawnSync2 } from "child_process";
7182
7202
  import * as fsSync from "fs";
7183
- import { promises as fs11 } from "fs";
7184
- import path27 from "path";
7203
+ import { promises as fs10 } from "fs";
7204
+ import path28 from "path";
7185
7205
 
7186
7206
  // src/hooks/curator-postmortem.ts
7187
7207
  import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync4 } from "fs";
@@ -7900,11 +7920,11 @@ var _internals8 = {
7900
7920
  return KnowledgeConfigSchema2.parse({});
7901
7921
  },
7902
7922
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig) => {
7903
- const { applyCuratorKnowledgeUpdates } = await import("./curator-np2ky29t.js");
7923
+ const { applyCuratorKnowledgeUpdates } = await import("./curator-1nr4qszq.js");
7904
7924
  return applyCuratorKnowledgeUpdates(directory, recommendations, knowledgeConfig);
7905
7925
  },
7906
7926
  checkHivePromotions: async (entries, knowledgeConfig) => {
7907
- const { checkHivePromotions } = await import("./hive-promoter-y9r8d315.js");
7927
+ const { checkHivePromotions } = await import("./hive-promoter-j4e6rfa6.js");
7908
7928
  return checkHivePromotions(entries, knowledgeConfig);
7909
7929
  },
7910
7930
  applyProposalTriage: async (directory, triage) => {
@@ -7954,7 +7974,7 @@ var _internals8 = {
7954
7974
  return result;
7955
7975
  },
7956
7976
  readPriorDriftReports: async (directory) => {
7957
- const { readPriorDriftReports } = await import("./curator-drift-6ad8mxxb.js");
7977
+ const { readPriorDriftReports } = await import("./curator-drift-ed7p5mfy.js");
7958
7978
  return readPriorDriftReports(directory);
7959
7979
  },
7960
7980
  readSwarmKnowledge: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory))
@@ -7964,8 +7984,8 @@ var _internals8 = {
7964
7984
  import path16 from "path";
7965
7985
 
7966
7986
  // src/hooks/curator.ts
7967
- import { randomUUID as randomUUID4 } from "crypto";
7968
- import * as fs6 from "fs";
7987
+ import { randomUUID as randomUUID5 } from "crypto";
7988
+ import * as fs5 from "fs";
7969
7989
  import * as path15 from "path";
7970
7990
 
7971
7991
  // src/hooks/knowledge-escalator.ts
@@ -8403,12 +8423,12 @@ function formatLearningSummary(metrics) {
8403
8423
 
8404
8424
  // src/services/skill-reviser.ts
8405
8425
  init_logger();
8406
- import { readFile as readFile4, rename as rename3, writeFile as writeFile4 } from "fs/promises";
8426
+ import { readFile as readFile5, rename as rename4, writeFile as writeFile5 } from "fs/promises";
8407
8427
 
8408
8428
  // src/services/skill-improver-quota.ts
8409
8429
  var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
8410
8430
  import { existsSync as existsSync8 } from "fs";
8411
- import { mkdir as mkdir4, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
8431
+ import { mkdir as mkdir4, readFile as readFile4, rename as rename3, writeFile as writeFile4 } from "fs/promises";
8412
8432
  import * as path13 from "path";
8413
8433
  var LOCK_ACQUIRE_TIMEOUT_MS = 1e4;
8414
8434
  var LOCK_RETRY_OPTS = {
@@ -8453,7 +8473,7 @@ async function readState(filePath) {
8453
8473
  if (!existsSync8(filePath))
8454
8474
  return null;
8455
8475
  try {
8456
- const raw = await readFile3(filePath, "utf-8");
8476
+ const raw = await readFile4(filePath, "utf-8");
8457
8477
  const parsed = JSON.parse(raw);
8458
8478
  if (typeof parsed.date !== "string" || typeof parsed.calls_used !== "number" || typeof parsed.max_calls !== "number" || parsed.window !== "utc" && parsed.window !== "local") {
8459
8479
  return null;
@@ -8466,8 +8486,8 @@ async function readState(filePath) {
8466
8486
  async function writeState(filePath, state) {
8467
8487
  await mkdir4(path13.dirname(filePath), { recursive: true });
8468
8488
  const tmp = `${filePath}.tmp-${process.pid}`;
8469
- await writeFile3(tmp, JSON.stringify(state, null, 2), "utf-8");
8470
- await rename2(tmp, filePath);
8489
+ await writeFile4(tmp, JSON.stringify(state, null, 2), "utf-8");
8490
+ await rename3(tmp, filePath);
8471
8491
  }
8472
8492
  async function getQuotaState(directory, opts) {
8473
8493
  const filePath = resolveQuotaPath(directory, opts.scope);
@@ -8544,7 +8564,7 @@ var MAX_REVISION_CALLS_PER_PHASE = 3;
8544
8564
  var DEFAULT_MAX_CALLS = 10;
8545
8565
  async function getSkillVersion(skillPath) {
8546
8566
  try {
8547
- const content = await readFile4(skillPath, "utf-8");
8567
+ const content = await readFile5(skillPath, "utf-8");
8548
8568
  const match = content.match(/^version:\s*(\d+)\s*$/m);
8549
8569
  return match ? parseInt(match[1], 10) : 1;
8550
8570
  } catch {
@@ -8681,8 +8701,8 @@ async function reviseSkill(params) {
8681
8701
  };
8682
8702
  }
8683
8703
  const tmpPath = `${params.skillPath}.tmp-${process.pid}-${Date.now()}`;
8684
- await writeFile4(tmpPath, revised, "utf-8");
8685
- await rename3(tmpPath, params.skillPath);
8704
+ await writeFile5(tmpPath, revised, "utf-8");
8705
+ await rename4(tmpPath, params.skillPath);
8686
8706
  const newVersion = params.currentVersion + 1;
8687
8707
  const entry = {
8688
8708
  version: newVersion,
@@ -8758,9 +8778,9 @@ async function reviseSkill(params) {
8758
8778
  };
8759
8779
  }
8760
8780
  const tmpPath = `${params.skillPath}.tmp-${process.pid}-${Date.now()}`;
8761
- await writeFile4(tmpPath, `${finalOutput}
8781
+ await writeFile5(tmpPath, `${finalOutput}
8762
8782
  `, "utf-8");
8763
- await rename3(tmpPath, params.skillPath);
8783
+ await rename4(tmpPath, params.skillPath);
8764
8784
  const newVersion = expectedVersion;
8765
8785
  const entry = {
8766
8786
  version: newVersion,
@@ -8814,7 +8834,7 @@ init_logger();
8814
8834
 
8815
8835
  // src/hooks/skill-usage-log.ts
8816
8836
  import * as crypto2 from "crypto";
8817
- import * as fs5 from "fs";
8837
+ import * as fs4 from "fs";
8818
8838
  import * as path14 from "path";
8819
8839
  function resolveLogPath(directory) {
8820
8840
  return validateSwarmPath(directory, "skill-usage.jsonl");
@@ -8824,16 +8844,16 @@ function normalizeComplianceVerdict(verdict) {
8824
8844
  }
8825
8845
  var _internals10 = {
8826
8846
  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),
8847
+ appendFileSync: fs4.appendFileSync.bind(fs4),
8848
+ readFileSync: fs4.readFileSync.bind(fs4),
8849
+ writeFileSync: fs4.writeFileSync.bind(fs4),
8850
+ renameSync: fs4.renameSync.bind(fs4),
8851
+ mkdirSync: fs4.mkdirSync.bind(fs4),
8852
+ existsSync: fs4.existsSync.bind(fs4),
8853
+ statSync: fs4.statSync.bind(fs4),
8854
+ openSync: fs4.openSync.bind(fs4),
8855
+ readSync: fs4.readSync.bind(fs4),
8856
+ closeSync: fs4.closeSync.bind(fs4),
8837
8857
  pruneSkillUsageLog,
8838
8858
  resolveSourceKnowledgeIds,
8839
8859
  applySkillUsageFeedback,
@@ -9340,7 +9360,7 @@ var _internals11 = {
9340
9360
  retireOrMarkStale,
9341
9361
  retireSkill,
9342
9362
  getArchivedKnowledgeIds,
9343
- readFileAsync: (filePath, encoding) => import("fs/promises").then((fs7) => fs7.readFile(filePath, encoding)),
9363
+ readFileAsync: (filePath, encoding) => import("fs/promises").then((fs6) => fs6.readFile(filePath, encoding)),
9344
9364
  readKnowledge,
9345
9365
  reviseSkill,
9346
9366
  getSkillVersion,
@@ -9393,13 +9413,25 @@ async function autoRetireSkills(directory, _curatorKnowledgePath, excludeSlugs)
9393
9413
  warn(`[curator] ${observations[observations.length - 1]}`);
9394
9414
  continue;
9395
9415
  }
9396
- const result = await _internals11.retireOrMarkStale(directory, path15.dirname(active.path), allArchivedIds);
9397
- if (result.action === "retire") {
9398
- observations.push(`Skill '${active.slug}' auto-retired: all source knowledge entries archived`);
9399
- warn(`[curator] ${observations[observations.length - 1]}`);
9400
- } else if (result.action === "stale") {
9401
- observations.push(`Skill '${active.slug}' marked stale: some source knowledge entries archived`);
9402
- warn(`[curator] ${observations[observations.length - 1]}`);
9416
+ let archivedSourceMatched = false;
9417
+ if (allArchivedIds.size > 0) {
9418
+ try {
9419
+ const content = await _internals11.readFileAsync(active.path, "utf-8");
9420
+ const sourceIds = _internals11.parseDraftFrontmatter(content)?.sourceKnowledgeIds ?? [];
9421
+ archivedSourceMatched = sourceIds.some((id) => allArchivedIds.has(id));
9422
+ } catch {
9423
+ archivedSourceMatched = false;
9424
+ }
9425
+ }
9426
+ if (archivedSourceMatched) {
9427
+ const result = await _internals11.retireOrMarkStale(directory, path15.dirname(active.path), allArchivedIds);
9428
+ if (result.action === "retire") {
9429
+ observations.push(`Skill '${active.slug}' auto-retired: all source knowledge entries archived`);
9430
+ warn(`[curator] ${observations[observations.length - 1]}`);
9431
+ } else if (result.action === "stale") {
9432
+ observations.push(`Skill '${active.slug}' marked stale: some source knowledge entries archived`);
9433
+ warn(`[curator] ${observations[observations.length - 1]}`);
9434
+ }
9403
9435
  }
9404
9436
  }
9405
9437
  } catch (autoRetireErr) {
@@ -9424,6 +9456,29 @@ function parseKnowledgeRecommendationsWithDiagnostics(llmOutput) {
9424
9456
  continue;
9425
9457
  const match = trimmed.match(/^-\s+entry\s+(\S+)\s+\(([^)]+)\):\s+(.+)$/i);
9426
9458
  if (!match) {
9459
+ const newCandidate = trimmed.match(/^-\s+new candidate:\s+(.+)$/i);
9460
+ if (newCandidate) {
9461
+ const text2 = newCandidate[1].trim().replace(/\s+\([^)]+\)$/, "");
9462
+ recommendations.push({
9463
+ action: "promote",
9464
+ entry_id: undefined,
9465
+ lesson: text2,
9466
+ reason: text2
9467
+ });
9468
+ continue;
9469
+ }
9470
+ const staleEntry = trimmed.match(/^-\s+entry\s+(\S+)\s+appears stale:\s+(.+)$/i);
9471
+ if (staleEntry) {
9472
+ const uuid2 = staleEntry[1];
9473
+ const text2 = staleEntry[2].trim().replace(/\s+\([^)]+\)$/, "");
9474
+ recommendations.push({
9475
+ action: "archive",
9476
+ entry_id: UUID_V4.test(uuid2) ? uuid2 : undefined,
9477
+ lesson: text2,
9478
+ reason: text2
9479
+ });
9480
+ continue;
9481
+ }
9427
9482
  diagnostics.push({
9428
9483
  section: "OBSERVATIONS",
9429
9484
  line: trimmed,
@@ -9567,16 +9622,16 @@ function arrayOfStrings(v) {
9567
9622
  function readLatestPostMortemDigest(directory) {
9568
9623
  try {
9569
9624
  const swarmDir = path15.join(directory, ".swarm");
9570
- if (!fs6.existsSync(swarmDir))
9625
+ if (!fs5.existsSync(swarmDir))
9571
9626
  return null;
9572
- const candidates = fs6.readdirSync(swarmDir).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name)).map((name) => {
9627
+ const candidates = fs5.readdirSync(swarmDir).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name)).map((name) => {
9573
9628
  const filePath = path15.join(swarmDir, name);
9574
- return { name, filePath, mtimeMs: fs6.statSync(filePath).mtimeMs };
9629
+ return { name, filePath, mtimeMs: fs5.statSync(filePath).mtimeMs };
9575
9630
  }).sort((a, b) => b.mtimeMs - a.mtimeMs);
9576
9631
  const latest = candidates[0];
9577
9632
  if (!latest)
9578
9633
  return null;
9579
- const content = fs6.readFileSync(latest.filePath, "utf-8");
9634
+ const content = fs5.readFileSync(latest.filePath, "utf-8");
9580
9635
  const summary = content.match(/SUMMARY:\s*\n([\s\S]*?)(?:\n[A-Z_]+:|\n##|$)/);
9581
9636
  const body = (summary?.[1]?.trim() || content.slice(0, 1500)).slice(0, 1500);
9582
9637
  return `${latest.name}
@@ -9613,7 +9668,7 @@ async function readCuratorSummary(directory) {
9613
9668
  }
9614
9669
  async function writeCuratorSummary(directory, summary) {
9615
9670
  const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
9616
- fs6.mkdirSync(path15.dirname(resolvedPath), { recursive: true });
9671
+ fs5.mkdirSync(path15.dirname(resolvedPath), { recursive: true });
9617
9672
  await bunWrite(resolvedPath, JSON.stringify(summary, null, 2));
9618
9673
  }
9619
9674
  function normalizeAgentName(name) {
@@ -10054,7 +10109,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
10054
10109
  if (knowledgeApplicationFindings.length > 0) {
10055
10110
  try {
10056
10111
  const evidenceDir = path15.join(directory, ".swarm", "evidence", String(phase));
10057
- fs6.mkdirSync(evidenceDir, { recursive: true });
10112
+ fs5.mkdirSync(evidenceDir, { recursive: true });
10058
10113
  const findingsPath = path15.join(evidenceDir, "curator-findings.json");
10059
10114
  await bunWrite(findingsPath, JSON.stringify({ findings: knowledgeApplicationFindings }, null, 2));
10060
10115
  } catch (err) {
@@ -10357,7 +10412,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
10357
10412
  }
10358
10413
  const now = new Date().toISOString();
10359
10414
  const newEntry = {
10360
- id: randomUUID4(),
10415
+ id: randomUUID5(),
10361
10416
  tier: "swarm",
10362
10417
  lesson,
10363
10418
  category: rec.category ?? "other",
@@ -10674,18 +10729,18 @@ async function promoteFromSwarm(directory, lessonId) {
10674
10729
  // src/hooks/knowledge-curator.ts
10675
10730
  import { createHash as createHash4 } from "crypto";
10676
10731
  import { existsSync as existsSync13 } from "fs";
10677
- import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
10732
+ import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile8, writeFile as writeFile8 } from "fs/promises";
10678
10733
  import * as path21 from "path";
10679
10734
 
10680
10735
  // src/services/synonym-map.ts
10681
10736
  var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
10682
10737
  import {
10683
10738
  mkdir as mkdir5,
10684
- readFile as readFile5,
10685
- rename as rename4,
10739
+ readFile as readFile6,
10740
+ rename as rename5,
10686
10741
  stat as stat3,
10687
10742
  unlink,
10688
- writeFile as writeFile5
10743
+ writeFile as writeFile6
10689
10744
  } from "fs/promises";
10690
10745
  import * as path17 from "path";
10691
10746
  var SYNONYM_MAP_FILENAME = "synonym-map.json";
@@ -10835,7 +10890,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
10835
10890
  const st = await stat3(filePath);
10836
10891
  if (st.size > ceiling)
10837
10892
  return emptySynonymMap();
10838
- const raw = await readFile5(filePath, "utf-8");
10893
+ const raw = await readFile6(filePath, "utf-8");
10839
10894
  return coerceSynonymMap(JSON.parse(raw), maxPairs);
10840
10895
  } catch {
10841
10896
  return emptySynonymMap();
@@ -10845,8 +10900,8 @@ async function writeSynonymMapAtomic(filePath, map) {
10845
10900
  await mkdir5(path17.dirname(filePath), { recursive: true });
10846
10901
  const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
10847
10902
  try {
10848
- await writeFile5(tmp, JSON.stringify(map, null, 2), "utf-8");
10849
- await rename4(tmp, filePath);
10903
+ await writeFile6(tmp, JSON.stringify(map, null, 2), "utf-8");
10904
+ await rename5(tmp, filePath);
10850
10905
  } finally {
10851
10906
  try {
10852
10907
  await unlink(tmp);
@@ -10919,17 +10974,17 @@ function reinforceSwarmKnowledgeEntry(entry, confirmation) {
10919
10974
 
10920
10975
  // src/hooks/micro-reflector.ts
10921
10976
  import { existsSync as existsSync12 } from "fs";
10922
- import { readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
10977
+ import { readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
10923
10978
  import * as path20 from "path";
10924
10979
  init_logger();
10925
10980
 
10926
10981
  // src/hooks/skill-propagation-gate.ts
10927
- import * as fs8 from "fs";
10982
+ import * as fs7 from "fs";
10928
10983
  import * as path19 from "path";
10929
10984
  init_logger();
10930
10985
 
10931
10986
  // src/hooks/skill-scoring.ts
10932
- import * as fs7 from "fs";
10987
+ import * as fs6 from "fs";
10933
10988
  import * as path18 from "path";
10934
10989
  var FREQUENCY_CAP = 10;
10935
10990
  var FREQUENCY_WEIGHT = 0.3;
@@ -10997,6 +11052,9 @@ function normalizeTriggerList(values) {
10997
11052
  }
10998
11053
  return out;
10999
11054
  }
11055
+ function finiteRankValue(value) {
11056
+ return Number.isFinite(value) ? value : 0;
11057
+ }
11000
11058
  function parseInlineStringList(rawValue) {
11001
11059
  const trimmed = rawValue.trim();
11002
11060
  if (!trimmed)
@@ -11103,13 +11161,13 @@ function parseSkillFrontmatter(content, skillPath) {
11103
11161
  return meta;
11104
11162
  }
11105
11163
  function readFilePrefix(filePath) {
11106
- const fd = fs7.openSync(filePath, "r");
11164
+ const fd = fs6.openSync(filePath, "r");
11107
11165
  try {
11108
11166
  const buffer = Buffer.alloc(SKILL_FRONTMATTER_READ_BYTES);
11109
- const bytesRead = fs7.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
11167
+ const bytesRead = fs6.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
11110
11168
  return buffer.toString("utf-8", 0, bytesRead);
11111
11169
  } finally {
11112
- fs7.closeSync(fd);
11170
+ fs6.closeSync(fd);
11113
11171
  }
11114
11172
  }
11115
11173
  function readSkillMetadata(skillPath, directory) {
@@ -11215,15 +11273,19 @@ function rankSkillsForContext(skills, taskContext, directory) {
11215
11273
  const complianceRate = entriesWithVerdict.length > 0 ? compliantCount / entriesWithVerdict.length : 0;
11216
11274
  results.push({
11217
11275
  skillPath,
11218
- score,
11276
+ score: finiteRankValue(score),
11219
11277
  usageCount: skillEntries.length,
11220
11278
  complianceRate
11221
11279
  });
11222
11280
  }
11223
11281
  results.sort((a, b) => {
11224
- if (b.score !== a.score)
11225
- return b.score - a.score;
11226
- return b.usageCount - a.usageCount;
11282
+ const scoreDelta = finiteRankValue(b.score) - finiteRankValue(a.score);
11283
+ if (scoreDelta !== 0)
11284
+ return scoreDelta;
11285
+ const usageDelta = b.usageCount - a.usageCount;
11286
+ if (usageDelta !== 0)
11287
+ return usageDelta;
11288
+ return a.skillPath.localeCompare(b.skillPath);
11227
11289
  });
11228
11290
  return results;
11229
11291
  }
@@ -11258,7 +11320,7 @@ function formatSkillIndexWithContext(skills, directory) {
11258
11320
  const usageLogPath = path18.join(directory, ".swarm", "skill-usage.jsonl");
11259
11321
  let hasHistory = false;
11260
11322
  try {
11261
- const stat4 = fs7.statSync(usageLogPath);
11323
+ const stat4 = fs6.statSync(usageLogPath);
11262
11324
  hasHistory = stat4.size > 0;
11263
11325
  } catch {}
11264
11326
  if (!hasHistory) {
@@ -11421,13 +11483,13 @@ var SKILL_SEARCH_ROOTS = [
11421
11483
  ];
11422
11484
  var MAX_SCORING_SESSION_ENTRIES = 500;
11423
11485
  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),
11486
+ readdirSync: fs7.readdirSync.bind(fs7),
11487
+ existsSync: fs7.existsSync.bind(fs7),
11488
+ statSync: fs7.statSync.bind(fs7),
11489
+ mkdirSync: fs7.mkdirSync.bind(fs7),
11490
+ appendFileSync: fs7.appendFileSync.bind(fs7),
11491
+ readFileSync: fs7.readFileSync.bind(fs7),
11492
+ writeFileSync: fs7.writeFileSync.bind(fs7),
11431
11493
  skillPropagationGateBefore: null,
11432
11494
  skillPropagationTransformScan: null,
11433
11495
  SKILL_CAPABLE_AGENTS,
@@ -11948,7 +12010,7 @@ async function readTaskTrajectory(directory, taskId) {
11948
12010
  const filePath = validateSwarmPath(directory, rel);
11949
12011
  if (!existsSync12(filePath))
11950
12012
  return [];
11951
- const content = await readFile6(filePath, "utf-8");
12013
+ const content = await readFile7(filePath, "utf-8");
11952
12014
  const out = [];
11953
12015
  for (const line of content.split(`
11954
12016
  `)) {
@@ -12418,11 +12480,11 @@ async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BAT
12418
12480
  if (!existsSync13(filePath))
12419
12481
  return [];
12420
12482
  const consumed = [];
12421
- await transactFile(filePath, async (p) => readInsightJsonl(await readFile7(p, "utf-8").catch(() => "")), async (p, data) => {
12483
+ await transactFile(filePath, async (p) => readInsightJsonl(await readFile8(p, "utf-8").catch(() => "")), async (p, data) => {
12422
12484
  const body = data.length === 0 ? "" : `${data.map((c) => JSON.stringify(c)).join(`
12423
12485
  `)}
12424
12486
  `;
12425
- await writeFile7(p, body, "utf-8");
12487
+ await writeFile8(p, body, "utf-8");
12426
12488
  }, (all) => {
12427
12489
  if (all.length === 0)
12428
12490
  return null;
@@ -12902,7 +12964,7 @@ var _internals15 = {
12902
12964
 
12903
12965
  // src/scope/scope-persistence.ts
12904
12966
  var import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
12905
- import * as fs9 from "fs";
12967
+ import * as fs8 from "fs";
12906
12968
  import * as path22 from "path";
12907
12969
  var DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
12908
12970
  var LOCK_STALE_MS = 30 * 1000;
@@ -12938,12 +13000,12 @@ function getScopesDir(directory) {
12938
13000
  }
12939
13001
  function clearAllScopes(directory) {
12940
13002
  try {
12941
- fs9.rmSync(getScopesDir(directory), { recursive: true, force: true });
13003
+ fs8.rmSync(getScopesDir(directory), { recursive: true, force: true });
12942
13004
  } catch {}
12943
13005
  }
12944
13006
 
12945
13007
  // src/services/session-reflection.ts
12946
- import { promises as fs10 } from "fs";
13008
+ import { promises as fs9 } from "fs";
12947
13009
  import * as path23 from "path";
12948
13010
 
12949
13011
  // src/hooks/abort-utils.ts
@@ -13106,12 +13168,12 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
13106
13168
  const taxonomy = {};
13107
13169
  try {
13108
13170
  const evidenceDir = path23.join(directory, ".swarm", "evidence");
13109
- const entries = await fs10.readdir(evidenceDir);
13171
+ const entries = await fs9.readdir(evidenceDir);
13110
13172
  const retroDirs = entries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
13111
13173
  for (const retroDir of retroDirs) {
13112
13174
  const evidencePath = path23.join(evidenceDir, retroDir, "evidence.json");
13113
13175
  try {
13114
- const content = await fs10.readFile(evidencePath, "utf-8");
13176
+ const content = await fs9.readFile(evidencePath, "utf-8");
13115
13177
  const parsed = JSON.parse(content);
13116
13178
  const bundleEntries = parsed.entries ?? [parsed];
13117
13179
  for (const entry of bundleEntries) {
@@ -13139,13 +13201,13 @@ async function gatherGateFailures(directory) {
13139
13201
  const failures = new Map;
13140
13202
  try {
13141
13203
  const evidenceDir = path23.join(directory, ".swarm", "evidence");
13142
- const entries = await fs10.readdir(evidenceDir);
13204
+ const entries = await fs9.readdir(evidenceDir);
13143
13205
  for (const entry of entries) {
13144
13206
  if (entry.startsWith("retro-"))
13145
13207
  continue;
13146
13208
  const evidencePath = path23.join(evidenceDir, entry, "evidence.json");
13147
13209
  try {
13148
- const content = await fs10.readFile(evidencePath, "utf-8");
13210
+ const content = await fs9.readFile(evidencePath, "utf-8");
13149
13211
  const parsed = JSON.parse(content);
13150
13212
  const bundleEntries = parsed.entries ?? [parsed];
13151
13213
  for (const e of bundleEntries) {
@@ -13337,18 +13399,18 @@ async function writeSessionReflection(directory, result) {
13337
13399
  lines.push(result.architectReport);
13338
13400
  const content = lines.join(`
13339
13401
  `);
13340
- await fs10.writeFile(reflectionPath, content, "utf-8");
13402
+ await fs9.writeFile(reflectionPath, content, "utf-8");
13341
13403
  return reflectionPath;
13342
13404
  }
13343
13405
 
13344
13406
  // src/services/skill-improver.ts
13345
13407
  import { existsSync as existsSync15 } from "fs";
13346
- import { mkdir as mkdir8, readFile as readFile8, rename as rename5, writeFile as writeFile9 } from "fs/promises";
13408
+ import { mkdir as mkdir8, readFile as readFile9, rename as rename6, writeFile as writeFile10 } from "fs/promises";
13347
13409
  import * as path25 from "path";
13348
13410
  init_logger();
13349
13411
 
13350
13412
  // src/services/trajectory-cluster.ts
13351
- import { mkdir as mkdir7, writeFile as writeFile8 } from "fs/promises";
13413
+ import { mkdir as mkdir7, writeFile as writeFile9 } from "fs/promises";
13352
13414
  import * as path24 from "path";
13353
13415
  init_logger();
13354
13416
  var MACRO_TRAJECTORY_WINDOW = 200;
@@ -13486,7 +13548,7 @@ async function writeMotifProposals(directory, opts = {}) {
13486
13548
  for (const motif of motifs.slice(0, max)) {
13487
13549
  const slug = `motif-${slugify(motif.signature)}`;
13488
13550
  const filePath = path24.join(proposalsDir, `${slug}.md`);
13489
- await writeFile8(filePath, buildMotifProposal(motif), "utf-8");
13551
+ await writeFile9(filePath, buildMotifProposal(motif), "utf-8");
13490
13552
  result.proposalsWritten.push(filePath);
13491
13553
  }
13492
13554
  return result;
@@ -13631,7 +13693,7 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
13631
13693
  for (const motif of motifs.slice(0, max)) {
13632
13694
  const slug = workflowSlug(motif.signature);
13633
13695
  const filePath = path24.join(proposalsDir, `${slug}.md`);
13634
- await writeFile8(filePath, buildWorkflowProposal(motif), "utf-8");
13696
+ await writeFile9(filePath, buildWorkflowProposal(motif), "utf-8");
13635
13697
  result.proposalsWritten.push(filePath);
13636
13698
  }
13637
13699
  return result;
@@ -13755,8 +13817,8 @@ function timestampSlug(d) {
13755
13817
  async function atomicWrite(p, content) {
13756
13818
  await mkdir8(path25.dirname(p), { recursive: true });
13757
13819
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
13758
- await writeFile9(tmp, content, "utf-8");
13759
- await rename5(tmp, p);
13820
+ await writeFile10(tmp, content, "utf-8");
13821
+ await rename6(tmp, p);
13760
13822
  }
13761
13823
  async function gatherInventory(directory) {
13762
13824
  const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
@@ -13770,7 +13832,7 @@ async function gatherInventory(directory) {
13770
13832
  for (const skill of skills.active) {
13771
13833
  let content;
13772
13834
  try {
13773
- content = await readFile8(skill.path, "utf-8");
13835
+ content = await readFile9(skill.path, "utf-8");
13774
13836
  } catch {
13775
13837
  continue;
13776
13838
  }
@@ -13946,7 +14008,7 @@ async function reconcileStaleActiveSkills(directory, options = {}) {
13946
14008
  for (const skill of skills.active) {
13947
14009
  let content;
13948
14010
  try {
13949
- content = await readFile8(skill.path, "utf-8");
14011
+ content = await readFile9(skill.path, "utf-8");
13950
14012
  } catch {
13951
14013
  continue;
13952
14014
  }
@@ -14268,6 +14330,8 @@ function readEarliestSessionStart(directory) {
14268
14330
  }
14269
14331
 
14270
14332
  // src/tools/write-retro.ts
14333
+ import { existsSync as existsSync17 } from "fs";
14334
+ import path27 from "path";
14271
14335
  async function executeWriteRetro(args, directory) {
14272
14336
  if (/^(CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9])(:|$)/i.test(directory)) {
14273
14337
  return JSON.stringify({
@@ -14275,6 +14339,12 @@ async function executeWriteRetro(args, directory) {
14275
14339
  message: "Invalid directory: reserved device name"
14276
14340
  }, null, 2);
14277
14341
  }
14342
+ if (!existsSync17(path27.join(directory, ".swarm"))) {
14343
+ return JSON.stringify({
14344
+ success: false,
14345
+ message: `Cannot write evidence in "${directory}" \u2014 no .swarm/ folder was found. Run write_retro from an initialized project root.`
14346
+ }, null, 2);
14347
+ }
14278
14348
  const phase = args.phase;
14279
14349
  if (!Number.isInteger(phase) || phase < 1) {
14280
14350
  return JSON.stringify({
@@ -14682,20 +14752,20 @@ function countSessionKnowledgeEntries(entries, sessionStart, fallbackCount) {
14682
14752
  async function copyDirRecursiveWithFailures(src, dest) {
14683
14753
  let count = 0;
14684
14754
  const failures = [];
14685
- const entries = await fs11.readdir(src);
14686
- await fs11.mkdir(dest, { recursive: true });
14755
+ const entries = await fs10.readdir(src);
14756
+ await fs10.mkdir(dest, { recursive: true });
14687
14757
  for (const entry of entries) {
14688
- const srcEntry = path27.join(src, entry);
14689
- const destEntry = path27.join(dest, entry);
14758
+ const srcEntry = path28.join(src, entry);
14759
+ const destEntry = path28.join(dest, entry);
14690
14760
  try {
14691
- const stat4 = await fs11.stat(srcEntry);
14761
+ const stat4 = await fs10.stat(srcEntry);
14692
14762
  if (stat4.isDirectory()) {
14693
14763
  const subResult = await copyDirRecursiveWithFailures(srcEntry, destEntry);
14694
14764
  count += subResult.copied;
14695
14765
  failures.push(...subResult.failures);
14696
14766
  } else {
14697
14767
  try {
14698
- await fs11.copyFile(srcEntry, destEntry);
14768
+ await fs10.copyFile(srcEntry, destEntry);
14699
14769
  count++;
14700
14770
  } catch (err) {
14701
14771
  const errno = err?.code;
@@ -14871,20 +14941,20 @@ async function runFinalizeStage(ctx) {
14871
14941
  ctx.warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
14872
14942
  }
14873
14943
  }
14874
- const lessonsFilePath = path27.join(ctx.swarmDir, "close-lessons.md");
14944
+ const lessonsFilePath = path28.join(ctx.swarmDir, "close-lessons.md");
14875
14945
  try {
14876
- const lessonsText = await fs11.readFile(lessonsFilePath, "utf-8");
14946
+ const lessonsText = await fs10.readFile(lessonsFilePath, "utf-8");
14877
14947
  ctx.explicitLessons = lessonsText.split(`
14878
14948
  `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
14879
14949
  } catch {}
14880
14950
  try {
14881
- const evidenceDir = path27.join(ctx.swarmDir, "evidence");
14882
- const evidenceEntries = await fs11.readdir(evidenceDir);
14951
+ const evidenceDir = path28.join(ctx.swarmDir, "evidence");
14952
+ const evidenceEntries = await fs10.readdir(evidenceDir);
14883
14953
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
14884
14954
  for (const retroDir of retroDirs) {
14885
- const evidencePath = path27.join(evidenceDir, retroDir, "evidence.json");
14955
+ const evidencePath = path28.join(evidenceDir, retroDir, "evidence.json");
14886
14956
  try {
14887
- const content = await fs11.readFile(evidencePath, "utf-8");
14957
+ const content = await fs10.readFile(evidencePath, "utf-8");
14888
14958
  const parsed = JSON.parse(content);
14889
14959
  const entries = parsed.entries ?? [parsed];
14890
14960
  for (const entry of entries) {
@@ -14928,7 +14998,7 @@ async function runFinalizeStage(ctx) {
14928
14998
  console.warn("[close-command] curateAndStoreSwarm error:", error2);
14929
14999
  }
14930
15000
  if (ctx.curationSucceeded && ctx.allLessons.length > 0) {
14931
- await fs11.unlink(lessonsFilePath).catch(() => {});
15001
+ await fs10.unlink(lessonsFilePath).catch(() => {});
14932
15002
  }
14933
15003
  if (ctx.curationSucceeded) {
14934
15004
  if (ctx.config.hive_enabled === false) {} else {
@@ -15066,7 +15136,7 @@ async function copySqliteSafe(srcPath, destPath) {
15066
15136
  let checkpointVerified = false;
15067
15137
  try {
15068
15138
  const result = spawnSync2("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
15069
- cwd: path27.dirname(srcPath),
15139
+ cwd: path28.dirname(srcPath),
15070
15140
  encoding: "utf-8",
15071
15141
  stdio: ["ignore", "pipe", "pipe"],
15072
15142
  timeout: 1e4,
@@ -15077,7 +15147,7 @@ async function copySqliteSafe(srcPath, destPath) {
15077
15147
  const code = result.error.code;
15078
15148
  if (code === "ENOENT") {
15079
15149
  try {
15080
- await fs11.copyFile(srcPath, destPath);
15150
+ await fs10.copyFile(srcPath, destPath);
15081
15151
  return {
15082
15152
  success: true,
15083
15153
  reason: "copied without WAL checkpoint (sqlite3 CLI unavailable)"
@@ -15116,7 +15186,7 @@ async function copySqliteSafe(srcPath, destPath) {
15116
15186
  };
15117
15187
  }
15118
15188
  try {
15119
- await fs11.copyFile(srcPath, destPath);
15189
+ await fs10.copyFile(srcPath, destPath);
15120
15190
  if (checkpointVerified) {
15121
15191
  return { success: true };
15122
15192
  }
@@ -15134,9 +15204,9 @@ async function copySqliteSafe(srcPath, destPath) {
15134
15204
  async function runArchiveStage(ctx) {
15135
15205
  ctx.timestamp = new Date().toISOString().replace(/[:.]/g, "-");
15136
15206
  ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
15137
- ctx.archiveDir = path27.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
15207
+ ctx.archiveDir = path28.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
15138
15208
  try {
15139
- await fs11.mkdir(ctx.archiveDir, { recursive: true });
15209
+ await fs10.mkdir(ctx.archiveDir, { recursive: true });
15140
15210
  const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
15141
15211
  const linkedKnowledgeShared = isLinked(ctx.directory);
15142
15212
  if (linkedKnowledgeShared) {
@@ -15149,8 +15219,8 @@ async function runArchiveStage(ctx) {
15149
15219
  if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
15150
15220
  continue;
15151
15221
  }
15152
- const srcPath = path27.join(ctx.swarmDir, artifact);
15153
- const destPath = path27.join(ctx.archiveDir, artifact);
15222
+ const srcPath = path28.join(ctx.swarmDir, artifact);
15223
+ const destPath = path28.join(ctx.archiveDir, artifact);
15154
15224
  if (artifact === "swarm.db") {
15155
15225
  const result = await copySqliteSafe(srcPath, destPath);
15156
15226
  if (result.skipped) {} else if (result.success) {
@@ -15166,7 +15236,7 @@ async function runArchiveStage(ctx) {
15166
15236
  }
15167
15237
  } else {
15168
15238
  try {
15169
- await fs11.copyFile(srcPath, destPath);
15239
+ await fs10.copyFile(srcPath, destPath);
15170
15240
  ctx.archivedFileCount++;
15171
15241
  if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
15172
15242
  ctx.archivedActiveStateFiles.add(artifact);
@@ -15181,12 +15251,12 @@ async function runArchiveStage(ctx) {
15181
15251
  }
15182
15252
  }
15183
15253
  }
15184
- const dynamicArchiveArtifacts = (await fs11.readdir(ctx.swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
15254
+ const dynamicArchiveArtifacts = (await fs10.readdir(ctx.swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
15185
15255
  for (const artifact of dynamicArchiveArtifacts) {
15186
- const srcPath = path27.join(ctx.swarmDir, artifact);
15187
- const destPath = path27.join(ctx.archiveDir, artifact);
15256
+ const srcPath = path28.join(ctx.swarmDir, artifact);
15257
+ const destPath = path28.join(ctx.archiveDir, artifact);
15188
15258
  try {
15189
- await fs11.copyFile(srcPath, destPath);
15259
+ await fs10.copyFile(srcPath, destPath);
15190
15260
  ctx.archivedFileCount++;
15191
15261
  ctx.archivedActiveStateFiles.add(artifact);
15192
15262
  } catch (err) {
@@ -15199,8 +15269,8 @@ async function runArchiveStage(ctx) {
15199
15269
  }
15200
15270
  }
15201
15271
  for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
15202
- const srcDir = path27.join(ctx.swarmDir, dirName);
15203
- const destDir = path27.join(ctx.archiveDir, dirName);
15272
+ const srcDir = path28.join(ctx.swarmDir, dirName);
15273
+ const destDir = path28.join(ctx.archiveDir, dirName);
15204
15274
  try {
15205
15275
  const result = await copyDirRecursiveWithFailures(srcDir, destDir);
15206
15276
  ctx.archivedFileCount += result.copied;
@@ -15277,9 +15347,9 @@ async function runCleanStage(ctx) {
15277
15347
  ctx.warnings.push(reason ? `Preserved ${artifact} because it was not successfully archived: ${reason}.` : `Preserved ${artifact} because it was not successfully archived.`);
15278
15348
  continue;
15279
15349
  }
15280
- const filePath = path27.join(ctx.swarmDir, artifact);
15350
+ const filePath = path28.join(ctx.swarmDir, artifact);
15281
15351
  try {
15282
- await fs11.unlink(filePath);
15352
+ await fs10.unlink(filePath);
15283
15353
  cleanedFiles.push(artifact);
15284
15354
  } catch (err) {
15285
15355
  const errno = err?.code;
@@ -15297,7 +15367,7 @@ async function runCleanStage(ctx) {
15297
15367
  continue;
15298
15368
  }
15299
15369
  try {
15300
- await fs11.unlink(path27.join(ctx.swarmDir, artifact));
15370
+ await fs10.unlink(path28.join(ctx.swarmDir, artifact));
15301
15371
  cleanedFiles.push(artifact);
15302
15372
  } catch (err) {
15303
15373
  const errno = err?.code;
@@ -15311,18 +15381,18 @@ async function runCleanStage(ctx) {
15311
15381
  if (!ctx.archivedActiveStateDirs.has(dirName)) {
15312
15382
  continue;
15313
15383
  }
15314
- const dirPath = path27.join(ctx.swarmDir, dirName);
15384
+ const dirPath = path28.join(ctx.swarmDir, dirName);
15315
15385
  try {
15316
- await fs11.rm(dirPath, { recursive: true, force: true });
15386
+ await fs10.rm(dirPath, { recursive: true, force: true });
15317
15387
  cleanedFiles.push(`${dirName}/`);
15318
15388
  } catch {}
15319
15389
  }
15320
15390
  try {
15321
- const swarmFiles = await fs11.readdir(ctx.swarmDir);
15391
+ const swarmFiles = await fs10.readdir(ctx.swarmDir);
15322
15392
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
15323
15393
  for (const backup of configBackups) {
15324
15394
  try {
15325
- await fs11.unlink(path27.join(ctx.swarmDir, backup));
15395
+ await fs10.unlink(path28.join(ctx.swarmDir, backup));
15326
15396
  configBackupsRemoved++;
15327
15397
  } catch (err) {
15328
15398
  const errno = err?.code;
@@ -15335,7 +15405,7 @@ async function runCleanStage(ctx) {
15335
15405
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
15336
15406
  for (const sibling of ledgerSiblings) {
15337
15407
  try {
15338
- await fs11.unlink(path27.join(ctx.swarmDir, sibling));
15408
+ await fs10.unlink(path28.join(ctx.swarmDir, sibling));
15339
15409
  } catch (err) {
15340
15410
  const errno = err?.code;
15341
15411
  if (errno === "ENOENT") {} else {
@@ -15353,16 +15423,16 @@ async function runCleanStage(ctx) {
15353
15423
  }
15354
15424
  let swarmPlanFilesRemoved = 0;
15355
15425
  const candidates = [
15356
- path27.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
15357
- path27.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
15358
- path27.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
15359
- path27.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
15360
- path27.join(ctx.directory, "SWARM_PLAN.json"),
15361
- path27.join(ctx.directory, "SWARM_PLAN.md")
15426
+ path28.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
15427
+ path28.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
15428
+ path28.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
15429
+ path28.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
15430
+ path28.join(ctx.directory, "SWARM_PLAN.json"),
15431
+ path28.join(ctx.directory, "SWARM_PLAN.md")
15362
15432
  ];
15363
15433
  for (const candidate of candidates) {
15364
15434
  try {
15365
- await fs11.unlink(candidate);
15435
+ await fs10.unlink(candidate);
15366
15436
  swarmPlanFilesRemoved++;
15367
15437
  } catch (err) {
15368
15438
  if (err?.code !== "ENOENT") {
@@ -15372,11 +15442,11 @@ async function runCleanStage(ctx) {
15372
15442
  }
15373
15443
  let tmpFilesRemoved = 0;
15374
15444
  try {
15375
- const swarmFiles = await fs11.readdir(ctx.swarmDir);
15445
+ const swarmFiles = await fs10.readdir(ctx.swarmDir);
15376
15446
  const tmpFiles = swarmFiles.filter((f) => f.startsWith(".tmp."));
15377
15447
  for (const tmp of tmpFiles) {
15378
15448
  try {
15379
- await fs11.unlink(path27.join(ctx.swarmDir, tmp));
15449
+ await fs10.unlink(path28.join(ctx.swarmDir, tmp));
15380
15450
  tmpFilesRemoved++;
15381
15451
  } catch (err) {
15382
15452
  const errno = err?.code;
@@ -15398,7 +15468,7 @@ async function runCleanStage(ctx) {
15398
15468
  }
15399
15469
  for (const terminalFile of TERMINAL_STATE_FILES) {
15400
15470
  try {
15401
- await fs11.unlink(path27.join(ctx.swarmDir, terminalFile));
15471
+ await fs10.unlink(path28.join(ctx.swarmDir, terminalFile));
15402
15472
  if (!cleanedFiles.includes(terminalFile)) {
15403
15473
  cleanedFiles.push(terminalFile);
15404
15474
  }
@@ -15411,7 +15481,7 @@ async function runCleanStage(ctx) {
15411
15481
  }
15412
15482
  }
15413
15483
  clearAllScopes(ctx.directory);
15414
- const contextPath = path27.join(ctx.swarmDir, "context.md");
15484
+ const contextPath = path28.join(ctx.swarmDir, "context.md");
15415
15485
  const contextContent = [
15416
15486
  "# Context",
15417
15487
  "",
@@ -15423,9 +15493,9 @@ async function runCleanStage(ctx) {
15423
15493
  ""
15424
15494
  ].join(`
15425
15495
  `);
15426
- const contextTempPath = path27.join(path27.dirname(contextPath), `${path27.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15496
+ const contextTempPath = path28.join(path28.dirname(contextPath), `${path28.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15427
15497
  try {
15428
- await fs11.writeFile(contextTempPath, contextContent, "utf-8");
15498
+ await fs10.writeFile(contextTempPath, contextContent, "utf-8");
15429
15499
  fsSync.renameSync(contextTempPath, contextPath);
15430
15500
  } catch (error2) {
15431
15501
  try {
@@ -15487,7 +15557,7 @@ async function runAlignStage(ctx) {
15487
15557
  return { gitAlignResult, prunedBranches };
15488
15558
  }
15489
15559
  async function handleCloseCommand(directory, args, options = {}) {
15490
- const swarmDir = path27.join(directory, ".swarm");
15560
+ const swarmDir = path28.join(directory, ".swarm");
15491
15561
  try {
15492
15562
  const stat4 = fsSync.lstatSync(swarmDir);
15493
15563
  if (stat4.isSymbolicLink()) {
@@ -15501,18 +15571,18 @@ async function handleCloseCommand(directory, args, options = {}) {
15501
15571
  const planPath = validateSwarmPath(directory, "plan.json");
15502
15572
  let planExists = false;
15503
15573
  let planData = {
15504
- title: path27.basename(directory) || "Ad-hoc session",
15574
+ title: path28.basename(directory) || "Ad-hoc session",
15505
15575
  phases: []
15506
15576
  };
15507
15577
  try {
15508
- const content = await fs11.readFile(planPath, "utf-8");
15578
+ const content = await fs10.readFile(planPath, "utf-8");
15509
15579
  planData = JSON.parse(content);
15510
15580
  planExists = true;
15511
15581
  } catch (error2) {
15512
15582
  if (error2?.code !== "ENOENT") {
15513
15583
  return `\u274C Failed to read plan.json: ${error2 instanceof Error ? error2.message : String(error2)}`;
15514
15584
  }
15515
- const swarmDirExists = await fs11.access(swarmDir).then(() => true).catch(() => false);
15585
+ const swarmDirExists = await fs10.access(swarmDir).then(() => true).catch(() => false);
15516
15586
  if (!swarmDirExists) {
15517
15587
  return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
15518
15588
  }
@@ -15526,15 +15596,15 @@ async function handleCloseCommand(directory, args, options = {}) {
15526
15596
  }
15527
15597
  try {
15528
15598
  if (!planExists) {
15529
- const archiveDir = path27.join(swarmDir, "archive");
15599
+ const archiveDir = path28.join(swarmDir, "archive");
15530
15600
  try {
15531
- const archiveEntries = await fs11.readdir(archiveDir);
15601
+ const archiveEntries = await fs10.readdir(archiveDir);
15532
15602
  const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
15533
15603
  if (hasArchiveBundle) {
15534
15604
  const hasActiveState = [
15535
15605
  ...ACTIVE_STATE_TO_CLEAN,
15536
15606
  ...ACTIVE_STATE_DIRS_TO_CLEAN
15537
- ].some((entry) => fsSync.existsSync(path27.join(swarmDir, entry)));
15607
+ ].some((entry) => fsSync.existsSync(path28.join(swarmDir, entry)));
15538
15608
  if (!hasActiveState) {
15539
15609
  return `\u2705 Already finalized \u2014 nothing to do.
15540
15610
 
@@ -15662,9 +15732,9 @@ This project was already finalized in a previous /swarm close run. The plan has
15662
15732
  ...ctx.warnings.length > 0 ? ["## Warnings", ...ctx.warnings.map((w) => `- ${w}`), ""] : []
15663
15733
  ].join(`
15664
15734
  `);
15665
- const closeSummaryTempPath = path27.join(path27.dirname(closeSummaryPath), `${path27.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15735
+ const closeSummaryTempPath = path28.join(path28.dirname(closeSummaryPath), `${path28.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15666
15736
  try {
15667
- await fs11.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
15737
+ await fs10.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
15668
15738
  fsSync.renameSync(closeSummaryTempPath, closeSummaryPath);
15669
15739
  } catch (error2) {
15670
15740
  try {
@@ -16006,14 +16076,14 @@ function buildStatusMessage(session, plan) {
16006
16076
 
16007
16077
  // src/commands/config.ts
16008
16078
  import * as os6 from "os";
16009
- import * as path28 from "path";
16079
+ import * as path29 from "path";
16010
16080
  function getUserConfigDir2() {
16011
- return process.env.XDG_CONFIG_HOME || path28.join(os6.homedir(), ".config");
16081
+ return process.env.XDG_CONFIG_HOME || path29.join(os6.homedir(), ".config");
16012
16082
  }
16013
16083
  async function handleConfigCommand(directory, _args) {
16014
16084
  const config = loadPluginConfig(directory);
16015
- const userConfigPath = path28.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
16016
- const projectConfigPath = path28.join(directory, ".opencode", "opencode-swarm.json");
16085
+ const userConfigPath = path29.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
16086
+ const projectConfigPath = path29.join(directory, ".opencode", "opencode-swarm.json");
16017
16087
  const lines = [
16018
16088
  "## Swarm Configuration",
16019
16089
  "",
@@ -16031,9 +16101,9 @@ async function handleConfigCommand(directory, _args) {
16031
16101
  }
16032
16102
 
16033
16103
  // src/services/skill-consolidation.ts
16034
- import { existsSync as existsSync18 } from "fs";
16035
- import { mkdir as mkdir9, readFile as readFile9, rename as rename6, writeFile as writeFile10 } from "fs/promises";
16036
- import * as path29 from "path";
16104
+ import { existsSync as existsSync19 } from "fs";
16105
+ import { mkdir as mkdir9, readFile as readFile10, rename as rename7, writeFile as writeFile11 } from "fs/promises";
16106
+ import * as path30 from "path";
16037
16107
 
16038
16108
  // src/utils/timeout.ts
16039
16109
  async function withTimeout(promise, ms, timeoutError) {
@@ -16058,14 +16128,14 @@ var DEFAULT_CONSOLIDATION_MAX_CALLS_PER_RUN = 1;
16058
16128
  var CONSOLIDATION_RUN_TIMEOUT_MS = 5 * 60 * 1000;
16059
16129
  var runningByDirectory = new Map;
16060
16130
  function consolidationStatePath(directory) {
16061
- return path29.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
16131
+ return path30.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
16062
16132
  }
16063
16133
  async function readState2(directory) {
16064
16134
  const filePath = consolidationStatePath(directory);
16065
- if (!existsSync18(filePath))
16135
+ if (!existsSync19(filePath))
16066
16136
  return {};
16067
16137
  try {
16068
- const parsed = JSON.parse(await readFile9(filePath, "utf-8"));
16138
+ const parsed = JSON.parse(await readFile10(filePath, "utf-8"));
16069
16139
  if (!parsed || typeof parsed !== "object")
16070
16140
  return {};
16071
16141
  return parsed;
@@ -16074,10 +16144,10 @@ async function readState2(directory) {
16074
16144
  }
16075
16145
  }
16076
16146
  async function atomicWrite2(filePath, content) {
16077
- await mkdir9(path29.dirname(filePath), { recursive: true });
16147
+ await mkdir9(path30.dirname(filePath), { recursive: true });
16078
16148
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
16079
- await writeFile10(tmp, content, "utf-8");
16080
- await rename6(tmp, filePath);
16149
+ await writeFile11(tmp, content, "utf-8");
16150
+ await rename7(tmp, filePath);
16081
16151
  }
16082
16152
  async function writeState2(directory, state) {
16083
16153
  await atomicWrite2(consolidationStatePath(directory), `${JSON.stringify(state, null, 2)}
@@ -16154,7 +16224,7 @@ async function runSkillConsolidationInner(req) {
16154
16224
  };
16155
16225
  }
16156
16226
  async function runSkillConsolidation(req) {
16157
- const key = path29.resolve(req.directory);
16227
+ const key = path30.resolve(req.directory);
16158
16228
  const existing = runningByDirectory.get(key);
16159
16229
  if (existing) {
16160
16230
  return {
@@ -16355,8 +16425,8 @@ async function handleCouncilCommand(_directory, args) {
16355
16425
 
16356
16426
  // src/commands/coupling.ts
16357
16427
  import { randomBytes } from "crypto";
16358
- import * as fs12 from "fs";
16359
- import * as path31 from "path";
16428
+ import * as fs11 from "fs";
16429
+ import * as path32 from "path";
16360
16430
 
16361
16431
  // src/turbo/epic/cochange-source.ts
16362
16432
  import * as child_process3 from "child_process";
@@ -16364,9 +16434,9 @@ import { promisify as promisify2 } from "util";
16364
16434
 
16365
16435
  // src/tools/co-change-analyzer.ts
16366
16436
  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";
16369
- import * as path30 from "path";
16437
+ import { randomUUID as randomUUID6 } from "crypto";
16438
+ import { readdir as readdir2, readFile as readFile11, stat as stat4 } from "fs/promises";
16439
+ import * as path31 from "path";
16370
16440
  import { promisify } from "util";
16371
16441
  function getExecFileAsync() {
16372
16442
  return promisify(child_process2.execFile);
@@ -16470,7 +16540,7 @@ async function scanSourceFiles(dir) {
16470
16540
  try {
16471
16541
  const entries = await readdir2(dir, { withFileTypes: true });
16472
16542
  for (const entry of entries) {
16473
- const fullPath = path30.join(dir, entry.name);
16543
+ const fullPath = path31.join(dir, entry.name);
16474
16544
  if (entry.isDirectory()) {
16475
16545
  if (skipDirs.has(entry.name)) {
16476
16546
  continue;
@@ -16478,7 +16548,7 @@ async function scanSourceFiles(dir) {
16478
16548
  const subFiles = await scanSourceFiles(fullPath);
16479
16549
  results.push(...subFiles);
16480
16550
  } else if (entry.isFile()) {
16481
- const ext = path30.extname(entry.name);
16551
+ const ext = path31.extname(entry.name);
16482
16552
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
16483
16553
  results.push(fullPath);
16484
16554
  }
@@ -16492,7 +16562,7 @@ async function getStaticEdges(directory) {
16492
16562
  const sourceFiles = await scanSourceFiles(directory);
16493
16563
  for (const sourceFile of sourceFiles) {
16494
16564
  try {
16495
- const content = await readFile10(sourceFile, "utf-8");
16565
+ const content = await readFile11(sourceFile, "utf-8");
16496
16566
  const importRegex = /(?:import|require)\s*(?:\(?\s*['"`]|.*?from\s+['"`])([^'"`]+)['"`]/g;
16497
16567
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
16498
16568
  const importPath = match[1].trim();
@@ -16500,8 +16570,8 @@ async function getStaticEdges(directory) {
16500
16570
  continue;
16501
16571
  }
16502
16572
  try {
16503
- const sourceDir = path30.dirname(sourceFile);
16504
- const resolvedPath = path30.resolve(sourceDir, importPath);
16573
+ const sourceDir = path31.dirname(sourceFile);
16574
+ const resolvedPath = path31.resolve(sourceDir, importPath);
16505
16575
  const extensions = [
16506
16576
  "",
16507
16577
  ".ts",
@@ -16526,8 +16596,8 @@ async function getStaticEdges(directory) {
16526
16596
  if (!targetFile) {
16527
16597
  continue;
16528
16598
  }
16529
- const relSource = path30.relative(directory, sourceFile).replace(/\\/g, "/");
16530
- const relTarget = path30.relative(directory, targetFile).replace(/\\/g, "/");
16599
+ const relSource = path31.relative(directory, sourceFile).replace(/\\/g, "/");
16600
+ const relTarget = path31.relative(directory, targetFile).replace(/\\/g, "/");
16531
16601
  const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
16532
16602
  edges.add(key);
16533
16603
  } catch {}
@@ -16539,7 +16609,7 @@ async function getStaticEdges(directory) {
16539
16609
  function isTestImplementationPair(fileA, fileB) {
16540
16610
  const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
16541
16611
  const getBaseName = (filePath) => {
16542
- const base = path30.basename(filePath);
16612
+ const base = path31.basename(filePath);
16543
16613
  for (const pattern of testPatterns) {
16544
16614
  if (base.endsWith(pattern)) {
16545
16615
  return base.slice(0, -pattern.length);
@@ -16549,16 +16619,16 @@ function isTestImplementationPair(fileA, fileB) {
16549
16619
  };
16550
16620
  const baseA = getBaseName(fileA);
16551
16621
  const baseB = getBaseName(fileB);
16552
- return baseA === baseB && baseA !== path30.basename(fileA) && baseA !== path30.basename(fileB);
16622
+ return baseA === baseB && baseA !== path31.basename(fileA) && baseA !== path31.basename(fileB);
16553
16623
  }
16554
16624
  function hasSharedPrefix(fileA, fileB) {
16555
- const dirA = path30.dirname(fileA);
16556
- const dirB = path30.dirname(fileB);
16625
+ const dirA = path31.dirname(fileA);
16626
+ const dirB = path31.dirname(fileB);
16557
16627
  if (dirA !== dirB) {
16558
16628
  return false;
16559
16629
  }
16560
- const baseA = path30.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
16561
- const baseB = path30.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
16630
+ const baseA = path31.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
16631
+ const baseB = path31.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
16562
16632
  if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
16563
16633
  return true;
16564
16634
  }
@@ -16613,8 +16683,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
16613
16683
  const entries = [];
16614
16684
  const now = new Date().toISOString();
16615
16685
  for (const pair of pairs.slice(0, 10)) {
16616
- const baseA = path30.basename(pair.fileA);
16617
- const baseB = path30.basename(pair.fileB);
16686
+ const baseA = path31.basename(pair.fileA);
16687
+ const baseB = path31.basename(pair.fileB);
16618
16688
  let lesson = `Files ${pair.fileA} and ${pair.fileB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
16619
16689
  if (lesson.length > 280) {
16620
16690
  lesson = `Files ${baseA} and ${baseB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
@@ -16627,7 +16697,7 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
16627
16697
  }
16628
16698
  const confidence = Math.min(0.3 + 0.2 * Math.min(pair.coChangeCount / 10, 1), 0.5);
16629
16699
  entries.push({
16630
- id: randomUUID5(),
16700
+ id: randomUUID6(),
16631
16701
  tier: "swarm",
16632
16702
  lesson,
16633
16703
  category: "architecture",
@@ -17040,17 +17110,17 @@ function parseArgs3(args) {
17040
17110
  return parsed;
17041
17111
  }
17042
17112
  function persistReportJson(directory, report) {
17043
- const epicDir = path31.join(directory, ".swarm", "epic");
17044
- fs12.mkdirSync(epicDir, { recursive: true });
17045
- const filePath = path31.join(epicDir, "coupling-report.json");
17113
+ const epicDir = path32.join(directory, ".swarm", "epic");
17114
+ fs11.mkdirSync(epicDir, { recursive: true });
17115
+ const filePath = path32.join(epicDir, "coupling-report.json");
17046
17116
  const tmpPath = `${filePath}.tmp.${randomBytes(8).toString("hex")}`;
17047
- fs12.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
17117
+ fs11.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
17048
17118
  `, "utf-8");
17049
17119
  try {
17050
- fs12.renameSync(tmpPath, filePath);
17120
+ fs11.renameSync(tmpPath, filePath);
17051
17121
  } catch (err) {
17052
17122
  try {
17053
- fs12.unlinkSync(tmpPath);
17123
+ fs11.unlinkSync(tmpPath);
17054
17124
  } catch {}
17055
17125
  throw err;
17056
17126
  }
@@ -17101,7 +17171,7 @@ Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>
17101
17171
  persistStatus = {
17102
17172
  requested: true,
17103
17173
  written: true,
17104
- path: path31.relative(directory, writtenAt)
17174
+ path: path32.relative(directory, writtenAt).replace(/\\/g, "/")
17105
17175
  };
17106
17176
  } catch (err) {
17107
17177
  persistStatus = {
@@ -17140,8 +17210,8 @@ var _internals22 = {
17140
17210
  loadCuratorDeps: async () => {
17141
17211
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
17142
17212
  import("./schema-vw2ffhe9.js"),
17143
- import("./curator-np2ky29t.js"),
17144
- import("./curator-llm-factory-gdhtm1hh.js")
17213
+ import("./curator-1nr4qszq.js"),
17214
+ import("./curator-llm-factory-x9tk7e6m.js")
17145
17215
  ]);
17146
17216
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
17147
17217
  }
@@ -17233,7 +17303,7 @@ function formatCurationSummary(summary) {
17233
17303
  }
17234
17304
 
17235
17305
  // src/commands/dark-matter.ts
17236
- import path32 from "path";
17306
+ import path33 from "path";
17237
17307
  async function handleDarkMatterCommand(directory, args) {
17238
17308
  const options = {};
17239
17309
  for (let i = 0;i < args.length; i++) {
@@ -17265,7 +17335,7 @@ Ensure this is a git repository with commit history.`;
17265
17335
  const output = formatDarkMatterOutput(pairs);
17266
17336
  if (pairs.length > 0) {
17267
17337
  try {
17268
- const projectName = path32.basename(path32.resolve(directory));
17338
+ const projectName = path33.basename(path33.resolve(directory));
17269
17339
  const entries = darkMatterToKnowledgeEntries(pairs, projectName);
17270
17340
  if (entries.length > 0) {
17271
17341
  const knowledgePath = resolveSwarmKnowledgePath(directory);
@@ -17631,13 +17701,13 @@ ${USAGE5}`;
17631
17701
 
17632
17702
  // src/services/diagnose-service.ts
17633
17703
  import * as child_process4 from "child_process";
17634
- import { existsSync as existsSync21, readdirSync as readdirSync4, readFileSync as readFileSync11, statSync as statSync7 } from "fs";
17635
- import path37 from "path";
17704
+ import { existsSync as existsSync22, readdirSync as readdirSync4, readFileSync as readFileSync11, statSync as statSync7 } from "fs";
17705
+ import * as path38 from "path";
17636
17706
  import { fileURLToPath } from "url";
17637
17707
  // package.json
17638
17708
  var package_default = {
17639
17709
  name: "opencode-swarm",
17640
- version: "7.107.1",
17710
+ version: "7.107.3",
17641
17711
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
17642
17712
  main: "dist/index.js",
17643
17713
  types: "dist/index.d.ts",
@@ -17745,44 +17815,44 @@ var package_default = {
17745
17815
 
17746
17816
  // src/config/cache-paths.ts
17747
17817
  import * as os7 from "os";
17748
- import * as path33 from "path";
17818
+ import * as path34 from "path";
17749
17819
  function getPluginConfigDir() {
17750
- return path33.join(process.env.XDG_CONFIG_HOME || path33.join(os7.homedir(), ".config"), "opencode");
17820
+ return path34.join(process.env.XDG_CONFIG_HOME || path34.join(os7.homedir(), ".config"), "opencode");
17751
17821
  }
17752
17822
  function getPluginCachePaths() {
17753
- const cacheBase = process.env.XDG_CACHE_HOME || path33.join(os7.homedir(), ".cache");
17823
+ const cacheBase = process.env.XDG_CACHE_HOME || path34.join(os7.homedir(), ".cache");
17754
17824
  const configDir = getPluginConfigDir();
17755
17825
  const paths = [
17756
- path33.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
17757
- path33.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
17758
- path33.join(configDir, "node_modules", "opencode-swarm")
17826
+ path34.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
17827
+ path34.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
17828
+ path34.join(configDir, "node_modules", "opencode-swarm")
17759
17829
  ];
17760
17830
  if (process.platform === "darwin") {
17761
- const libCaches = path33.join(os7.homedir(), "Library", "Caches");
17762
- paths.push(path33.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path33.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
17831
+ const libCaches = path34.join(os7.homedir(), "Library", "Caches");
17832
+ paths.push(path34.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path34.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
17763
17833
  }
17764
17834
  if (process.platform === "win32") {
17765
- const localAppData = process.env.LOCALAPPDATA || path33.join(os7.homedir(), "AppData", "Local");
17766
- const appData = process.env.APPDATA || path33.join(os7.homedir(), "AppData", "Roaming");
17767
- paths.push(path33.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path33.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path33.join(appData, "opencode", "node_modules", "opencode-swarm"));
17835
+ const localAppData = process.env.LOCALAPPDATA || path34.join(os7.homedir(), "AppData", "Local");
17836
+ const appData = process.env.APPDATA || path34.join(os7.homedir(), "AppData", "Roaming");
17837
+ paths.push(path34.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path34.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path34.join(appData, "opencode", "node_modules", "opencode-swarm"));
17768
17838
  }
17769
17839
  return paths;
17770
17840
  }
17771
17841
  function getPluginLockFilePaths() {
17772
- const cacheBase = process.env.XDG_CACHE_HOME || path33.join(os7.homedir(), ".cache");
17842
+ const cacheBase = process.env.XDG_CACHE_HOME || path34.join(os7.homedir(), ".cache");
17773
17843
  const configDir = getPluginConfigDir();
17774
17844
  const paths = [
17775
- path33.join(cacheBase, "opencode", "bun.lock"),
17776
- path33.join(cacheBase, "opencode", "bun.lockb"),
17777
- path33.join(configDir, "package-lock.json")
17845
+ path34.join(cacheBase, "opencode", "bun.lock"),
17846
+ path34.join(cacheBase, "opencode", "bun.lockb"),
17847
+ path34.join(configDir, "package-lock.json")
17778
17848
  ];
17779
17849
  if (process.platform === "darwin") {
17780
- const libCaches = path33.join(os7.homedir(), "Library", "Caches");
17781
- paths.push(path33.join(libCaches, "opencode", "bun.lock"), path33.join(libCaches, "opencode", "bun.lockb"));
17850
+ const libCaches = path34.join(os7.homedir(), "Library", "Caches");
17851
+ paths.push(path34.join(libCaches, "opencode", "bun.lock"), path34.join(libCaches, "opencode", "bun.lockb"));
17782
17852
  }
17783
17853
  if (process.platform === "win32") {
17784
- const localAppData = process.env.LOCALAPPDATA || path33.join(os7.homedir(), "AppData", "Local");
17785
- paths.push(path33.join(localAppData, "opencode", "bun.lock"), path33.join(localAppData, "opencode", "bun.lockb"));
17854
+ const localAppData = process.env.LOCALAPPDATA || path34.join(os7.homedir(), "AppData", "Local");
17855
+ paths.push(path34.join(localAppData, "opencode", "bun.lock"), path34.join(localAppData, "opencode", "bun.lockb"));
17786
17856
  }
17787
17857
  return paths;
17788
17858
  }
@@ -17792,11 +17862,11 @@ init_capability_probe();
17792
17862
  init_executor();
17793
17863
 
17794
17864
  // src/services/knowledge-diagnostics.ts
17795
- import { existsSync as existsSync20 } from "fs";
17796
- import { readFile as readFile11 } from "fs/promises";
17865
+ import { existsSync as existsSync21 } from "fs";
17866
+ import { readFile as readFile12 } from "fs/promises";
17797
17867
 
17798
17868
  // src/services/version-check.ts
17799
- import { existsSync as existsSync19, mkdirSync as mkdirSync13, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
17869
+ import { existsSync as existsSync20, mkdirSync as mkdirSync13, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
17800
17870
  import { homedir as homedir6 } from "os";
17801
17871
  import { join as join32 } from "path";
17802
17872
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
@@ -17812,10 +17882,10 @@ function cacheFile() {
17812
17882
  }
17813
17883
  function readVersionCache() {
17814
17884
  try {
17815
- const path37 = cacheFile();
17816
- if (!existsSync19(path37))
17885
+ const path38 = cacheFile();
17886
+ if (!existsSync20(path38))
17817
17887
  return null;
17818
- const raw = readFileSync10(path37, "utf-8");
17888
+ const raw = readFileSync10(path38, "utf-8");
17819
17889
  const parsed = JSON.parse(raw);
17820
17890
  if (typeof parsed?.checkedAt !== "number")
17821
17891
  return null;
@@ -17867,9 +17937,9 @@ var SEVEN_DAYS_MS2 = 7 * 24 * 60 * 60 * 1000;
17867
17937
  var UNACTIONABLE_BACKLOG_WARN = 100;
17868
17938
  var INSIGHT_BACKLOG_WARN = 50;
17869
17939
  async function readRawLines(filePath) {
17870
- if (!existsSync20(filePath))
17940
+ if (!existsSync21(filePath))
17871
17941
  return { entries: [], corrupt: 0 };
17872
- const content = await readFile11(filePath, "utf-8");
17942
+ const content = await readFile12(filePath, "utf-8");
17873
17943
  const entries = [];
17874
17944
  let corrupt = 0;
17875
17945
  for (const line of content.split(`
@@ -17992,10 +18062,10 @@ async function computeKnowledgeDebug(directory) {
17992
18062
  };
17993
18063
  }
17994
18064
  async function safeJsonlCount(filePath) {
17995
- if (!filePath || !existsSync20(filePath))
18065
+ if (!filePath || !existsSync21(filePath))
17996
18066
  return 0;
17997
18067
  try {
17998
- const content = await readFile11(filePath, "utf-8");
18068
+ const content = await readFile12(filePath, "utf-8");
17999
18069
  let n = 0;
18000
18070
  for (const line of content.split(`
18001
18071
  `)) {
@@ -18070,8 +18140,8 @@ var REQUIRED_CACHE_GRAMMAR_ASSETS = [
18070
18140
  "tree-sitter-typescript.wasm"
18071
18141
  ];
18072
18142
  function resolveCachePackageRoot(cachePath) {
18073
- const nestedPackageRoot = path37.join(cachePath, "node_modules", "opencode-swarm");
18074
- return existsSync21(nestedPackageRoot) ? nestedPackageRoot : cachePath;
18143
+ const nestedPackageRoot = path38.join(cachePath, "node_modules", "opencode-swarm");
18144
+ return existsSync22(nestedPackageRoot) ? nestedPackageRoot : cachePath;
18075
18145
  }
18076
18146
  var _internals26 = {
18077
18147
  detectSandboxCapability: () => sandboxCapabilityProbe.detect(),
@@ -18322,7 +18392,7 @@ async function checkConfigBackups(directory) {
18322
18392
  }
18323
18393
  async function checkGitRepository(directory) {
18324
18394
  try {
18325
- if (!existsSync21(directory) || !statSync7(directory).isDirectory()) {
18395
+ if (!existsSync22(directory) || !statSync7(directory).isDirectory()) {
18326
18396
  return {
18327
18397
  name: "Git Repository",
18328
18398
  status: "\u274C",
@@ -18386,8 +18456,8 @@ async function checkSpecStaleness(directory, plan) {
18386
18456
  };
18387
18457
  }
18388
18458
  async function checkConfigParseability(directory) {
18389
- const configPath = path37.join(directory, ".opencode/opencode-swarm.json");
18390
- if (!existsSync21(configPath)) {
18459
+ const configPath = path38.join(directory, ".opencode/opencode-swarm.json");
18460
+ if (!existsSync22(configPath)) {
18391
18461
  return {
18392
18462
  name: "Config Parseability",
18393
18463
  status: "\u2705",
@@ -18415,7 +18485,7 @@ function resolveGrammarDir(thisDir) {
18415
18485
  const normalized = thisDir.replace(/\\/g, "/");
18416
18486
  const isSource = normalized.endsWith("/src/services");
18417
18487
  const isCliBundle = normalized.endsWith("/cli");
18418
- return isSource || isCliBundle ? path37.join(thisDir, "..", "lang", "grammars") : path37.join(thisDir, "lang", "grammars");
18488
+ return isSource || isCliBundle ? path38.join(thisDir, "..", "lang", "grammars") : path38.join(thisDir, "lang", "grammars");
18419
18489
  }
18420
18490
  async function checkGrammarWasmFiles() {
18421
18491
  const grammarFiles = [
@@ -18439,14 +18509,14 @@ async function checkGrammarWasmFiles() {
18439
18509
  "tree-sitter-ini.wasm",
18440
18510
  "tree-sitter-regex.wasm"
18441
18511
  ];
18442
- const thisDir = path37.dirname(fileURLToPath(import.meta.url));
18512
+ const thisDir = path38.dirname(fileURLToPath(import.meta.url));
18443
18513
  const grammarDir = resolveGrammarDir(thisDir);
18444
18514
  const missing = [];
18445
- if (!existsSync21(path37.join(grammarDir, "tree-sitter.wasm"))) {
18515
+ if (!existsSync22(path38.join(grammarDir, "tree-sitter.wasm"))) {
18446
18516
  missing.push("tree-sitter.wasm (core runtime)");
18447
18517
  }
18448
18518
  for (const file of grammarFiles) {
18449
- if (!existsSync21(path37.join(grammarDir, file))) {
18519
+ if (!existsSync22(path38.join(grammarDir, file))) {
18450
18520
  missing.push(file);
18451
18521
  }
18452
18522
  }
@@ -18464,8 +18534,8 @@ async function checkGrammarWasmFiles() {
18464
18534
  };
18465
18535
  }
18466
18536
  async function checkCheckpointManifest(directory) {
18467
- const manifestPath = path37.join(directory, ".swarm/checkpoints.json");
18468
- if (!existsSync21(manifestPath)) {
18537
+ const manifestPath = path38.join(directory, ".swarm/checkpoints.json");
18538
+ if (!existsSync22(manifestPath)) {
18469
18539
  return {
18470
18540
  name: "Checkpoint Manifest",
18471
18541
  status: "\u2705",
@@ -18516,8 +18586,8 @@ async function checkCheckpointManifest(directory) {
18516
18586
  }
18517
18587
  }
18518
18588
  async function checkEventStreamIntegrity(directory) {
18519
- const eventsPath = path37.join(directory, ".swarm/events.jsonl");
18520
- if (!existsSync21(eventsPath)) {
18589
+ const eventsPath = path38.join(directory, ".swarm/events.jsonl");
18590
+ if (!existsSync22(eventsPath)) {
18521
18591
  return {
18522
18592
  name: "Event Stream",
18523
18593
  status: "\u2705",
@@ -18557,8 +18627,8 @@ async function checkEventStreamIntegrity(directory) {
18557
18627
  }
18558
18628
  }
18559
18629
  async function checkSteeringDirectives(directory) {
18560
- const eventsPath = path37.join(directory, ".swarm/events.jsonl");
18561
- if (!existsSync21(eventsPath)) {
18630
+ const eventsPath = path38.join(directory, ".swarm/events.jsonl");
18631
+ if (!existsSync22(eventsPath)) {
18562
18632
  return {
18563
18633
  name: "Steering Directives",
18564
18634
  status: "\u2705",
@@ -18613,8 +18683,8 @@ async function checkCurator(directory) {
18613
18683
  detail: "Disabled (enable via curator.enabled)"
18614
18684
  };
18615
18685
  }
18616
- const summaryPath = path37.join(directory, ".swarm/curator-summary.json");
18617
- if (!existsSync21(summaryPath)) {
18686
+ const summaryPath = path38.join(directory, ".swarm/curator-summary.json");
18687
+ if (!existsSync22(summaryPath)) {
18618
18688
  return {
18619
18689
  name: "Curator",
18620
18690
  status: "\u2705",
@@ -18815,8 +18885,8 @@ async function getDiagnoseData(directory) {
18815
18885
  checks.push(await checkCurator(directory));
18816
18886
  checks.push(await checkKnowledgeHealth(directory));
18817
18887
  try {
18818
- const evidenceDir = path37.join(directory, ".swarm", "evidence");
18819
- const snapshotFiles = existsSync21(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
18888
+ const evidenceDir = path38.join(directory, ".swarm", "evidence");
18889
+ const snapshotFiles = existsSync22(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
18820
18890
  if (snapshotFiles.length > 0) {
18821
18891
  const latest = snapshotFiles.sort().pop();
18822
18892
  checks.push({
@@ -18849,14 +18919,14 @@ async function getDiagnoseData(directory) {
18849
18919
  const cacheRows = [];
18850
18920
  for (const cachePath of cachePaths) {
18851
18921
  try {
18852
- if (!existsSync21(cachePath)) {
18922
+ if (!existsSync22(cachePath)) {
18853
18923
  cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
18854
18924
  continue;
18855
18925
  }
18856
18926
  const packageRoot = resolveCachePackageRoot(cachePath);
18857
18927
  const cacheLabel = packageRoot === cachePath ? cachePath : `${cachePath} -> ${packageRoot}`;
18858
- const missingGrammarAssets = REQUIRED_CACHE_GRAMMAR_ASSETS.filter((file) => !existsSync21(path37.join(packageRoot, "dist", "lang", "grammars", file)));
18859
- const pkgJsonPath = path37.join(packageRoot, "package.json");
18928
+ const missingGrammarAssets = REQUIRED_CACHE_GRAMMAR_ASSETS.filter((file) => !existsSync22(path38.join(packageRoot, "dist", "lang", "grammars", file)));
18929
+ const pkgJsonPath = path38.join(packageRoot, "package.json");
18860
18930
  try {
18861
18931
  const raw = readFileSync11(pkgJsonPath, "utf-8");
18862
18932
  const parsed = JSON.parse(raw);
@@ -19231,10 +19301,10 @@ function decideEpicActivation(tasks, cochangePairs, commitsObserved, options) {
19231
19301
 
19232
19302
  // src/turbo/epic/calibration.ts
19233
19303
  init_logger();
19234
- import * as fs14 from "fs";
19235
- import * as path38 from "path";
19304
+ import * as fs13 from "fs";
19305
+ import * as path39 from "path";
19236
19306
  var STATE_FILE = "calibration.json";
19237
- var STATE_REL_DIR = path38.join(".swarm", "epic");
19307
+ var STATE_REL_DIR = path39.join(".swarm", "epic");
19238
19308
  function nowISO() {
19239
19309
  return new Date().toISOString();
19240
19310
  }
@@ -19256,13 +19326,13 @@ function markUnreadable(directory, reason) {
19256
19326
  error(`[epic/calibration] state file unreadable for ${directory}: ${reason} \u2014 failing closed`);
19257
19327
  }
19258
19328
  function repairCalibrationUnreadable(directory) {
19259
- const filePath = path38.join(directory, STATE_REL_DIR, STATE_FILE);
19260
- if (!fs14.existsSync(filePath)) {
19329
+ const filePath = path39.join(directory, STATE_REL_DIR, STATE_FILE);
19330
+ if (!fs13.existsSync(filePath)) {
19261
19331
  stateUnreadableMap.delete(directory);
19262
19332
  return;
19263
19333
  }
19264
19334
  try {
19265
- const raw = fs14.readFileSync(filePath, "utf-8");
19335
+ const raw = fs13.readFileSync(filePath, "utf-8");
19266
19336
  const parsed = JSON.parse(raw);
19267
19337
  if (!isValidCalibrationShape(parsed)) {
19268
19338
  stateUnreadableMap.set(directory, true);
@@ -19288,9 +19358,9 @@ function isValidCalibrationShape(candidate) {
19288
19358
  return true;
19289
19359
  }
19290
19360
  function ensureSwarmEpicDir(directory) {
19291
- const dir = path38.resolve(directory, STATE_REL_DIR);
19292
- if (!fs14.existsSync(dir)) {
19293
- fs14.mkdirSync(dir, { recursive: true });
19361
+ const dir = path39.resolve(directory, STATE_REL_DIR);
19362
+ if (!fs13.existsSync(dir)) {
19363
+ fs13.mkdirSync(dir, { recursive: true });
19294
19364
  }
19295
19365
  return dir;
19296
19366
  }
@@ -19300,18 +19370,18 @@ function loadCalibrationState(directory) {
19300
19370
  if (stateUnreadableMap.get(directory))
19301
19371
  return null;
19302
19372
  }
19303
- const filePath = path38.join(directory, STATE_REL_DIR, STATE_FILE);
19373
+ const filePath = path39.join(directory, STATE_REL_DIR, STATE_FILE);
19304
19374
  try {
19305
- if (!fs14.existsSync(filePath)) {
19375
+ if (!fs13.existsSync(filePath)) {
19306
19376
  const seed = emptyCalibrationState();
19307
19377
  try {
19308
19378
  ensureSwarmEpicDir(directory);
19309
- fs14.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
19379
+ fs13.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
19310
19380
  `, "utf-8");
19311
19381
  } catch {}
19312
19382
  return seed;
19313
19383
  }
19314
- const raw = fs14.readFileSync(filePath, "utf-8");
19384
+ const raw = fs13.readFileSync(filePath, "utf-8");
19315
19385
  const parsed = JSON.parse(raw);
19316
19386
  if (!isValidCalibrationShape(parsed)) {
19317
19387
  markUnreadable(directory, `malformed shape (version=${parsed?.version}, hotModuleAdditions type=${Array.isArray(parsed?.hotModuleAdditions) ? "array" : typeof parsed?.hotModuleAdditions})`);
@@ -19326,36 +19396,36 @@ function loadCalibrationState(directory) {
19326
19396
 
19327
19397
  // src/turbo/epic/divergence-recorder.ts
19328
19398
  init_logger();
19329
- import * as fs15 from "fs";
19330
- import * as path39 from "path";
19331
- var EVIDENCE_REL_DIR = path39.join(".swarm", "epic");
19399
+ import * as fs14 from "fs";
19400
+ import * as path40 from "path";
19401
+ var EVIDENCE_REL_DIR = path40.join(".swarm", "epic");
19332
19402
  var EVIDENCE_FILE = "divergence.jsonl";
19333
19403
  var MAX_TAIL_BYTES2 = 16 * 1024 * 1024;
19334
19404
  function readDivergenceHistory(directory, options) {
19335
- const filePath = path39.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
19336
- if (!fs15.existsSync(filePath)) {
19405
+ const filePath = path40.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
19406
+ if (!fs14.existsSync(filePath)) {
19337
19407
  return [];
19338
19408
  }
19339
19409
  const maxBytes = options?.maxBytes ?? MAX_TAIL_BYTES2;
19340
19410
  let raw;
19341
19411
  let tailTruncated = false;
19342
19412
  try {
19343
- const stat5 = fs15.statSync(filePath);
19413
+ const stat5 = fs14.statSync(filePath);
19344
19414
  if (Number.isFinite(maxBytes) && stat5.size > maxBytes) {
19345
- const fd = fs15.openSync(filePath, "r");
19415
+ const fd = fs14.openSync(filePath, "r");
19346
19416
  try {
19347
19417
  const buf = Buffer.alloc(maxBytes);
19348
19418
  const offset = stat5.size - maxBytes;
19349
- fs15.readSync(fd, buf, 0, maxBytes, offset);
19419
+ fs14.readSync(fd, buf, 0, maxBytes, offset);
19350
19420
  raw = buf.toString("utf-8");
19351
19421
  tailTruncated = true;
19352
19422
  } finally {
19353
19423
  try {
19354
- fs15.closeSync(fd);
19424
+ fs14.closeSync(fd);
19355
19425
  } catch {}
19356
19426
  }
19357
19427
  } else {
19358
- raw = fs15.readFileSync(filePath, "utf-8");
19428
+ raw = fs14.readFileSync(filePath, "utf-8");
19359
19429
  }
19360
19430
  } catch {
19361
19431
  return [];
@@ -19380,16 +19450,16 @@ function readDivergenceHistory(directory, options) {
19380
19450
  }
19381
19451
 
19382
19452
  // src/turbo/epic/promotion-evidence.ts
19383
- import * as fs16 from "fs";
19384
- import * as path40 from "path";
19385
- var EVIDENCE_REL_DIR2 = path40.join(".swarm", "evidence");
19453
+ import * as fs15 from "fs";
19454
+ import * as path41 from "path";
19455
+ var EVIDENCE_REL_DIR2 = path41.join(".swarm", "evidence");
19386
19456
  var EVIDENCE_FILE2 = "epic-promotions.jsonl";
19387
19457
  function readPromotionEvidence(directory) {
19388
- const filePath = path40.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
19389
- if (!fs16.existsSync(filePath)) {
19458
+ const filePath = path41.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
19459
+ if (!fs15.existsSync(filePath)) {
19390
19460
  return [];
19391
19461
  }
19392
- const raw = fs16.readFileSync(filePath, "utf-8");
19462
+ const raw = fs15.readFileSync(filePath, "utf-8");
19393
19463
  const lines = raw.split(`
19394
19464
  `).filter((l) => l.trim().length > 0);
19395
19465
  const records = [];
@@ -19894,7 +19964,7 @@ async function handleEvidenceCommand(directory, args) {
19894
19964
  return formatTaskEvidenceMarkdown(evidenceData);
19895
19965
  }
19896
19966
  async function handleEvidenceSummaryCommand(directory) {
19897
- const { buildEvidenceSummary } = await import("./evidence-summary-service-dh44gevz.js");
19967
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-9r28ds8t.js");
19898
19968
  const artifact = await buildEvidenceSummary(directory);
19899
19969
  if (!artifact) {
19900
19970
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -19958,8 +20028,8 @@ async function handleExportCommand(directory, _args) {
19958
20028
  }
19959
20029
  // src/full-auto/state.ts
19960
20030
  var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
19961
- import * as fs17 from "fs";
19962
- import * as path41 from "path";
20031
+ import * as fs16 from "fs";
20032
+ import * as path42 from "path";
19963
20033
  init_logger();
19964
20034
  var lockfile4 = import_proper_lockfile4.default;
19965
20035
  var STATE_FILE2 = "full-auto-state.json";
@@ -19967,9 +20037,9 @@ function nowISO2() {
19967
20037
  return new Date().toISOString();
19968
20038
  }
19969
20039
  function ensureSwarmDir(directory) {
19970
- const swarmDir = path41.resolve(directory, ".swarm");
19971
- if (!fs17.existsSync(swarmDir)) {
19972
- fs17.mkdirSync(swarmDir, { recursive: true });
20040
+ const swarmDir = path42.resolve(directory, ".swarm");
20041
+ if (!fs16.existsSync(swarmDir)) {
20042
+ fs16.mkdirSync(swarmDir, { recursive: true });
19973
20043
  }
19974
20044
  return swarmDir;
19975
20045
  }
@@ -20027,7 +20097,7 @@ function withStateLock(directory, fn) {
20027
20097
  let release;
20028
20098
  try {
20029
20099
  const lockTarget = validateSwarmPath(directory, STATE_FILE2);
20030
- if (!fs17.existsSync(lockTarget)) {
20100
+ if (!fs16.existsSync(lockTarget)) {
20031
20101
  ensureSwarmDir(directory);
20032
20102
  const seed = {
20033
20103
  version: 2,
@@ -20035,7 +20105,7 @@ function withStateLock(directory, fn) {
20035
20105
  oversightSequence: 0,
20036
20106
  sessions: {}
20037
20107
  };
20038
- fs17.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
20108
+ fs16.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
20039
20109
  `, "utf-8");
20040
20110
  }
20041
20111
  release = lockfile4.lockSync(lockTarget, {
@@ -20085,7 +20155,7 @@ function readPersisted(directory) {
20085
20155
  const filePath = validateSwarmPath(directory, STATE_FILE2);
20086
20156
  let stats;
20087
20157
  try {
20088
- stats = fs17.statSync(filePath);
20158
+ stats = fs16.statSync(filePath);
20089
20159
  } catch {
20090
20160
  clearStateUnreadable();
20091
20161
  readCache.delete(filePath);
@@ -20096,7 +20166,7 @@ function readPersisted(directory) {
20096
20166
  clearStateUnreadable();
20097
20167
  return structuredClone(cached.state);
20098
20168
  }
20099
- const raw = fs17.readFileSync(filePath, "utf-8");
20169
+ const raw = fs16.readFileSync(filePath, "utf-8");
20100
20170
  const parsed = JSON.parse(raw);
20101
20171
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 2 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
20102
20172
  markStateUnreadable(`malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -20121,8 +20191,8 @@ function readPersisted(directory) {
20121
20191
  error(`[full-auto/state] Failed to read ${STATE_FILE2}: ${reason} \u2014 attempting .bak recovery`);
20122
20192
  try {
20123
20193
  const bakPath = validateSwarmPath(directory, `${STATE_FILE2}.bak`);
20124
- if (fs17.existsSync(bakPath)) {
20125
- const raw = fs17.readFileSync(bakPath, "utf-8");
20194
+ if (fs16.existsSync(bakPath)) {
20195
+ const raw = fs16.readFileSync(bakPath, "utf-8");
20126
20196
  const parsed = JSON.parse(raw);
20127
20197
  if (parsed?.version === 2 && parsed.sessions && !Array.isArray(parsed.sessions)) {
20128
20198
  warn(`[full-auto/state] Recovered from ${STATE_FILE2}.bak`);
@@ -20162,23 +20232,23 @@ function writePersisted(directory, persisted) {
20162
20232
  throw new Error(`Full-Auto state persistence prepare failed: ${msg}`);
20163
20233
  }
20164
20234
  try {
20165
- if (fs17.existsSync(filePath)) {
20166
- fs17.copyFileSync(filePath, bakPath);
20235
+ if (fs16.existsSync(filePath)) {
20236
+ fs16.copyFileSync(filePath, bakPath);
20167
20237
  }
20168
20238
  } catch {}
20169
20239
  try {
20170
- fs17.writeFileSync(tmpPath, payload, "utf-8");
20240
+ fs16.writeFileSync(tmpPath, payload, "utf-8");
20171
20241
  try {
20172
- const fd = fs17.openSync(tmpPath, "r+");
20242
+ const fd = fs16.openSync(tmpPath, "r+");
20173
20243
  try {
20174
- fs17.fsyncSync(fd);
20244
+ fs16.fsyncSync(fd);
20175
20245
  } finally {
20176
- fs17.closeSync(fd);
20246
+ fs16.closeSync(fd);
20177
20247
  }
20178
20248
  } catch {}
20179
- fs17.renameSync(tmpPath, filePath);
20249
+ fs16.renameSync(tmpPath, filePath);
20180
20250
  readCache.delete(filePath);
20181
- const readback = fs17.readFileSync(filePath, "utf-8");
20251
+ const readback = fs16.readFileSync(filePath, "utf-8");
20182
20252
  const parsed = JSON.parse(readback);
20183
20253
  if (parsed?.version !== 2) {
20184
20254
  throw new Error("Round-trip readback returned wrong version");
@@ -20779,7 +20849,7 @@ var _internals29 = {
20779
20849
 
20780
20850
  // src/session/snapshot-writer.ts
20781
20851
  import { closeSync as closeSync6, fsyncSync as fsyncSync2, mkdirSync as mkdirSync18, openSync as openSync6, renameSync as renameSync9 } from "fs";
20782
- import * as path42 from "path";
20852
+ import * as path43 from "path";
20783
20853
  var _writeInFlight = Promise.resolve();
20784
20854
  function serializeAgentSession(s) {
20785
20855
  const gateLog = {};
@@ -20832,6 +20902,12 @@ function serializeAgentSession(s) {
20832
20902
  lastCoderDelegationTaskId: s.lastCoderDelegationTaskId ?? null,
20833
20903
  currentTaskId: s.currentTaskId ?? null,
20834
20904
  turboMode: s.turboMode ?? false,
20905
+ ...s.turboStrategy !== undefined && { turboStrategy: s.turboStrategy },
20906
+ leanTurboActive: s.leanTurboActive ?? false,
20907
+ ...s.leanTurboCurrentPhase !== undefined && {
20908
+ leanTurboCurrentPhase: s.leanTurboCurrentPhase
20909
+ },
20910
+ epicModeActive: s.epicModeActive ?? false,
20835
20911
  gateLog,
20836
20912
  reviewerCallCount,
20837
20913
  lastGateFailure: s.lastGateFailure ?? null,
@@ -20886,7 +20962,7 @@ async function writeSnapshot(directory, state) {
20886
20962
  }
20887
20963
  const content = JSON.stringify(snapshot, null, 2);
20888
20964
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
20889
- const dir = path42.dirname(resolvedPath);
20965
+ const dir = path43.dirname(resolvedPath);
20890
20966
  mkdirSync18(dir, { recursive: true });
20891
20967
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
20892
20968
  await bunWrite(tempPath, content);
@@ -20922,13 +20998,21 @@ var _internals30 = {
20922
20998
  };
20923
20999
 
20924
21000
  // src/commands/handoff.ts
20925
- async function handleHandoffCommand(directory, _args) {
21001
+ var HANDOFF_SOURCE_SESSION_PREFIX = "<!-- opencode-swarm-handoff-source-session:";
21002
+ function formatSessionScopedHandoffMarkdown(markdown, sessionID) {
21003
+ if (!sessionID) {
21004
+ return markdown;
21005
+ }
21006
+ return `${HANDOFF_SOURCE_SESSION_PREFIX} ${encodeURIComponent(sessionID)} -->
21007
+ ${markdown}`;
21008
+ }
21009
+ async function handleHandoffCommand(directory, _args, sessionID) {
20926
21010
  const handoffData = await getHandoffData(directory);
20927
21011
  const markdown = formatHandoffMarkdown(handoffData);
20928
21012
  try {
20929
21013
  const resolvedPath = validateSwarmPath(directory, "handoff.md");
20930
21014
  const tempPath = `${resolvedPath}.tmp.${crypto4.randomUUID()}`;
20931
- await bunWrite(tempPath, markdown);
21015
+ await bunWrite(tempPath, formatSessionScopedHandoffMarkdown(markdown, sessionID));
20932
21016
  try {
20933
21017
  renameSync10(tempPath, resolvedPath);
20934
21018
  } catch (renameErr) {
@@ -21389,23 +21473,23 @@ ${USAGE6}`;
21389
21473
  }
21390
21474
 
21391
21475
  // src/commands/knowledge.ts
21392
- import { join as join37 } from "path";
21476
+ import { join as join38 } from "path";
21393
21477
 
21394
21478
  // src/hooks/knowledge-migrator.ts
21395
21479
  init_logger();
21396
- import { randomUUID as randomUUID7 } from "crypto";
21397
- import { existsSync as existsSync26, readFileSync as readFileSync16 } from "fs";
21398
- import { mkdir as mkdir10, readFile as readFile12, writeFile as writeFile11 } from "fs/promises";
21480
+ import { randomUUID as randomUUID8 } from "crypto";
21481
+ import { existsSync as existsSync27, readFileSync as readFileSync16 } from "fs";
21482
+ import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile12 } from "fs/promises";
21399
21483
  import * as os11 from "os";
21400
- import * as path43 from "path";
21484
+ import * as path44 from "path";
21401
21485
 
21402
21486
  // src/hooks/knowledge-types.ts
21403
21487
  var KNOWLEDGE_SCHEMA_VERSION = 2;
21404
21488
 
21405
21489
  // src/hooks/knowledge-migrator.ts
21406
21490
  async function migrateKnowledgeToExternal(_directory, _config) {
21407
- const externalSentinelPath = path43.join(_directory, ".swarm", ".knowledge-external-migrated");
21408
- const contextPath = path43.join(_directory, ".swarm", "context.md");
21491
+ const externalSentinelPath = path44.join(_directory, ".swarm", ".knowledge-external-migrated");
21492
+ const contextPath = path44.join(_directory, ".swarm", "context.md");
21409
21493
  if (_internals32.existsSync(externalSentinelPath)) {
21410
21494
  return {
21411
21495
  migrated: false,
@@ -21463,17 +21547,17 @@ var _internals32 = {
21463
21547
  inferProjectName,
21464
21548
  writeSentinel,
21465
21549
  resolveLegacyHiveKnowledgePath,
21466
- existsSync: existsSync26,
21550
+ existsSync: existsSync27,
21467
21551
  readFileSync: readFileSync16,
21468
- readFile: readFile12,
21552
+ readFile: readFile13,
21469
21553
  mkdir: mkdir10,
21470
- writeFile: writeFile11
21554
+ writeFile: writeFile12
21471
21555
  };
21472
21556
  async function migrateContextToKnowledge(directory, config) {
21473
- const sentinelPath = path43.join(directory, ".swarm", ".knowledge-migrated");
21474
- const contextPath = path43.join(directory, ".swarm", "context.md");
21557
+ const sentinelPath = path44.join(directory, ".swarm", ".knowledge-migrated");
21558
+ const contextPath = path44.join(directory, ".swarm", "context.md");
21475
21559
  const knowledgePath = resolveSwarmKnowledgePath(directory);
21476
- if (existsSync26(sentinelPath)) {
21560
+ if (existsSync27(sentinelPath)) {
21477
21561
  return {
21478
21562
  migrated: false,
21479
21563
  entriesMigrated: 0,
@@ -21482,7 +21566,7 @@ async function migrateContextToKnowledge(directory, config) {
21482
21566
  skippedReason: "sentinel-exists"
21483
21567
  };
21484
21568
  }
21485
- if (!existsSync26(contextPath)) {
21569
+ if (!existsSync27(contextPath)) {
21486
21570
  return {
21487
21571
  migrated: false,
21488
21572
  entriesMigrated: 0,
@@ -21491,7 +21575,7 @@ async function migrateContextToKnowledge(directory, config) {
21491
21575
  skippedReason: "no-context-file"
21492
21576
  };
21493
21577
  }
21494
- const contextContent = await readFile12(contextPath, "utf-8");
21578
+ const contextContent = await readFile13(contextPath, "utf-8");
21495
21579
  if (contextContent.trim().length === 0) {
21496
21580
  return {
21497
21581
  migrated: false,
@@ -21535,7 +21619,7 @@ async function migrateContextToKnowledge(directory, config) {
21535
21619
  }
21536
21620
  const inferredTags = inferTags(raw.text);
21537
21621
  const entry = {
21538
- id: randomUUID7(),
21622
+ id: randomUUID8(),
21539
21623
  tier: "swarm",
21540
21624
  lesson: _internals32.truncateLesson(raw.text),
21541
21625
  category: raw.categoryHint ?? _internals32.inferCategoryFromText(raw.text),
@@ -21573,8 +21657,8 @@ async function migrateContextToKnowledge(directory, config) {
21573
21657
  async function migrateHiveKnowledgeLegacy(config) {
21574
21658
  const legacyHivePath = _internals32.resolveLegacyHiveKnowledgePath();
21575
21659
  const canonicalHivePath = resolveHiveKnowledgePath();
21576
- const sentinelPath = path43.join(path43.dirname(canonicalHivePath), ".hive-knowledge-migrated");
21577
- if (existsSync26(sentinelPath)) {
21660
+ const sentinelPath = path44.join(path44.dirname(canonicalHivePath), ".hive-knowledge-migrated");
21661
+ if (existsSync27(sentinelPath)) {
21578
21662
  return {
21579
21663
  migrated: false,
21580
21664
  entriesMigrated: 0,
@@ -21583,7 +21667,7 @@ async function migrateHiveKnowledgeLegacy(config) {
21583
21667
  skippedReason: "sentinel-exists"
21584
21668
  };
21585
21669
  }
21586
- if (!existsSync26(legacyHivePath)) {
21670
+ if (!existsSync27(legacyHivePath)) {
21587
21671
  return {
21588
21672
  migrated: false,
21589
21673
  entriesMigrated: 0,
@@ -21635,7 +21719,7 @@ async function migrateHiveKnowledgeLegacy(config) {
21635
21719
  const scopeTag = legacyEntry.scope_tag || "global";
21636
21720
  const legacyId = legacyEntry.id;
21637
21721
  const existingIds = new Set(existingHiveEntries.map((e) => e.id));
21638
- const resolvedId = legacyId && existingIds.has(legacyId) ? randomUUID7() : legacyId || randomUUID7();
21722
+ const resolvedId = legacyId && existingIds.has(legacyId) ? randomUUID8() : legacyId || randomUUID8();
21639
21723
  if (legacyId && existingIds.has(legacyId)) {
21640
21724
  warn(`[knowledge-migrator] Legacy entry ID collision for "${legacyId}", generating new UUID`);
21641
21725
  }
@@ -21784,8 +21868,8 @@ function truncateLesson2(text) {
21784
21868
  return `${text.slice(0, 277)}...`;
21785
21869
  }
21786
21870
  function inferProjectName(directory) {
21787
- const packageJsonPath = path43.join(directory, "package.json");
21788
- if (existsSync26(packageJsonPath)) {
21871
+ const packageJsonPath = path44.join(directory, "package.json");
21872
+ if (existsSync27(packageJsonPath)) {
21789
21873
  try {
21790
21874
  const pkg = JSON.parse(readFileSync16(packageJsonPath, "utf-8"));
21791
21875
  if (pkg.name && typeof pkg.name === "string") {
@@ -21793,7 +21877,7 @@ function inferProjectName(directory) {
21793
21877
  }
21794
21878
  } catch {}
21795
21879
  }
21796
- return path43.basename(directory);
21880
+ return path44.basename(directory);
21797
21881
  }
21798
21882
  async function writeSentinel(sentinelPath, migrated, dropped) {
21799
21883
  const sentinel = {
@@ -21805,7 +21889,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
21805
21889
  schema_version: 1,
21806
21890
  migration_tool: "knowledge-migrator.ts"
21807
21891
  };
21808
- await _internals32.mkdir(path43.dirname(sentinelPath), { recursive: true });
21892
+ await _internals32.mkdir(path44.dirname(sentinelPath), { recursive: true });
21809
21893
  await _internals32.writeFile(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
21810
21894
  }
21811
21895
  function resolveLegacyHiveKnowledgePath() {
@@ -21813,13 +21897,13 @@ function resolveLegacyHiveKnowledgePath() {
21813
21897
  const home = process.env.HOME || os11.homedir();
21814
21898
  let dataDir;
21815
21899
  if (platform === "win32") {
21816
- dataDir = path43.join(process.env.LOCALAPPDATA || path43.join(home, "AppData", "Local"), "opencode-swarm", "Data");
21900
+ dataDir = path44.join(process.env.LOCALAPPDATA || path44.join(home, "AppData", "Local"), "opencode-swarm", "Data");
21817
21901
  } else if (platform === "darwin") {
21818
- dataDir = path43.join(home, "Library", "Application Support", "opencode-swarm");
21902
+ dataDir = path44.join(home, "Library", "Application Support", "opencode-swarm");
21819
21903
  } else {
21820
- dataDir = path43.join(process.env.XDG_DATA_HOME || path43.join(home, ".local", "share"), "opencode-swarm");
21904
+ dataDir = path44.join(process.env.XDG_DATA_HOME || path44.join(home, ".local", "share"), "opencode-swarm");
21821
21905
  }
21822
- return path43.join(dataDir, "hive-knowledge.jsonl");
21906
+ return path44.join(dataDir, "hive-knowledge.jsonl");
21823
21907
  }
21824
21908
 
21825
21909
  // src/commands/knowledge.ts
@@ -21873,7 +21957,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
21873
21957
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
21874
21958
  }
21875
21959
  try {
21876
- const quarantinePath = join37(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
21960
+ const quarantinePath = join38(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
21877
21961
  const entries = await readKnowledge(quarantinePath);
21878
21962
  const resolved = resolveEntryByPrefix(entries, inputId);
21879
21963
  if ("error" in resolved) {
@@ -22124,15 +22208,15 @@ var _internals33 = {
22124
22208
  };
22125
22209
 
22126
22210
  // src/commands/link.ts
22127
- import { existsSync as existsSync27 } from "fs";
22128
- import * as path45 from "path";
22211
+ import { existsSync as existsSync28 } from "fs";
22212
+ import * as path46 from "path";
22129
22213
 
22130
22214
  // src/knowledge/identity.ts
22131
22215
  import * as child_process5 from "child_process";
22132
22216
  import { createHash as createHash5 } from "crypto";
22133
- import * as path44 from "path";
22217
+ import * as path45 from "path";
22134
22218
  function deriveProjectHash(directory) {
22135
- const absolutePath = path44.resolve(directory);
22219
+ const absolutePath = path45.resolve(directory);
22136
22220
  let hashInput;
22137
22221
  try {
22138
22222
  const remoteUrl = child_process5.execSync("git remote get-url origin", {
@@ -22152,9 +22236,9 @@ function deriveProjectHash(directory) {
22152
22236
  // src/commands/link.ts
22153
22237
  var DEDUP_THRESHOLD = 0.6;
22154
22238
  async function mergeLocalKnowledgeIntoLink(localSwarmDir, linkDir) {
22155
- const localPath = path45.join(localSwarmDir, "knowledge.jsonl");
22156
- const sharedPath = path45.join(linkDir, "knowledge.jsonl");
22157
- if (!existsSync27(localPath))
22239
+ const localPath = path46.join(localSwarmDir, "knowledge.jsonl");
22240
+ const sharedPath = path46.join(linkDir, "knowledge.jsonl");
22241
+ if (!existsSync28(localPath))
22158
22242
  return { merged: 0, skipped: 0 };
22159
22243
  let merged = 0;
22160
22244
  let skipped = 0;
@@ -22251,7 +22335,7 @@ ${formatStatus(directory)}`;
22251
22335
  const linkDir = resolveLinkDir(linkId);
22252
22336
  let merge;
22253
22337
  try {
22254
- merge = await mergeLocalKnowledgeIntoLink(path45.join(directory, ".swarm"), linkDir);
22338
+ merge = await mergeLocalKnowledgeIntoLink(path46.join(directory, ".swarm"), linkDir);
22255
22339
  } catch (error2) {
22256
22340
  return `\u274C Failed to merge local knowledge into the link store: ${error2 instanceof Error ? error2.message : String(error2)}`;
22257
22341
  }
@@ -22447,13 +22531,13 @@ ${USAGE7}`;
22447
22531
  }
22448
22532
 
22449
22533
  // src/commands/memory.ts
22450
- import { existsSync as existsSync28 } from "fs";
22451
- import * as path48 from "path";
22534
+ import { existsSync as existsSync29 } from "fs";
22535
+ import * as path49 from "path";
22452
22536
  import { fileURLToPath as fileURLToPath2 } from "url";
22453
22537
  // src/memory/evaluation.ts
22454
- import * as fs18 from "fs/promises";
22538
+ import * as fs17 from "fs/promises";
22455
22539
  import * as os12 from "os";
22456
- import * as path46 from "path";
22540
+ import * as path47 from "path";
22457
22541
  var DEFAULT_PROVIDERS = [
22458
22542
  "local-jsonl",
22459
22543
  "sqlite"
@@ -22465,7 +22549,7 @@ var DEFAULT_MODES = [
22465
22549
  ];
22466
22550
  var DEFAULT_TIMESTAMP = "2026-05-26T12:00:00.000Z";
22467
22551
  async function evaluateMemoryRecallFixtures(options) {
22468
- const fixtureDirectory = path46.resolve(options.fixtureDirectory);
22552
+ const fixtureDirectory = path47.resolve(options.fixtureDirectory);
22469
22553
  const providers = options.providers ?? DEFAULT_PROVIDERS;
22470
22554
  const modes = options.modes ?? DEFAULT_MODES;
22471
22555
  const generatedAt = new Date().toISOString();
@@ -22474,7 +22558,7 @@ async function evaluateMemoryRecallFixtures(options) {
22474
22558
  for (const fixture of fixtures) {
22475
22559
  const materialized = materializeFixture(fixture);
22476
22560
  for (const providerName of providers) {
22477
- const tempRoot = await fs18.realpath(await fs18.mkdtemp(path46.join(os12.tmpdir(), "swarm-memory-eval-")));
22561
+ const tempRoot = await fs17.realpath(await fs17.mkdtemp(path47.join(os12.tmpdir(), "swarm-memory-eval-")));
22478
22562
  const provider = createEvaluationProvider(providerName, tempRoot);
22479
22563
  try {
22480
22564
  await provider.initialize?.();
@@ -22517,7 +22601,7 @@ async function evaluateMemoryRecallFixtures(options) {
22517
22601
  async function rmTempRoot(tempRoot) {
22518
22602
  for (let attempt = 0;attempt < 10; attempt++) {
22519
22603
  try {
22520
- await fs18.rm(tempRoot, { recursive: true, force: true });
22604
+ await fs17.rm(tempRoot, { recursive: true, force: true });
22521
22605
  return;
22522
22606
  } catch (err) {
22523
22607
  if (attempt === 9)
@@ -22527,11 +22611,11 @@ async function rmTempRoot(tempRoot) {
22527
22611
  }
22528
22612
  }
22529
22613
  async function loadRecallEvaluationFixtures(fixtureDirectory) {
22530
- const entries = await fs18.readdir(fixtureDirectory, { withFileTypes: true });
22614
+ const entries = await fs17.readdir(fixtureDirectory, { withFileTypes: true });
22531
22615
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
22532
22616
  const fixtures = [];
22533
22617
  for (const file of files) {
22534
- const raw = await fs18.readFile(path46.join(fixtureDirectory, file), "utf-8");
22618
+ const raw = await fs17.readFile(path47.join(fixtureDirectory, file), "utf-8");
22535
22619
  fixtures.push(validateFixture(JSON.parse(raw), file));
22536
22620
  }
22537
22621
  return fixtures;
@@ -22807,14 +22891,14 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
22807
22891
  curatorMemoryDecisions: exports_external.array(CuratorMemoryDecisionSchema).max(20).optional()
22808
22892
  }).passthrough();
22809
22893
  // src/memory/consolidation-log.ts
22810
- import { appendFile as appendFile3, mkdir as mkdir11, readFile as readFile14 } from "fs/promises";
22811
- import * as path47 from "path";
22812
- var LOG_RELATIVE_PATH = path47.join("memory", "consolidation-log.jsonl");
22894
+ import { appendFile as appendFile3, mkdir as mkdir11, readFile as readFile15 } from "fs/promises";
22895
+ import * as path48 from "path";
22896
+ var LOG_RELATIVE_PATH = path48.join("memory", "consolidation-log.jsonl");
22813
22897
  async function readConsolidationLog(directory) {
22814
22898
  const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
22815
22899
  let raw;
22816
22900
  try {
22817
- raw = await readFile14(filePath, "utf-8");
22901
+ raw = await readFile15(filePath, "utf-8");
22818
22902
  } catch {
22819
22903
  return [];
22820
22904
  }
@@ -22832,7 +22916,7 @@ async function readConsolidationLog(directory) {
22832
22916
  }
22833
22917
 
22834
22918
  // src/commands/memory.ts
22835
- var PACKAGE_ROOT = path48.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
22919
+ var PACKAGE_ROOT = path49.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
22836
22920
  async function handleMemoryCommand(_directory, _args) {
22837
22921
  return [
22838
22922
  "## Swarm Memory",
@@ -22891,7 +22975,7 @@ async function handleMemoryStatusCommand(directory, _args) {
22891
22975
  `- Provider: \`${config.provider}\``,
22892
22976
  `- Storage: \`${storageDir}\``,
22893
22977
  `- SQLite path: \`${sqlitePath}\``,
22894
- `- SQLite database exists: \`${existsSync28(sqlitePath)}\``,
22978
+ `- SQLite database exists: \`${existsSync29(sqlitePath)}\``,
22895
22979
  `- Automatic destructive cleanup: \`disabled\``,
22896
22980
  "",
22897
22981
  "### Legacy JSONL"
@@ -23189,7 +23273,7 @@ function resolveCommandMemoryConfig(directory) {
23189
23273
  }
23190
23274
  function parseEvaluateArgs(directory, args) {
23191
23275
  let json = false;
23192
- let fixtureDirectory = path48.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
23276
+ let fixtureDirectory = path49.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
23193
23277
  for (let i = 0;i < args.length; i++) {
23194
23278
  const arg = args[i];
23195
23279
  if (arg === "--json") {
@@ -23203,10 +23287,10 @@ function parseEvaluateArgs(directory, args) {
23203
23287
  error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
23204
23288
  };
23205
23289
  }
23206
- const resolvedFixtures = path48.resolve(directory, next);
23207
- const canonical = path48.normalize(resolvedFixtures) + path48.sep;
23208
- const allowedRootA = path48.normalize(directory) + path48.sep;
23209
- const allowedRootB = path48.normalize(path48.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path48.sep;
23290
+ const resolvedFixtures = path49.resolve(directory, next);
23291
+ const canonical = path49.normalize(resolvedFixtures) + path49.sep;
23292
+ const allowedRootA = path49.normalize(directory) + path49.sep;
23293
+ const allowedRootB = path49.normalize(path49.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path49.sep;
23210
23294
  if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
23211
23295
  return {
23212
23296
  error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
@@ -23245,15 +23329,15 @@ function parseMaintenanceArgs(args, options) {
23245
23329
  return { limit, confirm };
23246
23330
  }
23247
23331
  function resolvePackageRootFromModule(modulePath) {
23248
- const moduleDir = path48.dirname(modulePath);
23249
- const leaf = path48.basename(moduleDir);
23332
+ const moduleDir = path49.dirname(modulePath);
23333
+ const leaf = path49.basename(moduleDir);
23250
23334
  if (leaf === "commands" || leaf === "cli") {
23251
- return path48.resolve(moduleDir, "..", "..");
23335
+ return path49.resolve(moduleDir, "..", "..");
23252
23336
  }
23253
23337
  if (leaf === "dist") {
23254
- return path48.resolve(moduleDir, "..");
23338
+ return path49.resolve(moduleDir, "..");
23255
23339
  }
23256
- return path48.resolve(moduleDir, "..");
23340
+ return path49.resolve(moduleDir, "..");
23257
23341
  }
23258
23342
  function formatMigrationResult(label, report) {
23259
23343
  if (!report) {
@@ -23987,12 +24071,12 @@ var _internals39 = {
23987
24071
  };
23988
24072
 
23989
24073
  // src/services/preflight-service.ts
23990
- import * as fs25 from "fs";
23991
- import * as path55 from "path";
24074
+ import * as fs24 from "fs";
24075
+ import * as path56 from "path";
23992
24076
 
23993
24077
  // src/tools/lint.ts
23994
- import * as fs19 from "fs";
23995
- import * as path49 from "path";
24078
+ import * as fs18 from "fs";
24079
+ import * as path50 from "path";
23996
24080
 
23997
24081
  // src/utils/path-security.ts
23998
24082
  function containsPathTraversal(str) {
@@ -24048,9 +24132,9 @@ function validateArgs(args) {
24048
24132
  }
24049
24133
  function getLinterCommand(linter, mode, projectDir) {
24050
24134
  const isWindows = process.platform === "win32";
24051
- const binDir = path49.join(projectDir, "node_modules", ".bin");
24052
- const biomeBin = isWindows ? path49.join(binDir, "biome.EXE") : path49.join(binDir, "biome");
24053
- const eslintBin = isWindows ? path49.join(binDir, "eslint.cmd") : path49.join(binDir, "eslint");
24135
+ const binDir = path50.join(projectDir, "node_modules", ".bin");
24136
+ const biomeBin = isWindows ? path50.join(binDir, "biome.EXE") : path50.join(binDir, "biome");
24137
+ const eslintBin = isWindows ? path50.join(binDir, "eslint.cmd") : path50.join(binDir, "eslint");
24054
24138
  switch (linter) {
24055
24139
  case "biome":
24056
24140
  if (mode === "fix") {
@@ -24066,7 +24150,7 @@ function getLinterCommand(linter, mode, projectDir) {
24066
24150
  }
24067
24151
  function getAdditionalLinterCommand(linter, mode, cwd) {
24068
24152
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
24069
- const gradlew = fs19.existsSync(path49.join(cwd, gradlewName)) ? path49.join(cwd, gradlewName) : null;
24153
+ const gradlew = fs18.existsSync(path50.join(cwd, gradlewName)) ? path50.join(cwd, gradlewName) : null;
24070
24154
  switch (linter) {
24071
24155
  case "ruff":
24072
24156
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -24100,12 +24184,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
24100
24184
  }
24101
24185
  }
24102
24186
  function detectRuff(cwd) {
24103
- if (fs19.existsSync(path49.join(cwd, "ruff.toml")))
24187
+ if (fs18.existsSync(path50.join(cwd, "ruff.toml")))
24104
24188
  return isCommandAvailable("ruff");
24105
24189
  try {
24106
- const pyproject = path49.join(cwd, "pyproject.toml");
24107
- if (fs19.existsSync(pyproject)) {
24108
- const content = fs19.readFileSync(pyproject, "utf-8");
24190
+ const pyproject = path50.join(cwd, "pyproject.toml");
24191
+ if (fs18.existsSync(pyproject)) {
24192
+ const content = fs18.readFileSync(pyproject, "utf-8");
24109
24193
  if (content.includes("[tool.ruff]"))
24110
24194
  return isCommandAvailable("ruff");
24111
24195
  }
@@ -24113,21 +24197,21 @@ function detectRuff(cwd) {
24113
24197
  return false;
24114
24198
  }
24115
24199
  function detectClippy(cwd) {
24116
- return fs19.existsSync(path49.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
24200
+ return fs18.existsSync(path50.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
24117
24201
  }
24118
24202
  function detectGolangciLint(cwd) {
24119
- return fs19.existsSync(path49.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24203
+ return fs18.existsSync(path50.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24120
24204
  }
24121
24205
  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"));
24206
+ const hasMaven = fs18.existsSync(path50.join(cwd, "pom.xml"));
24207
+ const hasGradle = fs18.existsSync(path50.join(cwd, "build.gradle")) || fs18.existsSync(path50.join(cwd, "build.gradle.kts"));
24208
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs18.existsSync(path50.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
24125
24209
  return (hasMaven || hasGradle) && hasBinary;
24126
24210
  }
24127
24211
  function detectKtlint(cwd) {
24128
- const hasKotlin = fs19.existsSync(path49.join(cwd, "build.gradle.kts")) || fs19.existsSync(path49.join(cwd, "build.gradle")) || (() => {
24212
+ const hasKotlin = fs18.existsSync(path50.join(cwd, "build.gradle.kts")) || fs18.existsSync(path50.join(cwd, "build.gradle")) || (() => {
24129
24213
  try {
24130
- return fs19.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
24214
+ return fs18.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
24131
24215
  } catch {
24132
24216
  return false;
24133
24217
  }
@@ -24136,7 +24220,7 @@ function detectKtlint(cwd) {
24136
24220
  }
24137
24221
  function detectDotnetFormat(cwd) {
24138
24222
  try {
24139
- const files = fs19.readdirSync(cwd);
24223
+ const files = fs18.readdirSync(cwd);
24140
24224
  const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
24141
24225
  return hasCsproj && isCommandAvailable("dotnet");
24142
24226
  } catch {
@@ -24144,14 +24228,14 @@ function detectDotnetFormat(cwd) {
24144
24228
  }
24145
24229
  }
24146
24230
  function detectCppcheck(cwd) {
24147
- if (fs19.existsSync(path49.join(cwd, "CMakeLists.txt"))) {
24231
+ if (fs18.existsSync(path50.join(cwd, "CMakeLists.txt"))) {
24148
24232
  return isCommandAvailable("cppcheck");
24149
24233
  }
24150
24234
  try {
24151
- const dirsToCheck = [cwd, path49.join(cwd, "src")];
24235
+ const dirsToCheck = [cwd, path50.join(cwd, "src")];
24152
24236
  const hasCpp = dirsToCheck.some((dir) => {
24153
24237
  try {
24154
- return fs19.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
24238
+ return fs18.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
24155
24239
  } catch {
24156
24240
  return false;
24157
24241
  }
@@ -24162,13 +24246,13 @@ function detectCppcheck(cwd) {
24162
24246
  }
24163
24247
  }
24164
24248
  function detectSwiftlint(cwd) {
24165
- return fs19.existsSync(path49.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
24249
+ return fs18.existsSync(path50.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
24166
24250
  }
24167
24251
  function detectDartAnalyze(cwd) {
24168
- return fs19.existsSync(path49.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
24252
+ return fs18.existsSync(path50.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
24169
24253
  }
24170
24254
  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"));
24255
+ return (fs18.existsSync(path50.join(cwd, "Gemfile")) || fs18.existsSync(path50.join(cwd, "gems.rb")) || fs18.existsSync(path50.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
24172
24256
  }
24173
24257
  function detectAdditionalLinter(cwd) {
24174
24258
  if (detectRuff(cwd))
@@ -24196,10 +24280,10 @@ function detectAdditionalLinter(cwd) {
24196
24280
  function findBinInAncestors(startDir, binName) {
24197
24281
  let dir = startDir;
24198
24282
  while (true) {
24199
- const candidate = path49.join(dir, "node_modules", ".bin", binName);
24200
- if (fs19.existsSync(candidate))
24283
+ const candidate = path50.join(dir, "node_modules", ".bin", binName);
24284
+ if (fs18.existsSync(candidate))
24201
24285
  return candidate;
24202
- const parent = path49.dirname(dir);
24286
+ const parent = path50.dirname(dir);
24203
24287
  if (parent === dir)
24204
24288
  break;
24205
24289
  dir = parent;
@@ -24208,11 +24292,11 @@ function findBinInAncestors(startDir, binName) {
24208
24292
  }
24209
24293
  function findBinInEnvPath(binName) {
24210
24294
  const searchPath = process.env.PATH ?? "";
24211
- for (const dir of searchPath.split(path49.delimiter)) {
24295
+ for (const dir of searchPath.split(path50.delimiter)) {
24212
24296
  if (!dir)
24213
24297
  continue;
24214
- const candidate = path49.join(dir, binName);
24215
- if (fs19.existsSync(candidate))
24298
+ const candidate = path50.join(dir, binName);
24299
+ if (fs18.existsSync(candidate))
24216
24300
  return candidate;
24217
24301
  }
24218
24302
  return null;
@@ -24220,17 +24304,17 @@ function findBinInEnvPath(binName) {
24220
24304
  async function detectAvailableLinter(directory) {
24221
24305
  if (!directory)
24222
24306
  return null;
24223
- if (!fs19.existsSync(directory))
24307
+ if (!fs18.existsSync(directory))
24224
24308
  return null;
24225
24309
  const projectDir = directory;
24226
24310
  const isWindows = process.platform === "win32";
24227
- const biomeBin = isWindows ? path49.join(projectDir, "node_modules", ".bin", "biome.EXE") : path49.join(projectDir, "node_modules", ".bin", "biome");
24228
- const eslintBin = isWindows ? path49.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path49.join(projectDir, "node_modules", ".bin", "eslint");
24311
+ const biomeBin = isWindows ? path50.join(projectDir, "node_modules", ".bin", "biome.EXE") : path50.join(projectDir, "node_modules", ".bin", "biome");
24312
+ const eslintBin = isWindows ? path50.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path50.join(projectDir, "node_modules", ".bin", "eslint");
24229
24313
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
24230
24314
  if (localResult)
24231
24315
  return localResult;
24232
- const biomeAncestor = findBinInAncestors(path49.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
24233
- const eslintAncestor = findBinInAncestors(path49.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
24316
+ const biomeAncestor = findBinInAncestors(path50.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
24317
+ const eslintAncestor = findBinInAncestors(path50.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
24234
24318
  if (biomeAncestor || eslintAncestor) {
24235
24319
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
24236
24320
  }
@@ -24253,7 +24337,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24253
24337
  const result = await Promise.race([biomeExit, timeout]);
24254
24338
  if (result === "timeout") {
24255
24339
  biomeProc.kill();
24256
- } else if (biomeProc.exitCode === 0 && fs19.existsSync(biomeBin)) {
24340
+ } else if (biomeProc.exitCode === 0 && fs18.existsSync(biomeBin)) {
24257
24341
  return "biome";
24258
24342
  }
24259
24343
  } catch {}
@@ -24267,7 +24351,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24267
24351
  const result = await Promise.race([eslintExit, timeout]);
24268
24352
  if (result === "timeout") {
24269
24353
  eslintProc.kill();
24270
- } else if (eslintProc.exitCode === 0 && fs19.existsSync(eslintBin)) {
24354
+ } else if (eslintProc.exitCode === 0 && fs18.existsSync(eslintBin)) {
24271
24355
  return "eslint";
24272
24356
  }
24273
24357
  } catch {}
@@ -24443,8 +24527,8 @@ var _internals40 = {
24443
24527
  };
24444
24528
 
24445
24529
  // src/tools/secretscan.ts
24446
- import * as fs20 from "fs";
24447
- import * as path50 from "path";
24530
+ import * as fs19 from "fs";
24531
+ import * as path51 from "path";
24448
24532
  var MAX_FILE_PATH_LENGTH = 500;
24449
24533
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
24450
24534
  var MAX_FILES_SCANNED = 1000;
@@ -24671,11 +24755,11 @@ function isGlobOrPathPattern(pattern) {
24671
24755
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
24672
24756
  }
24673
24757
  function loadSecretScanIgnore(scanDir) {
24674
- const ignorePath = path50.join(scanDir, ".secretscanignore");
24758
+ const ignorePath = path51.join(scanDir, ".secretscanignore");
24675
24759
  try {
24676
- if (!fs20.existsSync(ignorePath))
24760
+ if (!fs19.existsSync(ignorePath))
24677
24761
  return [];
24678
- const content = fs20.readFileSync(ignorePath, "utf8");
24762
+ const content = fs19.readFileSync(ignorePath, "utf8");
24679
24763
  const patterns = [];
24680
24764
  for (const rawLine of content.split(/\r?\n/)) {
24681
24765
  const line = rawLine.trim();
@@ -24694,7 +24778,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
24694
24778
  if (exactNames.has(entry))
24695
24779
  return true;
24696
24780
  for (const pattern of globPatterns) {
24697
- if (path50.matchesGlob(relPath, pattern))
24781
+ if (path51.matchesGlob(relPath, pattern))
24698
24782
  return true;
24699
24783
  }
24700
24784
  return false;
@@ -24715,7 +24799,7 @@ function validateDirectoryInput(dir) {
24715
24799
  return null;
24716
24800
  }
24717
24801
  function isBinaryFile(filePath, buffer) {
24718
- const ext = path50.extname(filePath).toLowerCase();
24802
+ const ext = path51.extname(filePath).toLowerCase();
24719
24803
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
24720
24804
  return true;
24721
24805
  }
@@ -24790,11 +24874,11 @@ function createRedactedContext(line, findings) {
24790
24874
  result += line.slice(lastEnd);
24791
24875
  return result;
24792
24876
  }
24793
- var O_NOFOLLOW = process.platform !== "win32" ? fs20.constants.O_NOFOLLOW : undefined;
24877
+ var O_NOFOLLOW = process.platform !== "win32" ? fs19.constants.O_NOFOLLOW : undefined;
24794
24878
  function scanFileForSecrets(filePath) {
24795
24879
  const findings = [];
24796
24880
  try {
24797
- const lstat2 = fs20.lstatSync(filePath);
24881
+ const lstat2 = fs19.lstatSync(filePath);
24798
24882
  if (lstat2.isSymbolicLink()) {
24799
24883
  return findings;
24800
24884
  }
@@ -24803,14 +24887,14 @@ function scanFileForSecrets(filePath) {
24803
24887
  }
24804
24888
  let buffer;
24805
24889
  if (O_NOFOLLOW !== undefined) {
24806
- const fd = fs20.openSync(filePath, "r", O_NOFOLLOW);
24890
+ const fd = fs19.openSync(filePath, "r", O_NOFOLLOW);
24807
24891
  try {
24808
- buffer = fs20.readFileSync(fd);
24892
+ buffer = fs19.readFileSync(fd);
24809
24893
  } finally {
24810
- fs20.closeSync(fd);
24894
+ fs19.closeSync(fd);
24811
24895
  }
24812
24896
  } else {
24813
- buffer = fs20.readFileSync(filePath);
24897
+ buffer = fs19.readFileSync(filePath);
24814
24898
  }
24815
24899
  if (isBinaryFile(filePath, buffer)) {
24816
24900
  return findings;
@@ -24852,9 +24936,9 @@ function isSymlinkLoop(realPath, visited) {
24852
24936
  return false;
24853
24937
  }
24854
24938
  function isPathWithinScope(realPath, scanDir) {
24855
- const resolvedScanDir = path50.resolve(scanDir);
24856
- const resolvedRealPath = path50.resolve(realPath);
24857
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path50.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
24939
+ const resolvedScanDir = path51.resolve(scanDir);
24940
+ const resolvedRealPath = path51.resolve(realPath);
24941
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path51.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
24858
24942
  }
24859
24943
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
24860
24944
  skippedDirs: 0,
@@ -24865,7 +24949,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24865
24949
  const files = [];
24866
24950
  let entries;
24867
24951
  try {
24868
- entries = fs20.readdirSync(dir);
24952
+ entries = fs19.readdirSync(dir);
24869
24953
  } catch {
24870
24954
  stats.fileErrors++;
24871
24955
  return files;
@@ -24880,15 +24964,15 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24880
24964
  return a.localeCompare(b);
24881
24965
  });
24882
24966
  for (const entry of entries) {
24883
- const fullPath = path50.join(dir, entry);
24884
- const relPath = path50.relative(scanDir, fullPath).replace(/\\/g, "/");
24967
+ const fullPath = path51.join(dir, entry);
24968
+ const relPath = path51.relative(scanDir, fullPath).replace(/\\/g, "/");
24885
24969
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
24886
24970
  stats.skippedDirs++;
24887
24971
  continue;
24888
24972
  }
24889
24973
  let lstat2;
24890
24974
  try {
24891
- lstat2 = fs20.lstatSync(fullPath);
24975
+ lstat2 = fs19.lstatSync(fullPath);
24892
24976
  } catch {
24893
24977
  stats.fileErrors++;
24894
24978
  continue;
@@ -24900,7 +24984,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24900
24984
  if (lstat2.isDirectory()) {
24901
24985
  let realPath;
24902
24986
  try {
24903
- realPath = fs20.realpathSync(fullPath);
24987
+ realPath = fs19.realpathSync(fullPath);
24904
24988
  } catch {
24905
24989
  stats.fileErrors++;
24906
24990
  continue;
@@ -24916,7 +25000,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24916
25000
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
24917
25001
  files.push(...subFiles);
24918
25002
  } else if (lstat2.isFile()) {
24919
- const ext = path50.extname(fullPath).toLowerCase();
25003
+ const ext = path51.extname(fullPath).toLowerCase();
24920
25004
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
24921
25005
  files.push(fullPath);
24922
25006
  } else {
@@ -24982,15 +25066,15 @@ var secretscan = createSwarmTool({
24982
25066
  }
24983
25067
  }
24984
25068
  try {
24985
- const _scanDirRaw = path50.resolve(directory);
25069
+ const _scanDirRaw = path51.resolve(directory);
24986
25070
  const scanDir = (() => {
24987
25071
  try {
24988
- return fs20.realpathSync(_scanDirRaw);
25072
+ return fs19.realpathSync(_scanDirRaw);
24989
25073
  } catch {
24990
25074
  return _scanDirRaw;
24991
25075
  }
24992
25076
  })();
24993
- if (!fs20.existsSync(scanDir)) {
25077
+ if (!fs19.existsSync(scanDir)) {
24994
25078
  const errorResult = {
24995
25079
  error: "directory not found",
24996
25080
  scan_dir: directory,
@@ -25001,7 +25085,7 @@ var secretscan = createSwarmTool({
25001
25085
  };
25002
25086
  return JSON.stringify(errorResult, null, 2);
25003
25087
  }
25004
- const dirStat = fs20.statSync(scanDir);
25088
+ const dirStat = fs19.statSync(scanDir);
25005
25089
  if (!dirStat.isDirectory()) {
25006
25090
  const errorResult = {
25007
25091
  error: "target must be a directory, not a file",
@@ -25052,7 +25136,7 @@ var secretscan = createSwarmTool({
25052
25136
  break;
25053
25137
  const fileFindings = scanFileForSecrets(filePath);
25054
25138
  try {
25055
- const stat5 = fs20.statSync(filePath);
25139
+ const stat5 = fs19.statSync(filePath);
25056
25140
  if (stat5.size > MAX_FILE_SIZE_BYTES) {
25057
25141
  skippedFiles++;
25058
25142
  continue;
@@ -25144,12 +25228,12 @@ var _internals41 = {
25144
25228
  };
25145
25229
 
25146
25230
  // src/tools/test-runner.ts
25147
- import * as fs24 from "fs";
25148
- import * as path54 from "path";
25231
+ import * as fs23 from "fs";
25232
+ import * as path55 from "path";
25149
25233
 
25150
25234
  // src/test-impact/analyzer.ts
25151
- import fs21 from "fs";
25152
- import path51 from "path";
25235
+ import fs20 from "fs";
25236
+ import path52 from "path";
25153
25237
  var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
25154
25238
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
25155
25239
  var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
@@ -25176,7 +25260,7 @@ function sharedTrailingSegments(a, b) {
25176
25260
  function isCacheStale(impactMap, generatedAtMs) {
25177
25261
  for (const sourcePath of Object.keys(impactMap)) {
25178
25262
  try {
25179
- const stat5 = fs21.statSync(sourcePath);
25263
+ const stat5 = fs20.statSync(sourcePath);
25180
25264
  if (stat5.mtimeMs > generatedAtMs) {
25181
25265
  return true;
25182
25266
  }
@@ -25190,15 +25274,15 @@ function resolveRelativeImport(fromDir, importPath) {
25190
25274
  if (!importPath.startsWith(".")) {
25191
25275
  return null;
25192
25276
  }
25193
- const resolved = path51.resolve(fromDir, importPath);
25194
- if (path51.extname(resolved)) {
25195
- if (fs21.existsSync(resolved) && fs21.statSync(resolved).isFile()) {
25277
+ const resolved = path52.resolve(fromDir, importPath);
25278
+ if (path52.extname(resolved)) {
25279
+ if (fs20.existsSync(resolved) && fs20.statSync(resolved).isFile()) {
25196
25280
  return normalizePath2(resolved);
25197
25281
  }
25198
25282
  } else {
25199
25283
  for (const ext of EXTENSIONS_TO_TRY) {
25200
25284
  const withExt = resolved + ext;
25201
- if (fs21.existsSync(withExt) && fs21.statSync(withExt).isFile()) {
25285
+ if (fs20.existsSync(withExt) && fs20.statSync(withExt).isFile()) {
25202
25286
  return normalizePath2(withExt);
25203
25287
  }
25204
25288
  }
@@ -25211,30 +25295,30 @@ function resolvePythonImport(fromDir, module) {
25211
25295
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
25212
25296
  let baseDir = fromDir;
25213
25297
  for (let i = 1;i < leadingDots; i++) {
25214
- baseDir = path51.dirname(baseDir);
25298
+ baseDir = path52.dirname(baseDir);
25215
25299
  }
25216
25300
  const rest = module.slice(leadingDots);
25217
25301
  if (rest.length === 0) {
25218
- const initPath = path51.join(baseDir, "__init__.py");
25219
- if (fs21.existsSync(initPath) && fs21.statSync(initPath).isFile()) {
25302
+ const initPath = path52.join(baseDir, "__init__.py");
25303
+ if (fs20.existsSync(initPath) && fs20.statSync(initPath).isFile()) {
25220
25304
  return normalizePath2(initPath);
25221
25305
  }
25222
25306
  return null;
25223
25307
  }
25224
- const subpath = rest.replace(/\./g, path51.sep);
25308
+ const subpath = rest.replace(/\./g, path52.sep);
25225
25309
  const candidates = [
25226
- `${path51.join(baseDir, subpath)}.py`,
25227
- path51.join(baseDir, subpath, "__init__.py")
25310
+ `${path52.join(baseDir, subpath)}.py`,
25311
+ path52.join(baseDir, subpath, "__init__.py")
25228
25312
  ];
25229
25313
  for (const c of candidates) {
25230
- if (fs21.existsSync(c) && fs21.statSync(c).isFile())
25314
+ if (fs20.existsSync(c) && fs20.statSync(c).isFile())
25231
25315
  return normalizePath2(c);
25232
25316
  }
25233
25317
  return null;
25234
25318
  }
25235
25319
  var goModuleCache = new Map;
25236
25320
  function findGoModule(fromDir) {
25237
- const resolved = path51.resolve(fromDir);
25321
+ const resolved = path52.resolve(fromDir);
25238
25322
  let cur = resolved;
25239
25323
  const walked = [];
25240
25324
  for (let i = 0;i < 16; i++) {
@@ -25246,8 +25330,8 @@ function findGoModule(fromDir) {
25246
25330
  }
25247
25331
  walked.push(cur);
25248
25332
  try {
25249
- const goMod = path51.join(cur, "go.mod");
25250
- const content = fs21.readFileSync(goMod, "utf-8");
25333
+ const goMod = path52.join(cur, "go.mod");
25334
+ const content = fs20.readFileSync(goMod, "utf-8");
25251
25335
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
25252
25336
  if (moduleMatch) {
25253
25337
  const result = { moduleRoot: cur, modulePath: moduleMatch[1] };
@@ -25257,10 +25341,10 @@ function findGoModule(fromDir) {
25257
25341
  }
25258
25342
  } catch {}
25259
25343
  try {
25260
- fs21.accessSync(path51.join(cur, ".git"));
25344
+ fs20.accessSync(path52.join(cur, ".git"));
25261
25345
  break;
25262
25346
  } catch {}
25263
- const parent = path51.dirname(cur);
25347
+ const parent = path52.dirname(cur);
25264
25348
  if (parent === cur)
25265
25349
  break;
25266
25350
  cur = parent;
@@ -25272,20 +25356,20 @@ function findGoModule(fromDir) {
25272
25356
  function resolveGoImport(fromDir, importPath) {
25273
25357
  let dir = null;
25274
25358
  if (importPath.startsWith(".")) {
25275
- dir = path51.resolve(fromDir, importPath);
25359
+ dir = path52.resolve(fromDir, importPath);
25276
25360
  } else {
25277
25361
  const mod = findGoModule(fromDir);
25278
25362
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
25279
25363
  const subpath = importPath.slice(mod.modulePath.length);
25280
- dir = path51.join(mod.moduleRoot, subpath);
25364
+ dir = path52.join(mod.moduleRoot, subpath);
25281
25365
  }
25282
25366
  }
25283
25367
  if (dir === null)
25284
25368
  return [];
25285
- if (!fs21.existsSync(dir) || !fs21.statSync(dir).isDirectory())
25369
+ if (!fs20.existsSync(dir) || !fs20.statSync(dir).isDirectory())
25286
25370
  return [];
25287
25371
  try {
25288
- return fs21.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path51.join(dir, f)));
25372
+ return fs20.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path52.join(dir, f)));
25289
25373
  } catch {
25290
25374
  return [];
25291
25375
  }
@@ -25305,13 +25389,13 @@ function findTestFilesSync(cwd) {
25305
25389
  function walk(dir, visitedInodes) {
25306
25390
  let entries;
25307
25391
  try {
25308
- entries = fs21.readdirSync(dir, { withFileTypes: true });
25392
+ entries = fs20.readdirSync(dir, { withFileTypes: true });
25309
25393
  } catch {
25310
25394
  return;
25311
25395
  }
25312
25396
  let dirInode;
25313
25397
  try {
25314
- dirInode = fs21.statSync(dir).ino;
25398
+ dirInode = fs20.statSync(dir).ino;
25315
25399
  } catch {
25316
25400
  return;
25317
25401
  }
@@ -25324,15 +25408,15 @@ function findTestFilesSync(cwd) {
25324
25408
  for (const entry of entries) {
25325
25409
  if (entry.isDirectory()) {
25326
25410
  if (!skipDirs.has(entry.name)) {
25327
- walk(path51.join(dir, entry.name), visitedInodes);
25411
+ walk(path52.join(dir, entry.name), visitedInodes);
25328
25412
  }
25329
25413
  } else if (entry.isFile()) {
25330
25414
  const name = entry.name;
25331
25415
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
25332
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path51.sep}tests${path51.sep}`) && name.endsWith(".py");
25416
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path52.sep}tests${path52.sep}`) && name.endsWith(".py");
25333
25417
  const isGoTest = /.+_test\.go$/.test(name);
25334
25418
  if (isTsTest || isPyTest || isGoTest) {
25335
- testFiles.push(normalizePath2(path51.join(dir, entry.name)));
25419
+ testFiles.push(normalizePath2(path52.join(dir, entry.name)));
25336
25420
  }
25337
25421
  }
25338
25422
  }
@@ -25357,8 +25441,8 @@ function extractImports(content) {
25357
25441
  ];
25358
25442
  }
25359
25443
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
25360
- const ext = path51.extname(testFile).toLowerCase();
25361
- const testDir = path51.dirname(testFile);
25444
+ const ext = path52.extname(testFile).toLowerCase();
25445
+ const testDir = path52.dirname(testFile);
25362
25446
  function addEdge(source) {
25363
25447
  if (!impactMap[source])
25364
25448
  impactMap[source] = [];
@@ -25395,12 +25479,13 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
25395
25479
  }
25396
25480
  }
25397
25481
  async function buildImpactMapInternal(cwd) {
25482
+ _clearGoModuleCache();
25398
25483
  const testFiles = findTestFilesSync(cwd);
25399
25484
  const impactMap = {};
25400
25485
  for (const testFile of testFiles) {
25401
25486
  let content;
25402
25487
  try {
25403
- content = fs21.readFileSync(testFile, "utf-8");
25488
+ content = fs20.readFileSync(testFile, "utf-8");
25404
25489
  } catch {
25405
25490
  continue;
25406
25491
  }
@@ -25431,10 +25516,10 @@ async function buildImpactMap(cwd) {
25431
25516
  return impactMap;
25432
25517
  }
25433
25518
  async function loadImpactMap(cwd, options) {
25434
- const cachePath = path51.join(cwd, ".swarm", "cache", "impact-map.json");
25435
- if (fs21.existsSync(cachePath)) {
25519
+ const cachePath = path52.join(cwd, ".swarm", "cache", "impact-map.json");
25520
+ if (fs20.existsSync(cachePath)) {
25436
25521
  try {
25437
- const content = fs21.readFileSync(cachePath, "utf-8");
25522
+ const content = fs20.readFileSync(cachePath, "utf-8");
25438
25523
  const data = JSON.parse(content);
25439
25524
  if (data.map !== null && typeof data.map === "object" && !Array.isArray(data.map)) {
25440
25525
  const map = data.map;
@@ -25464,21 +25549,21 @@ async function loadImpactMap(cwd, options) {
25464
25549
  return _internals42.buildImpactMap(cwd);
25465
25550
  }
25466
25551
  async function saveImpactMap(cwd, impactMap) {
25467
- if (!path51.isAbsolute(cwd)) {
25552
+ if (!path52.isAbsolute(cwd)) {
25468
25553
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
25469
25554
  }
25470
25555
  _internals42.validateProjectRoot(cwd);
25471
- const cacheDir2 = path51.join(cwd, ".swarm", "cache");
25472
- const cachePath = path51.join(cacheDir2, "impact-map.json");
25473
- if (!fs21.existsSync(cacheDir2)) {
25474
- fs21.mkdirSync(cacheDir2, { recursive: true });
25556
+ const cacheDir2 = path52.join(cwd, ".swarm", "cache");
25557
+ const cachePath = path52.join(cacheDir2, "impact-map.json");
25558
+ if (!fs20.existsSync(cacheDir2)) {
25559
+ fs20.mkdirSync(cacheDir2, { recursive: true });
25475
25560
  }
25476
25561
  const data = {
25477
25562
  generatedAt: new Date().toISOString(),
25478
25563
  fileCount: Object.keys(impactMap).length,
25479
25564
  map: impactMap
25480
25565
  };
25481
- fs21.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
25566
+ fs20.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
25482
25567
  }
25483
25568
  async function analyzeImpact(changedFiles, cwd, budget) {
25484
25569
  if (!Array.isArray(changedFiles)) {
@@ -25501,7 +25586,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
25501
25586
  budgetExceeded = true;
25502
25587
  break;
25503
25588
  }
25504
- const normalizedChanged = normalizePath2(path51.resolve(changedFile));
25589
+ const normalizedChanged = normalizePath2(path52.resolve(changedFile));
25505
25590
  const tests = impactMap[normalizedChanged];
25506
25591
  if (tests && tests.length > 0) {
25507
25592
  for (const test of tests) {
@@ -25515,13 +25600,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
25515
25600
  if (budgetExceeded)
25516
25601
  break;
25517
25602
  } else {
25518
- const changedDir = normalizePath2(path51.dirname(normalizedChanged));
25519
- const changedInputDir = normalizePath2(path51.dirname(changedFile));
25603
+ const changedDir = normalizePath2(path52.dirname(normalizedChanged));
25604
+ const changedInputDir = normalizePath2(path52.dirname(changedFile));
25520
25605
  const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
25521
25606
  return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
25522
25607
  }).sort(([sourceA], [sourceB]) => {
25523
- const sourceDirA = normalizePath2(path51.dirname(sourceA));
25524
- const sourceDirB = normalizePath2(path51.dirname(sourceB));
25608
+ const sourceDirA = normalizePath2(path52.dirname(sourceA));
25609
+ const sourceDirB = normalizePath2(path52.dirname(sourceB));
25525
25610
  const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
25526
25611
  const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
25527
25612
  if (exactA !== exactB)
@@ -25847,8 +25932,8 @@ function detectFlakyTests(allHistory) {
25847
25932
  }
25848
25933
 
25849
25934
  // src/test-impact/history-store.ts
25850
- import fs22 from "fs";
25851
- import path52 from "path";
25935
+ import fs21 from "fs";
25936
+ import path53 from "path";
25852
25937
  var MAX_HISTORY_PER_TEST = 20;
25853
25938
  var MAX_ERROR_LENGTH = 500;
25854
25939
  var MAX_STACK_LENGTH = 200;
@@ -25860,10 +25945,10 @@ function getHistoryPath(workingDir) {
25860
25945
  if (!workingDir) {
25861
25946
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
25862
25947
  }
25863
- if (!path52.isAbsolute(workingDir)) {
25948
+ if (!path53.isAbsolute(workingDir)) {
25864
25949
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
25865
25950
  }
25866
- return path52.join(workingDir, ".swarm", "cache", "test-history.jsonl");
25951
+ return path53.join(workingDir, ".swarm", "cache", "test-history.jsonl");
25867
25952
  }
25868
25953
  function sanitizeErrorMessage(errorMessage) {
25869
25954
  if (errorMessage === undefined) {
@@ -25955,10 +26040,10 @@ function batchAppendTestRuns(records, workingDir) {
25955
26040
  }
25956
26041
  }
25957
26042
  const historyPath = getHistoryPath(workingDir);
25958
- const historyDir = path52.dirname(historyPath);
26043
+ const historyDir = path53.dirname(historyPath);
25959
26044
  _internals43.validateProjectRoot(workingDir);
25960
- if (!fs22.existsSync(historyDir)) {
25961
- fs22.mkdirSync(historyDir, { recursive: true });
26045
+ if (!fs21.existsSync(historyDir)) {
26046
+ fs21.mkdirSync(historyDir, { recursive: true });
25962
26047
  }
25963
26048
  withHistoryWriteLock(historyPath, () => {
25964
26049
  const existingRecords = readAllRecords(historyPath);
@@ -25992,13 +26077,13 @@ function batchAppendTestRuns(records, workingDir) {
25992
26077
  `)}
25993
26078
  `;
25994
26079
  const tempPath = `${historyPath}.tmp`;
25995
- fs22.writeFileSync(tempPath, content, "utf-8");
25996
- fs22.renameSync(tempPath, historyPath);
26080
+ fs21.writeFileSync(tempPath, content, "utf-8");
26081
+ fs21.renameSync(tempPath, historyPath);
25997
26082
  } catch (err) {
25998
26083
  try {
25999
26084
  const tempPath = `${historyPath}.tmp`;
26000
- if (fs22.existsSync(tempPath)) {
26001
- fs22.unlinkSync(tempPath);
26085
+ if (fs21.existsSync(tempPath)) {
26086
+ fs21.unlinkSync(tempPath);
26002
26087
  }
26003
26088
  } catch {}
26004
26089
  throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
@@ -26010,7 +26095,7 @@ function withHistoryWriteLock(historyPath, fn) {
26010
26095
  const deadline = Date.now() + HISTORY_WRITE_LOCK_TIMEOUT_MS;
26011
26096
  while (true) {
26012
26097
  try {
26013
- fs22.mkdirSync(lockPath);
26098
+ fs21.mkdirSync(lockPath);
26014
26099
  break;
26015
26100
  } catch (error2) {
26016
26101
  const code = error2 instanceof Error && "code" in error2 ? error2.code : undefined;
@@ -26021,9 +26106,9 @@ function withHistoryWriteLock(historyPath, fn) {
26021
26106
  throw new Error(`Timed out waiting for test history lock: ${historyPath}`);
26022
26107
  }
26023
26108
  try {
26024
- const lockStat = fs22.statSync(lockPath);
26109
+ const lockStat = fs21.statSync(lockPath);
26025
26110
  if (Date.now() - lockStat.mtimeMs >= HISTORY_WRITE_LOCK_STALE_MS) {
26026
- fs22.rmSync(lockPath, { recursive: true, force: true });
26111
+ fs21.rmSync(lockPath, { recursive: true, force: true });
26027
26112
  continue;
26028
26113
  }
26029
26114
  } catch {}
@@ -26038,7 +26123,7 @@ function withHistoryWriteLock(historyPath, fn) {
26038
26123
  return fn();
26039
26124
  } finally {
26040
26125
  try {
26041
- fs22.rmSync(lockPath, { recursive: true, force: true });
26126
+ fs21.rmSync(lockPath, { recursive: true, force: true });
26042
26127
  } catch {}
26043
26128
  }
26044
26129
  function sleepSync(ms) {
@@ -26047,11 +26132,11 @@ function withHistoryWriteLock(historyPath, fn) {
26047
26132
  }
26048
26133
  }
26049
26134
  function readAllRecords(historyPath) {
26050
- if (!fs22.existsSync(historyPath)) {
26135
+ if (!fs21.existsSync(historyPath)) {
26051
26136
  return [];
26052
26137
  }
26053
26138
  try {
26054
- const content = fs22.readFileSync(historyPath, "utf-8");
26139
+ const content = fs21.readFileSync(historyPath, "utf-8");
26055
26140
  const lines = content.split(`
26056
26141
  `);
26057
26142
  const records = [];
@@ -26084,8 +26169,8 @@ var _internals43 = {
26084
26169
  };
26085
26170
 
26086
26171
  // src/tools/resolve-working-directory.ts
26087
- import * as fs23 from "fs";
26088
- import * as path53 from "path";
26172
+ import * as fs22 from "fs";
26173
+ import * as path54 from "path";
26089
26174
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26090
26175
  if (workingDirectory == null || workingDirectory === "") {
26091
26176
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
@@ -26108,14 +26193,12 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26108
26193
  message: "Invalid working_directory: null bytes are not allowed"
26109
26194
  };
26110
26195
  }
26111
- if (process.platform === "win32") {
26112
- const devicePathPattern = /^\\\\|^(NUL|CON|AUX|COM[1-9]|LPT[1-9])(\..*)?$/i;
26113
- if (devicePathPattern.test(workingDirectory)) {
26114
- return {
26115
- success: false,
26116
- message: "Invalid working_directory: Windows device paths are not allowed"
26117
- };
26118
- }
26196
+ const reservedDevicePattern = /^(NUL|CON|AUX|COM[1-9]|LPT[1-9])(\..*)?$/i;
26197
+ if (workingDirectory.startsWith("\\\\") || process.platform === "win32" && reservedDevicePattern.test(workingDirectory)) {
26198
+ return {
26199
+ success: false,
26200
+ message: "Invalid working_directory: Windows device paths are not allowed"
26201
+ };
26119
26202
  }
26120
26203
  const rawPathParts = workingDirectory.split(/[\\/]/);
26121
26204
  if (rawPathParts.includes("..")) {
@@ -26124,11 +26207,11 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26124
26207
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
26125
26208
  };
26126
26209
  }
26127
- const normalizedDir = path53.normalize(workingDirectory);
26128
- const resolvedDir = path53.resolve(normalizedDir);
26210
+ const normalizedDir = path54.normalize(workingDirectory);
26211
+ const resolvedDir = path54.resolve(normalizedDir);
26129
26212
  let statResult;
26130
26213
  try {
26131
- statResult = fs23.statSync(resolvedDir);
26214
+ statResult = fs22.statSync(resolvedDir);
26132
26215
  } catch {
26133
26216
  return {
26134
26217
  success: false,
@@ -26144,16 +26227,16 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26144
26227
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
26145
26228
  return { success: true, directory: resolvedDir };
26146
26229
  }
26147
- const resolvedFallback = path53.resolve(fallbackDirectory);
26230
+ const resolvedFallback = path54.resolve(fallbackDirectory);
26148
26231
  let fallbackExists = false;
26149
26232
  try {
26150
- fs23.statSync(resolvedFallback);
26233
+ fs22.statSync(resolvedFallback);
26151
26234
  fallbackExists = true;
26152
26235
  } catch {
26153
26236
  fallbackExists = false;
26154
26237
  }
26155
26238
  if (fallbackExists) {
26156
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path53.sep);
26239
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path54.sep);
26157
26240
  if (isSubdirectory) {
26158
26241
  return {
26159
26242
  success: false,
@@ -26176,7 +26259,7 @@ async function estimateFanOut(sourceFiles, cwd) {
26176
26259
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
26177
26260
  const uniqueTestFiles = new Set;
26178
26261
  for (const sourceFile of sourceFiles) {
26179
- const resolvedPath = path54.resolve(cwd, sourceFile);
26262
+ const resolvedPath = path55.resolve(cwd, sourceFile);
26180
26263
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
26181
26264
  const testFiles = impactMap[normalizedPath];
26182
26265
  if (testFiles) {
@@ -26261,19 +26344,19 @@ function hasDevDependency(devDeps, ...patterns) {
26261
26344
  return hasPackageJsonDependency(devDeps, ...patterns);
26262
26345
  }
26263
26346
  function detectGoTest(cwd) {
26264
- return fs24.existsSync(path54.join(cwd, "go.mod")) && isCommandAvailable("go");
26347
+ return fs23.existsSync(path55.join(cwd, "go.mod")) && isCommandAvailable("go");
26265
26348
  }
26266
26349
  function detectJavaMaven(cwd) {
26267
- return fs24.existsSync(path54.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
26350
+ return fs23.existsSync(path55.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
26268
26351
  }
26269
26352
  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"));
26353
+ const hasBuildFile = fs23.existsSync(path55.join(cwd, "build.gradle")) || fs23.existsSync(path55.join(cwd, "build.gradle.kts"));
26354
+ const hasGradlew = fs23.existsSync(path55.join(cwd, "gradlew")) || fs23.existsSync(path55.join(cwd, "gradlew.bat"));
26272
26355
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
26273
26356
  }
26274
26357
  function detectDotnetTest(cwd) {
26275
26358
  try {
26276
- const files = fs24.readdirSync(cwd);
26359
+ const files = fs23.readdirSync(cwd);
26277
26360
  const hasCsproj = files.some((f) => f.endsWith(".csproj"));
26278
26361
  return hasCsproj && isCommandAvailable("dotnet");
26279
26362
  } catch {
@@ -26281,25 +26364,25 @@ function detectDotnetTest(cwd) {
26281
26364
  }
26282
26365
  }
26283
26366
  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"));
26367
+ const hasSource = fs23.existsSync(path55.join(cwd, "CMakeLists.txt"));
26368
+ const hasBuildCache = fs23.existsSync(path55.join(cwd, "CMakeCache.txt")) || fs23.existsSync(path55.join(cwd, "build", "CMakeCache.txt"));
26286
26369
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
26287
26370
  }
26288
26371
  function detectSwiftTest(cwd) {
26289
- return fs24.existsSync(path54.join(cwd, "Package.swift")) && isCommandAvailable("swift");
26372
+ return fs23.existsSync(path55.join(cwd, "Package.swift")) && isCommandAvailable("swift");
26290
26373
  }
26291
26374
  function detectDartTest(cwd) {
26292
- return fs24.existsSync(path54.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
26375
+ return fs23.existsSync(path55.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
26293
26376
  }
26294
26377
  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"));
26378
+ const hasRSpecFile = fs23.existsSync(path55.join(cwd, ".rspec"));
26379
+ const hasGemfile = fs23.existsSync(path55.join(cwd, "Gemfile"));
26380
+ const hasSpecDir = fs23.existsSync(path55.join(cwd, "spec"));
26298
26381
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
26299
26382
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
26300
26383
  }
26301
26384
  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");
26385
+ return fs23.existsSync(path55.join(cwd, "test")) && (fs23.existsSync(path55.join(cwd, "Gemfile")) || fs23.existsSync(path55.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
26303
26386
  }
26304
26387
  var DISPATCH_FRAMEWORK_MAP = {
26305
26388
  bun: "bun",
@@ -26384,9 +26467,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
26384
26467
  async function detectTestFramework(cwd) {
26385
26468
  const baseDir = cwd;
26386
26469
  try {
26387
- const packageJsonPath = path54.join(baseDir, "package.json");
26388
- if (fs24.existsSync(packageJsonPath)) {
26389
- const content = fs24.readFileSync(packageJsonPath, "utf-8");
26470
+ const packageJsonPath = path55.join(baseDir, "package.json");
26471
+ if (fs23.existsSync(packageJsonPath)) {
26472
+ const content = fs23.readFileSync(packageJsonPath, "utf-8");
26390
26473
  const pkg = JSON.parse(content);
26391
26474
  const _deps = pkg.dependencies || {};
26392
26475
  const devDeps = pkg.devDependencies || {};
@@ -26405,38 +26488,38 @@ async function detectTestFramework(cwd) {
26405
26488
  return "jest";
26406
26489
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
26407
26490
  return "mocha";
26408
- if (fs24.existsSync(path54.join(baseDir, "bun.lockb")) || fs24.existsSync(path54.join(baseDir, "bun.lock"))) {
26491
+ if (fs23.existsSync(path55.join(baseDir, "bun.lockb")) || fs23.existsSync(path55.join(baseDir, "bun.lock"))) {
26409
26492
  if (scripts.test?.includes("bun"))
26410
26493
  return "bun";
26411
26494
  }
26412
26495
  }
26413
26496
  } catch {}
26414
26497
  try {
26415
- const pyprojectTomlPath = path54.join(baseDir, "pyproject.toml");
26416
- const setupCfgPath = path54.join(baseDir, "setup.cfg");
26417
- const requirementsTxtPath = path54.join(baseDir, "requirements.txt");
26418
- if (fs24.existsSync(pyprojectTomlPath)) {
26419
- const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
26498
+ const pyprojectTomlPath = path55.join(baseDir, "pyproject.toml");
26499
+ const setupCfgPath = path55.join(baseDir, "setup.cfg");
26500
+ const requirementsTxtPath = path55.join(baseDir, "requirements.txt");
26501
+ if (fs23.existsSync(pyprojectTomlPath)) {
26502
+ const content = fs23.readFileSync(pyprojectTomlPath, "utf-8");
26420
26503
  if (content.includes("[tool.pytest"))
26421
26504
  return "pytest";
26422
26505
  if (content.includes("pytest"))
26423
26506
  return "pytest";
26424
26507
  }
26425
- if (fs24.existsSync(setupCfgPath)) {
26426
- const content = fs24.readFileSync(setupCfgPath, "utf-8");
26508
+ if (fs23.existsSync(setupCfgPath)) {
26509
+ const content = fs23.readFileSync(setupCfgPath, "utf-8");
26427
26510
  if (content.includes("[pytest]"))
26428
26511
  return "pytest";
26429
26512
  }
26430
- if (fs24.existsSync(requirementsTxtPath)) {
26431
- const content = fs24.readFileSync(requirementsTxtPath, "utf-8");
26513
+ if (fs23.existsSync(requirementsTxtPath)) {
26514
+ const content = fs23.readFileSync(requirementsTxtPath, "utf-8");
26432
26515
  if (content.includes("pytest"))
26433
26516
  return "pytest";
26434
26517
  }
26435
26518
  } catch {}
26436
26519
  try {
26437
- const cargoTomlPath = path54.join(baseDir, "Cargo.toml");
26438
- if (fs24.existsSync(cargoTomlPath)) {
26439
- const content = fs24.readFileSync(cargoTomlPath, "utf-8");
26520
+ const cargoTomlPath = path55.join(baseDir, "Cargo.toml");
26521
+ if (fs23.existsSync(cargoTomlPath)) {
26522
+ const content = fs23.readFileSync(cargoTomlPath, "utf-8");
26440
26523
  if (content.includes("[dev-dependencies]")) {
26441
26524
  if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
26442
26525
  return "cargo";
@@ -26445,10 +26528,10 @@ async function detectTestFramework(cwd) {
26445
26528
  }
26446
26529
  } catch {}
26447
26530
  try {
26448
- const pesterConfigPath = path54.join(baseDir, "pester.config.ps1");
26449
- const pesterConfigJsonPath = path54.join(baseDir, "pester.config.ps1.json");
26450
- const pesterPs1Path = path54.join(baseDir, "tests.ps1");
26451
- if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
26531
+ const pesterConfigPath = path55.join(baseDir, "pester.config.ps1");
26532
+ const pesterConfigJsonPath = path55.join(baseDir, "pester.config.ps1.json");
26533
+ const pesterPs1Path = path55.join(baseDir, "tests.ps1");
26534
+ if (fs23.existsSync(pesterConfigPath) || fs23.existsSync(pesterConfigJsonPath) || fs23.existsSync(pesterPs1Path)) {
26452
26535
  return "pester";
26453
26536
  }
26454
26537
  } catch {}
@@ -26490,12 +26573,12 @@ function isTestDirectoryPath(normalizedPath) {
26490
26573
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
26491
26574
  }
26492
26575
  function resolveWorkspacePath(file, workingDir) {
26493
- return path54.isAbsolute(file) ? path54.resolve(file) : path54.resolve(workingDir, file);
26576
+ return path55.isAbsolute(file) ? path55.resolve(file) : path55.resolve(workingDir, file);
26494
26577
  }
26495
26578
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
26496
26579
  if (!preferRelative)
26497
26580
  return absolutePath;
26498
- return path54.relative(workingDir, absolutePath);
26581
+ return path55.relative(workingDir, absolutePath);
26499
26582
  }
26500
26583
  function dedupePush(target, value) {
26501
26584
  if (!target.includes(value)) {
@@ -26532,18 +26615,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
26532
26615
  }
26533
26616
  }
26534
26617
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
26535
- const relativeDir = path54.dirname(relativePath);
26618
+ const relativeDir = path55.dirname(relativePath);
26536
26619
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
26537
26620
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
26538
- const rootDir = path54.join(workingDir, dirName);
26539
- return nestedRelativeDir ? [rootDir, path54.join(rootDir, nestedRelativeDir)] : [rootDir];
26621
+ const rootDir = path55.join(workingDir, dirName);
26622
+ return nestedRelativeDir ? [rootDir, path55.join(rootDir, nestedRelativeDir)] : [rootDir];
26540
26623
  });
26541
26624
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
26542
26625
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
26543
- directories.push(path54.join(workingDir, "src/test/java", path54.dirname(normalizedRelativePath.slice("src/main/java/".length))));
26626
+ directories.push(path55.join(workingDir, "src/test/java", path55.dirname(normalizedRelativePath.slice("src/main/java/".length))));
26544
26627
  }
26545
26628
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
26546
- directories.push(path54.join(workingDir, "src/test/kotlin", path54.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
26629
+ directories.push(path55.join(workingDir, "src/test/kotlin", path55.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
26547
26630
  }
26548
26631
  return [...new Set(directories)];
26549
26632
  }
@@ -26551,19 +26634,19 @@ function hasCompoundTestExtension(filename) {
26551
26634
  const lower = filename.toLowerCase();
26552
26635
  return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
26553
26636
  }
26554
- function isLanguageSpecificTestFile(basename10) {
26555
- const lower = basename10.toLowerCase();
26637
+ function isLanguageSpecificTestFile(basename11) {
26638
+ const lower = basename11.toLowerCase();
26556
26639
  if (lower.endsWith("_test.go"))
26557
26640
  return true;
26558
26641
  if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
26559
26642
  return true;
26560
26643
  if (lower.endsWith("_spec.rb"))
26561
26644
  return true;
26562
- if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename10) || basename10.endsWith("Test.java") || basename10.endsWith("Tests.java") || lower.endsWith("it.java")))
26645
+ if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename11) || basename11.endsWith("Test.java") || basename11.endsWith("Tests.java") || lower.endsWith("it.java")))
26563
26646
  return true;
26564
26647
  if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
26565
26648
  return true;
26566
- if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename10) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
26649
+ if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename11) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
26567
26650
  return true;
26568
26651
  if (lower.endsWith(".tests.ps1"))
26569
26652
  return true;
@@ -26571,23 +26654,23 @@ function isLanguageSpecificTestFile(basename10) {
26571
26654
  }
26572
26655
  function isConventionTestFilePath(filePath) {
26573
26656
  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);
26657
+ const basename11 = path55.basename(filePath);
26658
+ return hasCompoundTestExtension(basename11) || basename11.includes(".spec.") || basename11.includes(".test.") || isLanguageSpecificTestFile(basename11) || isTestDirectoryPath(normalizedPath);
26576
26659
  }
26577
26660
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
26578
26661
  const testFiles = [];
26579
26662
  for (const file of sourceFiles) {
26580
26663
  const absoluteFile = resolveWorkspacePath(file, workingDir);
26581
- const relativeFile = path54.relative(workingDir, absoluteFile);
26582
- const basename10 = path54.basename(absoluteFile);
26583
- const dirname24 = path54.dirname(absoluteFile);
26584
- const preferRelativeOutput = !path54.isAbsolute(file);
26664
+ const relativeFile = path55.relative(workingDir, absoluteFile);
26665
+ const basename11 = path55.basename(absoluteFile);
26666
+ const dirname25 = path55.dirname(absoluteFile);
26667
+ const preferRelativeOutput = !path55.isAbsolute(file);
26585
26668
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
26586
26669
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
26587
26670
  continue;
26588
26671
  }
26589
- const nameWithoutExt = basename10.replace(/\.[^.]+$/, "");
26590
- const ext = path54.extname(basename10);
26672
+ const nameWithoutExt = basename11.replace(/\.[^.]+$/, "");
26673
+ const ext = path55.extname(basename11);
26591
26674
  const genericTestNames = [
26592
26675
  `${nameWithoutExt}.spec${ext}`,
26593
26676
  `${nameWithoutExt}.test${ext}`
@@ -26596,20 +26679,20 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
26596
26679
  const colocatedCandidates = [
26597
26680
  ...genericTestNames,
26598
26681
  ...languageSpecificTestNames
26599
- ].map((candidateName) => path54.join(dirname24, candidateName));
26682
+ ].map((candidateName) => path55.join(dirname25, candidateName));
26600
26683
  const testDirectoryNames = [
26601
- basename10,
26684
+ basename11,
26602
26685
  ...genericTestNames,
26603
26686
  ...languageSpecificTestNames
26604
26687
  ];
26605
26688
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
26606
26689
  const possibleTestFiles = [
26607
26690
  ...colocatedCandidates,
26608
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path54.join(dirname24, dirName, candidateName))),
26609
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path54.join(candidateDir, candidateName)))
26691
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path55.join(dirname25, dirName, candidateName))),
26692
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path55.join(candidateDir, candidateName)))
26610
26693
  ];
26611
26694
  for (const testFile of possibleTestFiles) {
26612
- if (fs24.existsSync(testFile)) {
26695
+ if (fs23.existsSync(testFile)) {
26613
26696
  dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
26614
26697
  }
26615
26698
  }
@@ -26626,8 +26709,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26626
26709
  for (const testFile of candidateTestFiles) {
26627
26710
  try {
26628
26711
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
26629
- const content = fs24.readFileSync(absoluteTestFile, "utf-8");
26630
- const testDir = path54.dirname(absoluteTestFile);
26712
+ const content = fs23.readFileSync(absoluteTestFile, "utf-8");
26713
+ const testDir = path55.dirname(absoluteTestFile);
26631
26714
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
26632
26715
  let match;
26633
26716
  match = importRegex.exec(content);
@@ -26635,8 +26718,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26635
26718
  const importPath = match[1];
26636
26719
  let resolvedImport;
26637
26720
  if (importPath.startsWith(".")) {
26638
- resolvedImport = path54.resolve(testDir, importPath);
26639
- const existingExt = path54.extname(resolvedImport);
26721
+ resolvedImport = path55.resolve(testDir, importPath);
26722
+ const existingExt = path55.extname(resolvedImport);
26640
26723
  if (!existingExt) {
26641
26724
  for (const extToTry of [
26642
26725
  ".ts",
@@ -26647,7 +26730,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26647
26730
  ".cjs"
26648
26731
  ]) {
26649
26732
  const withExt = resolvedImport + extToTry;
26650
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
26733
+ if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
26651
26734
  resolvedImport = withExt;
26652
26735
  break;
26653
26736
  }
@@ -26656,12 +26739,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26656
26739
  } else {
26657
26740
  continue;
26658
26741
  }
26659
- const importBasename = path54.basename(resolvedImport, path54.extname(resolvedImport));
26660
- const importDir = path54.dirname(resolvedImport);
26742
+ const importBasename = path55.basename(resolvedImport, path55.extname(resolvedImport));
26743
+ const importDir = path55.dirname(resolvedImport);
26661
26744
  for (const sourceFile of absoluteSourceFiles) {
26662
- const sourceDir = path54.dirname(sourceFile);
26663
- const sourceBasename = path54.basename(sourceFile, path54.extname(sourceFile));
26664
- const isRelatedDir = importDir === sourceDir || importDir === path54.join(sourceDir, "__tests__") || importDir === path54.join(sourceDir, "tests") || importDir === path54.join(sourceDir, "test") || importDir === path54.join(sourceDir, "spec");
26745
+ const sourceDir = path55.dirname(sourceFile);
26746
+ const sourceBasename = path55.basename(sourceFile, path55.extname(sourceFile));
26747
+ const isRelatedDir = importDir === sourceDir || importDir === path55.join(sourceDir, "__tests__") || importDir === path55.join(sourceDir, "tests") || importDir === path55.join(sourceDir, "test") || importDir === path55.join(sourceDir, "spec");
26665
26748
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
26666
26749
  dedupePush(testFiles, testFile);
26667
26750
  break;
@@ -26674,8 +26757,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26674
26757
  while (match !== null) {
26675
26758
  const importPath = match[1];
26676
26759
  if (importPath.startsWith(".")) {
26677
- let resolvedImport = path54.resolve(testDir, importPath);
26678
- const existingExt = path54.extname(resolvedImport);
26760
+ let resolvedImport = path55.resolve(testDir, importPath);
26761
+ const existingExt = path55.extname(resolvedImport);
26679
26762
  if (!existingExt) {
26680
26763
  for (const extToTry of [
26681
26764
  ".ts",
@@ -26686,18 +26769,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26686
26769
  ".cjs"
26687
26770
  ]) {
26688
26771
  const withExt = resolvedImport + extToTry;
26689
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
26772
+ if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
26690
26773
  resolvedImport = withExt;
26691
26774
  break;
26692
26775
  }
26693
26776
  }
26694
26777
  }
26695
- const importDir = path54.dirname(resolvedImport);
26696
- const importBasename = path54.basename(resolvedImport, path54.extname(resolvedImport));
26778
+ const importDir = path55.dirname(resolvedImport);
26779
+ const importBasename = path55.basename(resolvedImport, path55.extname(resolvedImport));
26697
26780
  for (const sourceFile of absoluteSourceFiles) {
26698
- const sourceDir = path54.dirname(sourceFile);
26699
- const sourceBasename = path54.basename(sourceFile, path54.extname(sourceFile));
26700
- const isRelatedDir = importDir === sourceDir || importDir === path54.join(sourceDir, "__tests__") || importDir === path54.join(sourceDir, "tests") || importDir === path54.join(sourceDir, "test") || importDir === path54.join(sourceDir, "spec");
26781
+ const sourceDir = path55.dirname(sourceFile);
26782
+ const sourceBasename = path55.basename(sourceFile, path55.extname(sourceFile));
26783
+ const isRelatedDir = importDir === sourceDir || importDir === path55.join(sourceDir, "__tests__") || importDir === path55.join(sourceDir, "tests") || importDir === path55.join(sourceDir, "test") || importDir === path55.join(sourceDir, "spec");
26701
26784
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
26702
26785
  dedupePush(testFiles, testFile);
26703
26786
  break;
@@ -26817,8 +26900,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
26817
26900
  return ["mvn", "test"];
26818
26901
  case "gradle": {
26819
26902
  const isWindows = process.platform === "win32";
26820
- const hasGradlewBat = fs24.existsSync(path54.join(baseDir, "gradlew.bat"));
26821
- const hasGradlew = fs24.existsSync(path54.join(baseDir, "gradlew"));
26903
+ const hasGradlewBat = fs23.existsSync(path55.join(baseDir, "gradlew.bat"));
26904
+ const hasGradlew = fs23.existsSync(path55.join(baseDir, "gradlew"));
26822
26905
  if (hasGradlewBat && isWindows)
26823
26906
  return ["gradlew.bat", "test"];
26824
26907
  if (hasGradlew)
@@ -26835,7 +26918,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
26835
26918
  "cmake-build-release",
26836
26919
  "out"
26837
26920
  ];
26838
- const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path54.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
26921
+ const actualBuildDir = buildDirCandidates.find((d) => fs23.existsSync(path55.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
26839
26922
  return ["ctest", "--test-dir", actualBuildDir];
26840
26923
  }
26841
26924
  case "swift-test":
@@ -27269,13 +27352,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27269
27352
  };
27270
27353
  }
27271
27354
  const startTime = Date.now();
27272
- const vitestJsonOutputPath = framework === "vitest" ? path54.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
27355
+ const vitestJsonOutputPath = framework === "vitest" ? path55.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
27273
27356
  try {
27274
27357
  if (vitestJsonOutputPath) {
27275
27358
  try {
27276
- fs24.mkdirSync(path54.dirname(vitestJsonOutputPath), { recursive: true });
27277
- if (fs24.existsSync(vitestJsonOutputPath)) {
27278
- fs24.unlinkSync(vitestJsonOutputPath);
27359
+ fs23.mkdirSync(path55.dirname(vitestJsonOutputPath), { recursive: true });
27360
+ if (fs23.existsSync(vitestJsonOutputPath)) {
27361
+ fs23.unlinkSync(vitestJsonOutputPath);
27279
27362
  }
27280
27363
  } catch {}
27281
27364
  }
@@ -27301,8 +27384,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27301
27384
  }
27302
27385
  if (vitestJsonOutputPath) {
27303
27386
  try {
27304
- if (fs24.existsSync(vitestJsonOutputPath)) {
27305
- const vitestJsonOutput = fs24.readFileSync(vitestJsonOutputPath, "utf-8");
27387
+ if (fs23.existsSync(vitestJsonOutputPath)) {
27388
+ const vitestJsonOutput = fs23.readFileSync(vitestJsonOutputPath, "utf-8");
27306
27389
  if (vitestJsonOutput.trim().length > 0) {
27307
27390
  output += (output ? `
27308
27391
  ` : "") + vitestJsonOutput;
@@ -27441,10 +27524,10 @@ var SKIP_DIRECTORIES = new Set([
27441
27524
  ]);
27442
27525
  function normalizeHistoryTestFile(testFile, workingDir) {
27443
27526
  const normalized = testFile.replace(/\\/g, "/");
27444
- if (!path54.isAbsolute(testFile))
27527
+ if (!path55.isAbsolute(testFile))
27445
27528
  return normalized;
27446
- const relative7 = path54.relative(workingDir, testFile);
27447
- if (relative7.startsWith("..") || path54.isAbsolute(relative7)) {
27529
+ const relative7 = path55.relative(workingDir, testFile);
27530
+ if (relative7.startsWith("..") || path55.isAbsolute(relative7)) {
27448
27531
  return normalized;
27449
27532
  }
27450
27533
  return relative7.replace(/\\/g, "/");
@@ -27683,7 +27766,7 @@ var test_runner = createSwarmTool({
27683
27766
  const sourceFiles = args.files.filter((file) => {
27684
27767
  if (directTestFiles.includes(file))
27685
27768
  return false;
27686
- const ext = path54.extname(file).toLowerCase();
27769
+ const ext = path55.extname(file).toLowerCase();
27687
27770
  return SOURCE_EXTENSIONS.has(ext);
27688
27771
  });
27689
27772
  const invalidFiles = args.files.filter((file) => !directTestFiles.includes(file) && !sourceFiles.includes(file));
@@ -27729,7 +27812,7 @@ var test_runner = createSwarmTool({
27729
27812
  if (isConventionTestFilePath(f)) {
27730
27813
  return false;
27731
27814
  }
27732
- const ext = path54.extname(f).toLowerCase();
27815
+ const ext = path55.extname(f).toLowerCase();
27733
27816
  return SOURCE_EXTENSIONS.has(ext);
27734
27817
  });
27735
27818
  if (sourceFiles.length === 0) {
@@ -27779,7 +27862,7 @@ var test_runner = createSwarmTool({
27779
27862
  if (isConventionTestFilePath(f)) {
27780
27863
  return false;
27781
27864
  }
27782
- const ext = path54.extname(f).toLowerCase();
27865
+ const ext = path55.extname(f).toLowerCase();
27783
27866
  return SOURCE_EXTENSIONS.has(ext);
27784
27867
  });
27785
27868
  if (sourceFiles.length === 0) {
@@ -27831,8 +27914,8 @@ var test_runner = createSwarmTool({
27831
27914
  }
27832
27915
  if (impactResult.impactedTests.length > 0) {
27833
27916
  testFiles = impactResult.impactedTests.map((absPath) => {
27834
- const relativePath = path54.relative(workingDir, absPath);
27835
- return path54.isAbsolute(relativePath) ? absPath : relativePath;
27917
+ const relativePath = path55.relative(workingDir, absPath);
27918
+ return path55.isAbsolute(relativePath) ? absPath : relativePath;
27836
27919
  });
27837
27920
  } else {
27838
27921
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -27927,8 +28010,8 @@ function validateDirectoryPath(dir) {
27927
28010
  if (dir.includes("..")) {
27928
28011
  throw new Error("Directory path must not contain path traversal sequences");
27929
28012
  }
27930
- const normalized = path55.normalize(dir);
27931
- const absolutePath = path55.isAbsolute(normalized) ? normalized : path55.resolve(normalized);
28013
+ const normalized = path56.normalize(dir);
28014
+ const absolutePath = path56.isAbsolute(normalized) ? normalized : path56.resolve(normalized);
27932
28015
  return absolutePath;
27933
28016
  }
27934
28017
  function validateTimeout(timeoutMs, defaultValue) {
@@ -27951,9 +28034,9 @@ function validateTimeout(timeoutMs, defaultValue) {
27951
28034
  }
27952
28035
  function getPackageVersion(dir) {
27953
28036
  try {
27954
- const packagePath = path55.join(dir, "package.json");
27955
- if (fs25.existsSync(packagePath)) {
27956
- const content = fs25.readFileSync(packagePath, "utf-8");
28037
+ const packagePath = path56.join(dir, "package.json");
28038
+ if (fs24.existsSync(packagePath)) {
28039
+ const content = fs24.readFileSync(packagePath, "utf-8");
27957
28040
  const pkg = JSON.parse(content);
27958
28041
  return pkg.version ?? null;
27959
28042
  }
@@ -27962,9 +28045,9 @@ function getPackageVersion(dir) {
27962
28045
  }
27963
28046
  function getChangelogVersion(dir) {
27964
28047
  try {
27965
- const changelogPath = path55.join(dir, "CHANGELOG.md");
27966
- if (fs25.existsSync(changelogPath)) {
27967
- const content = fs25.readFileSync(changelogPath, "utf-8");
28048
+ const changelogPath = path56.join(dir, "CHANGELOG.md");
28049
+ if (fs24.existsSync(changelogPath)) {
28050
+ const content = fs24.readFileSync(changelogPath, "utf-8");
27968
28051
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
27969
28052
  if (match) {
27970
28053
  return match[1];
@@ -27976,10 +28059,10 @@ function getChangelogVersion(dir) {
27976
28059
  function getVersionFileVersion(dir) {
27977
28060
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
27978
28061
  for (const file of possibleFiles) {
27979
- const filePath = path55.join(dir, file);
27980
- if (fs25.existsSync(filePath)) {
28062
+ const filePath = path56.join(dir, file);
28063
+ if (fs24.existsSync(filePath)) {
27981
28064
  try {
27982
- const content = fs25.readFileSync(filePath, "utf-8").trim();
28065
+ const content = fs24.readFileSync(filePath, "utf-8").trim();
27983
28066
  const match = content.match(/(\d+\.\d+\.\d+)/);
27984
28067
  if (match) {
27985
28068
  return match[1];
@@ -28713,8 +28796,8 @@ async function handleQaGatesCommand(directory, args, sessionID) {
28713
28796
  }
28714
28797
 
28715
28798
  // src/commands/reset.ts
28716
- import * as fs26 from "fs";
28717
- import * as path56 from "path";
28799
+ import * as fs25 from "fs";
28800
+ import * as path57 from "path";
28718
28801
 
28719
28802
  // src/background/circuit-breaker.ts
28720
28803
  class CircuitBreaker {
@@ -29421,8 +29504,8 @@ async function handleResetCommand(directory, args) {
29421
29504
  for (const filename of filesToReset) {
29422
29505
  try {
29423
29506
  const resolvedPath = validateSwarmPath(directory, filename);
29424
- if (fs26.existsSync(resolvedPath)) {
29425
- fs26.unlinkSync(resolvedPath);
29507
+ if (fs25.existsSync(resolvedPath)) {
29508
+ fs25.unlinkSync(resolvedPath);
29426
29509
  results.push(`- \u2705 Deleted ${filename}`);
29427
29510
  } else {
29428
29511
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -29433,9 +29516,9 @@ async function handleResetCommand(directory, args) {
29433
29516
  }
29434
29517
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
29435
29518
  try {
29436
- const rootPath = path56.join(directory, filename);
29437
- if (fs26.existsSync(rootPath)) {
29438
- fs26.unlinkSync(rootPath);
29519
+ const rootPath = path57.join(directory, filename);
29520
+ if (fs25.existsSync(rootPath)) {
29521
+ fs25.unlinkSync(rootPath);
29439
29522
  results.push(`- \u2705 Deleted ${filename} (root)`);
29440
29523
  }
29441
29524
  } catch (err) {
@@ -29450,8 +29533,8 @@ async function handleResetCommand(directory, args) {
29450
29533
  }
29451
29534
  try {
29452
29535
  const summariesPath = validateSwarmPath(directory, "summaries");
29453
- if (fs26.existsSync(summariesPath)) {
29454
- fs26.rmSync(summariesPath, { recursive: true, force: true });
29536
+ if (fs25.existsSync(summariesPath)) {
29537
+ fs25.rmSync(summariesPath, { recursive: true, force: true });
29455
29538
  results.push("- \u2705 Deleted summaries/ directory");
29456
29539
  } else {
29457
29540
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -29470,15 +29553,15 @@ async function handleResetCommand(directory, args) {
29470
29553
  }
29471
29554
 
29472
29555
  // src/commands/reset-session.ts
29473
- import * as fs29 from "fs";
29474
- import * as path59 from "path";
29556
+ import * as fs28 from "fs";
29557
+ import * as path60 from "path";
29475
29558
 
29476
29559
  // src/prm/trajectory-store.ts
29477
- import * as fs27 from "fs/promises";
29478
- import * as path57 from "path";
29560
+ import * as fs26 from "fs/promises";
29561
+ import * as path58 from "path";
29479
29562
  var MAX_TRACKED_TRAJECTORY_SESSIONS = 500;
29480
29563
  function getTrajectoryPath(sessionId, directory) {
29481
- const relativePath = path57.join("trajectories", `${sessionId}.jsonl`);
29564
+ const relativePath = path58.join("trajectories", `${sessionId}.jsonl`);
29482
29565
  return validateSwarmPath(directory, relativePath);
29483
29566
  }
29484
29567
  var _inMemoryTrajectoryCache = new Map;
@@ -29508,7 +29591,7 @@ function clearTrajectoryCache(sessionId) {
29508
29591
  async function readTrajectory(sessionId, directory) {
29509
29592
  try {
29510
29593
  const trajectoryPath = getTrajectoryPath(sessionId, directory);
29511
- const content = await fs27.readFile(trajectoryPath, "utf-8");
29594
+ const content = await fs26.readFile(trajectoryPath, "utf-8");
29512
29595
  const lines = content.split(`
29513
29596
  `).filter((line) => line.trim().length > 0);
29514
29597
  const entries = [];
@@ -29533,15 +29616,15 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
29533
29616
  for (const subdir of ["trajectories", "replays"]) {
29534
29617
  try {
29535
29618
  const dirPath = validateSwarmPath(directory, subdir);
29536
- const entries = await fs27.readdir(dirPath, { withFileTypes: true });
29619
+ const entries = await fs26.readdir(dirPath, { withFileTypes: true });
29537
29620
  for (const entry of entries) {
29538
29621
  if (!entry.isFile())
29539
29622
  continue;
29540
- const filePath = path57.join(dirPath, entry.name);
29623
+ const filePath = path58.join(dirPath, entry.name);
29541
29624
  try {
29542
- const stat6 = await fs27.stat(filePath);
29625
+ const stat6 = await fs26.stat(filePath);
29543
29626
  if (now - stat6.mtimeMs > cutoffMs) {
29544
- await fs27.unlink(filePath);
29627
+ await fs26.unlink(filePath);
29545
29628
  }
29546
29629
  } catch {}
29547
29630
  }
@@ -29963,17 +30046,17 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
29963
30046
  };
29964
30047
  }
29965
30048
  // src/prm/replay.ts
29966
- import { promises as fs28 } from "fs";
29967
- import path58 from "path";
30049
+ import { promises as fs27 } from "fs";
30050
+ import path59 from "path";
29968
30051
  function isPathSafe(targetPath, basePath) {
29969
- const resolvedTarget = path58.resolve(targetPath);
29970
- const resolvedBase = path58.resolve(basePath);
29971
- const rel = path58.relative(resolvedBase, resolvedTarget);
29972
- return !rel.startsWith("..") && !path58.isAbsolute(rel);
30052
+ const resolvedTarget = path59.resolve(targetPath);
30053
+ const resolvedBase = path59.resolve(basePath);
30054
+ const rel = path59.relative(resolvedBase, resolvedTarget);
30055
+ return !rel.startsWith("..") && !path59.isAbsolute(rel);
29973
30056
  }
29974
30057
  function isWithinReplaysDir(targetPath) {
29975
- const resolved = path58.resolve(targetPath);
29976
- const parts = resolved.split(path58.sep);
30058
+ const resolved = path59.resolve(targetPath);
30059
+ const parts = resolved.split(path59.sep);
29977
30060
  for (let i = 0;i < parts.length - 1; i++) {
29978
30061
  if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
29979
30062
  return true;
@@ -29986,15 +30069,15 @@ function sanitizeFilename(input) {
29986
30069
  }
29987
30070
  async function startReplayRecording(sessionID, directory) {
29988
30071
  try {
29989
- const replayDir = path58.join(directory, ".swarm", "replays");
30072
+ const replayDir = path59.join(directory, ".swarm", "replays");
29990
30073
  const safeSessionID = sanitizeFilename(sessionID);
29991
30074
  const filename = `${safeSessionID}-${Date.now()}.jsonl`;
29992
- const filepath = path58.join(replayDir, filename);
30075
+ const filepath = path59.join(replayDir, filename);
29993
30076
  if (!isPathSafe(filepath, replayDir)) {
29994
30077
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
29995
30078
  return null;
29996
30079
  }
29997
- await fs28.mkdir(replayDir, { recursive: true });
30080
+ await fs27.mkdir(replayDir, { recursive: true });
29998
30081
  return filepath;
29999
30082
  } catch (err) {
30000
30083
  console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err}`);
@@ -30014,7 +30097,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
30014
30097
  };
30015
30098
  const line = `${JSON.stringify(fullEntry)}
30016
30099
  `;
30017
- await fs28.appendFile(artifactPath, line, "utf-8");
30100
+ await fs27.appendFile(artifactPath, line, "utf-8");
30018
30101
  } catch (err) {
30019
30102
  console.warn(`[replay] Failed to record entry: ${err}`);
30020
30103
  }
@@ -30059,10 +30142,11 @@ function errorMessage(err) {
30059
30142
  }
30060
30143
  async function handleResetSessionCommand(directory, _args) {
30061
30144
  const results = [];
30145
+ let statePath;
30062
30146
  try {
30063
- const statePath = validateSwarmPath(directory, "session/state.json");
30064
- if (fs29.existsSync(statePath)) {
30065
- fs29.unlinkSync(statePath);
30147
+ statePath = validateSwarmPath(directory, "session/state.json");
30148
+ if (fs28.existsSync(statePath)) {
30149
+ fs28.unlinkSync(statePath);
30066
30150
  results.push("\u2705 Deleted .swarm/session/state.json");
30067
30151
  } else {
30068
30152
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -30070,11 +30154,11 @@ async function handleResetSessionCommand(directory, _args) {
30070
30154
  } catch {
30071
30155
  results.push("\u274C Failed to delete state.json");
30072
30156
  }
30073
- const sessionDir = path59.dirname(validateSwarmPath(directory, "session/state.json"));
30157
+ const sessionDir = statePath ? path60.dirname(statePath) : undefined;
30074
30158
  let sessionFiles = [];
30075
- if (fs29.existsSync(sessionDir)) {
30159
+ if (sessionDir && fs28.existsSync(sessionDir)) {
30076
30160
  try {
30077
- sessionFiles = fs29.readdirSync(sessionDir);
30161
+ sessionFiles = fs28.readdirSync(sessionDir);
30078
30162
  } catch (err) {
30079
30163
  results.push(`\u274C Failed to read session directory: ${errorMessage(err)}`);
30080
30164
  }
@@ -30082,13 +30166,13 @@ async function handleResetSessionCommand(directory, _args) {
30082
30166
  for (const file of sessionFiles) {
30083
30167
  if (file === "state.json")
30084
30168
  continue;
30085
- const filePath = path59.join(sessionDir, file);
30169
+ const filePath = path60.join(sessionDir, file);
30086
30170
  try {
30087
- if (!fs29.existsSync(filePath))
30171
+ if (!fs28.existsSync(filePath))
30088
30172
  continue;
30089
- if (!fs29.lstatSync(filePath).isFile())
30173
+ if (!fs28.lstatSync(filePath).isFile())
30090
30174
  continue;
30091
- fs29.unlinkSync(filePath);
30175
+ fs28.unlinkSync(filePath);
30092
30176
  results.push(`\u2713 Deleted ${file}`);
30093
30177
  } catch (err) {
30094
30178
  results.push(`\u274C Failed to delete ${file}: ${errorMessage(err)}`);
@@ -30104,10 +30188,10 @@ async function handleResetSessionCommand(directory, _args) {
30104
30188
  const chainCount = swarmState.delegationChains.size;
30105
30189
  swarmState.delegationChains.clear();
30106
30190
  results.push(`\u2705 Cleared ${chainCount} delegation chain(s)`);
30107
- const worktreesDir = path59.resolve(path59.dirname(directory), ".swarm-worktrees");
30191
+ const worktreesDir = path60.resolve(path60.dirname(directory), ".swarm-worktrees");
30108
30192
  try {
30109
- if (fs29.existsSync(worktreesDir)) {
30110
- fs29.rmSync(worktreesDir, { recursive: true, force: true });
30193
+ if (fs28.existsSync(worktreesDir)) {
30194
+ fs28.rmSync(worktreesDir, { recursive: true, force: true });
30111
30195
  results.push("\u2705 Removed .swarm-worktrees/ directory");
30112
30196
  }
30113
30197
  } catch (err) {
@@ -30137,7 +30221,7 @@ async function handleResetSessionCommand(directory, _args) {
30137
30221
  }
30138
30222
 
30139
30223
  // src/summaries/manager.ts
30140
- import * as path60 from "path";
30224
+ import * as path61 from "path";
30141
30225
  var SUMMARY_ID_REGEX = /^S\d+$/;
30142
30226
  function sanitizeSummaryId(id) {
30143
30227
  if (!id || id.length === 0) {
@@ -30161,7 +30245,7 @@ function sanitizeSummaryId(id) {
30161
30245
  }
30162
30246
  async function loadFullOutput(directory, id) {
30163
30247
  const sanitizedId = sanitizeSummaryId(id);
30164
- const relativePath = path60.join("summaries", `${sanitizedId}.json`);
30248
+ const relativePath = path61.join("summaries", `${sanitizedId}.json`);
30165
30249
  validateSwarmPath(directory, relativePath);
30166
30250
  const content = await readSwarmFileAsync(directory, relativePath);
30167
30251
  if (content === null) {
@@ -30213,18 +30297,91 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
30213
30297
  }
30214
30298
 
30215
30299
  // src/commands/rollback.ts
30216
- import * as fs30 from "fs";
30217
- import * as path61 from "path";
30300
+ import * as fs29 from "fs";
30301
+ import * as path62 from "path";
30302
+ function safeParseToolJson(result) {
30303
+ try {
30304
+ const jsonStr = typeof result === "string" ? result : result.output;
30305
+ return JSON.parse(jsonStr);
30306
+ } catch {
30307
+ return null;
30308
+ }
30309
+ }
30310
+ async function listGitCheckpoints(directory) {
30311
+ try {
30312
+ const result = await checkpoint.execute({ action: "list" }, {
30313
+ directory
30314
+ });
30315
+ const parsed = safeParseToolJson(result);
30316
+ if (!parsed)
30317
+ return null;
30318
+ if (parsed.success !== true || !Array.isArray(parsed.checkpoints)) {
30319
+ return null;
30320
+ }
30321
+ return parsed.checkpoints;
30322
+ } catch {
30323
+ return null;
30324
+ }
30325
+ }
30326
+ function formatGitCheckpointList(checkpoints) {
30327
+ if (checkpoints.length === 0) {
30328
+ return "No checkpoints found. Create one with `/swarm checkpoint save <label>`";
30329
+ }
30330
+ return [
30331
+ "## Available Checkpoints",
30332
+ "",
30333
+ ...checkpoints.map((c, index) => `- ${index + 1}. "${c.label}" - ${new Date(c.timestamp).toLocaleString()} (${c.sha.slice(0, 12)})`),
30334
+ "",
30335
+ "Run `/swarm rollback <label-or-number>` to restore to a checkpoint."
30336
+ ].join(`
30337
+ `);
30338
+ }
30339
+ function resolveGitCheckpoint(checkpoints, selector) {
30340
+ const index = Number.parseInt(selector, 10);
30341
+ if (/^\d+$/.test(selector) && index >= 1 && index <= checkpoints.length) {
30342
+ return checkpoints[index - 1] ?? null;
30343
+ }
30344
+ return checkpoints.find((c) => c.label === selector) ?? null;
30345
+ }
30346
+ async function restoreGitCheckpoint(directory, selected) {
30347
+ const result = await checkpoint.execute({ action: "restore", label: selected.label }, { directory });
30348
+ const parsed = safeParseToolJson(result);
30349
+ if (!parsed) {
30350
+ return `Error: Failed to parse checkpoint response for "${selected.label}"`;
30351
+ }
30352
+ if (parsed.success !== true) {
30353
+ return `Error: ${parsed.error || `Failed to restore checkpoint "${selected.label}"`}`;
30354
+ }
30355
+ const eventsPath = validateSwarmPath(directory, "events.jsonl");
30356
+ const rollbackEvent = {
30357
+ type: "rollback",
30358
+ label: selected.label,
30359
+ sha: selected.sha,
30360
+ timestamp: new Date().toISOString(),
30361
+ source: "checkpoints.json"
30362
+ };
30363
+ try {
30364
+ fs29.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30365
+ `);
30366
+ } catch (error2) {
30367
+ console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
30368
+ }
30369
+ return `Rolled back to checkpoint "${selected.label}" (${selected.sha.slice(0, 12)})`;
30370
+ }
30218
30371
  async function handleRollbackCommand(directory, args) {
30219
30372
  const phaseArg = args[0];
30220
30373
  if (!phaseArg) {
30221
30374
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
30222
- if (!fs30.existsSync(manifestPath2)) {
30223
- return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
30375
+ if (!fs29.existsSync(manifestPath2)) {
30376
+ const gitCheckpoints = await listGitCheckpoints(directory);
30377
+ if (gitCheckpoints) {
30378
+ return formatGitCheckpointList(gitCheckpoints);
30379
+ }
30380
+ return "No checkpoints found. Use `/swarm checkpoint save <label>` to create checkpoints.";
30224
30381
  }
30225
30382
  let manifest2;
30226
30383
  try {
30227
- manifest2 = JSON.parse(fs30.readFileSync(manifestPath2, "utf-8"));
30384
+ manifest2 = JSON.parse(fs29.readFileSync(manifestPath2, "utf-8"));
30228
30385
  } catch {
30229
30386
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
30230
30387
  }
@@ -30243,15 +30400,31 @@ async function handleRollbackCommand(directory, args) {
30243
30400
  }
30244
30401
  const targetPhase = parseInt(phaseArg, 10);
30245
30402
  if (Number.isNaN(targetPhase) || targetPhase < 1) {
30246
- return "Error: Phase number must be a positive integer.";
30403
+ const gitCheckpoints = await listGitCheckpoints(directory);
30404
+ if (!gitCheckpoints) {
30405
+ return "Error: Phase number must be a positive integer.";
30406
+ }
30407
+ const selected = resolveGitCheckpoint(gitCheckpoints, phaseArg);
30408
+ if (!selected) {
30409
+ return `Error: Checkpoint "${phaseArg}" not found. Available checkpoints: ${gitCheckpoints.map((c) => `"${c.label}"`).join(", ") || "none"}`;
30410
+ }
30411
+ return restoreGitCheckpoint(directory, selected);
30247
30412
  }
30248
30413
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
30249
- if (!fs30.existsSync(manifestPath)) {
30250
- return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
30414
+ if (!fs29.existsSync(manifestPath)) {
30415
+ const gitCheckpoints = await listGitCheckpoints(directory);
30416
+ if (!gitCheckpoints) {
30417
+ return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
30418
+ }
30419
+ const selected = resolveGitCheckpoint(gitCheckpoints, phaseArg);
30420
+ if (!selected) {
30421
+ return `Error: Checkpoint ${phaseArg} not found. Available checkpoints: ${gitCheckpoints.map((c, index) => `${index + 1}="${c.label}"`).join(", ") || "none"}`;
30422
+ }
30423
+ return restoreGitCheckpoint(directory, selected);
30251
30424
  }
30252
30425
  let manifest;
30253
30426
  try {
30254
- manifest = JSON.parse(fs30.readFileSync(manifestPath, "utf-8"));
30427
+ manifest = JSON.parse(fs29.readFileSync(manifestPath, "utf-8"));
30255
30428
  } catch {
30256
30429
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
30257
30430
  }
@@ -30261,10 +30434,10 @@ async function handleRollbackCommand(directory, args) {
30261
30434
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
30262
30435
  }
30263
30436
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
30264
- if (!fs30.existsSync(checkpointDir)) {
30437
+ if (!fs29.existsSync(checkpointDir)) {
30265
30438
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
30266
30439
  }
30267
- const checkpointFiles = fs30.readdirSync(checkpointDir);
30440
+ const checkpointFiles = fs29.readdirSync(checkpointDir);
30268
30441
  if (checkpointFiles.length === 0) {
30269
30442
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
30270
30443
  }
@@ -30280,10 +30453,10 @@ async function handleRollbackCommand(directory, args) {
30280
30453
  if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
30281
30454
  continue;
30282
30455
  }
30283
- const src = path61.join(checkpointDir, file);
30284
- const dest = path61.join(swarmDir, file);
30456
+ const src = path62.join(checkpointDir, file);
30457
+ const dest = path62.join(swarmDir, file);
30285
30458
  try {
30286
- fs30.cpSync(src, dest, { recursive: true, force: true });
30459
+ fs29.cpSync(src, dest, { recursive: true, force: true });
30287
30460
  successes.push(file);
30288
30461
  } catch (error2) {
30289
30462
  failures.push({ file, error: error2.message });
@@ -30300,11 +30473,11 @@ async function handleRollbackCommand(directory, args) {
30300
30473
  ].join(`
30301
30474
  `);
30302
30475
  }
30303
- const existingLedgerPath = path61.join(swarmDir, "plan-ledger.jsonl");
30476
+ const existingLedgerPath = path62.join(swarmDir, "plan-ledger.jsonl");
30304
30477
  let ledgerDeletionFailed = false;
30305
- if (fs30.existsSync(existingLedgerPath)) {
30478
+ if (fs29.existsSync(existingLedgerPath)) {
30306
30479
  try {
30307
- fs30.unlinkSync(existingLedgerPath);
30480
+ fs29.unlinkSync(existingLedgerPath);
30308
30481
  } catch (err) {
30309
30482
  ledgerDeletionFailed = true;
30310
30483
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -30313,9 +30486,9 @@ async function handleRollbackCommand(directory, args) {
30313
30486
  }
30314
30487
  if (!ledgerDeletionFailed) {
30315
30488
  try {
30316
- const planJsonPath = path61.join(swarmDir, "plan.json");
30317
- if (fs30.existsSync(planJsonPath)) {
30318
- const planRaw = fs30.readFileSync(planJsonPath, "utf-8");
30489
+ const planJsonPath = path62.join(swarmDir, "plan.json");
30490
+ if (fs29.existsSync(planJsonPath)) {
30491
+ const planRaw = fs29.readFileSync(planJsonPath, "utf-8");
30319
30492
  const plan = PlanSchema.parse(JSON.parse(planRaw));
30320
30493
  const planId = derivePlanId(plan);
30321
30494
  const planHash = computePlanHash(plan);
@@ -30343,7 +30516,7 @@ async function handleRollbackCommand(directory, args) {
30343
30516
  timestamp: new Date().toISOString()
30344
30517
  };
30345
30518
  try {
30346
- fs30.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30519
+ fs29.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30347
30520
  `);
30348
30521
  } catch (error2) {
30349
30522
  console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
@@ -30360,9 +30533,9 @@ async function handleRollbackCommand(directory, args) {
30360
30533
  }
30361
30534
 
30362
30535
  // src/commands/sdd.ts
30363
- import * as fs31 from "fs";
30364
- import * as path62 from "path";
30365
- var SWARM_SPEC_REL = path62.join(".swarm", "spec.md");
30536
+ import * as fs30 from "fs";
30537
+ import * as path63 from "path";
30538
+ var SWARM_SPEC_REL = path63.join(".swarm", "spec.md");
30366
30539
  var USAGE9 = `Usage:
30367
30540
  /swarm sdd status [--json] [--source <provider>]
30368
30541
  /swarm sdd validate [--json] [--change <id>] [--source <provider>] [--feature <id>]
@@ -30478,7 +30651,7 @@ ${USAGE9}`;
30478
30651
  }
30479
30652
  const speckitDetection = detectSpeckit(directory);
30480
30653
  const speckitPresent = speckitDetection.features.length > 0;
30481
- const nativeSpecExists = fs31.existsSync(path62.join(directory, SWARM_SPEC_REL));
30654
+ const nativeSpecExists = fs30.existsSync(path63.join(directory, SWARM_SPEC_REL));
30482
30655
  if (speckitPresent && !parsed.source && !nativeSpecExists) {
30483
30656
  const openspecProjection = buildOpenSpecProjectionSync(directory);
30484
30657
  if (openspecProjection !== null) {
@@ -30548,7 +30721,7 @@ ${USAGE9}`;
30548
30721
  ${USAGE9}`;
30549
30722
  }
30550
30723
  let useSpeckit = false;
30551
- const nativeSpecExists = fs31.existsSync(path62.join(directory, SWARM_SPEC_REL));
30724
+ const nativeSpecExists = fs30.existsSync(path63.join(directory, SWARM_SPEC_REL));
30552
30725
  if (parsed.source === "speckit") {
30553
30726
  useSpeckit = true;
30554
30727
  } else if (!parsed.source && !nativeSpecExists) {
@@ -30859,13 +31032,13 @@ Ensure this is a git repository with commit history.`;
30859
31032
  const report = reportLines.filter(Boolean).join(`
30860
31033
  `);
30861
31034
  try {
30862
- const fs32 = await import("fs/promises");
30863
- const path63 = await import("path");
30864
- const reportPath = path63.join(directory, ".swarm", "simulate-report.md");
30865
- await fs32.mkdir(path63.dirname(reportPath), { recursive: true });
30866
- const reportTempPath = path63.join(path63.dirname(reportPath), `${path63.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
31035
+ const fs31 = await import("fs/promises");
31036
+ const path64 = await import("path");
31037
+ const reportPath = path64.join(directory, ".swarm", "simulate-report.md");
31038
+ await fs31.mkdir(path64.dirname(reportPath), { recursive: true });
31039
+ const reportTempPath = path64.join(path64.dirname(reportPath), `${path64.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
30867
31040
  try {
30868
- await fs32.writeFile(reportTempPath, report, "utf-8");
31041
+ await fs31.writeFile(reportTempPath, report, "utf-8");
30869
31042
  renameSync11(reportTempPath, reportPath);
30870
31043
  } catch (err) {
30871
31044
  try {
@@ -30891,8 +31064,8 @@ async function handleSpecifyCommand(_directory, args) {
30891
31064
 
30892
31065
  // src/services/status-service.ts
30893
31066
  import * as fsSync2 from "fs";
30894
- import { readFile as readFile16 } from "fs/promises";
30895
- import * as path64 from "path";
31067
+ import { readFile as readFile17 } from "fs/promises";
31068
+ import * as path65 from "path";
30896
31069
 
30897
31070
  // src/hooks/extractors.ts
30898
31071
  function extractCurrentPhase(planContent) {
@@ -30936,16 +31109,16 @@ function extractCurrentPhaseFromPlan2(plan) {
30936
31109
 
30937
31110
  // src/turbo/lean/state.ts
30938
31111
  init_logger();
30939
- import * as fs32 from "fs";
30940
- import * as path63 from "path";
31112
+ import * as fs31 from "fs";
31113
+ import * as path64 from "path";
30941
31114
  var STATE_FILE3 = "turbo-state.json";
30942
31115
  function nowISO3() {
30943
31116
  return new Date().toISOString();
30944
31117
  }
30945
31118
  function ensureSwarmDir2(directory) {
30946
- const swarmDir = path63.resolve(directory, ".swarm");
30947
- if (!fs32.existsSync(swarmDir)) {
30948
- fs32.mkdirSync(swarmDir, { recursive: true });
31119
+ const swarmDir = path64.resolve(directory, ".swarm");
31120
+ if (!fs31.existsSync(swarmDir)) {
31121
+ fs31.mkdirSync(swarmDir, { recursive: true });
30949
31122
  }
30950
31123
  return swarmDir;
30951
31124
  }
@@ -30988,17 +31161,17 @@ function markStateUnreadable2(directory, reason) {
30988
31161
  }
30989
31162
  function readPersisted2(directory) {
30990
31163
  try {
30991
- const filePath = path63.join(directory, ".swarm", STATE_FILE3);
30992
- if (!fs32.existsSync(filePath)) {
31164
+ const filePath = path64.join(directory, ".swarm", STATE_FILE3);
31165
+ if (!fs31.existsSync(filePath)) {
30993
31166
  const seed = emptyPersisted2();
30994
31167
  try {
30995
31168
  ensureSwarmDir2(directory);
30996
- fs32.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
31169
+ fs31.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
30997
31170
  `, "utf-8");
30998
31171
  } catch {}
30999
31172
  return seed;
31000
31173
  }
31001
- const raw = fs32.readFileSync(filePath, "utf-8");
31174
+ const raw = fs31.readFileSync(filePath, "utf-8");
31002
31175
  const parsed = JSON.parse(raw);
31003
31176
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
31004
31177
  markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -31024,7 +31197,7 @@ function writePersisted2(directory, persisted) {
31024
31197
  let payload;
31025
31198
  try {
31026
31199
  ensureSwarmDir2(directory);
31027
- filePath = path63.join(directory, ".swarm", STATE_FILE3);
31200
+ filePath = path64.join(directory, ".swarm", STATE_FILE3);
31028
31201
  tmpPath = `${filePath}.tmp.${Date.now()}`;
31029
31202
  persisted.updatedAt = nowISO3();
31030
31203
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -31035,14 +31208,14 @@ function writePersisted2(directory, persisted) {
31035
31208
  throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
31036
31209
  }
31037
31210
  try {
31038
- fs32.writeFileSync(tmpPath, payload, "utf-8");
31039
- fs32.renameSync(tmpPath, filePath);
31211
+ fs31.writeFileSync(tmpPath, payload, "utf-8");
31212
+ fs31.renameSync(tmpPath, filePath);
31040
31213
  } catch (error2) {
31041
31214
  const msg = error2 instanceof Error ? error2.message : String(error2);
31042
31215
  error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
31043
31216
  try {
31044
- if (fs32.existsSync(tmpPath)) {
31045
- fs32.unlinkSync(tmpPath);
31217
+ if (fs31.existsSync(tmpPath)) {
31218
+ fs31.unlinkSync(tmpPath);
31046
31219
  }
31047
31220
  } catch {}
31048
31221
  throw new Error(`Lean Turbo state persistence failed: ${msg}`);
@@ -31142,7 +31315,7 @@ var _internals47 = {
31142
31315
  };
31143
31316
  function readSpecStalenessSnapshot(directory) {
31144
31317
  try {
31145
- const p = path64.join(directory, ".swarm", "spec-staleness.json");
31318
+ const p = path65.join(directory, ".swarm", "spec-staleness.json");
31146
31319
  if (!fsSync2.existsSync(p))
31147
31320
  return { stale: false };
31148
31321
  const raw = fsSync2.readFileSync(p, "utf-8");
@@ -31395,7 +31568,7 @@ async function safeLineCount(filePath) {
31395
31568
  try {
31396
31569
  if (!fsSync2.existsSync(filePath))
31397
31570
  return 0;
31398
- const content = await readFile16(filePath, "utf-8");
31571
+ const content = await readFile17(filePath, "utf-8");
31399
31572
  let n = 0;
31400
31573
  for (const line of content.split(`
31401
31574
  `)) {
@@ -31674,13 +31847,13 @@ function buildStatusMessage2(session, directory, sessionID) {
31674
31847
  }
31675
31848
 
31676
31849
  // src/commands/unlink.ts
31677
- import { existsSync as existsSync39 } from "fs";
31678
- import * as path65 from "path";
31850
+ import { existsSync as existsSync40 } from "fs";
31851
+ import * as path66 from "path";
31679
31852
  var DEDUP_THRESHOLD2 = 0.6;
31680
31853
  async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
31681
- const sharedPath = path65.join(linkDir, "knowledge.jsonl");
31682
- const localPath = path65.join(localSwarmDir, "knowledge.jsonl");
31683
- if (!existsSync39(sharedPath))
31854
+ const sharedPath = path66.join(linkDir, "knowledge.jsonl");
31855
+ const localPath = path66.join(localSwarmDir, "knowledge.jsonl");
31856
+ if (!existsSync40(sharedPath))
31684
31857
  return 0;
31685
31858
  const sharedEntries = await readKnowledge(sharedPath);
31686
31859
  if (sharedEntries.length === 0)
@@ -31714,7 +31887,7 @@ async function handleUnlinkCommand(directory, args) {
31714
31887
  let copied = 0;
31715
31888
  if (copyBack) {
31716
31889
  try {
31717
- copied = await copySharedKnowledgeToLocal(linkDir, path65.join(directory, ".swarm"));
31890
+ copied = await copySharedKnowledgeToLocal(linkDir, path66.join(directory, ".swarm"));
31718
31891
  } catch (error2) {
31719
31892
  return `\u274C Failed to copy shared knowledge back to local: ${error2 instanceof Error ? error2.message : String(error2)}`;
31720
31893
  }
@@ -31876,7 +32049,7 @@ function buildDetailedHelp(commandName, entry) {
31876
32049
  async function handleHelpCommand(ctx) {
31877
32050
  const targetCommand = ctx.args.join(" ");
31878
32051
  if (!targetCommand) {
31879
- const { buildHelpText } = await import("./index-87d4wsv9.js");
32052
+ const { buildHelpText } = await import("./index-502f6np6.js");
31880
32053
  return buildHelpText();
31881
32054
  }
31882
32055
  const tokens = targetCommand.split(/\s+/);
@@ -31885,7 +32058,7 @@ async function handleHelpCommand(ctx) {
31885
32058
  return _internals49.buildDetailedHelp(resolved.key, resolved.entry);
31886
32059
  }
31887
32060
  const similar = _internals49.findSimilarCommands(targetCommand);
31888
- const { buildHelpText: fullHelp } = await import("./index-87d4wsv9.js");
32061
+ const { buildHelpText: fullHelp } = await import("./index-502f6np6.js");
31889
32062
  if (similar.length > 0) {
31890
32063
  return `Command '/swarm ${targetCommand}' not found.
31891
32064
 
@@ -32018,7 +32191,7 @@ var COMMAND_REGISTRY = {
32018
32191
  },
32019
32192
  "guardrail explain": {
32020
32193
  handler: async (ctx) => {
32021
- const { handleGuardrailExplain } = await import("./guardrail-explain-414smfg4.js");
32194
+ const { handleGuardrailExplain } = await import("./guardrail-explain-etdrhd4d.js");
32022
32195
  return handleGuardrailExplain(ctx.directory, ctx.args);
32023
32196
  },
32024
32197
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -32028,7 +32201,7 @@ var COMMAND_REGISTRY = {
32028
32201
  },
32029
32202
  "guardrail-log": {
32030
32203
  handler: async (ctx) => {
32031
- const { handleGuardrailLog } = await import("./guardrail-log-fsc85hwa.js");
32204
+ const { handleGuardrailLog } = await import("./guardrail-log-2rns4g6d.js");
32032
32205
  return handleGuardrailLog(ctx.directory, ctx.args);
32033
32206
  },
32034
32207
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -32540,9 +32713,9 @@ Subcommands:
32540
32713
  },
32541
32714
  rollback: {
32542
32715
  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>",
32716
+ description: "Restore swarm state or project files to a checkpoint",
32717
+ 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.",
32718
+ args: "<phase-number|label|list-number>",
32546
32719
  category: "utility",
32547
32720
  toolPolicy: "restricted"
32548
32721
  },
@@ -32555,7 +32728,7 @@ Subcommands:
32555
32728
  toolPolicy: "agent"
32556
32729
  },
32557
32730
  handoff: {
32558
- handler: (ctx) => handleHandoffCommand(ctx.directory, ctx.args),
32731
+ handler: (ctx) => handleHandoffCommand(ctx.directory, ctx.args, ctx.sessionID),
32559
32732
  description: "Prepare state for clean model switch (new session)",
32560
32733
  args: "",
32561
32734
  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 +32954,7 @@ Subcommands:
32781
32954
  checkpoint: {
32782
32955
  handler: (ctx) => handleCheckpointCommand(ctx.directory, ctx.args),
32783
32956
  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.",
32957
+ 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
32958
  args: "<save|restore|delete|list> <label>",
32786
32959
  category: "utility",
32787
32960
  clashesWithNativeCcCommand: "/checkpoint",
@@ -32801,24 +32974,24 @@ function validateAliases() {
32801
32974
  continue;
32802
32975
  }
32803
32976
  const visited = new Set;
32804
- const path66 = [];
32977
+ const path67 = [];
32805
32978
  let current = target;
32806
32979
  while (current) {
32807
32980
  const currentEntry = COMMAND_REGISTRY[current];
32808
32981
  if (!currentEntry)
32809
32982
  break;
32810
32983
  if (visited.has(current)) {
32811
- const cycleStart = path66.indexOf(current);
32984
+ const cycleStart = path67.indexOf(current);
32812
32985
  const fullChain = [
32813
32986
  name,
32814
- ...path66.slice(0, cycleStart > 0 ? cycleStart : path66.length),
32987
+ ...path67.slice(0, cycleStart > 0 ? cycleStart : path67.length),
32815
32988
  current
32816
32989
  ].join(" \u2192 ");
32817
32990
  errors.push(`Circular alias detected: ${fullChain}`);
32818
32991
  break;
32819
32992
  }
32820
32993
  visited.add(current);
32821
- path66.push(current);
32994
+ path67.push(current);
32822
32995
  current = currentEntry.aliasOf || "";
32823
32996
  }
32824
32997
  }
@@ -34157,7 +34330,7 @@ init_logger();
34157
34330
 
34158
34331
  // src/hooks/guardrails/destructive-command.ts
34159
34332
  import * as fsSync3 from "fs";
34160
- import * as path66 from "path";
34333
+ import * as path67 from "path";
34161
34334
  var DC_MAX_UNWRAP_DEPTH = 5;
34162
34335
  var DC_SAFE_TARGETS = new Set([
34163
34336
  "node_modules",
@@ -34321,16 +34494,16 @@ function dcIsRemotePath(p) {
34321
34494
  return DC_REMOTE_PREFIXES.some((pfx) => p.startsWith(pfx));
34322
34495
  }
34323
34496
  function dcLstatAncestorWalk(targetPath, cwd) {
34324
- const normalizedTarget = path66.resolve(cwd, targetPath);
34325
- const normalizedCwd = path66.resolve(cwd);
34497
+ const normalizedTarget = path67.resolve(cwd, targetPath);
34498
+ const normalizedCwd = path67.resolve(cwd);
34326
34499
  const ancestors = [];
34327
34500
  let current = normalizedTarget;
34328
34501
  while (true) {
34329
34502
  ancestors.push(current);
34330
- const parent = path66.dirname(current);
34503
+ const parent = path67.dirname(current);
34331
34504
  if (parent === current)
34332
34505
  break;
34333
- const rel = path66.relative(normalizedCwd, current);
34506
+ const rel = path67.relative(normalizedCwd, current);
34334
34507
  if (rel === "" || rel.startsWith(".."))
34335
34508
  break;
34336
34509
  current = parent;
@@ -34369,14 +34542,14 @@ function dcValidateTargets(targets, cwd) {
34369
34542
  const lstatBlock = dcLstatAncestorWalk(t, cwd);
34370
34543
  if (lstatBlock)
34371
34544
  return lstatBlock;
34372
- const basename11 = path66.basename(t);
34373
- if (t === basename11 && DC_SAFE_TARGETS.has(t)) {
34545
+ const basename12 = path67.basename(t);
34546
+ if (t === basename12 && DC_SAFE_TARGETS.has(t)) {
34374
34547
  continue;
34375
34548
  }
34376
34549
  if (DC_FS_ROOTS.has(t) || DC_FS_ROOTS.has(t.replace(/\//g, "\\"))) {
34377
34550
  return `BLOCKED: Destructive command targets filesystem root "${t}"`;
34378
34551
  }
34379
- if (path66.isAbsolute(t) || /^[A-Za-z]:/.test(t)) {
34552
+ if (path67.isAbsolute(t) || /^[A-Za-z]:/.test(t)) {
34380
34553
  for (const blocked of DC_BLOCKED_ABSOLUTE_PREFIXES) {
34381
34554
  if (t.startsWith(blocked)) {
34382
34555
  return `BLOCKED: Destructive command targets system path "${t}" which is under protected prefix "${blocked}"`;
@@ -34391,9 +34564,9 @@ function dcCheckJunctionCreation(segment, cwd) {
34391
34564
  if (mklinkMatch) {
34392
34565
  const target = mklinkMatch[2].trim();
34393
34566
  if (!dcHasUnresolvableVars(target)) {
34394
- const resolved = path66.resolve(cwd, target);
34395
- const rel = path66.relative(cwd, resolved);
34396
- if (rel.startsWith("..") || path66.isAbsolute(rel)) {
34567
+ const resolved = path67.resolve(cwd, target);
34568
+ const rel = path67.relative(cwd, resolved);
34569
+ if (rel.startsWith("..") || path67.isAbsolute(rel)) {
34397
34570
  return `BLOCKED: Junction/symlink creation targeting path outside working directory: mklink target "${target}" resolves to "${resolved}" which is outside "${cwd}". Creating junctions to external paths and then deleting them recursively can destroy data.`;
34398
34571
  }
34399
34572
  }
@@ -34405,9 +34578,9 @@ function dcCheckJunctionCreation(segment, cwd) {
34405
34578
  if (newItemMatch) {
34406
34579
  const target = newItemMatch[1].trim();
34407
34580
  if (!dcHasUnresolvableVars(target)) {
34408
- const resolved = path66.resolve(cwd, target);
34409
- const rel = path66.relative(cwd, resolved);
34410
- if (rel.startsWith("..") || path66.isAbsolute(rel)) {
34581
+ const resolved = path67.resolve(cwd, target);
34582
+ const rel = path67.relative(cwd, resolved);
34583
+ if (rel.startsWith("..") || path67.isAbsolute(rel)) {
34411
34584
  return `BLOCKED: Junction/symlink creation targeting path outside working directory: New-Item target "${target}" resolves to "${resolved}" which is outside "${cwd}". This pattern caused the K2.6 data-loss incident.`;
34412
34585
  }
34413
34586
  }
@@ -34417,9 +34590,9 @@ function dcCheckJunctionCreation(segment, cwd) {
34417
34590
  if (lnMatch) {
34418
34591
  const target = lnMatch[1].trim();
34419
34592
  if (!dcHasUnresolvableVars(target)) {
34420
- const resolved = path66.resolve(cwd, target);
34421
- const rel = path66.relative(cwd, resolved);
34422
- if (rel.startsWith("..") || path66.isAbsolute(rel)) {
34593
+ const resolved = path67.resolve(cwd, target);
34594
+ const rel = path67.relative(cwd, resolved);
34595
+ if (rel.startsWith("..") || path67.isAbsolute(rel)) {
34423
34596
  return `BLOCKED: Symlink creation targeting path outside working directory: ln -s target "${target}" resolves to "${resolved}" which is outside "${cwd}". Symlinks to external paths combined with recursive deletion can destroy data.`;
34424
34597
  }
34425
34598
  }
@@ -34790,10 +34963,10 @@ function classifySwarmCommandChatFallbackUse(resolved) {
34790
34963
  init_executor();
34791
34964
 
34792
34965
  // src/hooks/shell-write-detect.ts
34793
- import * as path67 from "path";
34966
+ import * as path68 from "path";
34794
34967
  import parse from "bash-parser";
34795
- function buildDedupeKey(category, operator, path68) {
34796
- return `${category}|${operator}|${path68 ?? "null"}`;
34968
+ function buildDedupeKey(category, operator, path69) {
34969
+ return `${category}|${operator}|${path69 ?? "null"}`;
34797
34970
  }
34798
34971
  var REDIRECT_WRITE_TOKENS = new Set([
34799
34972
  "GREAT",
@@ -34853,16 +35026,16 @@ function detectProcessSubstitutionWrites(command) {
34853
35026
  results.push(builtinResult);
34854
35027
  const appendMatch = stage.match(/^\s*(.*?)\s*>>(\s*)(\S+)\s*$/);
34855
35028
  if (appendMatch) {
34856
- const path68 = appendMatch[3];
34857
- if (path68 && !isNullDevice(path68)) {
34858
- results.push({ category: "redirect", operator: ">>", path: path68 });
35029
+ const path69 = appendMatch[3];
35030
+ if (path69 && !isNullDevice(path69)) {
35031
+ results.push({ category: "redirect", operator: ">>", path: path69 });
34859
35032
  }
34860
35033
  } else {
34861
35034
  const writeMatch = stage.match(/^\s*(.*?)\s*>(?!>)(\s*)(\S+)\s*$/);
34862
35035
  if (writeMatch) {
34863
- const path68 = writeMatch[3];
34864
- if (path68 && !isNullDevice(path68)) {
34865
- results.push({ category: "redirect", operator: ">", path: path68 });
35036
+ const path69 = writeMatch[3];
35037
+ if (path69 && !isNullDevice(path69)) {
35038
+ results.push({ category: "redirect", operator: ">", path: path69 });
34866
35039
  }
34867
35040
  }
34868
35041
  }
@@ -35036,8 +35209,8 @@ function extractRedirectPath(fileNode) {
35036
35209
  return null;
35037
35210
  return text;
35038
35211
  }
35039
- function isNullDevice(path68) {
35040
- return path68 === "/dev/null" || path68 === "/dev/zero" || path68 === "/dev/urandom";
35212
+ function isNullDevice(path69) {
35213
+ return path69 === "/dev/null" || path69 === "/dev/zero" || path69 === "/dev/urandom";
35041
35214
  }
35042
35215
  function isNumeric(s) {
35043
35216
  return /^\d+$/.test(s);
@@ -35057,12 +35230,12 @@ function detectRedirects(cmd) {
35057
35230
  if (!opType || !REDIRECT_ALL_WRITE_TOKENS.has(opType))
35058
35231
  continue;
35059
35232
  const fileNode = r.file;
35060
- const path68 = extractRedirectPath(fileNode);
35233
+ const path69 = extractRedirectPath(fileNode);
35061
35234
  const opLabel = operatorLabel(opNode);
35062
35235
  if (REDIRECT_WRITE_TOKENS.has(opType)) {
35063
- results.push({ category: "redirect", operator: opLabel, path: path68 });
35236
+ results.push({ category: "redirect", operator: opLabel, path: path69 });
35064
35237
  } else if (REDIRECT_HERE_TOKENS.has(opType)) {
35065
- results.push({ category: "here_doc", operator: opLabel, path: path68 });
35238
+ results.push({ category: "here_doc", operator: opLabel, path: path69 });
35066
35239
  }
35067
35240
  }
35068
35241
  return results;
@@ -35105,9 +35278,9 @@ function detectBuiltinWrites(cmd) {
35105
35278
  const suffixWords2 = getSuffixWords(cmd);
35106
35279
  for (const word of suffixWords2) {
35107
35280
  if (word.startsWith("of=")) {
35108
- const path68 = word.slice(3);
35109
- if (path68 && !isNullDevice(path68)) {
35110
- results.push({ category: "builtin_write", operator: "dd of=", path: path68 });
35281
+ const path69 = word.slice(3);
35282
+ if (path69 && !isNullDevice(path69)) {
35283
+ results.push({ category: "builtin_write", operator: "dd of=", path: path69 });
35111
35284
  }
35112
35285
  }
35113
35286
  }
@@ -35226,12 +35399,12 @@ function detectNetworkDownloaders(cmd) {
35226
35399
  for (let i = 0;i < suffixWords.length; i++) {
35227
35400
  const word = suffixWords[i];
35228
35401
  if (word === "-o" && i + 1 < suffixWords.length) {
35229
- const path68 = suffixWords[i + 1];
35230
- if (!path68.startsWith("-")) {
35402
+ const path69 = suffixWords[i + 1];
35403
+ if (!path69.startsWith("-")) {
35231
35404
  results.push({
35232
35405
  category: "network_download",
35233
35406
  operator: "curl -o",
35234
- path: path68
35407
+ path: path69
35235
35408
  });
35236
35409
  }
35237
35410
  } else if (word.startsWith("-o") && word.length > 2) {
@@ -35246,12 +35419,12 @@ function detectNetworkDownloaders(cmd) {
35246
35419
  for (let i = 0;i < suffixWords.length; i++) {
35247
35420
  const word = suffixWords[i];
35248
35421
  if (word === "-O" && i + 1 < suffixWords.length) {
35249
- const path68 = suffixWords[i + 1];
35250
- if (!path68.startsWith("-")) {
35422
+ const path69 = suffixWords[i + 1];
35423
+ if (!path69.startsWith("-")) {
35251
35424
  results.push({
35252
35425
  category: "network_download",
35253
35426
  operator: "wget -O",
35254
- path: path68
35427
+ path: path69
35255
35428
  });
35256
35429
  }
35257
35430
  } else if (word.startsWith("-O") && word.length > 2) {
@@ -35360,9 +35533,9 @@ function detectGitDestructive(cmd) {
35360
35533
  if (first === "checkout") {
35361
35534
  const dashDashIdx = suffixWords.indexOf("--");
35362
35535
  if (dashDashIdx !== -1 && dashDashIdx + 1 < suffixWords.length) {
35363
- const path68 = suffixWords[dashDashIdx + 1];
35364
- const op = path68 === "." ? "git checkout -- ." : "git checkout --";
35365
- results.push({ category: "git_destructive", operator: op, path: path68 });
35536
+ const path69 = suffixWords[dashDashIdx + 1];
35537
+ const op = path69 === "." ? "git checkout -- ." : "git checkout --";
35538
+ results.push({ category: "git_destructive", operator: op, path: path69 });
35366
35539
  }
35367
35540
  } else if (first === "restore") {
35368
35541
  const hasHard = suffixWords.some((w) => w === "--hard" || w === "-H" || w.startsWith("-") && w.includes("H"));
@@ -35482,10 +35655,10 @@ function detectPowerShellWrites(command) {
35482
35655
  if (redirectMatch) {
35483
35656
  const beforeRedirect = redirectMatch[1];
35484
35657
  const op = redirectMatch[2];
35485
- const path68 = redirectMatch[3];
35658
+ const path69 = redirectMatch[3];
35486
35659
  const fdRedirectPattern = /\d>\s*$|\s\d>&$/;
35487
35660
  if (!fdRedirectPattern.test(`${beforeRedirect} ${op}`)) {
35488
- results.push({ category: "redirect", operator: op, path: path68 });
35661
+ results.push({ category: "redirect", operator: op, path: path69 });
35489
35662
  }
35490
35663
  }
35491
35664
  const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
@@ -35498,12 +35671,12 @@ function detectPowerShellWrites(command) {
35498
35671
  }
35499
35672
  const iwrMatch = trimmed.match(/^(?:Invoke-WebRequest|curl)\s.*?(?:-OutFile\s+(\S+)|-o\s+(\S+))/i);
35500
35673
  if (iwrMatch) {
35501
- const path68 = iwrMatch[1] || iwrMatch[2];
35502
- if (path68) {
35674
+ const path69 = iwrMatch[1] || iwrMatch[2];
35675
+ if (path69) {
35503
35676
  results.push({
35504
35677
  category: "network_download",
35505
35678
  operator: "Invoke-WebRequest -OutFile",
35506
- path: path68
35679
+ path: path69
35507
35680
  });
35508
35681
  }
35509
35682
  }
@@ -35515,15 +35688,15 @@ function detectPowerShellWrites(command) {
35515
35688
  const rest = cmd.slice(cmdletMatch[0].length).trim();
35516
35689
  const pathFlagMatch = rest.match(/(?:-Path|-FilePath|-LiteralPath)\s+("([^"]+)"|'([^']+)'|(\S+))/i);
35517
35690
  if (pathFlagMatch) {
35518
- const path68 = pathFlagMatch[2] ?? pathFlagMatch[3] ?? pathFlagMatch[4] ?? "";
35519
- return { category: "redirect", operator: cmdletName, path: path68 };
35691
+ const path69 = pathFlagMatch[2] ?? pathFlagMatch[3] ?? pathFlagMatch[4] ?? "";
35692
+ return { category: "redirect", operator: cmdletName, path: path69 };
35520
35693
  }
35521
35694
  const tokens = rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
35522
35695
  for (const token of tokens) {
35523
35696
  if (token.startsWith("-"))
35524
35697
  continue;
35525
- const path68 = token.replace(/^["']|["']$/g, "");
35526
- return { category: "redirect", operator: cmdletName, path: path68 };
35698
+ const path69 = token.replace(/^["']|["']$/g, "");
35699
+ return { category: "redirect", operator: cmdletName, path: path69 };
35527
35700
  }
35528
35701
  return null;
35529
35702
  }
@@ -35539,9 +35712,9 @@ function detectPowerShellWrites(command) {
35539
35712
  for (const token of tokens) {
35540
35713
  if (token.startsWith("-"))
35541
35714
  continue;
35542
- const path68 = token.replace(/^["']|["']$/g, "");
35543
- if (path68) {
35544
- results.push({ category: "redirect", operator: cmdletName, path: path68 });
35715
+ const path69 = token.replace(/^["']|["']$/g, "");
35716
+ if (path69) {
35717
+ results.push({ category: "redirect", operator: cmdletName, path: path69 });
35545
35718
  break;
35546
35719
  }
35547
35720
  }
@@ -35554,8 +35727,8 @@ function detectPowerShellWrites(command) {
35554
35727
  const rest = cmd.slice(opMatch[0].length).trim();
35555
35728
  const destFlagMatch = rest.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);
35556
35729
  if (destFlagMatch) {
35557
- const path68 = destFlagMatch[1].replace(/^["']|["']$/g, "");
35558
- return { category: "builtin_write", operator: cmdletName, path: path68 };
35730
+ const path69 = destFlagMatch[1].replace(/^["']|["']$/g, "");
35731
+ return { category: "builtin_write", operator: cmdletName, path: path69 };
35559
35732
  }
35560
35733
  const tokens = [];
35561
35734
  const flagTakingValue = new Set([
@@ -35594,11 +35767,11 @@ function detectPowerShellWrites(command) {
35594
35767
  }
35595
35768
  }
35596
35769
  if (tokens.length >= 2) {
35597
- const path68 = tokens[tokens.length - 1].replace(/^["']|["']$/g, "");
35598
- return { category: "builtin_write", operator: cmdletName, path: path68 };
35770
+ const path69 = tokens[tokens.length - 1].replace(/^["']|["']$/g, "");
35771
+ return { category: "builtin_write", operator: cmdletName, path: path69 };
35599
35772
  } else if (tokens.length === 1) {
35600
- const path68 = tokens[0].replace(/^["']|["']$/g, "");
35601
- return { category: "builtin_write", operator: cmdletName, path: path68 };
35773
+ const path69 = tokens[0].replace(/^["']|["']$/g, "");
35774
+ return { category: "builtin_write", operator: cmdletName, path: path69 };
35602
35775
  }
35603
35776
  return null;
35604
35777
  }
@@ -35612,14 +35785,14 @@ function detectPowerShellWrites(command) {
35612
35785
  const afterCmdlet = pipeFileOpMatch[2].trim();
35613
35786
  const destFlagMatch = afterCmdlet.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);
35614
35787
  if (destFlagMatch) {
35615
- const path68 = destFlagMatch[1].replace(/^["']|["']$/g, "");
35616
- results.push({ category: "builtin_write", operator: cmdletName, path: path68 });
35788
+ const path69 = destFlagMatch[1].replace(/^["']|["']$/g, "");
35789
+ results.push({ category: "builtin_write", operator: cmdletName, path: path69 });
35617
35790
  } else {
35618
35791
  const tokens = afterCmdlet.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
35619
35792
  const nonFlagTokens = tokens.filter((t) => !t.startsWith("-") && t.length > 0);
35620
35793
  if (nonFlagTokens.length > 0) {
35621
- const path68 = nonFlagTokens[nonFlagTokens.length - 1].replace(/^["']|["']$/g, "");
35622
- results.push({ category: "builtin_write", operator: cmdletName, path: path68 });
35794
+ const path69 = nonFlagTokens[nonFlagTokens.length - 1].replace(/^["']|["']$/g, "");
35795
+ results.push({ category: "builtin_write", operator: cmdletName, path: path69 });
35623
35796
  }
35624
35797
  }
35625
35798
  }
@@ -35672,10 +35845,10 @@ function detectCmdWrites(command) {
35672
35845
  if (redirectMatch) {
35673
35846
  const beforeRedirect = redirectMatch[1];
35674
35847
  const op = redirectMatch[2];
35675
- const path68 = redirectMatch[3];
35848
+ const path69 = redirectMatch[3];
35676
35849
  const fdRedirectPattern = /\d>&?$/;
35677
35850
  if (!fdRedirectPattern.test(beforeRedirect)) {
35678
- results.push({ category: "redirect", operator: op, path: path68 });
35851
+ results.push({ category: "redirect", operator: op, path: path69 });
35679
35852
  }
35680
35853
  }
35681
35854
  const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
@@ -35733,8 +35906,8 @@ function detectCmdWrites(command) {
35733
35906
  const rawTokens = rest.match(/(\/?[^\s]+|"[^"]*"|'[^']*')/g) ?? [];
35734
35907
  const tokens = rawTokens.filter((t) => !t.startsWith("/"));
35735
35908
  if (tokens.length > 0) {
35736
- const path68 = tokens[0].replace(/^["']|["']$/g, "");
35737
- return { category: "builtin_write", operator: "del", path: path68 };
35909
+ const path69 = tokens[0].replace(/^["']|["']$/g, "");
35910
+ return { category: "builtin_write", operator: "del", path: path69 };
35738
35911
  }
35739
35912
  return null;
35740
35913
  }
@@ -35744,16 +35917,16 @@ function detectCmdWrites(command) {
35744
35917
  }
35745
35918
  const rdMatch = innerCommand.match(/^rd\s+(?:\/s\s+|\/q\s+)*(\S+)/i);
35746
35919
  if (rdMatch) {
35747
- const path68 = rdMatch[1].replace(/^["']|["']$/g, "");
35748
- if (!path68.startsWith("/")) {
35749
- results.push({ category: "builtin_write", operator: "rd", path: path68 });
35920
+ const path69 = rdMatch[1].replace(/^["']|["']$/g, "");
35921
+ if (!path69.startsWith("/")) {
35922
+ results.push({ category: "builtin_write", operator: "rd", path: path69 });
35750
35923
  }
35751
35924
  }
35752
35925
  const mdMatch = trimmed.match(/^md\s+(\S+)/i);
35753
35926
  if (mdMatch) {
35754
- const path68 = mdMatch[1].replace(/^["']|["']$/g, "");
35755
- if (!path68.startsWith("/")) {
35756
- results.push({ category: "builtin_write", operator: "md", path: path68 });
35927
+ const path69 = mdMatch[1].replace(/^["']|["']$/g, "");
35928
+ if (!path69.startsWith("/")) {
35929
+ results.push({ category: "builtin_write", operator: "md", path: path69 });
35757
35930
  }
35758
35931
  }
35759
35932
  const echoMatch = trimmed.match(/^echo\s+(\S+.*?)\s+((?:>){1,2})\s*(\S+)$/i);
@@ -35869,9 +36042,10 @@ function resolvePath(pathText, cwd) {
35869
36042
  return null;
35870
36043
  const isWindowsPath = /^[a-zA-Z]:[\\\\/]/.test(cwd) || cwd.includes("\\");
35871
36044
  if (isWindowsPath) {
35872
- return path67.win32.resolve(cwd, pathText);
36045
+ return path68.win32.resolve(cwd, pathText);
35873
36046
  }
35874
- return path67.posix.resolve(cwd, pathText);
36047
+ const normalizedRelativeWindowsPath = !path68.posix.isAbsolute(pathText) && !/^[a-zA-Z]:[\\/]/.test(pathText) ? pathText.replace(/\\/g, "/") : pathText;
36048
+ return path68.posix.resolve(cwd, normalizedRelativeWindowsPath);
35875
36049
  }
35876
36050
  function getCdTarget(cmd) {
35877
36051
  if (!cmd || typeof cmd !== "object")
@@ -35938,7 +36112,7 @@ function collectWritesWithNodes(node, out, cwdStack) {
35938
36112
  for (const cmd of node.commands) {
35939
36113
  const cdTarget = getCdTarget(cmd);
35940
36114
  if (cdTarget) {
35941
- currentStack[0] = path67.posix.resolve(currentStack[0] ?? "/", cdTarget);
36115
+ currentStack[0] = path68.posix.resolve(currentStack[0] ?? "/", cdTarget);
35942
36116
  collectWritesWithNodes(cmd, out, currentStack);
35943
36117
  } else {
35944
36118
  collectWritesWithNodes(cmd, out, currentStack);
@@ -35984,7 +36158,7 @@ function collectWritesWithNodes(node, out, cwdStack) {
35984
36158
  const effectiveCwd = cwdStack[0] ?? "/";
35985
36159
  const cdTarget = getCdTarget(node);
35986
36160
  if (cdTarget) {
35987
- cwdStack[0] = path67.posix.resolve(cwdStack[0] ?? "/", cdTarget);
36161
+ cwdStack[0] = path68.posix.resolve(cwdStack[0] ?? "/", cdTarget);
35988
36162
  return;
35989
36163
  }
35990
36164
  const writesFromRedirs = getWritesFromCommandRedirs(node, effectiveCwd);
@@ -36030,12 +36204,12 @@ function getWritesFromRedirectNode(redirect, _context) {
36030
36204
  if (!opType || !REDIRECT_ALL_WRITE_TOKENS.has(opType))
36031
36205
  return [];
36032
36206
  const fileNode = r.file;
36033
- const path68 = extractRedirectPath(fileNode);
36207
+ const path69 = extractRedirectPath(fileNode);
36034
36208
  const opLabel = operatorLabel(opNode);
36035
36209
  if (REDIRECT_WRITE_TOKENS.has(opType)) {
36036
- return [{ category: "redirect", operator: opLabel, path: path68 }];
36210
+ return [{ category: "redirect", operator: opLabel, path: path69 }];
36037
36211
  } else if (REDIRECT_HERE_TOKENS.has(opType)) {
36038
- return [{ category: "here_doc", operator: opLabel, path: path68 }];
36212
+ return [{ category: "here_doc", operator: opLabel, path: path69 }];
36039
36213
  }
36040
36214
  return [];
36041
36215
  }
@@ -36156,6 +36330,15 @@ var ACTIVE_PARALLEL_TASK_STATES = new Set([
36156
36330
  "tests_run"
36157
36331
  ]);
36158
36332
 
36333
+ // src/hooks/realtime-learning-nudge.ts
36334
+ var realtimeLearningNudgeBySession = new Map;
36335
+ function resetRealtimeLearningNudgeState() {
36336
+ realtimeLearningNudgeBySession.clear();
36337
+ }
36338
+ function clearRealtimeLearningNudgeSession(sessionID) {
36339
+ realtimeLearningNudgeBySession.delete(sessionID);
36340
+ }
36341
+
36159
36342
  // src/session/worktree-link-suggestion.ts
36160
36343
  import { execFile as execFile3 } from "child_process";
36161
36344
  var GIT_TIMEOUT_MS2 = 1500;
@@ -36298,6 +36481,7 @@ function resetSwarmState() {
36298
36481
  swarmState.environmentProfiles.clear();
36299
36482
  clearPendingCoderScope();
36300
36483
  resetStandardWorktreeIsolationState();
36484
+ resetRealtimeLearningNudgeState();
36301
36485
  _councilDisagreementWarned.clear();
36302
36486
  }
36303
36487
  function resetSwarmStatePreservingSingletons() {
@@ -36436,6 +36620,7 @@ function startAgentSession(sessionId, agentName, staleDurationMs = STALE_SESSION
36436
36620
  }
36437
36621
  function endAgentSession(sessionId) {
36438
36622
  swarmState.agentSessions.delete(sessionId);
36623
+ clearRealtimeLearningNudgeSession(sessionId);
36439
36624
  }
36440
36625
  function getAgentSession(sessionId) {
36441
36626
  return swarmState.agentSessions.get(sessionId);
@@ -36778,8 +36963,8 @@ function evidenceToWorkflowState(evidence) {
36778
36963
  }
36779
36964
  async function readPlanFromDisk(directory) {
36780
36965
  try {
36781
- const planPath = path68.join(directory, ".swarm", "plan.json");
36782
- const content = await fs33.readFile(planPath, "utf-8");
36966
+ const planPath = path69.join(directory, ".swarm", "plan.json");
36967
+ const content = await fs32.readFile(planPath, "utf-8");
36783
36968
  const parsed = JSON.parse(content);
36784
36969
  return PlanSchema.parse(parsed);
36785
36970
  } catch {
@@ -36789,8 +36974,8 @@ async function readPlanFromDisk(directory) {
36789
36974
  async function readGateEvidenceFromDisk(directory) {
36790
36975
  const evidenceMap = new Map;
36791
36976
  try {
36792
- const evidenceDir = path68.join(directory, ".swarm", "evidence");
36793
- const entries = await fs33.readdir(evidenceDir, { withFileTypes: true });
36977
+ const evidenceDir = path69.join(directory, ".swarm", "evidence");
36978
+ const entries = await fs32.readdir(evidenceDir, { withFileTypes: true });
36794
36979
  for (const entry of entries) {
36795
36980
  if (!entry.isFile() || !entry.name.endsWith(".json")) {
36796
36981
  continue;
@@ -36800,8 +36985,8 @@ async function readGateEvidenceFromDisk(directory) {
36800
36985
  continue;
36801
36986
  }
36802
36987
  try {
36803
- const filePath = path68.join(evidenceDir, entry.name);
36804
- const content = await fs33.readFile(filePath, "utf-8");
36988
+ const filePath = path69.join(evidenceDir, entry.name);
36989
+ const content = await fs32.readFile(filePath, "utf-8");
36805
36990
  const parsed = JSON.parse(content);
36806
36991
  if (parsed && typeof parsed.taskId === "string" && Array.isArray(parsed.required_gates)) {
36807
36992
  evidenceMap.set(taskId, parsed);
@@ -36942,7 +37127,7 @@ function hasActiveEpicMode(sessionID) {
36942
37127
  async function rehydratePrSubscriptions(sessionID, directory) {
36943
37128
  const map = new Map;
36944
37129
  try {
36945
- const { listActive: listActive2 } = await import("./pr-subscriptions-3c34rnm1.js");
37130
+ const { listActive: listActive2 } = await import("./pr-subscriptions-0dpn4epk.js");
36946
37131
  const records = await listActive2(directory);
36947
37132
  for (const record of records) {
36948
37133
  if (record.sessionID !== sessionID)