opencode-swarm 7.87.1 → 7.87.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.87.1",
72
+ version: "7.87.2",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -18060,6 +18060,24 @@ var init_git_binary_missing_error = __esm(() => {
18060
18060
  };
18061
18061
  });
18062
18062
 
18063
+ // src/utils/transient-retry.ts
18064
+ function isTransientSpawnError(error49) {
18065
+ if (!error49 || typeof error49 !== "object")
18066
+ return false;
18067
+ const code = error49.code;
18068
+ return code === "ETIMEDOUT";
18069
+ }
18070
+ function transientBackoff(attempt) {
18071
+ const delay = RETRY_BASE_DELAY_MS * 2 ** attempt;
18072
+ try {
18073
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, delay);
18074
+ } catch {
18075
+ const start2 = Date.now();
18076
+ while (Date.now() - start2 < delay) {}
18077
+ }
18078
+ }
18079
+ var MAX_TRANSIENT_RETRIES = 5, RETRY_BASE_DELAY_MS = 200;
18080
+
18063
18081
  // src/git/branch.ts
18064
18082
  import * as child_process from "node:child_process";
18065
18083
  import path6 from "node:path";
@@ -18092,26 +18110,34 @@ function gitExec(args2, cwd) {
18092
18110
  const subcommand = args2[0];
18093
18111
  const hardenedArgs = subcommand === "commit" || subcommand === "tag" ? ["-c", "commit.gpgsign=false", "-c", "tag.gpgsign=false", ...args2] : args2;
18094
18112
  for (const command of windowsGitCandidates()) {
18095
- const result = child_process.spawnSync(command, hardenedArgs, {
18096
- cwd,
18097
- encoding: "utf-8",
18098
- timeout: GIT_TIMEOUT_MS,
18099
- windowsHide: true,
18100
- maxBuffer: GIT_MAX_BUFFER_BYTES,
18101
- stdio: ["ignore", "pipe", "pipe"],
18102
- env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
18103
- });
18104
- if (result.error) {
18105
- if (isGitBinaryMissing(result.error)) {
18106
- missingGitError ??= result.error;
18107
- continue;
18113
+ for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
18114
+ const result = child_process.spawnSync(command, hardenedArgs, {
18115
+ cwd,
18116
+ encoding: "utf-8",
18117
+ timeout: GIT_TIMEOUT_MS,
18118
+ windowsHide: true,
18119
+ maxBuffer: GIT_MAX_BUFFER_BYTES,
18120
+ stdio: ["ignore", "pipe", "pipe"],
18121
+ env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
18122
+ });
18123
+ if (!result.error && result.status === 0) {
18124
+ return result.stdout;
18125
+ }
18126
+ if (result.error) {
18127
+ if (isGitBinaryMissing(result.error)) {
18128
+ missingGitError ??= result.error;
18129
+ break;
18130
+ }
18131
+ if (isTransientSpawnError(result.error) && attempt < MAX_TRANSIENT_RETRIES - 1) {
18132
+ transientBackoff(attempt);
18133
+ continue;
18134
+ }
18135
+ throw new Error(errorMessage(result.error));
18136
+ }
18137
+ if (result.status !== 0) {
18138
+ throw new Error(result.stderr || result.stdout || `git exited with ${result.status}`);
18108
18139
  }
18109
- throw new Error(errorMessage(result.error));
18110
- }
18111
- if (result.status !== 0) {
18112
- throw new Error(result.stderr || result.stdout || `git exited with ${result.status}`);
18113
18140
  }
18114
- return result.stdout;
18115
18141
  }
18116
18142
  throw new GitBinaryMissingError(process.platform === "win32" ? "git executable is not available on PATH or common Windows install locations" : "git executable is not available on PATH", { cause: missingGitError });
18117
18143
  }
@@ -60605,20 +60631,31 @@ function writeCheckpointLog(log2, directory) {
60605
60631
  fs23.renameSync(tempPath, logPath);
60606
60632
  }
60607
60633
  function gitExec2(args2, cwd) {
60608
- const result = child_process3.spawnSync("git", args2, {
60609
- cwd,
60610
- encoding: "utf-8",
60611
- timeout: GIT_TIMEOUT_MS2,
60612
- stdio: ["ignore", "pipe", "pipe"],
60613
- windowsHide: true
60614
- });
60615
- if (result.error) {
60616
- throw new Error(`git failed to start: ${result.error.code ?? "unknown"} — ${result.error.message}`);
60617
- }
60618
- if (result.status !== 0) {
60634
+ for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
60635
+ const result = child_process3.spawnSync("git", args2, {
60636
+ cwd,
60637
+ encoding: "utf-8",
60638
+ timeout: GIT_TIMEOUT_MS2,
60639
+ stdio: ["ignore", "pipe", "pipe"],
60640
+ windowsHide: true,
60641
+ maxBuffer: GIT_MAX_BUFFER_BYTES2
60642
+ });
60643
+ if (result.error) {
60644
+ const code = result.error.code;
60645
+ const message = result.error.message ?? "";
60646
+ const isTransient = isTransientSpawnError(result.error) || /ETIMEDOUT|timed out/i.test(message);
60647
+ if (!isTransient || attempt >= MAX_TRANSIENT_RETRIES - 1) {
60648
+ throw new Error(`git failed to start: ${code ?? "unknown"} — ${message}`);
60649
+ }
60650
+ transientBackoff(attempt);
60651
+ continue;
60652
+ }
60653
+ if (result.status === 0) {
60654
+ return result.stdout ?? "";
60655
+ }
60619
60656
  throw new Error(result.stderr?.trim() || `git exited with code ${result.status}`);
60620
60657
  }
60621
- return result.stdout;
60658
+ throw new Error("git command failed after transient retries");
60622
60659
  }
60623
60660
  function appendRetentionEvent(directory, event) {
60624
60661
  try {
@@ -60635,9 +60672,20 @@ function getCurrentSha(directory) {
60635
60672
  function isGitRepo2(directory) {
60636
60673
  try {
60637
60674
  gitExec2(["rev-parse", "--git-dir"], directory);
60638
- return true;
60639
- } catch {
60640
- return false;
60675
+ return { isRepo: true };
60676
+ } catch (e) {
60677
+ const message = e instanceof Error ? e.message : String(e);
60678
+ const isTransient = /ETIMEDOUT|timed out/i.test(message) && !/not a git repository/i.test(message);
60679
+ if (isTransient) {
60680
+ return {
60681
+ isRepo: false,
60682
+ warning: "git probe failed after retry exhaustion — treating as not a git repository"
60683
+ };
60684
+ }
60685
+ return {
60686
+ isRepo: false,
60687
+ warning: "git probe failed — directory may not be a git repository"
60688
+ };
60641
60689
  }
60642
60690
  }
60643
60691
  function handleSave(label, directory) {
@@ -60718,7 +60766,8 @@ function saveCheckpointRecord(label, directory) {
60718
60766
  return { success: false, error: `duplicate label: "${label}"` };
60719
60767
  }
60720
60768
  let sha = "";
60721
- if (isGitRepo2(directory)) {
60769
+ const repoProbe = isGitRepo2(directory);
60770
+ if (repoProbe.isRepo) {
60722
60771
  try {
60723
60772
  sha = getCurrentSha(directory);
60724
60773
  } catch {
@@ -60731,7 +60780,14 @@ function saveCheckpointRecord(label, directory) {
60731
60780
  timestamp: new Date().toISOString()
60732
60781
  });
60733
60782
  writeCheckpointLog(log2, directory);
60734
- return { success: true, sha };
60783
+ const result = {
60784
+ success: true,
60785
+ sha
60786
+ };
60787
+ if (!sha) {
60788
+ result.warning = "no git restore target — checkpoint recorded without a SHA (directory may not be a git repository or HEAD is unavailable)";
60789
+ }
60790
+ return result;
60735
60791
  } catch (e) {
60736
60792
  return {
60737
60793
  success: false,
@@ -60805,11 +60861,12 @@ function handleDelete(label, directory) {
60805
60861
  }, null, 2);
60806
60862
  }
60807
60863
  }
60808
- var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json", MAX_LABEL_LENGTH = 100, GIT_TIMEOUT_MS2 = 30000, SHELL_METACHARACTERS, SAFE_LABEL_PATTERN, CONTROL_CHAR_PATTERN, NON_ASCII_PATTERN, checkpoint;
60864
+ var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json", MAX_LABEL_LENGTH = 100, GIT_TIMEOUT_MS2 = 30000, GIT_MAX_BUFFER_BYTES2, SHELL_METACHARACTERS, SAFE_LABEL_PATTERN, CONTROL_CHAR_PATTERN, NON_ASCII_PATTERN, checkpoint;
60809
60865
  var init_checkpoint = __esm(() => {
60810
60866
  init_zod();
60811
60867
  init_config();
60812
60868
  init_create_tool();
60869
+ GIT_MAX_BUFFER_BYTES2 = 5 * 1024 * 1024;
60813
60870
  SHELL_METACHARACTERS = /[;|&$`(){}<>!'"]/;
60814
60871
  SAFE_LABEL_PATTERN = /^[a-zA-Z0-9_ -]+$/;
60815
60872
  CONTROL_CHAR_PATTERN = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/;
@@ -60821,11 +60878,12 @@ var init_checkpoint = __esm(() => {
60821
60878
  label: exports_external.string().optional().describe("Checkpoint label (required for save, restore, delete)")
60822
60879
  },
60823
60880
  execute: async (args2, directory) => {
60824
- if (!isGitRepo2(directory)) {
60881
+ const repoProbe = isGitRepo2(directory);
60882
+ if (!repoProbe.isRepo) {
60825
60883
  return JSON.stringify({
60826
60884
  action: "unknown",
60827
60885
  success: false,
60828
- error: "not a git repository"
60886
+ error: `${repoProbe.warning ?? "not a git repository"} — checkpoint tools require a git repository`
60829
60887
  }, null, 2);
60830
60888
  }
60831
60889
  let action;
@@ -62914,7 +62972,8 @@ async function runCuratorPostMortem(directory, options = {}) {
62914
62972
  } catch {
62915
62973
  warnings.push("Failed to load plan data.");
62916
62974
  }
62917
- const reportFilename = `post-mortem-${planId}.md`;
62975
+ const effectivePlanId = planId === "unknown" ? `unknown-${Date.now()}` : planId;
62976
+ const reportFilename = `post-mortem-${effectivePlanId}.md`;
62918
62977
  let reportPath;
62919
62978
  try {
62920
62979
  reportPath = validateSwarmPath(directory, reportFilename);
@@ -62930,22 +62989,22 @@ async function runCuratorPostMortem(directory, options = {}) {
62930
62989
  if (!options.force && isReportValid(reportPath)) {
62931
62990
  return {
62932
62991
  success: true,
62933
- planId,
62992
+ planId: effectivePlanId,
62934
62993
  reportPath,
62935
62994
  summary: "Post-mortem report already exists (idempotent skip).",
62936
62995
  warnings
62937
62996
  };
62938
62997
  }
62939
- const lock = await _internals28.acquirePostMortemLock(directory, planId);
62998
+ const lock = await _internals28.acquirePostMortemLock(directory, effectivePlanId);
62940
62999
  if (!lock.acquired) {
62941
63000
  return {
62942
63001
  success: false,
62943
- planId,
63002
+ planId: effectivePlanId,
62944
63003
  reportPath,
62945
63004
  summary: null,
62946
63005
  warnings: [
62947
63006
  ...warnings,
62948
- `Concurrent post-mortem run in progress for plan ${planId}; skipped.`
63007
+ `Concurrent post-mortem run in progress for plan ${effectivePlanId}; skipped.`
62949
63008
  ]
62950
63009
  };
62951
63010
  }
@@ -62995,7 +63054,7 @@ async function runCuratorPostMortem(directory, options = {}) {
62995
63054
  if (options.llmDelegate) {
62996
63055
  try {
62997
63056
  const { CURATOR_POSTMORTEM_PROMPT: CURATOR_POSTMORTEM_PROMPT2 } = await Promise.resolve().then(() => exports_explorer);
62998
- const userInput = assembleLLMInput(planId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
63057
+ const userInput = assembleLLMInput(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
62999
63058
  const ac = new AbortController;
63000
63059
  const timer = setTimeout(() => ac.abort(), 300000);
63001
63060
  let llmOutput;
@@ -63011,17 +63070,17 @@ async function runCuratorPostMortem(directory, options = {}) {
63011
63070
  } finally {
63012
63071
  clearTimeout(timer);
63013
63072
  }
63014
- reportContent = `# Post-Mortem Report: ${planId}
63073
+ reportContent = `# Post-Mortem Report: ${effectivePlanId}
63015
63074
  Generated: ${new Date().toISOString()}
63016
63075
 
63017
63076
  ${llmOutput}`;
63018
63077
  } catch (err2) {
63019
63078
  const msg = err2 instanceof Error ? err2.message : String(err2);
63020
63079
  warnings.push(`LLM delegate failed, falling back to data-only report: ${msg}`);
63021
- reportContent = _internals28.buildDataOnlyReport(planId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
63080
+ reportContent = _internals28.buildDataOnlyReport(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
63022
63081
  }
63023
63082
  } else {
63024
- reportContent = _internals28.buildDataOnlyReport(planId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
63083
+ reportContent = _internals28.buildDataOnlyReport(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
63025
63084
  }
63026
63085
  try {
63027
63086
  const { mkdirSync: mkdirSync16 } = await import("node:fs");
@@ -63031,7 +63090,7 @@ ${llmOutput}`;
63031
63090
  const msg = err2 instanceof Error ? err2.message : String(err2);
63032
63091
  return {
63033
63092
  success: false,
63034
- planId,
63093
+ planId: effectivePlanId,
63035
63094
  reportPath: null,
63036
63095
  summary: null,
63037
63096
  warnings: [...warnings, `Failed to write report: ${msg}`]
@@ -63041,13 +63100,13 @@ ${llmOutput}`;
63041
63100
  const neverAppliedCount = knowledgeSummary.filter((e) => e.applied === 0 && e.violated === 0 && e.ignored === 0).length;
63042
63101
  const totalViolations = knowledgeSummary.reduce((s, e) => s + e.violated, 0);
63043
63102
  const summary = [
63044
- `Post-mortem for plan "${planId}": ${totalEntries} knowledge entries reviewed.`,
63103
+ `Post-mortem for plan "${effectivePlanId}": ${totalEntries} knowledge entries reviewed.`,
63045
63104
  `${neverAppliedCount} never-applied entries flagged; ${totalViolations} total violations recorded.`,
63046
63105
  `${proposals.length} pending proposals, ${unactionable.length} quarantined entries.`
63047
63106
  ].join(" ");
63048
63107
  return {
63049
63108
  success: true,
63050
- planId,
63109
+ planId: effectivePlanId,
63051
63110
  reportPath,
63052
63111
  summary,
63053
63112
  warnings
@@ -71751,6 +71810,7 @@ var init_write_retro = __esm(() => {
71751
71810
  });
71752
71811
 
71753
71812
  // src/commands/close.ts
71813
+ import { spawnSync as spawnSync9 } from "node:child_process";
71754
71814
  import * as fsSync6 from "node:fs";
71755
71815
  import { promises as fs28 } from "node:fs";
71756
71816
  import path58 from "node:path";
@@ -71790,8 +71850,9 @@ function countSessionKnowledgeEntries(entries, sessionStart, fallbackCount) {
71790
71850
  return Number.isFinite(createdAtMs) && createdAtMs >= sessionStartMs;
71791
71851
  }).length;
71792
71852
  }
71793
- async function copyDirRecursive(src, dest) {
71853
+ async function copyDirRecursiveWithFailures(src, dest) {
71794
71854
  let count = 0;
71855
+ const failures = [];
71795
71856
  const entries = await fs28.readdir(src);
71796
71857
  await fs28.mkdir(dest, { recursive: true });
71797
71858
  for (const entry of entries) {
@@ -71800,17 +71861,32 @@ async function copyDirRecursive(src, dest) {
71800
71861
  try {
71801
71862
  const stat9 = await fs28.stat(srcEntry);
71802
71863
  if (stat9.isDirectory()) {
71803
- const subCount = await copyDirRecursive(srcEntry, destEntry).catch(() => 0);
71804
- count += subCount;
71864
+ const subResult = await copyDirRecursiveWithFailures(srcEntry, destEntry);
71865
+ count += subResult.copied;
71866
+ failures.push(...subResult.failures);
71805
71867
  } else {
71806
71868
  try {
71807
71869
  await fs28.copyFile(srcEntry, destEntry);
71808
71870
  count++;
71809
- } catch {}
71871
+ } catch (err2) {
71872
+ const errno = err2?.code;
71873
+ if (errno !== "ENOENT") {
71874
+ failures.push(`${srcEntry}: ${err2 instanceof Error ? err2.message : String(err2)}`);
71875
+ }
71876
+ }
71810
71877
  }
71811
- } catch {}
71878
+ } catch (err2) {
71879
+ const errno = err2?.code;
71880
+ if (errno !== "ENOENT") {
71881
+ failures.push(`${srcEntry}: ${err2 instanceof Error ? err2.message : String(err2)}`);
71882
+ }
71883
+ }
71812
71884
  }
71813
- return count;
71885
+ return { copied: count, failures };
71886
+ }
71887
+ async function copyDirRecursive(src, dest) {
71888
+ const result = await copyDirRecursiveWithFailures(src, dest);
71889
+ return result.copied;
71814
71890
  }
71815
71891
  function guaranteeAllPlansComplete(planData) {
71816
71892
  const closedPhaseIds = [];
@@ -72082,31 +72158,145 @@ async function runFinalizeStage(ctx) {
72082
72158
  ctx.warnings.push(`Post-mortem failed: ${msg}`);
72083
72159
  }
72084
72160
  }
72161
+ async function copySqliteSafe(srcPath, destPath) {
72162
+ if (!fsSync6.existsSync(srcPath)) {
72163
+ return {
72164
+ success: true,
72165
+ skipped: true,
72166
+ reason: "source does not exist (ENOENT)"
72167
+ };
72168
+ }
72169
+ let checkpointVerified = false;
72170
+ try {
72171
+ const result = spawnSync9("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
72172
+ cwd: path58.dirname(srcPath),
72173
+ encoding: "utf-8",
72174
+ stdio: ["ignore", "pipe", "pipe"],
72175
+ timeout: 1e4,
72176
+ windowsHide: true,
72177
+ maxBuffer: 1024
72178
+ });
72179
+ if (result.error) {
72180
+ const code = result.error.code;
72181
+ if (code === "ENOENT") {
72182
+ try {
72183
+ await fs28.copyFile(srcPath, destPath);
72184
+ return {
72185
+ success: true,
72186
+ reason: "copied without WAL checkpoint (sqlite3 CLI unavailable)"
72187
+ };
72188
+ } catch (copyErr) {
72189
+ return {
72190
+ success: false,
72191
+ reason: `fallback copy failed: ${copyErr instanceof Error ? copyErr.message : String(copyErr)}`
72192
+ };
72193
+ }
72194
+ }
72195
+ return {
72196
+ success: false,
72197
+ reason: `wal_checkpoint failed: ${result.error instanceof Error ? result.error.message : String(result.error)}`
72198
+ };
72199
+ }
72200
+ if (result.status !== 0) {
72201
+ return {
72202
+ success: false,
72203
+ reason: `wal_checkpoint exited with code ${result.status}`
72204
+ };
72205
+ }
72206
+ const output = (result.stdout || "").trim();
72207
+ const lines = output.split(`
72208
+ `).filter((l) => l.trim());
72209
+ if (lines.length >= 1) {
72210
+ const dataLine = lines[0];
72211
+ const columns = dataLine.split("|");
72212
+ const busyFlag = parseInt(columns[0], 10);
72213
+ checkpointVerified = !Number.isNaN(busyFlag) && busyFlag === 0;
72214
+ }
72215
+ } catch (err2) {
72216
+ return {
72217
+ success: false,
72218
+ reason: `wal_checkpoint error: ${err2 instanceof Error ? err2.message : String(err2)}`
72219
+ };
72220
+ }
72221
+ try {
72222
+ await fs28.copyFile(srcPath, destPath);
72223
+ if (checkpointVerified) {
72224
+ return { success: true };
72225
+ }
72226
+ return {
72227
+ success: true,
72228
+ reason: "WAL checkpoint incomplete (busy) — archive copy may be stale, original preserved"
72229
+ };
72230
+ } catch (err2) {
72231
+ return {
72232
+ success: false,
72233
+ reason: `copy failed: ${err2 instanceof Error ? err2.message : String(err2)}`
72234
+ };
72235
+ }
72236
+ }
72085
72237
  async function runArchiveStage(ctx) {
72086
72238
  ctx.timestamp = new Date().toISOString().replace(/[:.]/g, "-");
72087
72239
  ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
72088
72240
  ctx.archiveDir = path58.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
72089
72241
  try {
72090
72242
  await fs28.mkdir(ctx.archiveDir, { recursive: true });
72243
+ const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
72091
72244
  for (const artifact of ARCHIVE_ARTIFACTS) {
72245
+ if (WAL_SIDECAR_FILES.has(artifact)) {
72246
+ continue;
72247
+ }
72092
72248
  const srcPath = path58.join(ctx.swarmDir, artifact);
72093
72249
  const destPath = path58.join(ctx.archiveDir, artifact);
72094
- try {
72095
- await fs28.copyFile(srcPath, destPath);
72096
- ctx.archivedFileCount++;
72097
- if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
72098
- ctx.archivedActiveStateFiles.add(artifact);
72250
+ if (artifact === "swarm.db") {
72251
+ const result = await copySqliteSafe(srcPath, destPath);
72252
+ if (result.skipped) {} else if (result.success) {
72253
+ ctx.archivedFileCount++;
72254
+ if (result.reason) {
72255
+ ctx.warnings.push(`Archived ${artifact}: ${result.reason}. Original preserved to prevent data loss.`);
72256
+ } else {
72257
+ ctx.archivedActiveStateFiles.add(artifact);
72258
+ }
72259
+ } else {
72260
+ ctx.archiveFailureReasons.set(artifact, result.reason);
72261
+ ctx.warnings.push(`Failed to archive ${artifact}: ${result.reason}. File preserved (not cleaned up).`);
72099
72262
  }
72100
- } catch {}
72263
+ } else {
72264
+ try {
72265
+ await fs28.copyFile(srcPath, destPath);
72266
+ ctx.archivedFileCount++;
72267
+ if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
72268
+ ctx.archivedActiveStateFiles.add(artifact);
72269
+ }
72270
+ } catch (err2) {
72271
+ const errno = err2?.code;
72272
+ if (errno === "ENOENT") {} else {
72273
+ const reason = err2 instanceof Error ? err2.message : String(err2);
72274
+ ctx.archiveFailureReasons.set(artifact, `${errno ?? "unknown"}: ${reason}`);
72275
+ ctx.warnings.push(`Failed to archive ${artifact} [${errno ?? "unknown"}]: ${reason}. File preserved (not cleaned up).`);
72276
+ }
72277
+ }
72278
+ }
72101
72279
  }
72102
72280
  for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
72103
72281
  const srcDir = path58.join(ctx.swarmDir, dirName);
72104
72282
  const destDir = path58.join(ctx.archiveDir, dirName);
72105
72283
  try {
72106
- const copied = await copyDirRecursive(srcDir, destDir);
72107
- ctx.archivedFileCount += copied;
72108
- ctx.archivedActiveStateDirs.add(dirName);
72109
- } catch {}
72284
+ const result = await copyDirRecursiveWithFailures(srcDir, destDir);
72285
+ ctx.archivedFileCount += result.copied;
72286
+ if (result.failures.length === 0) {
72287
+ ctx.archivedActiveStateDirs.add(dirName);
72288
+ } else {
72289
+ ctx.warnings.push(`Directory ${dirName} not fully archived (${result.failures.length} failure(s)). Source preserved.`);
72290
+ for (const failure of result.failures) {
72291
+ ctx.warnings.push(` - ${failure}`);
72292
+ }
72293
+ }
72294
+ } catch (err2) {
72295
+ const code = err2.code;
72296
+ if (code !== "ENOENT") {
72297
+ ctx.warnings.push(`Failed to archive directory ${dirName} [${code ?? "unknown"}]: ${err2.message}. Source preserved.`);
72298
+ }
72299
+ }
72110
72300
  }
72111
72301
  ctx.archiveResult = `Archived ${ctx.archivedFileCount} artifact(s) to .swarm/archive/swarm-${ctx.timestamp}-${ctx.archiveSuffix}/`;
72112
72302
  } catch (archiveError) {
@@ -72147,14 +72337,21 @@ async function runCleanStage(ctx) {
72147
72337
  if (ctx.archivedActiveStateFiles.size > 0) {
72148
72338
  for (const artifact of ACTIVE_STATE_TO_CLEAN) {
72149
72339
  if (!ctx.archivedActiveStateFiles.has(artifact)) {
72150
- ctx.warnings.push(`Preserved ${artifact} because it was not successfully archived.`);
72340
+ const reason = ctx.archiveFailureReasons?.get(artifact);
72341
+ ctx.warnings.push(reason ? `Preserved ${artifact} because it was not successfully archived: ${reason}.` : `Preserved ${artifact} because it was not successfully archived.`);
72151
72342
  continue;
72152
72343
  }
72153
72344
  const filePath = path58.join(ctx.swarmDir, artifact);
72154
72345
  try {
72155
72346
  await fs28.unlink(filePath);
72156
72347
  cleanedFiles.push(artifact);
72157
- } catch {}
72348
+ } catch (err2) {
72349
+ const errno = err2?.code;
72350
+ if (errno === "ENOENT") {} else {
72351
+ const reason = err2 instanceof Error ? err2.message : String(err2);
72352
+ ctx.warnings.push(`Failed to clean active-state file ${artifact} [${errno ?? "unknown"}]: ${reason}`);
72353
+ }
72354
+ }
72158
72355
  }
72159
72356
  } else {
72160
72357
  ctx.warnings.push("Skipped active-state cleanup because no active-state files were archived. Files preserved to prevent data loss.");
@@ -72176,15 +72373,33 @@ async function runCleanStage(ctx) {
72176
72373
  try {
72177
72374
  await fs28.unlink(path58.join(ctx.swarmDir, backup));
72178
72375
  configBackupsRemoved++;
72179
- } catch {}
72376
+ } catch (err2) {
72377
+ const errno = err2?.code;
72378
+ if (errno === "ENOENT") {} else {
72379
+ const reason = err2 instanceof Error ? err2.message : String(err2);
72380
+ ctx.warnings.push(`Failed to clean config-backup ${backup} [${errno ?? "unknown"}]: ${reason}`);
72381
+ }
72382
+ }
72180
72383
  }
72181
72384
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
72182
72385
  for (const sibling of ledgerSiblings) {
72183
72386
  try {
72184
72387
  await fs28.unlink(path58.join(ctx.swarmDir, sibling));
72185
- } catch {}
72388
+ } catch (err2) {
72389
+ const errno = err2?.code;
72390
+ if (errno === "ENOENT") {} else {
72391
+ const reason = err2 instanceof Error ? err2.message : String(err2);
72392
+ ctx.warnings.push(`Failed to clean ledger sibling ${sibling} [${errno ?? "unknown"}]: ${reason}`);
72393
+ }
72394
+ }
72186
72395
  }
72187
- } catch {}
72396
+ } catch (err2) {
72397
+ const errno = err2?.code;
72398
+ if (errno === "ENOENT") {} else {
72399
+ const reason = err2 instanceof Error ? err2.message : String(err2);
72400
+ ctx.warnings.push(`Failed to read ${ctx.swarmDir} for stale-file cleanup [${errno ?? "unknown"}]: ${reason}`);
72401
+ }
72402
+ }
72188
72403
  let swarmPlanFilesRemoved = 0;
72189
72404
  const candidates = [
72190
72405
  path58.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
@@ -72210,9 +72425,21 @@ async function runCleanStage(ctx) {
72210
72425
  try {
72211
72426
  await fs28.unlink(path58.join(ctx.swarmDir, tmp));
72212
72427
  tmpFilesRemoved++;
72213
- } catch {}
72428
+ } catch (err2) {
72429
+ const errno = err2?.code;
72430
+ if (errno === "ENOENT") {} else {
72431
+ const reason = err2 instanceof Error ? err2.message : String(err2);
72432
+ ctx.warnings.push(`Failed to clean tmp file ${tmp} [${errno ?? "unknown"}]: ${reason}`);
72433
+ }
72434
+ }
72214
72435
  }
72215
- } catch {}
72436
+ } catch (err2) {
72437
+ const errno = err2?.code;
72438
+ if (errno === "ENOENT") {} else {
72439
+ const reason = err2 instanceof Error ? err2.message : String(err2);
72440
+ ctx.warnings.push(`Failed to read ${ctx.swarmDir} for tmp-file cleanup [${errno ?? "unknown"}]: ${reason}`);
72441
+ }
72442
+ }
72216
72443
  if (tmpFilesRemoved > 0) {
72217
72444
  cleanedFiles.push(`${tmpFilesRemoved} .tmp.* file(s)`);
72218
72445
  }
@@ -72229,9 +72456,14 @@ async function runCleanStage(ctx) {
72229
72456
  ""
72230
72457
  ].join(`
72231
72458
  `);
72459
+ const contextTempPath = path58.join(path58.dirname(contextPath), `${path58.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
72232
72460
  try {
72233
- await fs28.writeFile(contextPath, contextContent, "utf-8");
72461
+ await fs28.writeFile(contextTempPath, contextContent, "utf-8");
72462
+ fsSync6.renameSync(contextTempPath, contextPath);
72234
72463
  } catch (error93) {
72464
+ try {
72465
+ fsSync6.unlinkSync(contextTempPath);
72466
+ } catch {}
72235
72467
  const msg = error93 instanceof Error ? error93.message : String(error93);
72236
72468
  ctx.warnings.push(`Failed to reset context.md: ${msg}`);
72237
72469
  console.warn("[close-command] Failed to write context.md:", error93);
@@ -72325,15 +72557,33 @@ async function handleCloseCommand(directory, args2, options = {}) {
72325
72557
  if (!finalizeLock.acquired) {
72326
72558
  return `❌ Another /swarm finalize is already running for this project. If you are certain no other run is active, wait for the lock to expire or remove the stale lock and retry.`;
72327
72559
  }
72328
- const phases = planData.phases ?? [];
72329
- const inProgressPhases = phases.filter((p) => p.status === "in_progress");
72330
- const isForced = args2.includes("--force");
72331
- const runSkillReview = args2.includes("--skill-review");
72332
- let planAlreadyDone = false;
72333
- if (planExists) {
72334
- planAlreadyDone = phases.length > 0 && phases.every((p) => p.status === "complete" || p.status === "completed" || p.status === "blocked" || p.status === "closed");
72335
- }
72336
72560
  try {
72561
+ if (!planExists) {
72562
+ const archiveDir = path58.join(swarmDir, "archive");
72563
+ try {
72564
+ const archiveEntries = await fs28.readdir(archiveDir);
72565
+ const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
72566
+ if (hasArchiveBundle) {
72567
+ const hasActiveState = [
72568
+ ...ACTIVE_STATE_TO_CLEAN,
72569
+ ...ACTIVE_STATE_DIRS_TO_CLEAN
72570
+ ].some((entry) => fsSync6.existsSync(path58.join(swarmDir, entry)));
72571
+ if (!hasActiveState) {
72572
+ return `✅ Already finalized — nothing to do.
72573
+
72574
+ This project was already finalized in a previous /swarm close run. The plan has been archived and cleaned up. No further action is needed.`;
72575
+ }
72576
+ }
72577
+ } catch {}
72578
+ }
72579
+ const phases = planData.phases ?? [];
72580
+ const inProgressPhases = phases.filter((p) => p.status === "in_progress");
72581
+ const isForced = args2.includes("--force");
72582
+ const runSkillReview = args2.includes("--skill-review");
72583
+ let planAlreadyDone = false;
72584
+ if (planExists) {
72585
+ planAlreadyDone = phases.length > 0 && phases.every((p) => p.status === "complete" || p.status === "completed" || p.status === "blocked" || p.status === "closed");
72586
+ }
72337
72587
  const { config: loadedConfig } = _internals37.loadPluginConfigWithMeta(directory);
72338
72588
  const config3 = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
72339
72589
  const ctx = {
@@ -72370,6 +72620,7 @@ async function handleCloseCommand(directory, args2, options = {}) {
72370
72620
  archivedFileCount: 0,
72371
72621
  archivedActiveStateFiles: new Set,
72372
72622
  archivedActiveStateDirs: new Set,
72623
+ archiveFailureReasons: new Map,
72373
72624
  timestamp: "",
72374
72625
  archiveDir: "",
72375
72626
  archiveSuffix: "",
@@ -72432,9 +72683,14 @@ async function handleCloseCommand(directory, args2, options = {}) {
72432
72683
  ...ctx.warnings.length > 0 ? ["## Warnings", ...ctx.warnings.map((w) => `- ${w}`), ""] : []
72433
72684
  ].join(`
72434
72685
  `);
72686
+ const closeSummaryTempPath = path58.join(path58.dirname(closeSummaryPath), `${path58.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
72435
72687
  try {
72436
- await fs28.writeFile(closeSummaryPath, summaryContent, "utf-8");
72688
+ await fs28.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
72689
+ fsSync6.renameSync(closeSummaryTempPath, closeSummaryPath);
72437
72690
  } catch (error93) {
72691
+ try {
72692
+ fsSync6.unlinkSync(closeSummaryTempPath);
72693
+ } catch {}
72438
72694
  const msg = error93 instanceof Error ? error93.message : String(error93);
72439
72695
  ctx.warnings.push(`Failed to write close-summary.md: ${msg}`);
72440
72696
  console.warn("[close-command] Failed to write close-summary.md:", error93);
@@ -72877,7 +73133,7 @@ __export(exports_skill_consolidation, {
72877
73133
  consolidationStatePath: () => consolidationStatePath,
72878
73134
  _internals: () => _internals38
72879
73135
  });
72880
- import { existsSync as existsSync31 } from "node:fs";
73136
+ import { existsSync as existsSync32 } from "node:fs";
72881
73137
  import { mkdir as mkdir16, readFile as readFile16, rename as rename9, writeFile as writeFile14 } from "node:fs/promises";
72882
73138
  import * as path60 from "node:path";
72883
73139
  function consolidationStatePath(directory) {
@@ -72885,7 +73141,7 @@ function consolidationStatePath(directory) {
72885
73141
  }
72886
73142
  async function readState2(directory) {
72887
73143
  const filePath = consolidationStatePath(directory);
72888
- if (!existsSync31(filePath))
73144
+ if (!existsSync32(filePath))
72889
73145
  return {};
72890
73146
  try {
72891
73147
  const parsed = JSON.parse(await readFile16(filePath, "utf-8"));
@@ -74514,7 +74770,7 @@ var init_gate_bridge = __esm(() => {
74514
74770
  });
74515
74771
 
74516
74772
  // src/services/version-check.ts
74517
- import { existsSync as existsSync32, mkdirSync as mkdirSync20, readFileSync as readFileSync17, writeFileSync as writeFileSync13 } from "node:fs";
74773
+ import { existsSync as existsSync33, mkdirSync as mkdirSync20, readFileSync as readFileSync17, writeFileSync as writeFileSync13 } from "node:fs";
74518
74774
  import { homedir as homedir7 } from "node:os";
74519
74775
  import { join as join49 } from "node:path";
74520
74776
  function cacheDir() {
@@ -74528,7 +74784,7 @@ function cacheFile() {
74528
74784
  function readVersionCache() {
74529
74785
  try {
74530
74786
  const path65 = cacheFile();
74531
- if (!existsSync32(path65))
74787
+ if (!existsSync33(path65))
74532
74788
  return null;
74533
74789
  const raw = readFileSync17(path65, "utf-8");
74534
74790
  const parsed = JSON.parse(raw);
@@ -74626,10 +74882,10 @@ var init_version_check = __esm(() => {
74626
74882
  });
74627
74883
 
74628
74884
  // src/services/knowledge-diagnostics.ts
74629
- import { existsSync as existsSync33 } from "node:fs";
74885
+ import { existsSync as existsSync34 } from "node:fs";
74630
74886
  import { readFile as readFile18 } from "node:fs/promises";
74631
74887
  async function readRawLines(filePath) {
74632
- if (!existsSync33(filePath))
74888
+ if (!existsSync34(filePath))
74633
74889
  return { entries: [], corrupt: 0 };
74634
74890
  const content = await readFile18(filePath, "utf-8");
74635
74891
  const entries = [];
@@ -74754,7 +75010,7 @@ async function computeKnowledgeDebug(directory) {
74754
75010
  };
74755
75011
  }
74756
75012
  async function safeJsonlCount(filePath) {
74757
- if (!filePath || !existsSync33(filePath))
75013
+ if (!filePath || !existsSync34(filePath))
74758
75014
  return 0;
74759
75015
  try {
74760
75016
  const content = await readFile18(filePath, "utf-8");
@@ -74837,7 +75093,7 @@ var init_knowledge_diagnostics = __esm(() => {
74837
75093
 
74838
75094
  // src/services/diagnose-service.ts
74839
75095
  import * as child_process6 from "node:child_process";
74840
- import { existsSync as existsSync34, readdirSync as readdirSync7, readFileSync as readFileSync18, statSync as statSync11 } from "node:fs";
75096
+ import { existsSync as existsSync35, readdirSync as readdirSync7, readFileSync as readFileSync18, statSync as statSync11 } from "node:fs";
74841
75097
  import path65 from "node:path";
74842
75098
  import { fileURLToPath as fileURLToPath2 } from "node:url";
74843
75099
  function validateTaskDag(plan) {
@@ -75085,7 +75341,7 @@ async function checkConfigBackups(directory) {
75085
75341
  }
75086
75342
  async function checkGitRepository(directory) {
75087
75343
  try {
75088
- if (!existsSync34(directory) || !statSync11(directory).isDirectory()) {
75344
+ if (!existsSync35(directory) || !statSync11(directory).isDirectory()) {
75089
75345
  return {
75090
75346
  name: "Git Repository",
75091
75347
  status: "❌",
@@ -75150,7 +75406,7 @@ async function checkSpecStaleness(directory, plan) {
75150
75406
  }
75151
75407
  async function checkConfigParseability(directory) {
75152
75408
  const configPath = path65.join(directory, ".opencode/opencode-swarm.json");
75153
- if (!existsSync34(configPath)) {
75409
+ if (!existsSync35(configPath)) {
75154
75410
  return {
75155
75411
  name: "Config Parseability",
75156
75412
  status: "✅",
@@ -75205,11 +75461,11 @@ async function checkGrammarWasmFiles() {
75205
75461
  const thisDir = path65.dirname(fileURLToPath2(import.meta.url));
75206
75462
  const grammarDir = resolveGrammarDir(thisDir);
75207
75463
  const missing = [];
75208
- if (!existsSync34(path65.join(grammarDir, "tree-sitter.wasm"))) {
75464
+ if (!existsSync35(path65.join(grammarDir, "tree-sitter.wasm"))) {
75209
75465
  missing.push("tree-sitter.wasm (core runtime)");
75210
75466
  }
75211
75467
  for (const file3 of grammarFiles) {
75212
- if (!existsSync34(path65.join(grammarDir, file3))) {
75468
+ if (!existsSync35(path65.join(grammarDir, file3))) {
75213
75469
  missing.push(file3);
75214
75470
  }
75215
75471
  }
@@ -75228,7 +75484,7 @@ async function checkGrammarWasmFiles() {
75228
75484
  }
75229
75485
  async function checkCheckpointManifest(directory) {
75230
75486
  const manifestPath = path65.join(directory, ".swarm/checkpoints.json");
75231
- if (!existsSync34(manifestPath)) {
75487
+ if (!existsSync35(manifestPath)) {
75232
75488
  return {
75233
75489
  name: "Checkpoint Manifest",
75234
75490
  status: "✅",
@@ -75280,7 +75536,7 @@ async function checkCheckpointManifest(directory) {
75280
75536
  }
75281
75537
  async function checkEventStreamIntegrity(directory) {
75282
75538
  const eventsPath = path65.join(directory, ".swarm/events.jsonl");
75283
- if (!existsSync34(eventsPath)) {
75539
+ if (!existsSync35(eventsPath)) {
75284
75540
  return {
75285
75541
  name: "Event Stream",
75286
75542
  status: "✅",
@@ -75321,7 +75577,7 @@ async function checkEventStreamIntegrity(directory) {
75321
75577
  }
75322
75578
  async function checkSteeringDirectives(directory) {
75323
75579
  const eventsPath = path65.join(directory, ".swarm/events.jsonl");
75324
- if (!existsSync34(eventsPath)) {
75580
+ if (!existsSync35(eventsPath)) {
75325
75581
  return {
75326
75582
  name: "Steering Directives",
75327
75583
  status: "✅",
@@ -75377,7 +75633,7 @@ async function checkCurator(directory) {
75377
75633
  };
75378
75634
  }
75379
75635
  const summaryPath = path65.join(directory, ".swarm/curator-summary.json");
75380
- if (!existsSync34(summaryPath)) {
75636
+ if (!existsSync35(summaryPath)) {
75381
75637
  return {
75382
75638
  name: "Curator",
75383
75639
  status: "✅",
@@ -75579,7 +75835,7 @@ async function getDiagnoseData(directory) {
75579
75835
  checks5.push(await checkKnowledgeHealth(directory));
75580
75836
  try {
75581
75837
  const evidenceDir = path65.join(directory, ".swarm", "evidence");
75582
- const snapshotFiles = existsSync34(evidenceDir) ? readdirSync7(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
75838
+ const snapshotFiles = existsSync35(evidenceDir) ? readdirSync7(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
75583
75839
  if (snapshotFiles.length > 0) {
75584
75840
  const latest = snapshotFiles.sort().pop();
75585
75841
  checks5.push({
@@ -75612,7 +75868,7 @@ async function getDiagnoseData(directory) {
75612
75868
  const cacheRows = [];
75613
75869
  for (const cachePath of cachePaths) {
75614
75870
  try {
75615
- if (!existsSync34(cachePath)) {
75871
+ if (!existsSync35(cachePath)) {
75616
75872
  cacheRows.push(`⬜ ${cachePath} — absent`);
75617
75873
  continue;
75618
75874
  }
@@ -80899,7 +81155,7 @@ var init_handoff_service = __esm(() => {
80899
81155
  });
80900
81156
 
80901
81157
  // src/session/snapshot-writer.ts
80902
- import { closeSync as closeSync6, fsyncSync as fsyncSync2, mkdirSync as mkdirSync26, openSync as openSync6, renameSync as renameSync15 } from "node:fs";
81158
+ import { closeSync as closeSync6, fsyncSync as fsyncSync2, mkdirSync as mkdirSync26, openSync as openSync6, renameSync as renameSync16 } from "node:fs";
80903
81159
  import * as path72 from "node:path";
80904
81160
  function serializeAgentSession(s) {
80905
81161
  const gateLog = {};
@@ -81018,7 +81274,7 @@ async function writeSnapshot(directory, state) {
81018
81274
  closeSync6(fd);
81019
81275
  }
81020
81276
  } catch {}
81021
- renameSync15(tempPath, resolvedPath);
81277
+ renameSync16(tempPath, resolvedPath);
81022
81278
  } catch (error93) {
81023
81279
  log("[snapshot-writer] write failed", {
81024
81280
  error: error93 instanceof Error ? error93.message : String(error93)
@@ -81051,7 +81307,7 @@ var init_snapshot_writer = __esm(() => {
81051
81307
 
81052
81308
  // src/commands/handoff.ts
81053
81309
  import crypto7 from "node:crypto";
81054
- import { renameSync as renameSync16, unlinkSync as unlinkSync11 } from "node:fs";
81310
+ import { renameSync as renameSync17, unlinkSync as unlinkSync12 } from "node:fs";
81055
81311
  async function handleHandoffCommand(directory, _args) {
81056
81312
  const handoffData = await getHandoffData(directory);
81057
81313
  const markdown = formatHandoffMarkdown(handoffData);
@@ -81060,10 +81316,10 @@ async function handleHandoffCommand(directory, _args) {
81060
81316
  const tempPath = `${resolvedPath}.tmp.${crypto7.randomUUID()}`;
81061
81317
  await bunWrite(tempPath, markdown);
81062
81318
  try {
81063
- renameSync16(tempPath, resolvedPath);
81319
+ renameSync17(tempPath, resolvedPath);
81064
81320
  } catch (renameErr) {
81065
81321
  try {
81066
- unlinkSync11(tempPath);
81322
+ unlinkSync12(tempPath);
81067
81323
  } catch {}
81068
81324
  throw renameErr;
81069
81325
  }
@@ -81072,10 +81328,10 @@ async function handleHandoffCommand(directory, _args) {
81072
81328
  const promptTempPath = `${promptPath}.tmp.${crypto7.randomUUID()}`;
81073
81329
  await bunWrite(promptTempPath, continuationPrompt);
81074
81330
  try {
81075
- renameSync16(promptTempPath, promptPath);
81331
+ renameSync17(promptTempPath, promptPath);
81076
81332
  } catch (renameErr) {
81077
81333
  try {
81078
- unlinkSync11(promptTempPath);
81334
+ unlinkSync12(promptTempPath);
81079
81335
  } catch {}
81080
81336
  throw renameErr;
81081
81337
  }
@@ -81252,7 +81508,7 @@ var init_history = __esm(() => {
81252
81508
  });
81253
81509
 
81254
81510
  // src/commands/_shared/url-security.ts
81255
- import { spawnSync as spawnSync9 } from "node:child_process";
81511
+ import { spawnSync as spawnSync10 } from "node:child_process";
81256
81512
  function sanitizeUrl(raw) {
81257
81513
  let urlStr = raw.trim();
81258
81514
  urlStr = urlStr.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
@@ -81417,7 +81673,7 @@ var init_url_security = __esm(() => {
81417
81673
  IPV4_ZERO_NETWORK = /^0\./;
81418
81674
  IPV6_LINK_LOCAL = /^fe80:/i;
81419
81675
  IPV6_UNIQUE_LOCAL = /^f[cd][0-9a-f]{2}:/i;
81420
- _internals49 = { spawnSync: spawnSync9 };
81676
+ _internals49 = { spawnSync: spawnSync10 };
81421
81677
  });
81422
81678
 
81423
81679
  // src/commands/issue.ts
@@ -81546,7 +81802,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
81546
81802
 
81547
81803
  // src/hooks/knowledge-migrator.ts
81548
81804
  import { randomUUID as randomUUID6 } from "node:crypto";
81549
- import { existsSync as existsSync41, readFileSync as readFileSync25 } from "node:fs";
81805
+ import { existsSync as existsSync42, readFileSync as readFileSync25 } from "node:fs";
81550
81806
  import { mkdir as mkdir17, readFile as readFile19, writeFile as writeFile15 } from "node:fs/promises";
81551
81807
  import * as os14 from "node:os";
81552
81808
  import * as path73 from "node:path";
@@ -81563,7 +81819,7 @@ async function migrateContextToKnowledge(directory, config3) {
81563
81819
  const sentinelPath = path73.join(directory, ".swarm", ".knowledge-migrated");
81564
81820
  const contextPath = path73.join(directory, ".swarm", "context.md");
81565
81821
  const knowledgePath = resolveSwarmKnowledgePath(directory);
81566
- if (existsSync41(sentinelPath)) {
81822
+ if (existsSync42(sentinelPath)) {
81567
81823
  return {
81568
81824
  migrated: false,
81569
81825
  entriesMigrated: 0,
@@ -81572,7 +81828,7 @@ async function migrateContextToKnowledge(directory, config3) {
81572
81828
  skippedReason: "sentinel-exists"
81573
81829
  };
81574
81830
  }
81575
- if (!existsSync41(contextPath)) {
81831
+ if (!existsSync42(contextPath)) {
81576
81832
  return {
81577
81833
  migrated: false,
81578
81834
  entriesMigrated: 0,
@@ -81664,7 +81920,7 @@ async function migrateHiveKnowledgeLegacy(config3) {
81664
81920
  const legacyHivePath = _internals50.resolveLegacyHiveKnowledgePath();
81665
81921
  const canonicalHivePath = resolveHiveKnowledgePath();
81666
81922
  const sentinelPath = path73.join(path73.dirname(canonicalHivePath), ".hive-knowledge-migrated");
81667
- if (existsSync41(sentinelPath)) {
81923
+ if (existsSync42(sentinelPath)) {
81668
81924
  return {
81669
81925
  migrated: false,
81670
81926
  entriesMigrated: 0,
@@ -81673,7 +81929,7 @@ async function migrateHiveKnowledgeLegacy(config3) {
81673
81929
  skippedReason: "sentinel-exists"
81674
81930
  };
81675
81931
  }
81676
- if (!existsSync41(legacyHivePath)) {
81932
+ if (!existsSync42(legacyHivePath)) {
81677
81933
  return {
81678
81934
  migrated: false,
81679
81935
  entriesMigrated: 0,
@@ -81875,7 +82131,7 @@ function truncateLesson2(text) {
81875
82131
  }
81876
82132
  function inferProjectName(directory) {
81877
82133
  const packageJsonPath = path73.join(directory, "package.json");
81878
- if (existsSync41(packageJsonPath)) {
82134
+ if (existsSync42(packageJsonPath)) {
81879
82135
  try {
81880
82136
  const pkg = JSON.parse(readFileSync25(packageJsonPath, "utf-8"));
81881
82137
  if (pkg.name && typeof pkg.name === "string") {
@@ -83316,7 +83572,7 @@ var init_scoring = __esm(() => {
83316
83572
 
83317
83573
  // src/memory/local-jsonl-provider.ts
83318
83574
  import { randomUUID as randomUUID7 } from "node:crypto";
83319
- import { existsSync as existsSync42 } from "node:fs";
83575
+ import { existsSync as existsSync43 } from "node:fs";
83320
83576
  import {
83321
83577
  appendFile as appendFile9,
83322
83578
  mkdir as mkdir18,
@@ -83667,7 +83923,7 @@ function validateLoadedProposals(values, config3) {
83667
83923
  return { records, invalidCount };
83668
83924
  }
83669
83925
  async function readJsonl(filePath) {
83670
- if (!existsSync42(filePath))
83926
+ if (!existsSync43(filePath))
83671
83927
  return [];
83672
83928
  const content = await readFile20(filePath, "utf-8");
83673
83929
  const records = [];
@@ -83827,7 +84083,7 @@ var init_prompt_block = __esm(() => {
83827
84083
  });
83828
84084
 
83829
84085
  // src/memory/jsonl-migration.ts
83830
- import { existsSync as existsSync43 } from "node:fs";
84086
+ import { existsSync as existsSync44, renameSync as renameSync18, unlinkSync as unlinkSync13 } from "node:fs";
83831
84087
  import { copyFile as copyFile2, mkdir as mkdir19, readFile as readFile21, stat as stat10, writeFile as writeFile17 } from "node:fs/promises";
83832
84088
  import * as path75 from "node:path";
83833
84089
  function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
@@ -83859,10 +84115,10 @@ async function backupLegacyJsonl(rootDirectory, config3 = {}) {
83859
84115
  const results = [];
83860
84116
  for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
83861
84117
  const source = path75.join(storageDir, filename);
83862
- if (!existsSync43(source))
84118
+ if (!existsSync44(source))
83863
84119
  continue;
83864
84120
  const backup = path75.join(backupDir, `${filename}.pre-sqlite-migration`);
83865
- if (existsSync43(backup)) {
84121
+ if (existsSync44(backup)) {
83866
84122
  results.push({ source, backup, created: false });
83867
84123
  continue;
83868
84124
  }
@@ -83876,20 +84132,47 @@ async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
83876
84132
  await mkdir19(exportDir, { recursive: true });
83877
84133
  const memoriesPath = path75.join(exportDir, "memories.jsonl");
83878
84134
  const proposalsPath = path75.join(exportDir, "proposals.jsonl");
83879
- await writeFile17(memoriesPath, toJsonl(memories), "utf-8");
83880
- await writeFile17(proposalsPath, toJsonl(proposals), "utf-8");
84135
+ const memoriesTempPath = path75.join(path75.dirname(memoriesPath), `${path75.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
84136
+ try {
84137
+ await writeFile17(memoriesTempPath, toJsonl(memories), "utf-8");
84138
+ renameSync18(memoriesTempPath, memoriesPath);
84139
+ } catch (err2) {
84140
+ try {
84141
+ unlinkSync13(memoriesTempPath);
84142
+ } catch {}
84143
+ throw err2;
84144
+ }
84145
+ const proposalsTempPath = path75.join(path75.dirname(proposalsPath), `${path75.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
84146
+ try {
84147
+ await writeFile17(proposalsTempPath, toJsonl(proposals), "utf-8");
84148
+ renameSync18(proposalsTempPath, proposalsPath);
84149
+ } catch (err2) {
84150
+ try {
84151
+ unlinkSync13(proposalsTempPath);
84152
+ } catch {}
84153
+ throw err2;
84154
+ }
83881
84155
  return { directory: exportDir, memoriesPath, proposalsPath };
83882
84156
  }
83883
84157
  async function writeMigrationReport(rootDirectory, report, config3 = {}) {
83884
84158
  const reportPath = path75.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
83885
84159
  await mkdir19(path75.dirname(reportPath), { recursive: true });
83886
- await writeFile17(reportPath, `${JSON.stringify(report, null, 2)}
84160
+ const reportTempPath = path75.join(path75.dirname(reportPath), `${path75.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
84161
+ try {
84162
+ await writeFile17(reportTempPath, `${JSON.stringify(report, null, 2)}
83887
84163
  `, "utf-8");
84164
+ renameSync18(reportTempPath, reportPath);
84165
+ } catch (err2) {
84166
+ try {
84167
+ unlinkSync13(reportTempPath);
84168
+ } catch {}
84169
+ throw err2;
84170
+ }
83888
84171
  return reportPath;
83889
84172
  }
83890
84173
  async function readMigrationReport(rootDirectory, config3 = {}) {
83891
84174
  const reportPath = path75.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
83892
- if (!existsSync43(reportPath))
84175
+ if (!existsSync44(reportPath))
83893
84176
  return null;
83894
84177
  try {
83895
84178
  return JSON.parse(await readFile21(reportPath, "utf-8"));
@@ -83903,13 +84186,13 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
83903
84186
  for (const file3 of ["memories.jsonl", "proposals.jsonl"]) {
83904
84187
  const filePath = path75.join(storageDir, file3);
83905
84188
  let sizeBytes = 0;
83906
- if (existsSync43(filePath)) {
84189
+ if (existsSync44(filePath)) {
83907
84190
  sizeBytes = (await stat10(filePath)).size;
83908
84191
  }
83909
84192
  statuses.push({
83910
84193
  file: file3,
83911
84194
  path: filePath,
83912
- exists: existsSync43(filePath),
84195
+ exists: existsSync44(filePath),
83913
84196
  sizeBytes
83914
84197
  });
83915
84198
  }
@@ -83990,7 +84273,7 @@ async function readProposalJsonl(filePath, config3) {
83990
84273
  return { records, invalidRows, totalRows: rows.totalRows };
83991
84274
  }
83992
84275
  async function readJsonlRows(filePath) {
83993
- if (!existsSync43(filePath)) {
84276
+ if (!existsSync44(filePath)) {
83994
84277
  return { rows: [], invalidRows: [], totalRows: 0 };
83995
84278
  }
83996
84279
  const content = await readFile21(filePath, "utf-8");
@@ -85020,7 +85303,7 @@ var init_sqlite_provider = __esm(() => {
85020
85303
 
85021
85304
  // src/memory/gateway.ts
85022
85305
  import { createHash as createHash12 } from "node:crypto";
85023
- import { existsSync as existsSync44, readFileSync as readFileSync26 } from "node:fs";
85306
+ import { existsSync as existsSync45, readFileSync as readFileSync26 } from "node:fs";
85024
85307
  import * as path77 from "node:path";
85025
85308
 
85026
85309
  class MemoryGateway {
@@ -85345,7 +85628,7 @@ function readGitRemoteUrl(directory) {
85345
85628
  if (gitRemoteUrlCache.has(directory))
85346
85629
  return gitRemoteUrlCache.get(directory);
85347
85630
  const gitConfigPath = path77.join(directory, ".git", "config");
85348
- if (!existsSync44(gitConfigPath)) {
85631
+ if (!existsSync45(gitConfigPath)) {
85349
85632
  gitRemoteUrlCache.set(directory, undefined);
85350
85633
  return;
85351
85634
  }
@@ -86325,7 +86608,7 @@ var init_memory = __esm(() => {
86325
86608
  });
86326
86609
 
86327
86610
  // src/commands/memory.ts
86328
- import { existsSync as existsSync45 } from "node:fs";
86611
+ import { existsSync as existsSync46 } from "node:fs";
86329
86612
  import * as path80 from "node:path";
86330
86613
  import { fileURLToPath as fileURLToPath3 } from "node:url";
86331
86614
  async function handleMemoryCommand(_directory, _args) {
@@ -86357,7 +86640,7 @@ async function handleMemoryStatusCommand(directory, _args) {
86357
86640
  `- Provider: \`${config3.provider}\``,
86358
86641
  `- Storage: \`${storageDir}\``,
86359
86642
  `- SQLite path: \`${sqlitePath}\``,
86360
- `- SQLite database exists: \`${existsSync45(sqlitePath)}\``,
86643
+ `- SQLite database exists: \`${existsSync46(sqlitePath)}\``,
86361
86644
  `- Automatic destructive cleanup: \`disabled\``,
86362
86645
  "",
86363
86646
  "### Legacy JSONL"
@@ -91204,19 +91487,19 @@ function hasCompoundTestExtension(filename) {
91204
91487
  const lower = filename.toLowerCase();
91205
91488
  return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
91206
91489
  }
91207
- function isLanguageSpecificTestFile(basename12) {
91208
- const lower = basename12.toLowerCase();
91490
+ function isLanguageSpecificTestFile(basename13) {
91491
+ const lower = basename13.toLowerCase();
91209
91492
  if (lower.endsWith("_test.go"))
91210
91493
  return true;
91211
91494
  if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
91212
91495
  return true;
91213
91496
  if (lower.endsWith("_spec.rb"))
91214
91497
  return true;
91215
- if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename12) || basename12.endsWith("Test.java") || basename12.endsWith("Tests.java") || lower.endsWith("it.java")))
91498
+ if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename13) || basename13.endsWith("Test.java") || basename13.endsWith("Tests.java") || lower.endsWith("it.java")))
91216
91499
  return true;
91217
91500
  if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
91218
91501
  return true;
91219
- if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename12) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
91502
+ if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename13) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
91220
91503
  return true;
91221
91504
  if (lower.endsWith(".tests.ps1"))
91222
91505
  return true;
@@ -91224,23 +91507,23 @@ function isLanguageSpecificTestFile(basename12) {
91224
91507
  }
91225
91508
  function isConventionTestFilePath(filePath) {
91226
91509
  const normalizedPath = filePath.replace(/\\/g, "/");
91227
- const basename12 = path93.basename(filePath);
91228
- return hasCompoundTestExtension(basename12) || basename12.includes(".spec.") || basename12.includes(".test.") || isLanguageSpecificTestFile(basename12) || isTestDirectoryPath(normalizedPath);
91510
+ const basename13 = path93.basename(filePath);
91511
+ return hasCompoundTestExtension(basename13) || basename13.includes(".spec.") || basename13.includes(".test.") || isLanguageSpecificTestFile(basename13) || isTestDirectoryPath(normalizedPath);
91229
91512
  }
91230
91513
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
91231
91514
  const testFiles = [];
91232
91515
  for (const file3 of sourceFiles) {
91233
91516
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
91234
91517
  const relativeFile = path93.relative(workingDir, absoluteFile);
91235
- const basename12 = path93.basename(absoluteFile);
91518
+ const basename13 = path93.basename(absoluteFile);
91236
91519
  const dirname43 = path93.dirname(absoluteFile);
91237
91520
  const preferRelativeOutput = !path93.isAbsolute(file3);
91238
91521
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
91239
91522
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
91240
91523
  continue;
91241
91524
  }
91242
- const nameWithoutExt = basename12.replace(/\.[^.]+$/, "");
91243
- const ext = path93.extname(basename12);
91525
+ const nameWithoutExt = basename13.replace(/\.[^.]+$/, "");
91526
+ const ext = path93.extname(basename13);
91244
91527
  const genericTestNames = [
91245
91528
  `${nameWithoutExt}.spec${ext}`,
91246
91529
  `${nameWithoutExt}.test${ext}`
@@ -91251,7 +91534,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
91251
91534
  ...languageSpecificTestNames
91252
91535
  ].map((candidateName) => path93.join(dirname43, candidateName));
91253
91536
  const testDirectoryNames = [
91254
- basename12,
91537
+ basename13,
91255
91538
  ...genericTestNames,
91256
91539
  ...languageSpecificTestNames
91257
91540
  ];
@@ -94195,7 +94478,9 @@ async function handleResetCommand(directory, args2) {
94195
94478
  fs51.unlinkSync(rootPath);
94196
94479
  results.push(`- ✅ Deleted ${filename} (root)`);
94197
94480
  }
94198
- } catch {}
94481
+ } catch (err2) {
94482
+ results.push(`- ❌ Failed to delete ${filename}: ${err2 instanceof Error ? err2.message : String(err2)}`);
94483
+ }
94199
94484
  }
94200
94485
  try {
94201
94486
  resetAutomationManager();
@@ -95215,6 +95500,11 @@ var init_prm = __esm(() => {
95215
95500
  // src/commands/reset-session.ts
95216
95501
  import * as fs54 from "node:fs";
95217
95502
  import * as path98 from "node:path";
95503
+ function errorMessage2(err2) {
95504
+ if (err2 instanceof Error)
95505
+ return err2.message;
95506
+ return String(err2);
95507
+ }
95218
95508
  async function handleResetSessionCommand(directory, _args) {
95219
95509
  const results = [];
95220
95510
  try {
@@ -95228,22 +95518,30 @@ async function handleResetSessionCommand(directory, _args) {
95228
95518
  } catch {
95229
95519
  results.push("❌ Failed to delete state.json");
95230
95520
  }
95231
- try {
95232
- const sessionDir = path98.dirname(validateSwarmPath(directory, "session/state.json"));
95233
- if (fs54.existsSync(sessionDir)) {
95234
- const files = fs54.readdirSync(sessionDir);
95235
- const otherFiles = files.filter((f) => f !== "state.json");
95236
- let deletedCount = 0;
95237
- for (const file3 of otherFiles) {
95238
- const filePath = path98.join(sessionDir, file3);
95239
- if (fs54.lstatSync(filePath).isFile()) {
95240
- fs54.unlinkSync(filePath);
95241
- deletedCount++;
95242
- }
95243
- }
95244
- results.push(`✅ Cleaned ${deletedCount} additional session file(s)`);
95521
+ const sessionDir = path98.dirname(validateSwarmPath(directory, "session/state.json"));
95522
+ let sessionFiles = [];
95523
+ if (fs54.existsSync(sessionDir)) {
95524
+ try {
95525
+ sessionFiles = fs54.readdirSync(sessionDir);
95526
+ } catch (err2) {
95527
+ results.push(`❌ Failed to read session directory: ${errorMessage2(err2)}`);
95245
95528
  }
95246
- } catch {}
95529
+ }
95530
+ for (const file3 of sessionFiles) {
95531
+ if (file3 === "state.json")
95532
+ continue;
95533
+ const filePath = path98.join(sessionDir, file3);
95534
+ try {
95535
+ if (!fs54.existsSync(filePath))
95536
+ continue;
95537
+ if (!fs54.lstatSync(filePath).isFile())
95538
+ continue;
95539
+ fs54.unlinkSync(filePath);
95540
+ results.push(`✓ Deleted ${file3}`);
95541
+ } catch (err2) {
95542
+ results.push(`❌ Failed to delete ${file3}: ${errorMessage2(err2)}`);
95543
+ }
95544
+ }
95247
95545
  const sessionCount = swarmState.agentSessions.size;
95248
95546
  for (const [sessionId, session] of swarmState.agentSessions) {
95249
95547
  resetPrmSessionState(session, sessionId);
@@ -95273,7 +95571,7 @@ var init_reset_session = __esm(() => {
95273
95571
  });
95274
95572
 
95275
95573
  // src/summaries/manager.ts
95276
- import { mkdirSync as mkdirSync29, readdirSync as readdirSync17, renameSync as renameSync17, rmSync as rmSync5, statSync as statSync20 } from "node:fs";
95574
+ import { mkdirSync as mkdirSync29, readdirSync as readdirSync17, renameSync as renameSync19, rmSync as rmSync5, statSync as statSync20 } from "node:fs";
95277
95575
  import * as path99 from "node:path";
95278
95576
  function sanitizeSummaryId(id) {
95279
95577
  if (!id || id.length === 0) {
@@ -95323,7 +95621,7 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
95323
95621
  const tempPath = path99.join(summaryDir, `${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);
95324
95622
  try {
95325
95623
  await bunWrite(tempPath, entryJson);
95326
- renameSync17(tempPath, summaryPath);
95624
+ renameSync19(tempPath, summaryPath);
95327
95625
  } catch (error93) {
95328
95626
  try {
95329
95627
  rmSync5(tempPath, { force: true });
@@ -95457,6 +95755,7 @@ async function handleRollbackCommand(directory, args2) {
95457
95755
  ]);
95458
95756
  const successes = [];
95459
95757
  const failures = [];
95758
+ const warnings = [];
95460
95759
  for (const file3 of checkpointFiles) {
95461
95760
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
95462
95761
  continue;
@@ -95482,30 +95781,39 @@ async function handleRollbackCommand(directory, args2) {
95482
95781
  `);
95483
95782
  }
95484
95783
  const existingLedgerPath = path100.join(swarmDir, "plan-ledger.jsonl");
95784
+ let ledgerDeletionFailed = false;
95485
95785
  if (fs55.existsSync(existingLedgerPath)) {
95486
- fs55.unlinkSync(existingLedgerPath);
95487
- }
95488
- try {
95489
- const planJsonPath = path100.join(swarmDir, "plan.json");
95490
- if (fs55.existsSync(planJsonPath)) {
95491
- const planRaw = fs55.readFileSync(planJsonPath, "utf-8");
95492
- const plan = PlanSchema.parse(JSON.parse(planRaw));
95493
- const planId = derivePlanId(plan);
95494
- const planHash = computePlanHash(plan);
95495
- await initLedger(directory, planId, planHash, plan);
95496
- await appendLedgerEvent(directory, {
95497
- event_type: "plan_rebuilt",
95498
- source: "rollback",
95499
- plan_id: planId
95500
- });
95786
+ try {
95787
+ fs55.unlinkSync(existingLedgerPath);
95788
+ } catch (err2) {
95789
+ ledgerDeletionFailed = true;
95790
+ const errMsg = err2 instanceof Error ? err2.message : String(err2);
95791
+ warnings.push(`⚠️ Warning: Could not delete stale ledger (${errMsg}). The ledger may be inconsistent with the restored plan. Run /swarm reset-session to clean up session state.`);
95501
95792
  }
95502
- } catch (initError) {
95503
- return [
95504
- `Rollback restored files but failed to initialize ledger: ${initError instanceof Error ? initError.message : String(initError)}`,
95505
- "The .swarm/plan.json has been restored but the ledger may be out of sync.",
95506
- "Run /swarm reset-session to reinitialize the ledger."
95507
- ].join(`
95793
+ }
95794
+ if (!ledgerDeletionFailed) {
95795
+ try {
95796
+ const planJsonPath = path100.join(swarmDir, "plan.json");
95797
+ if (fs55.existsSync(planJsonPath)) {
95798
+ const planRaw = fs55.readFileSync(planJsonPath, "utf-8");
95799
+ const plan = PlanSchema.parse(JSON.parse(planRaw));
95800
+ const planId = derivePlanId(plan);
95801
+ const planHash = computePlanHash(plan);
95802
+ await initLedger(directory, planId, planHash, plan);
95803
+ await appendLedgerEvent(directory, {
95804
+ event_type: "plan_rebuilt",
95805
+ source: "rollback",
95806
+ plan_id: planId
95807
+ });
95808
+ }
95809
+ } catch (initError) {
95810
+ return [
95811
+ `Rollback restored files but failed to initialize ledger: ${initError instanceof Error ? initError.message : String(initError)}`,
95812
+ "The .swarm/plan.json has been restored but the ledger may be out of sync.",
95813
+ "Run /swarm reset-session to reinitialize the ledger."
95814
+ ].join(`
95508
95815
  `);
95816
+ }
95509
95817
  }
95510
95818
  const eventsPath = validateSwarmPath(directory, "events.jsonl");
95511
95819
  const rollbackEvent = {
@@ -95520,6 +95828,14 @@ async function handleRollbackCommand(directory, args2) {
95520
95828
  } catch (error93) {
95521
95829
  console.error("Failed to write rollback event:", error93 instanceof Error ? error93.message : String(error93));
95522
95830
  }
95831
+ if (warnings.length > 0) {
95832
+ return [
95833
+ ...warnings,
95834
+ "",
95835
+ `Rolled back to phase ${targetPhase}: ${checkpoint2.label || "no label"}`
95836
+ ].join(`
95837
+ `);
95838
+ }
95523
95839
  return `Rolled back to phase ${targetPhase}: ${checkpoint2.label || "no label"}`;
95524
95840
  }
95525
95841
  var init_rollback = __esm(() => {
@@ -95697,6 +96013,7 @@ var init_sdd = __esm(() => {
95697
96013
  });
95698
96014
 
95699
96015
  // src/commands/simulate.ts
96016
+ import { renameSync as renameSync20, unlinkSync as unlinkSync18 } from "node:fs";
95700
96017
  async function handleSimulateCommand(directory, args2) {
95701
96018
  const thresholdIndex = args2.indexOf("--threshold");
95702
96019
  const minCommitsIndex = args2.indexOf("--min-commits");
@@ -95748,7 +96065,16 @@ Ensure this is a git repository with commit history.`;
95748
96065
  const path101 = await import("node:path");
95749
96066
  const reportPath = path101.join(directory, ".swarm", "simulate-report.md");
95750
96067
  await fs56.mkdir(path101.dirname(reportPath), { recursive: true });
95751
- await fs56.writeFile(reportPath, report, "utf-8");
96068
+ const reportTempPath = path101.join(path101.dirname(reportPath), `${path101.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
96069
+ try {
96070
+ await fs56.writeFile(reportTempPath, report, "utf-8");
96071
+ renameSync20(reportTempPath, reportPath);
96072
+ } catch (err2) {
96073
+ try {
96074
+ unlinkSync18(reportTempPath);
96075
+ } catch {}
96076
+ throw err2;
96077
+ }
95752
96078
  } catch (err2) {
95753
96079
  const writeErr = err2 instanceof Error ? err2.message : String(err2);
95754
96080
  warn(`simulate: failed to write report to ${directory}/.swarm/simulate-report.md`, writeErr);
@@ -103469,11 +103795,11 @@ __export(exports_evidence_summary_integration, {
103469
103795
  createEvidenceSummaryIntegration: () => createEvidenceSummaryIntegration,
103470
103796
  EvidenceSummaryIntegration: () => EvidenceSummaryIntegration
103471
103797
  });
103472
- import { existsSync as existsSync57, mkdirSync as mkdirSync31, writeFileSync as writeFileSync18 } from "node:fs";
103798
+ import { existsSync as existsSync58, mkdirSync as mkdirSync31, writeFileSync as writeFileSync18 } from "node:fs";
103473
103799
  import * as path107 from "node:path";
103474
103800
  function persistSummary(projectDir, artifact, filename) {
103475
103801
  const swarmPath = path107.join(projectDir, ".swarm");
103476
- if (!existsSync57(swarmPath)) {
103802
+ if (!existsSync58(swarmPath)) {
103477
103803
  mkdirSync31(swarmPath, { recursive: true });
103478
103804
  }
103479
103805
  const artifactPath = path107.join(swarmPath, filename);
@@ -104485,11 +104811,11 @@ var init_schema3 = __esm(() => {
104485
104811
 
104486
104812
  // src/summaries/store.ts
104487
104813
  import {
104488
- existsSync as existsSync69,
104814
+ existsSync as existsSync70,
104489
104815
  mkdirSync as mkdirSync38,
104490
104816
  readFileSync as readFileSync48,
104491
- renameSync as renameSync23,
104492
- unlinkSync as unlinkSync19,
104817
+ renameSync as renameSync26,
104818
+ unlinkSync as unlinkSync22,
104493
104819
  writeFileSync as writeFileSync25
104494
104820
  } from "node:fs";
104495
104821
  import * as path120 from "node:path";
@@ -104498,11 +104824,11 @@ function writeRawSidecar(absPath, bundle) {
104498
104824
  const tempFile = `${absPath}.tmp-${Date.now()}-${process.pid}`;
104499
104825
  try {
104500
104826
  writeFileSync25(tempFile, JSON.stringify(bundle, null, 2), "utf-8");
104501
- renameSync23(tempFile, absPath);
104827
+ renameSync26(tempFile, absPath);
104502
104828
  } finally {
104503
- if (existsSync69(tempFile)) {
104829
+ if (existsSync70(tempFile)) {
104504
104830
  try {
104505
- unlinkSync19(tempFile);
104831
+ unlinkSync22(tempFile);
104506
104832
  } catch {}
104507
104833
  }
104508
104834
  }
@@ -104587,7 +104913,7 @@ function readSupervisorReportRaw(directory, phase) {
104587
104913
  } catch {
104588
104914
  return null;
104589
104915
  }
104590
- if (!existsSync69(abs))
104916
+ if (!existsSync70(abs))
104591
104917
  return null;
104592
104918
  try {
104593
104919
  const parsed = JSON.parse(readFileSync48(abs, "utf-8"));
@@ -107959,7 +108285,7 @@ __export(exports_runtime, {
107959
108285
  clearParserCache: () => clearParserCache,
107960
108286
  _internals: () => _internals80
107961
108287
  });
107962
- import { existsSync as existsSync74, statSync as statSync28 } from "node:fs";
108288
+ import { existsSync as existsSync75, statSync as statSync28 } from "node:fs";
107963
108289
  import * as path133 from "node:path";
107964
108290
  import { fileURLToPath as fileURLToPath4 } from "node:url";
107965
108291
  async function initTreeSitter() {
@@ -108027,7 +108353,7 @@ async function loadGrammar(languageId) {
108027
108353
  const parser = new Parser;
108028
108354
  const wasmFileName = getWasmFileName(normalizedId);
108029
108355
  const wasmPath = path133.join(getGrammarsDirAbsolute(), wasmFileName);
108030
- if (!existsSync74(wasmPath)) {
108356
+ if (!existsSync75(wasmPath)) {
108031
108357
  throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
108032
108358
  ` + `Make sure to run 'bun run build' to copy grammar files to dist/lang/grammars/`);
108033
108359
  }
@@ -108143,17 +108469,17 @@ function normalizeSeparators(filePath) {
108143
108469
  }
108144
108470
  function matchesDocPattern(filePath, patterns) {
108145
108471
  const normalizedPath = normalizeSeparators(filePath);
108146
- const basename15 = path135.basename(filePath);
108472
+ const basename16 = path135.basename(filePath);
108147
108473
  for (const pattern of patterns) {
108148
108474
  if (!pattern.includes("/") && !pattern.includes("\\")) {
108149
- if (basename15 === pattern) {
108475
+ if (basename16 === pattern) {
108150
108476
  return true;
108151
108477
  }
108152
108478
  continue;
108153
108479
  }
108154
108480
  if (pattern.startsWith("**/")) {
108155
108481
  const filenamePattern = pattern.slice(3);
108156
- if (basename15 === filenamePattern) {
108482
+ if (basename16 === filenamePattern) {
108157
108483
  return true;
108158
108484
  }
108159
108485
  continue;
@@ -108546,7 +108872,7 @@ var init_doc_scan = __esm(() => {
108546
108872
  });
108547
108873
 
108548
108874
  // src/hooks/knowledge-reader.ts
108549
- import { existsSync as existsSync75 } from "node:fs";
108875
+ import { existsSync as existsSync76 } from "node:fs";
108550
108876
  import { readFile as readFile28 } from "node:fs/promises";
108551
108877
  import * as path136 from "node:path";
108552
108878
  function inferCategoriesFromPhase(phaseDescription) {
@@ -108594,7 +108920,7 @@ function inferCategoriesFromPhase(phaseDescription) {
108594
108920
  }
108595
108921
  async function transactShownFile(shownFile, mutate) {
108596
108922
  return transactFile(shownFile, async (filePath) => {
108597
- if (!existsSync75(filePath))
108923
+ if (!existsSync76(filePath))
108598
108924
  return {};
108599
108925
  try {
108600
108926
  const content = await readFile28(filePath, "utf-8");
@@ -108724,7 +109050,7 @@ async function readMergedKnowledge(directory, config3, context, opts) {
108724
109050
  async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
108725
109051
  const shownFile = path136.join(directory, ".swarm", ".knowledge-shown.json");
108726
109052
  try {
108727
- if (!existsSync75(shownFile)) {
109053
+ if (!existsSync76(shownFile)) {
108728
109054
  return;
108729
109055
  }
108730
109056
  let shownIds;
@@ -110079,18 +110405,51 @@ var EvidencePlanSchema = exports_external.object({
110079
110405
  }).passthrough()).optional()
110080
110406
  }).passthrough();
110081
110407
  function ghExec(args2, cwd) {
110082
- const result = child_process7.spawnSync("gh", args2, {
110083
- cwd,
110084
- encoding: "utf-8",
110085
- timeout: GIT_TIMEOUT_MS3,
110086
- stdio: ["ignore", "pipe", "pipe"]
110087
- });
110088
- if (result.status !== 0) {
110089
- throw new Error(result.stderr || `gh exited with ${result.status}`);
110408
+ for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
110409
+ const result = child_process7.spawnSync("gh", args2, {
110410
+ cwd,
110411
+ encoding: "utf-8",
110412
+ timeout: GIT_TIMEOUT_MS3,
110413
+ windowsHide: true,
110414
+ maxBuffer: MAX_OUTPUT_BYTES4,
110415
+ stdio: ["ignore", "pipe", "pipe"]
110416
+ });
110417
+ if (result.error) {
110418
+ if (isTransientSpawnError(result.error) && attempt < MAX_TRANSIENT_RETRIES - 1) {
110419
+ transientBackoff(attempt);
110420
+ continue;
110421
+ }
110422
+ if (result.error.code === "ENOENT") {
110423
+ throw new Error(`gh failed to start: ENOENT — gh not installed or not on PATH`);
110424
+ }
110425
+ throw new Error(`gh failed to start: ${result.error.code} — ${result.error.message}`);
110426
+ }
110427
+ if (result.status !== 0) {
110428
+ throw new Error(result.stderr || result.stdout || `gh exited with ${result.status}`);
110429
+ }
110430
+ return result.stdout;
110090
110431
  }
110091
- return result.stdout;
110432
+ throw new Error("gh exited with null");
110092
110433
  }
110093
110434
  var MAX_OUTPUT_BYTES4 = 5 * 1024 * 1024;
110435
+ function spawnSyncWithTransientRetry(command, args2, options) {
110436
+ for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
110437
+ const result = child_process7.spawnSync(command, args2, options);
110438
+ if (result.error) {
110439
+ if (isTransientSpawnError(result.error) && attempt < MAX_TRANSIENT_RETRIES - 1) {
110440
+ transientBackoff(attempt);
110441
+ continue;
110442
+ }
110443
+ throw new Error(`${command} failed: ${result.error.code} — ${result.error.message}`);
110444
+ }
110445
+ if (result.status !== 0) {
110446
+ const reason = result.stderr || result.stdout || `${command} exited with ${result.status}`;
110447
+ throw new Error(`${command} failed: ${reason}`);
110448
+ }
110449
+ return result;
110450
+ }
110451
+ throw new Error(`${command} exited with null`);
110452
+ }
110094
110453
  async function ghExecAsync(args2, cwd) {
110095
110454
  return new Promise((resolve42, reject) => {
110096
110455
  const proc = child_process7.spawn("gh", args2, {
@@ -110152,7 +110511,7 @@ async function ghExecAsync(args2, cwd) {
110152
110511
  });
110153
110512
  });
110154
110513
  }
110155
- var _internals70 = { ghExec, ghExecAsync };
110514
+ var _internals70 = { ghExec, ghExecAsync, spawnSyncWithTransientRetry };
110156
110515
  async function getPRStatus(prNumber, repoFullName, cwd) {
110157
110516
  let stdout;
110158
110517
  try {
@@ -112184,7 +112543,7 @@ init_state2();
112184
112543
  init_utils();
112185
112544
  init_bun_compat();
112186
112545
  init_utils2();
112187
- import { renameSync as renameSync21, unlinkSync as unlinkSync17 } from "node:fs";
112546
+ import { renameSync as renameSync24, unlinkSync as unlinkSync20 } from "node:fs";
112188
112547
  import * as nodePath2 from "node:path";
112189
112548
  function createAgentActivityHooks(config3, directory) {
112190
112549
  if (config3.hooks?.agent_activity === false) {
@@ -112259,10 +112618,10 @@ async function doFlush(directory) {
112259
112618
  const tempPath = `${path116}.tmp`;
112260
112619
  try {
112261
112620
  await bunWrite(tempPath, updated);
112262
- renameSync21(tempPath, path116);
112621
+ renameSync24(tempPath, path116);
112263
112622
  } catch (writeError) {
112264
112623
  try {
112265
- unlinkSync17(tempPath);
112624
+ unlinkSync20(tempPath);
112266
112625
  } catch {}
112267
112626
  throw writeError;
112268
112627
  }
@@ -114441,7 +114800,7 @@ import * as path130 from "node:path";
114441
114800
  init_logger();
114442
114801
  init_path_security();
114443
114802
  import * as fsSync8 from "node:fs";
114444
- import { existsSync as existsSync70, realpathSync as realpathSync13 } from "node:fs";
114803
+ import { existsSync as existsSync71, realpathSync as realpathSync13 } from "node:fs";
114445
114804
  import * as fsPromises5 from "node:fs/promises";
114446
114805
  import * as os16 from "node:os";
114447
114806
  import * as path125 from "node:path";
@@ -115744,7 +116103,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
115744
116103
  if (realRoot === null) {
115745
116104
  return null;
115746
116105
  }
115747
- if (!existsSync70(resolved)) {
116106
+ if (!existsSync71(resolved)) {
115748
116107
  const EXTENSIONS = [
115749
116108
  ".ts",
115750
116109
  ".tsx",
@@ -115758,7 +116117,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
115758
116117
  let found = null;
115759
116118
  for (const ext of EXTENSIONS) {
115760
116119
  const candidate = resolved + ext;
115761
- if (existsSync70(candidate)) {
116120
+ if (existsSync71(candidate)) {
115762
116121
  found = candidate;
115763
116122
  break;
115764
116123
  }
@@ -116225,7 +116584,7 @@ async function buildWorkspaceGraphAsync(workspaceRoot, options) {
116225
116584
  const walkBudgetMs = options?.walkBudgetMs ?? DEFAULT_WALK_BUDGET_MS;
116226
116585
  const followSymlinks = options?.followSymlinks ?? false;
116227
116586
  const absoluteRoot = path125.resolve(workspaceRoot);
116228
- if (!existsSync70(absoluteRoot)) {
116587
+ if (!existsSync71(absoluteRoot)) {
116229
116588
  throw new Error(`Workspace directory does not exist: ${workspaceRoot}`);
116230
116589
  }
116231
116590
  if (isRefusedWorkspaceRoot(absoluteRoot)) {
@@ -116321,7 +116680,7 @@ function getCachedMtime(workspace) {
116321
116680
  }
116322
116681
  // src/tools/repo-graph/incremental.ts
116323
116682
  init_logger();
116324
- import { existsSync as existsSync72 } from "node:fs";
116683
+ import { existsSync as existsSync73 } from "node:fs";
116325
116684
  import * as fsPromises7 from "node:fs/promises";
116326
116685
  import * as path129 from "node:path";
116327
116686
 
@@ -116887,7 +117246,7 @@ function buildOntologyPreflightPacket(graph, filePaths = [], options = {}) {
116887
117246
  init_utils2();
116888
117247
  init_logger();
116889
117248
  init_path_security();
116890
- import { constants as constants5, existsSync as existsSync71, readFileSync as readFileSync51, statSync as statSync26 } from "node:fs";
117249
+ import { constants as constants5, existsSync as existsSync72, readFileSync as readFileSync51, statSync as statSync26 } from "node:fs";
116891
117250
  import * as fsPromises6 from "node:fs/promises";
116892
117251
  import * as path128 from "node:path";
116893
117252
  var WINDOWS_RENAME_MAX_RETRIES2 = 5;
@@ -116949,7 +117308,7 @@ async function loadGraph(workspace) {
116949
117308
  if (cached3 && !isDirty(normalized)) {
116950
117309
  try {
116951
117310
  const graphPath = getGraphPath(workspace);
116952
- if (existsSync71(graphPath)) {
117311
+ if (existsSync72(graphPath)) {
116953
117312
  const stats2 = await fsPromises6.stat(graphPath);
116954
117313
  const cachedMtime = getCachedMtime(normalized);
116955
117314
  if (cachedMtime !== undefined && stats2.mtimeMs !== cachedMtime) {
@@ -116966,7 +117325,7 @@ async function loadGraph(workspace) {
116966
117325
  }
116967
117326
  try {
116968
117327
  const graphPath = getGraphPath(workspace);
116969
- if (!existsSync71(graphPath)) {
117328
+ if (!existsSync72(graphPath)) {
116970
117329
  return null;
116971
117330
  }
116972
117331
  const stats2 = await fsPromises6.stat(graphPath);
@@ -117000,7 +117359,7 @@ function loadGraphSync(workspace) {
117000
117359
  const normalized = path128.normalize(workspace);
117001
117360
  try {
117002
117361
  const graphPath = getGraphPath(workspace);
117003
- if (!existsSync71(graphPath))
117362
+ if (!existsSync72(graphPath))
117004
117363
  return null;
117005
117364
  const stats2 = statSync26(graphPath);
117006
117365
  const content = readFileSync51(graphPath, "utf-8");
@@ -117130,7 +117489,7 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
117130
117489
  const updatedPaths = new Set;
117131
117490
  for (const rawFilePath of filePaths) {
117132
117491
  const normalizedPath = normalizeGraphPath(rawFilePath);
117133
- const fileExists = existsSync72(rawFilePath);
117492
+ const fileExists = existsSync73(rawFilePath);
117134
117493
  if (fileExists) {
117135
117494
  graph.edges = graph.edges.filter((e) => normalizeGraphPath(e.source) !== normalizedPath);
117136
117495
  const result = scanFile(rawFilePath, absoluteRoot, maxFileSize);
@@ -117170,7 +117529,7 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
117170
117529
  if (loadedMtime !== undefined) {
117171
117530
  try {
117172
117531
  const graphPath = getGraphPath(workspaceRoot);
117173
- if (existsSync72(graphPath)) {
117532
+ if (existsSync73(graphPath)) {
117174
117533
  const currentStats = await fsPromises7.stat(graphPath);
117175
117534
  if (currentStats.mtimeMs !== loadedMtime) {
117176
117535
  warn(`[repo-graph] Concurrent modification detected — falling back to full rebuild`);
@@ -121331,7 +121690,7 @@ init_task_file();
121331
121690
  init_logger();
121332
121691
  init_knowledge_store();
121333
121692
  var import_proper_lockfile9 = __toESM(require_proper_lockfile(), 1);
121334
- import { existsSync as existsSync77 } from "node:fs";
121693
+ import { existsSync as existsSync78 } from "node:fs";
121335
121694
  import { appendFile as appendFile13, mkdir as mkdir28, readFile as readFile30 } from "node:fs/promises";
121336
121695
  import * as path140 from "node:path";
121337
121696
  function resolveApplicationLogPath(directory) {
@@ -121420,7 +121779,7 @@ async function bumpCountersBatch(directory, bumps) {
121420
121779
  const swarmPath = resolveSwarmKnowledgePath(directory);
121421
121780
  await transactKnowledge(swarmPath, applyOne);
121422
121781
  const hivePath = resolveHiveKnowledgePath();
121423
- if (existsSync77(hivePath)) {
121782
+ if (existsSync78(hivePath)) {
121424
121783
  await transactKnowledge(hivePath, applyOne);
121425
121784
  }
121426
121785
  }
@@ -122394,7 +122753,7 @@ init_extractors();
122394
122753
  // src/hooks/phase-directives.ts
122395
122754
  init_knowledge_events();
122396
122755
  init_knowledge_store();
122397
- import { existsSync as existsSync78 } from "node:fs";
122756
+ import { existsSync as existsSync79 } from "node:fs";
122398
122757
  async function collectPhaseDirectiveIds(directory, phaseLabel) {
122399
122758
  const events = await readKnowledgeEvents(directory);
122400
122759
  const ids = new Set;
@@ -122414,7 +122773,7 @@ async function readEntriesById(directory) {
122414
122773
  for (const e of swarm)
122415
122774
  map3.set(e.id, e);
122416
122775
  const hivePath = resolveHiveKnowledgePath();
122417
- if (existsSync78(hivePath)) {
122776
+ if (existsSync79(hivePath)) {
122418
122777
  const hive = await readKnowledge(hivePath);
122419
122778
  for (const e of hive)
122420
122779
  if (!map3.has(e.id))
@@ -124306,7 +124665,7 @@ init_schema();
124306
124665
  // src/services/directive-predicate-runner.ts
124307
124666
  init_bun_compat();
124308
124667
  init_logger();
124309
- import { existsSync as existsSync81 } from "node:fs";
124668
+ import { existsSync as existsSync82 } from "node:fs";
124310
124669
  import * as path146 from "node:path";
124311
124670
  var PREDICATE_TIMEOUT_MS = 15000;
124312
124671
  var TOOL_BINARY_ALLOWLIST = new Set([
@@ -124348,7 +124707,7 @@ function findBinaryInPath(binary2) {
124348
124707
  if (!dir)
124349
124708
  continue;
124350
124709
  const candidate = path146.join(dir, exeName);
124351
- if (existsSync81(candidate))
124710
+ if (existsSync82(candidate))
124352
124711
  return candidate;
124353
124712
  }
124354
124713
  return null;
@@ -125180,7 +125539,7 @@ init_state3();
125180
125539
  init_utils2();
125181
125540
  init_state2();
125182
125541
  init_bun_compat();
125183
- import { renameSync as renameSync25 } from "node:fs";
125542
+ import { renameSync as renameSync28 } from "node:fs";
125184
125543
  var TRANSIENT_SESSION_FIELDS = [
125185
125544
  { name: "revisionLimitHit", resetValue: false },
125186
125545
  { name: "coderRevisions", resetValue: 0 },
@@ -125323,7 +125682,7 @@ async function readSnapshot(directory) {
125323
125682
  if (parsed.version !== 1 && parsed.version !== 2) {
125324
125683
  try {
125325
125684
  const quarantinePath = validateSwarmPath(directory, "session/state.json.quarantine");
125326
- renameSync25(resolvedPath, quarantinePath);
125685
+ renameSync28(resolvedPath, quarantinePath);
125327
125686
  } catch {}
125328
125687
  return null;
125329
125688
  }
@@ -125422,14 +125781,14 @@ init_zod();
125422
125781
  init_path_security();
125423
125782
  init_create_tool();
125424
125783
  import {
125425
- existsSync as existsSync83,
125784
+ existsSync as existsSync84,
125426
125785
  mkdirSync as mkdirSync39,
125427
125786
  mkdtempSync as mkdtempSync2,
125428
125787
  readFileSync as readFileSync56,
125429
125788
  realpathSync as realpathSync16,
125430
- renameSync as renameSync26,
125789
+ renameSync as renameSync29,
125431
125790
  rmdirSync,
125432
- unlinkSync as unlinkSync22,
125791
+ unlinkSync as unlinkSync25,
125433
125792
  writeFileSync as writeFileSync26
125434
125793
  } from "node:fs";
125435
125794
  import * as path149 from "node:path";
@@ -125783,15 +126142,15 @@ function atomicWriteFileSync2(targetPath, content) {
125783
126142
  }
125784
126143
  try {
125785
126144
  writeFileSync26(tempPath, content, "utf-8");
125786
- renameSync26(tempPath, targetPath);
126145
+ renameSync29(tempPath, targetPath);
125787
126146
  } finally {
125788
- if (existsSync83(tempPath)) {
126147
+ if (existsSync84(tempPath)) {
125789
126148
  try {
125790
- unlinkSync22(tempPath);
126149
+ unlinkSync25(tempPath);
125791
126150
  } catch {}
125792
126151
  }
125793
126152
  const tempDir = path149.dirname(tempPath);
125794
- if (tempDir !== dir && existsSync83(tempDir)) {
126153
+ if (tempDir !== dir && existsSync84(tempDir)) {
125795
126154
  try {
125796
126155
  rmdirSync(tempDir);
125797
126156
  } catch {}
@@ -125868,7 +126227,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
125868
126227
  };
125869
126228
  }
125870
126229
  const parentDir = path149.dirname(fullPath);
125871
- if (!existsSync83(parentDir)) {
126230
+ if (!existsSync84(parentDir)) {
125872
126231
  return {
125873
126232
  file: targetPath,
125874
126233
  status: "error",
@@ -125884,7 +126243,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
125884
126243
  ]
125885
126244
  };
125886
126245
  }
125887
- if (existsSync83(fullPath)) {
126246
+ if (existsSync84(fullPath)) {
125888
126247
  return {
125889
126248
  file: targetPath,
125890
126249
  status: "error",
@@ -125959,7 +126318,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
125959
126318
  ]
125960
126319
  };
125961
126320
  }
125962
- if (!existsSync83(fullPath)) {
126321
+ if (!existsSync84(fullPath)) {
125963
126322
  return {
125964
126323
  file: targetPath,
125965
126324
  status: "error",
@@ -125977,7 +126336,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
125977
126336
  }
125978
126337
  if (!dryRun) {
125979
126338
  try {
125980
- unlinkSync22(fullPath);
126339
+ unlinkSync25(fullPath);
125981
126340
  } catch (err2) {
125982
126341
  return {
125983
126342
  file: targetPath,
@@ -126003,7 +126362,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
126003
126362
  hunksFailed: 0
126004
126363
  };
126005
126364
  }
126006
- if (!existsSync83(fullPath)) {
126365
+ if (!existsSync84(fullPath)) {
126007
126366
  return {
126008
126367
  file: targetPath,
126009
126368
  status: "error",
@@ -126154,7 +126513,7 @@ var applyPatch = createSwarmTool({
126154
126513
  const dryRun = obj.dryRun ?? false;
126155
126514
  const allowCreates = obj.allowCreates ?? false;
126156
126515
  const allowDeletes = obj.allowDeletes ?? false;
126157
- if (!existsSync83(directory)) {
126516
+ if (!existsSync84(directory)) {
126158
126517
  return JSON.stringify(buildErrorResult("Workspace directory does not exist"), null, 2);
126159
126518
  }
126160
126519
  if (files.length === 0) {
@@ -127344,7 +127703,7 @@ function countCodeLines(content) {
127344
127703
  return lines.length;
127345
127704
  }
127346
127705
  function isTestFile(filePath) {
127347
- const basename17 = path153.basename(filePath);
127706
+ const basename18 = path153.basename(filePath);
127348
127707
  const _ext = path153.extname(filePath).toLowerCase();
127349
127708
  const testPatterns = [
127350
127709
  ".test.",
@@ -127360,7 +127719,7 @@ function isTestFile(filePath) {
127360
127719
  ".spec.jsx"
127361
127720
  ];
127362
127721
  for (const pattern of testPatterns) {
127363
- if (basename17.includes(pattern)) {
127722
+ if (basename18.includes(pattern)) {
127364
127723
  return true;
127365
127724
  }
127366
127725
  }
@@ -127973,7 +128332,7 @@ ${body2}`);
127973
128332
  // src/council/council-evidence-writer.ts
127974
128333
  init_zod();
127975
128334
  init_task_file();
127976
- import { appendFileSync as appendFileSync18, existsSync as existsSync88, mkdirSync as mkdirSync41, readFileSync as readFileSync62 } from "node:fs";
128335
+ import { appendFileSync as appendFileSync18, existsSync as existsSync89, mkdirSync as mkdirSync41, readFileSync as readFileSync62 } from "node:fs";
127977
128336
  import { join as join122 } from "node:path";
127978
128337
  var EVIDENCE_DIR2 = ".swarm/evidence";
127979
128338
  var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
@@ -128017,7 +128376,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
128017
128376
  const filePath = taskEvidencePath(workingDir, synthesis.taskId);
128018
128377
  await _internals88.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
128019
128378
  const existingRoot = Object.create(null);
128020
- if (existsSync88(filePath)) {
128379
+ if (existsSync89(filePath)) {
128021
128380
  try {
128022
128381
  const parsed = EvidenceFileSchema.parse(JSON.parse(readFileSync62(filePath, "utf-8")));
128023
128382
  safeAssignOwnProps(existingRoot, parsed);
@@ -128412,7 +128771,7 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
128412
128771
  // src/council/criteria-store.ts
128413
128772
  init_zod();
128414
128773
  init_task_file();
128415
- import { existsSync as existsSync89, mkdirSync as mkdirSync42, readFileSync as readFileSync63 } from "node:fs";
128774
+ import { existsSync as existsSync90, mkdirSync as mkdirSync42, readFileSync as readFileSync63 } from "node:fs";
128416
128775
  import { join as join123 } from "node:path";
128417
128776
  var COUNCIL_DIR = ".swarm/council";
128418
128777
  var CouncilCriteriaSchema = exports_external.object({
@@ -128436,7 +128795,7 @@ async function writeCriteria(workingDir, taskId, criteria) {
128436
128795
  }
128437
128796
  function readCriteria(workingDir, taskId) {
128438
128797
  const filePath = join123(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
128439
- if (!existsSync89(filePath))
128798
+ if (!existsSync90(filePath))
128440
128799
  return null;
128441
128800
  try {
128442
128801
  return CouncilCriteriaSchema.parse(JSON.parse(readFileSync63(filePath, "utf-8")));
@@ -130160,11 +130519,11 @@ init_zod();
130160
130519
  init_utils2();
130161
130520
  import { createHash as createHash18 } from "node:crypto";
130162
130521
  import {
130163
- existsSync as existsSync91,
130522
+ existsSync as existsSync92,
130164
130523
  mkdirSync as mkdirSync43,
130165
130524
  readFileSync as readFileSync66,
130166
- renameSync as renameSync27,
130167
- unlinkSync as unlinkSync23,
130525
+ renameSync as renameSync30,
130526
+ unlinkSync as unlinkSync26,
130168
130527
  writeFileSync as writeFileSync28
130169
130528
  } from "node:fs";
130170
130529
  import * as path159 from "node:path";
@@ -130211,7 +130570,7 @@ function storeLaneOutput(directory, input, now = Date.now) {
130211
130570
  const absPath = validateSwarmPath(directory, relPath);
130212
130571
  const timestamp = new Date(now()).toISOString();
130213
130572
  try {
130214
- if (existsSync91(absPath)) {
130573
+ if (existsSync92(absPath)) {
130215
130574
  const existing = LaneOutputArtifactSchema.safeParse(JSON.parse(readFileSync66(absPath, "utf-8")));
130216
130575
  if (existing.success && existing.data.digest === digest3) {
130217
130576
  return {
@@ -130265,7 +130624,7 @@ function readLaneOutput(directory, ref) {
130265
130624
  if (!REF_RE.test(ref))
130266
130625
  return null;
130267
130626
  const absPath = validateSwarmPath(directory, laneOutputRelativePath(ref));
130268
- if (!existsSync91(absPath))
130627
+ if (!existsSync92(absPath))
130269
130628
  return null;
130270
130629
  let parsed;
130271
130630
  try {
@@ -130354,7 +130713,7 @@ function writeAtomicJson(absPath, value) {
130354
130713
  let lastRenameError;
130355
130714
  for (let attempt = 0;attempt < WINDOWS_RENAME_MAX_RETRIES3; attempt++) {
130356
130715
  try {
130357
- renameSync27(tempFile, absPath);
130716
+ renameSync30(tempFile, absPath);
130358
130717
  lastRenameError = undefined;
130359
130718
  break;
130360
130719
  } catch (err2) {
@@ -130367,9 +130726,9 @@ function writeAtomicJson(absPath, value) {
130367
130726
  if (lastRenameError)
130368
130727
  throw lastRenameError;
130369
130728
  } finally {
130370
- if (existsSync91(tempFile)) {
130729
+ if (existsSync92(tempFile)) {
130371
130730
  try {
130372
- unlinkSync23(tempFile);
130731
+ unlinkSync26(tempFile);
130373
130732
  } catch {}
130374
130733
  }
130375
130734
  }
@@ -137219,7 +137578,7 @@ init_zod();
137219
137578
  init_config();
137220
137579
  init_knowledge_store();
137221
137580
  init_create_tool();
137222
- import { existsSync as existsSync97 } from "node:fs";
137581
+ import { existsSync as existsSync98 } from "node:fs";
137223
137582
  var DEFAULT_LIMIT = 10;
137224
137583
  var MAX_LESSON_LENGTH = 200;
137225
137584
  var VALID_CATEGORIES3 = [
@@ -137295,14 +137654,14 @@ function validateLimit(limit) {
137295
137654
  }
137296
137655
  async function readSwarmKnowledge(directory) {
137297
137656
  const swarmPath = resolveSwarmKnowledgePath(directory);
137298
- if (!existsSync97(swarmPath)) {
137657
+ if (!existsSync98(swarmPath)) {
137299
137658
  return [];
137300
137659
  }
137301
137660
  return readKnowledge(swarmPath);
137302
137661
  }
137303
137662
  async function readHiveKnowledge() {
137304
137663
  const hivePath = resolveHiveKnowledgePath();
137305
- if (!existsSync97(hivePath)) {
137664
+ if (!existsSync98(hivePath)) {
137306
137665
  return [];
137307
137666
  }
137308
137667
  return readKnowledge(hivePath);
@@ -138126,8 +138485,8 @@ import * as fs109 from "node:fs";
138126
138485
  import * as path170 from "node:path";
138127
138486
 
138128
138487
  // src/mutation/engine.ts
138129
- import { spawnSync as spawnSync12 } from "node:child_process";
138130
- import { unlinkSync as unlinkSync24, writeFileSync as writeFileSync30 } from "node:fs";
138488
+ import { spawnSync as spawnSync13 } from "node:child_process";
138489
+ import { unlinkSync as unlinkSync27, writeFileSync as writeFileSync30 } from "node:fs";
138131
138490
  import * as path169 from "node:path";
138132
138491
 
138133
138492
  // src/mutation/equivalence.ts
@@ -138304,7 +138663,7 @@ var _internals106 = {
138304
138663
  executeMutation,
138305
138664
  computeReport,
138306
138665
  executeMutationSuite,
138307
- spawnSync: spawnSync12
138666
+ spawnSync: spawnSync13
138308
138667
  };
138309
138668
  async function executeMutation(patch, testCommand, testFiles, workingDir) {
138310
138669
  const startTime = Date.now();
@@ -138415,7 +138774,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir) {
138415
138774
  revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
138416
138775
  }
138417
138776
  try {
138418
- unlinkSync24(patchFile);
138777
+ unlinkSync27(patchFile);
138419
138778
  } catch (_unlinkErr) {}
138420
138779
  }
138421
138780
  }
@@ -141312,8 +141671,8 @@ async function runNpmAudit(directory) {
141312
141671
  clean: findings.length === 0
141313
141672
  };
141314
141673
  } catch (error93) {
141315
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
141316
- if (errorMessage2.includes("audit") || errorMessage2.includes("command not found") || errorMessage2.includes("'npm' is not recognized")) {
141674
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
141675
+ if (errorMessage3.includes("audit") || errorMessage3.includes("command not found") || errorMessage3.includes("'npm' is not recognized")) {
141317
141676
  return {
141318
141677
  ecosystem: "npm",
141319
141678
  command,
@@ -141333,7 +141692,7 @@ async function runNpmAudit(directory) {
141333
141692
  highCount: 0,
141334
141693
  totalCount: 0,
141335
141694
  clean: true,
141336
- note: `Error running npm audit: ${errorMessage2}`
141695
+ note: `Error running npm audit: ${errorMessage3}`
141337
141696
  };
141338
141697
  }
141339
141698
  }
@@ -141454,8 +141813,8 @@ async function runPipAudit(directory) {
141454
141813
  clean: findings.length === 0
141455
141814
  };
141456
141815
  } catch (error93) {
141457
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
141458
- if (errorMessage2.includes("not found") || errorMessage2.includes("not recognized") || errorMessage2.includes("pip-audit")) {
141816
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
141817
+ if (errorMessage3.includes("not found") || errorMessage3.includes("not recognized") || errorMessage3.includes("pip-audit")) {
141459
141818
  return {
141460
141819
  ecosystem: "pip",
141461
141820
  command,
@@ -141475,7 +141834,7 @@ async function runPipAudit(directory) {
141475
141834
  highCount: 0,
141476
141835
  totalCount: 0,
141477
141836
  clean: true,
141478
- note: `Error running pip-audit: ${errorMessage2}`
141837
+ note: `Error running pip-audit: ${errorMessage3}`
141479
141838
  };
141480
141839
  }
141481
141840
  }
@@ -141556,8 +141915,8 @@ async function runCargoAudit(directory) {
141556
141915
  clean: findings.length === 0
141557
141916
  };
141558
141917
  } catch (error93) {
141559
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
141560
- if (errorMessage2.includes("not found") || errorMessage2.includes("not recognized") || errorMessage2.includes("cargo-audit")) {
141918
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
141919
+ if (errorMessage3.includes("not found") || errorMessage3.includes("not recognized") || errorMessage3.includes("cargo-audit")) {
141561
141920
  return {
141562
141921
  ecosystem: "cargo",
141563
141922
  command,
@@ -141577,7 +141936,7 @@ async function runCargoAudit(directory) {
141577
141936
  highCount: 0,
141578
141937
  totalCount: 0,
141579
141938
  clean: true,
141580
- note: `Error running cargo audit: ${errorMessage2}`
141939
+ note: `Error running cargo audit: ${errorMessage3}`
141581
141940
  };
141582
141941
  }
141583
141942
  }
@@ -141704,7 +142063,7 @@ async function runGoAudit(directory) {
141704
142063
  clean: findings.length === 0
141705
142064
  };
141706
142065
  } catch (error93) {
141707
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
142066
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
141708
142067
  return {
141709
142068
  ecosystem: "go",
141710
142069
  command,
@@ -141713,7 +142072,7 @@ async function runGoAudit(directory) {
141713
142072
  highCount: 0,
141714
142073
  totalCount: 0,
141715
142074
  clean: true,
141716
- note: `Error running govulncheck: ${errorMessage2}`
142075
+ note: `Error running govulncheck: ${errorMessage3}`
141717
142076
  };
141718
142077
  }
141719
142078
  }
@@ -141811,7 +142170,7 @@ async function runDotnetAudit(directory) {
141811
142170
  clean: findings.length === 0
141812
142171
  };
141813
142172
  } catch (error93) {
141814
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
142173
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
141815
142174
  return {
141816
142175
  ecosystem: "dotnet",
141817
142176
  command,
@@ -141820,7 +142179,7 @@ async function runDotnetAudit(directory) {
141820
142179
  highCount: 0,
141821
142180
  totalCount: 0,
141822
142181
  clean: true,
141823
- note: `Error running dotnet list package: ${errorMessage2}`
142182
+ note: `Error running dotnet list package: ${errorMessage3}`
141824
142183
  };
141825
142184
  }
141826
142185
  }
@@ -141947,8 +142306,8 @@ async function runBundleAudit(directory) {
141947
142306
  clean: findings.length === 0
141948
142307
  };
141949
142308
  } catch (error93) {
141950
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
141951
- const isNotInstalled = errorMessage2.includes("not recognized") || errorMessage2.includes("not found") || errorMessage2.includes("No such file") || errorMessage2.includes("ENOENT");
142309
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
142310
+ const isNotInstalled = errorMessage3.includes("not recognized") || errorMessage3.includes("not found") || errorMessage3.includes("No such file") || errorMessage3.includes("ENOENT");
141952
142311
  return {
141953
142312
  ecosystem: "ruby",
141954
142313
  command,
@@ -141957,7 +142316,7 @@ async function runBundleAudit(directory) {
141957
142316
  highCount: 0,
141958
142317
  totalCount: 0,
141959
142318
  clean: true,
141960
- note: isNotInstalled ? "bundle-audit not installed. Install with: gem install bundler-audit" : `Error running bundle-audit: ${errorMessage2}`
142319
+ note: isNotInstalled ? "bundle-audit not installed. Install with: gem install bundler-audit" : `Error running bundle-audit: ${errorMessage3}`
141961
142320
  };
141962
142321
  }
141963
142322
  }
@@ -142086,7 +142445,7 @@ async function runDartAudit(directory) {
142086
142445
  note: "dart pub outdated reports outdated packages, not security vulnerabilities"
142087
142446
  };
142088
142447
  } catch (error93) {
142089
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
142448
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
142090
142449
  return {
142091
142450
  ecosystem: "dart",
142092
142451
  command,
@@ -142095,7 +142454,7 @@ async function runDartAudit(directory) {
142095
142454
  highCount: 0,
142096
142455
  totalCount: 0,
142097
142456
  clean: true,
142098
- note: `Error running dart pub outdated: ${errorMessage2}`
142457
+ note: `Error running dart pub outdated: ${errorMessage3}`
142099
142458
  };
142100
142459
  }
142101
142460
  }
@@ -143970,11 +144329,11 @@ async function runSemgrep(options) {
143970
144329
  engine: "tier_a+tier_b"
143971
144330
  };
143972
144331
  } catch (error93) {
143973
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error running Semgrep";
144332
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error running Semgrep";
143974
144333
  return {
143975
144334
  available: true,
143976
144335
  findings: [],
143977
- error: errorMessage2,
144336
+ error: errorMessage3,
143978
144337
  engine: "tier_a"
143979
144338
  };
143980
144339
  }
@@ -145491,13 +145850,13 @@ var pre_check_batch = createSwarmTool({
145491
145850
  }, workspaceAnchor, directory);
145492
145851
  return JSON.stringify(result, null, 2);
145493
145852
  } catch (error93) {
145494
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
145853
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
145495
145854
  const errorResult = {
145496
145855
  gates_passed: false,
145497
- lint: { ran: false, error: errorMessage2, duration_ms: 0 },
145498
- secretscan: { ran: false, error: errorMessage2, duration_ms: 0 },
145499
- sast_scan: { ran: false, error: errorMessage2, duration_ms: 0 },
145500
- quality_budget: { ran: false, error: errorMessage2, duration_ms: 0 },
145856
+ lint: { ran: false, error: errorMessage3, duration_ms: 0 },
145857
+ secretscan: { ran: false, error: errorMessage3, duration_ms: 0 },
145858
+ sast_scan: { ran: false, error: errorMessage3, duration_ms: 0 },
145859
+ quality_budget: { ran: false, error: errorMessage3, duration_ms: 0 },
145501
145860
  total_duration_ms: 0
145502
145861
  };
145503
145862
  return JSON.stringify(errorResult, null, 2);
@@ -148118,7 +148477,7 @@ var schema_drift = createSwarmTool({
148118
148477
  };
148119
148478
  return JSON.stringify(result, null, 2);
148120
148479
  } catch (error93) {
148121
- const errorMessage2 = error93 instanceof Error ? error93.message : "Unknown error";
148480
+ const errorMessage3 = error93 instanceof Error ? error93.message : "Unknown error";
148122
148481
  const errorResult = {
148123
148482
  specFile: "",
148124
148483
  specPathCount: 0,
@@ -148129,7 +148488,7 @@ var schema_drift = createSwarmTool({
148129
148488
  phantomCount: 0,
148130
148489
  consistent: false
148131
148490
  };
148132
- return JSON.stringify({ ...errorResult, error: errorMessage2 }, null, 2);
148491
+ return JSON.stringify({ ...errorResult, error: errorMessage3 }, null, 2);
148133
148492
  }
148134
148493
  }
148135
148494
  });
@@ -148872,11 +149231,11 @@ ${content}
148872
149231
  init_zod();
148873
149232
  init_loader();
148874
149233
  import {
148875
- existsSync as existsSync111,
149234
+ existsSync as existsSync112,
148876
149235
  mkdirSync as mkdirSync49,
148877
149236
  readFileSync as readFileSync89,
148878
- renameSync as renameSync29,
148879
- unlinkSync as unlinkSync26,
149237
+ renameSync as renameSync32,
149238
+ unlinkSync as unlinkSync29,
148880
149239
  writeFileSync as writeFileSync36
148881
149240
  } from "node:fs";
148882
149241
  import path194 from "node:path";
@@ -149145,10 +149504,10 @@ function writePhaseCouncilEvidence(workingDir, synthesis, provenance) {
149145
149504
  const tempFile = `${evidenceFile}.tmp-${Date.now()}`;
149146
149505
  try {
149147
149506
  writeFileSync36(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
149148
- renameSync29(tempFile, evidenceFile);
149507
+ renameSync32(tempFile, evidenceFile);
149149
149508
  } finally {
149150
- if (existsSync111(tempFile)) {
149151
- unlinkSync26(tempFile);
149509
+ if (existsSync112(tempFile)) {
149510
+ unlinkSync29(tempFile);
149152
149511
  }
149153
149512
  }
149154
149513
  }