opencode-swarm 7.116.0 → 7.116.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.opencode/skills/commit-pr/SKILL.md +60 -579
  2. package/dist/cli/{curator-drift-c0by7063.js → curator-drift-7p2ky1th.js} +2 -2
  3. package/dist/cli/{curator-llm-factory-x96dr0zf.js → curator-llm-factory-9qn52fnv.js} +13 -13
  4. package/dist/cli/{curator-7s5yw6hw.js → curator-yxmtp8py.js} +13 -13
  5. package/dist/cli/{evidence-summary-service-ef6kgtev.js → evidence-summary-service-bwt6drb3.js} +5 -5
  6. package/dist/cli/{gate-evidence-thqt0beq.js → gate-evidence-j2m4cd85.js} +3 -2
  7. package/dist/cli/{guardrail-explain-kwqfkwch.js → guardrail-explain-xvyz2eag.js} +14 -14
  8. package/dist/cli/{hive-promoter-rkkx40qv.js → hive-promoter-ykqc60w1.js} +13 -13
  9. package/dist/cli/{index-bbsaxnj5.js → index-0pfqcjp6.js} +4 -0
  10. package/dist/cli/{index-qgeeyy75.js → index-34g1mv3c.js} +1 -1
  11. package/dist/cli/{index-a6f8b0vn.js → index-5bcrp3bc.js} +1 -1
  12. package/dist/cli/{index-k5ey429j.js → index-5h7d37nf.js} +7 -7
  13. package/dist/cli/{index-me46ffm2.js → index-7kcpkm4y.js} +433 -275
  14. package/dist/cli/{index-81vzywh3.js → index-abjjn4yh.js} +1 -1
  15. package/dist/cli/{index-tvgvb5pa.js → index-efdyjgeh.js} +2 -2
  16. package/dist/cli/{index-jtqkh8jf.js → index-fsrp8wp3.js} +10 -1
  17. package/dist/cli/{index-3yh67t1h.js → index-g4p13g8t.js} +3 -3
  18. package/dist/cli/{index-wh8949ef.js → index-kzj3fp7c.js} +3 -3
  19. package/dist/cli/{index-3b8n3dbd.js → index-p9jf8gt8.js} +14 -14
  20. package/dist/cli/{index-jyetmzcn.js → index-t5f01hnz.js} +3 -3
  21. package/dist/cli/{index-8bvh0qfa.js → index-wegc6xwr.js} +3 -3
  22. package/dist/cli/{index-s385axt1.js → index-wxkf3089.js} +3 -3
  23. package/dist/cli/{index-cnrhj56z.js → index-xdsd2hma.js} +6 -6
  24. package/dist/cli/index.js +13 -13
  25. package/dist/cli/{knowledge-escalator-0bq62d34.js → knowledge-escalator-tthw6c9q.js} +6 -6
  26. package/dist/cli/{knowledge-events-cwwky393.js → knowledge-events-hrbmwxxj.js} +4 -3
  27. package/dist/cli/{knowledge-store-q8x4h82m.js → knowledge-store-5cns5sns.js} +4 -4
  28. package/dist/cli/{knowledge-validator-zr0djm02.js → knowledge-validator-xre0s774.js} +5 -5
  29. package/dist/cli/{pending-delegations-rr9x47rd.js → pending-delegations-9cn17983.js} +2 -2
  30. package/dist/cli/{pr-subscriptions-cny2jz2d.js → pr-subscriptions-8a6jwek2.js} +3 -3
  31. package/dist/cli/{skill-generator-mz267btk.js → skill-generator-22nk6c6a.js} +7 -7
  32. package/dist/commands/close.d.ts +12 -0
  33. package/dist/commands/registry.d.ts +6 -6
  34. package/dist/commands/reset-backup.d.ts +32 -0
  35. package/dist/commands/reset-session.d.ts +2 -0
  36. package/dist/commands/reset.d.ts +9 -0
  37. package/dist/evidence/task-file.d.ts +7 -0
  38. package/dist/index.js +187 -184
  39. package/dist/utils/swarm-artifact-cache.d.ts +13 -0
  40. package/package.json +1 -1
@@ -93,7 +93,7 @@ import {
93
93
  saveTaskSetSnapshot,
94
94
  transientBackoff,
95
95
  validateProjectRoot
96
- } from "./index-cnrhj56z.js";
96
+ } from "./index-xdsd2hma.js";
97
97
  import {
98
98
  buildOpenSpecProjectionSync,
99
99
  detectSpeckit,
@@ -111,7 +111,7 @@ import {
111
111
  listActive,
112
112
  subscribe,
113
113
  unsubscribe
114
- } from "./index-a6f8b0vn.js";
114
+ } from "./index-5bcrp3bc.js";
115
115
  import {
116
116
  BUNDLED_PROJECT_SKILL_ROOT,
117
117
  DEFAULT_SKILL_MIN_CONFIDENCE,
@@ -133,7 +133,7 @@ import {
133
133
  retireSkill,
134
134
  selectCandidateEntries,
135
135
  syncBundledProjectSkillsIfMissingAsync
136
- } from "./index-s385axt1.js";
136
+ } from "./index-wxkf3089.js";
137
137
  import {
138
138
  appendUnactionable,
139
139
  quarantineEntry,
@@ -143,10 +143,10 @@ import {
143
143
  validateActionability,
144
144
  validateActionableFields,
145
145
  validateLesson
146
- } from "./index-jyetmzcn.js";
146
+ } from "./index-t5f01hnz.js";
147
147
  import {
148
148
  readRecentEscalations
149
- } from "./index-8bvh0qfa.js";
149
+ } from "./index-wegc6xwr.js";
150
150
  import {
151
151
  effectiveRetrievalOutcomes,
152
152
  readKnowledgeCounterRollups,
@@ -154,7 +154,7 @@ import {
154
154
  recordHiveKnowledgeEvent,
155
155
  recordKnowledgeEvent,
156
156
  resolveKnowledgeEventsPath
157
- } from "./index-3yh67t1h.js";
157
+ } from "./index-g4p13g8t.js";
158
158
  import {
159
159
  appendKnowledge,
160
160
  appendRejectedLesson,
@@ -178,7 +178,7 @@ import {
178
178
  rewriteKnowledge,
179
179
  transactFile,
180
180
  transactKnowledge
181
- } from "./index-k5ey429j.js";
181
+ } from "./index-5h7d37nf.js";
182
182
  import {
183
183
  KNOWLEDGE_SCHEMA_VERSION,
184
184
  OUTCOME_BLOCK_THRESHOLD,
@@ -192,7 +192,7 @@ import {
192
192
  resolveLinkDir,
193
193
  sanitizeLinkId,
194
194
  writeLinkPointer
195
- } from "./index-qgeeyy75.js";
195
+ } from "./index-34g1mv3c.js";
196
196
  import {
197
197
  CURATOR_INIT_PROMPT,
198
198
  CURATOR_PHASE_PROMPT,
@@ -209,7 +209,7 @@ import {
209
209
  readSwarmFileAsync,
210
210
  safeHook,
211
211
  validateSwarmPath
212
- } from "./index-wh8949ef.js";
212
+ } from "./index-kzj3fp7c.js";
213
213
  import {
214
214
  deepMerge
215
215
  } from "./index-p0arc26j.js";
@@ -221,7 +221,7 @@ import {
221
221
  } from "./index-zgwm4ryv.js";
222
222
  import {
223
223
  atomicWriteFile
224
- } from "./index-bbsaxnj5.js";
224
+ } from "./index-0pfqcjp6.js";
225
225
  import {
226
226
  exports_external
227
227
  } from "./index-293f68mj.js";
@@ -246,8 +246,8 @@ import {
246
246
  } from "./index-a76rekgs.js";
247
247
 
248
248
  // src/state.ts
249
- import * as fs40 from "fs/promises";
250
- import * as path78 from "path";
249
+ import * as fs41 from "fs/promises";
250
+ import * as path79 from "path";
251
251
 
252
252
  // src/db/qa-gate-profile.ts
253
253
  import { createHash } from "crypto";
@@ -9985,7 +9985,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9985
9985
  }
9986
9986
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
9987
9987
  try {
9988
- const skillModule = await import("./skill-generator-mz267btk.js");
9988
+ const skillModule = await import("./skill-generator-22nk6c6a.js");
9989
9989
  for (const cand of skillCandidates) {
9990
9990
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
9991
9991
  continue;
@@ -10266,7 +10266,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
10266
10266
  } catch {}
10267
10267
  }
10268
10268
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
10269
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-0bq62d34.js");
10269
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-tthw6c9q.js");
10270
10270
  for (const { id } of contradictedEntries) {
10271
10271
  try {
10272
10272
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -11227,11 +11227,11 @@ var _internals14 = {
11227
11227
  return KnowledgeConfigSchema2.parse({});
11228
11228
  },
11229
11229
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig) => {
11230
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-7s5yw6hw.js");
11230
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-yxmtp8py.js");
11231
11231
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig);
11232
11232
  },
11233
11233
  checkHivePromotions: async (entries, knowledgeConfig) => {
11234
- const { checkHivePromotions } = await import("./hive-promoter-rkkx40qv.js");
11234
+ const { checkHivePromotions } = await import("./hive-promoter-ykqc60w1.js");
11235
11235
  return checkHivePromotions(entries, knowledgeConfig);
11236
11236
  },
11237
11237
  applyProposalTriage: async (directory, triage) => {
@@ -11240,7 +11240,7 @@ var _internals14 = {
11240
11240
  activateProposal,
11241
11241
  listSkills: listSkills2,
11242
11242
  sanitizeSlug
11243
- } = await import("./skill-generator-mz267btk.js");
11243
+ } = await import("./skill-generator-22nk6c6a.js");
11244
11244
  const result = {
11245
11245
  approved: [],
11246
11246
  rejected: [],
@@ -11282,7 +11282,7 @@ var _internals14 = {
11282
11282
  return result;
11283
11283
  },
11284
11284
  readPriorDriftReports: async (directory) => {
11285
- const { readPriorDriftReports } = await import("./curator-drift-c0by7063.js");
11285
+ const { readPriorDriftReports } = await import("./curator-drift-7p2ky1th.js");
11286
11286
  return readPriorDriftReports(directory);
11287
11287
  },
11288
11288
  readSwarmKnowledge: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory))
@@ -15968,8 +15968,6 @@ var ARCHIVE_ARTIFACTS = [
15968
15968
  "dark-matter.md",
15969
15969
  "telemetry.jsonl",
15970
15970
  "swarm.db",
15971
- "swarm.db-shm",
15972
- "swarm.db-wal",
15973
15971
  "close-summary.md",
15974
15972
  "session-reflection.md",
15975
15973
  "spec.md",
@@ -15994,9 +15992,7 @@ var ACTIVE_STATE_TO_CLEAN = [
15994
15992
  "spec.md",
15995
15993
  "spec-staleness.json",
15996
15994
  "spec-snapshot.md",
15997
- "swarm.db",
15998
- "swarm.db-shm",
15999
- "swarm.db-wal"
15995
+ "swarm.db"
16000
15996
  ];
16001
15997
  var TERMINAL_STATE_FILES = [
16002
15998
  "plan.json",
@@ -16381,15 +16377,11 @@ async function runArchiveStage(ctx) {
16381
16377
  ctx.archiveDir = path31.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
16382
16378
  try {
16383
16379
  await fs12.mkdir(ctx.archiveDir, { recursive: true });
16384
- const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
16385
16380
  const linkedKnowledgeShared = isLinked(ctx.directory);
16386
16381
  if (linkedKnowledgeShared) {
16387
16382
  ctx.warnings.push("Worktree is linked: shared knowledge (knowledge.jsonl, knowledge-rejected.jsonl) lives in the link store and is not archived or cleaned by /swarm close. Manage it via the link.");
16388
16383
  }
16389
16384
  for (const artifact of ARCHIVE_ARTIFACTS) {
16390
- if (WAL_SIDECAR_FILES.has(artifact)) {
16391
- continue;
16392
- }
16393
16385
  if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
16394
16386
  continue;
16395
16387
  }
@@ -16732,6 +16724,56 @@ async function runAlignStage(ctx) {
16732
16724
  }
16733
16725
  return { gitAlignResult, prunedBranches };
16734
16726
  }
16727
+ async function runFinalizeDryRun(directory, swarmDir, planData, planExists) {
16728
+ const existsInSwarm = (name) => fsSync.existsSync(path31.join(swarmDir, name));
16729
+ const phases = planData.phases ?? [];
16730
+ const nonTerminalPhases = phases.filter((p) => p.status !== "complete" && p.status !== "completed" && p.status !== "blocked" && p.status !== "closed");
16731
+ const planAlreadyDone = planExists && phases.length > 0 && nonTerminalPhases.length === 0;
16732
+ const wouldArchive = ARCHIVE_ARTIFACTS.filter(existsInSwarm);
16733
+ const dynamicArchive = (await fs12.readdir(swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
16734
+ const wouldArchiveDirs = ACTIVE_STATE_DIRS_TO_CLEAN.filter(existsInSwarm);
16735
+ const wouldRemoveTerminal = TERMINAL_STATE_FILES.filter(existsInSwarm);
16736
+ const wouldCleanFiles = ACTIVE_STATE_TO_CLEAN.filter((f) => existsInSwarm(f) && !TERMINAL_STATE_FILES.includes(f));
16737
+ const gitStatus = _internals22.getGitRepositoryStatus(directory);
16738
+ const gitNote = gitStatus.isRepo ? "would align the working tree to main/remote (git reset), pruning merged branches only with --prune-branches" : "would skip git alignment (not a git repository / git unavailable)";
16739
+ const lines = [
16740
+ "## /swarm finalize \u2014 DRY RUN (no changes made)",
16741
+ "",
16742
+ "No lock is taken, no files are archived or deleted, no git command runs.",
16743
+ "",
16744
+ "### Plan",
16745
+ planExists ? planAlreadyDone ? "- Plan is already terminal \u2014 no phases/tasks would be force-closed." : nonTerminalPhases.length > 0 ? `- Would mark ${nonTerminalPhases.length} non-terminal phase(s) as closed: ${nonTerminalPhases.map((p) => `#${p.id} ${p.name}`).join(", ")}` : "- No phases present; nothing to close." : "- No plan.json \u2014 plan-free session; cleanup-only.",
16746
+ "",
16747
+ "### Would archive",
16748
+ wouldArchive.length > 0 || dynamicArchive.length > 0 || wouldArchiveDirs.length > 0 ? [
16749
+ ...wouldArchive.map((f) => `- ${f}`),
16750
+ ...dynamicArchive.map((f) => `- ${f}`),
16751
+ ...wouldArchiveDirs.map((d) => `- ${d}/`)
16752
+ ].join(`
16753
+ `) : "- (nothing present to archive)",
16754
+ "",
16755
+ "### Would clean (removed after successful archive)",
16756
+ wouldCleanFiles.length > 0 || wouldArchiveDirs.length > 0 ? [
16757
+ ...wouldCleanFiles.map((f) => `- ${f}`),
16758
+ ...wouldArchiveDirs.map((d) => `- ${d}/`)
16759
+ ].join(`
16760
+ `) : "- (nothing present to clean)",
16761
+ ...wouldRemoveTerminal.length > 0 ? [
16762
+ "",
16763
+ "### Would remove unconditionally (terminal plan-state)",
16764
+ ...wouldRemoveTerminal.map((f) => `- ${f}`)
16765
+ ] : [],
16766
+ "",
16767
+ "### Git",
16768
+ `- ${gitNote}`,
16769
+ "",
16770
+ "_Note: swarm.db-shm / swarm.db-wal are transient SQLite sidecars \u2014 they are never archived or cleaned. The clean list is an approximation of the archive-first guard._",
16771
+ "",
16772
+ "Run `/swarm finalize` (without `--dry-run`) to apply."
16773
+ ];
16774
+ return lines.join(`
16775
+ `);
16776
+ }
16735
16777
  async function handleCloseCommand(directory, args, options = {}) {
16736
16778
  const swarmDir = path31.join(directory, ".swarm");
16737
16779
  try {
@@ -16763,6 +16805,9 @@ async function handleCloseCommand(directory, args, options = {}) {
16763
16805
  return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
16764
16806
  }
16765
16807
  }
16808
+ if (args.includes("--dry-run")) {
16809
+ return _internals22.runFinalizeDryRun(directory, swarmDir, planData, planExists);
16810
+ }
16766
16811
  let finalizeLock = {
16767
16812
  acquired: false
16768
16813
  };
@@ -16920,11 +16965,17 @@ This project was already finalized in a previous /swarm close run. The plan has
16920
16965
  ctx.warnings.push(`Failed to write close-summary.md: ${msg}`);
16921
16966
  console.warn("[close-command] Failed to write close-summary.md:", error2);
16922
16967
  }
16923
- const sessionIdsToEnd = [...swarmState.agentSessions.keys()];
16924
- for (const sessionId of sessionIdsToEnd) {
16925
- _internals22.endAgentSession(sessionId);
16968
+ try {
16969
+ const sessionIdsToEnd = [...swarmState.agentSessions.keys()];
16970
+ for (const sessionId of sessionIdsToEnd) {
16971
+ _internals22.endAgentSession(sessionId);
16972
+ }
16973
+ _internals22.resetSwarmStatePreservingSingletons();
16974
+ } catch (teardownError) {
16975
+ const msg = teardownError instanceof Error ? teardownError.message : String(teardownError);
16976
+ ctx.warnings.push(`Session teardown encountered an error after finalization completed (state may not be fully reset): ${msg}`);
16977
+ console.warn("[close-command] teardown error:", teardownError);
16926
16978
  }
16927
- _internals22.resetSwarmStatePreservingSingletons();
16928
16979
  const retroWarnings = ctx.warnings.filter((w) => w.includes("Retrospective write") || w.includes("retrospective write") || w.includes("Session retrospective"));
16929
16980
  const otherWarnings = ctx.warnings.filter((w) => !w.includes("Retrospective write") && !w.includes("retrospective write") && !w.includes("Session retrospective"));
16930
16981
  let warningMsg = "";
@@ -17016,6 +17067,7 @@ var _internals22 = {
17016
17067
  runArchiveEvidenceRetention,
17017
17068
  runCleanStage,
17018
17069
  runAlignStage,
17070
+ runFinalizeDryRun,
17019
17071
  archiveEvidence,
17020
17072
  closePlanTerminalState,
17021
17073
  endAgentSession,
@@ -18373,8 +18425,8 @@ var _internals26 = {
18373
18425
  loadCuratorDeps: async () => {
18374
18426
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
18375
18427
  import("./schema-bqn7g3ez.js"),
18376
- import("./curator-7s5yw6hw.js"),
18377
- import("./curator-llm-factory-x96dr0zf.js")
18428
+ import("./curator-yxmtp8py.js"),
18429
+ import("./curator-llm-factory-9qn52fnv.js")
18378
18430
  ]);
18379
18431
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
18380
18432
  }
@@ -18870,7 +18922,7 @@ import { fileURLToPath } from "url";
18870
18922
  // package.json
18871
18923
  var package_default = {
18872
18924
  name: "opencode-swarm",
18873
- version: "7.116.0",
18925
+ version: "7.116.1",
18874
18926
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
18875
18927
  main: "dist/index.js",
18876
18928
  types: "dist/index.d.ts",
@@ -21153,7 +21205,7 @@ async function handleEvidenceCommand(directory, args) {
21153
21205
  return formatTaskEvidenceMarkdown(evidenceData);
21154
21206
  }
21155
21207
  async function handleEvidenceSummaryCommand(directory) {
21156
- const { buildEvidenceSummary } = await import("./evidence-summary-service-ef6kgtev.js");
21208
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-bwt6drb3.js");
21157
21209
  const artifact = await buildEvidenceSummary(directory);
21158
21210
  if (!artifact) {
21159
21211
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -34482,8 +34534,8 @@ async function handleQaGatesCommand(directory, args, sessionID) {
34482
34534
  }
34483
34535
 
34484
34536
  // src/commands/reset.ts
34485
- import * as fs33 from "fs";
34486
- import * as path66 from "path";
34537
+ import * as fs34 from "fs";
34538
+ import * as path67 from "path";
34487
34539
 
34488
34540
  // src/background/circuit-breaker.ts
34489
34541
  class CircuitBreaker {
@@ -35175,7 +35227,85 @@ function resetAutomationManager() {
35175
35227
  }
35176
35228
  }
35177
35229
 
35230
+ // src/commands/reset-backup.ts
35231
+ import * as fs33 from "fs";
35232
+ import * as path66 from "path";
35233
+ var RESET_BACKUP_RETENTION = 5;
35234
+ function backupSwarmStateBeforeReset(directory, kind, relEntries) {
35235
+ const warnings = [];
35236
+ const copied = [];
35237
+ const swarmDir = path66.join(directory, ".swarm");
35238
+ try {
35239
+ const stat4 = fs33.lstatSync(swarmDir);
35240
+ if (stat4.isSymbolicLink() || !stat4.isDirectory()) {
35241
+ return { backupDir: null, copied, warnings };
35242
+ }
35243
+ } catch {
35244
+ return { backupDir: null, copied, warnings };
35245
+ }
35246
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
35247
+ const backupsRoot = path66.join(swarmDir, "reset-backups");
35248
+ const backupDir = path66.join(backupsRoot, `${kind}-${timestamp}`);
35249
+ let backupDirCreated = false;
35250
+ const ensureBackupDir = () => {
35251
+ if (!backupDirCreated) {
35252
+ fs33.mkdirSync(backupDir, { recursive: true });
35253
+ backupDirCreated = true;
35254
+ }
35255
+ };
35256
+ for (const rel of relEntries) {
35257
+ let src;
35258
+ try {
35259
+ src = validateSwarmPath(directory, rel);
35260
+ } catch {
35261
+ warnings.push(`skipped backup of ${rel} (path validation failed)`);
35262
+ continue;
35263
+ }
35264
+ if (!fs33.existsSync(src))
35265
+ continue;
35266
+ try {
35267
+ ensureBackupDir();
35268
+ const dest = path66.join(backupDir, rel);
35269
+ fs33.mkdirSync(path66.dirname(dest), { recursive: true });
35270
+ fs33.cpSync(src, dest, { recursive: true });
35271
+ copied.push(rel);
35272
+ } catch (err) {
35273
+ warnings.push(`failed to back up ${rel}: ${err instanceof Error ? err.message : String(err)}`);
35274
+ }
35275
+ }
35276
+ if (copied.length === 0) {
35277
+ if (backupDirCreated) {
35278
+ try {
35279
+ fs33.rmSync(backupDir, { recursive: true, force: true });
35280
+ } catch {}
35281
+ }
35282
+ return { backupDir: null, copied, warnings };
35283
+ }
35284
+ pruneOldResetBackups(backupsRoot, warnings);
35285
+ return { backupDir, copied, warnings };
35286
+ }
35287
+ function pruneOldResetBackups(backupsRoot, warnings) {
35288
+ try {
35289
+ const entries = fs33.readdirSync(backupsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse();
35290
+ for (const stale of entries.slice(RESET_BACKUP_RETENTION)) {
35291
+ try {
35292
+ fs33.rmSync(path66.join(backupsRoot, stale), {
35293
+ recursive: true,
35294
+ force: true
35295
+ });
35296
+ } catch (err) {
35297
+ warnings.push(`failed to prune old backup ${stale}: ${err instanceof Error ? err.message : String(err)}`);
35298
+ }
35299
+ }
35300
+ } catch (err) {
35301
+ warnings.push(`failed to prune old reset backups: ${err instanceof Error ? err.message : String(err)}`);
35302
+ }
35303
+ }
35304
+
35178
35305
  // src/commands/reset.ts
35306
+ var _internals52 = {
35307
+ backupSwarmStateBeforeReset
35308
+ };
35179
35309
  async function handleResetCommand(directory, args) {
35180
35310
  const hasConfirm = args.includes("--confirm");
35181
35311
  if (!hasConfirm) {
@@ -35184,7 +35314,7 @@ async function handleResetCommand(directory, args) {
35184
35314
  "",
35185
35315
  "\u26A0\uFE0F This will delete all swarm state from .swarm/ (plan, context, checkpoints, SWARM_PLAN artifacts including .swarm/plan-export/)",
35186
35316
  "",
35187
- "**Tip**: Run `/swarm export` first to backup your state.",
35317
+ "A timestamped backup of the deleted state is saved to `.swarm/reset-backups/` automatically (restore by copying files back). Run `/swarm export` first if you also want a portable JSON snapshot.",
35188
35318
  "",
35189
35319
  "To confirm, run: `/swarm reset --confirm`"
35190
35320
  ].join(`
@@ -35206,11 +35336,26 @@ async function handleResetCommand(directory, args) {
35206
35336
  "events.jsonl"
35207
35337
  ];
35208
35338
  const results = [];
35339
+ try {
35340
+ const backup = _internals52.backupSwarmStateBeforeReset(directory, "reset", [
35341
+ ...filesToReset,
35342
+ "summaries"
35343
+ ]);
35344
+ if (backup.backupDir && backup.copied.length > 0) {
35345
+ const rel = path67.relative(directory, backup.backupDir);
35346
+ results.push(`- \uD83D\uDCE6 Backed up ${backup.copied.length} item(s) to ${rel}/ (restore by copying files back into .swarm/)`);
35347
+ }
35348
+ for (const w of backup.warnings) {
35349
+ results.push(`- \u26A0\uFE0F Backup warning: ${w}`);
35350
+ }
35351
+ } catch (err) {
35352
+ results.push(`- \u26A0\uFE0F Auto-backup failed (continuing with reset): ${err instanceof Error ? err.message : String(err)}`);
35353
+ }
35209
35354
  for (const filename of filesToReset) {
35210
35355
  try {
35211
35356
  const resolvedPath = validateSwarmPath(directory, filename);
35212
- if (fs33.existsSync(resolvedPath)) {
35213
- fs33.unlinkSync(resolvedPath);
35357
+ if (fs34.existsSync(resolvedPath)) {
35358
+ fs34.unlinkSync(resolvedPath);
35214
35359
  results.push(`- \u2705 Deleted ${filename}`);
35215
35360
  } else {
35216
35361
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -35221,9 +35366,9 @@ async function handleResetCommand(directory, args) {
35221
35366
  }
35222
35367
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
35223
35368
  try {
35224
- const rootPath = path66.join(directory, filename);
35225
- if (fs33.existsSync(rootPath)) {
35226
- fs33.unlinkSync(rootPath);
35369
+ const rootPath = path67.join(directory, filename);
35370
+ if (fs34.existsSync(rootPath)) {
35371
+ fs34.unlinkSync(rootPath);
35227
35372
  results.push(`- \u2705 Deleted ${filename} (root)`);
35228
35373
  }
35229
35374
  } catch (err) {
@@ -35238,8 +35383,8 @@ async function handleResetCommand(directory, args) {
35238
35383
  }
35239
35384
  try {
35240
35385
  const summariesPath = validateSwarmPath(directory, "summaries");
35241
- if (fs33.existsSync(summariesPath)) {
35242
- fs33.rmSync(summariesPath, { recursive: true, force: true });
35386
+ if (fs34.existsSync(summariesPath)) {
35387
+ fs34.rmSync(summariesPath, { recursive: true, force: true });
35243
35388
  results.push("- \u2705 Deleted summaries/ directory");
35244
35389
  } else {
35245
35390
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -35258,16 +35403,16 @@ async function handleResetCommand(directory, args) {
35258
35403
  }
35259
35404
 
35260
35405
  // src/commands/reset-session.ts
35261
- import * as fs36 from "fs";
35262
- import * as path69 from "path";
35406
+ import * as fs37 from "fs";
35407
+ import * as path70 from "path";
35263
35408
 
35264
35409
  // src/prm/trajectory-store.ts
35265
- import * as fs34 from "fs/promises";
35266
- import * as path67 from "path";
35410
+ import * as fs35 from "fs/promises";
35411
+ import * as path68 from "path";
35267
35412
  init_logger();
35268
35413
  var MAX_TRACKED_TRAJECTORY_SESSIONS = 500;
35269
35414
  function getTrajectoryPath(sessionId, directory) {
35270
- const relativePath2 = path67.join("trajectories", `${sessionId}.jsonl`);
35415
+ const relativePath2 = path68.join("trajectories", `${sessionId}.jsonl`);
35271
35416
  return validateSwarmPath(directory, relativePath2);
35272
35417
  }
35273
35418
  var _inMemoryTrajectoryCache = new Map;
@@ -35297,7 +35442,7 @@ function clearTrajectoryCache(sessionId) {
35297
35442
  async function readTrajectory(sessionId, directory) {
35298
35443
  try {
35299
35444
  const trajectoryPath = getTrajectoryPath(sessionId, directory);
35300
- const content = await fs34.readFile(trajectoryPath, "utf-8");
35445
+ const content = await fs35.readFile(trajectoryPath, "utf-8");
35301
35446
  const lines = content.split(`
35302
35447
  `).filter((line) => line.trim().length > 0);
35303
35448
  const entries = [];
@@ -35322,15 +35467,15 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
35322
35467
  for (const subdir of ["trajectories", "replays"]) {
35323
35468
  try {
35324
35469
  const dirPath = validateSwarmPath(directory, subdir);
35325
- const entries = await fs34.readdir(dirPath, { withFileTypes: true });
35470
+ const entries = await fs35.readdir(dirPath, { withFileTypes: true });
35326
35471
  for (const entry of entries) {
35327
35472
  if (!entry.isFile())
35328
35473
  continue;
35329
- const filePath = path67.join(dirPath, entry.name);
35474
+ const filePath = path68.join(dirPath, entry.name);
35330
35475
  try {
35331
- const stat5 = await fs34.stat(filePath);
35476
+ const stat5 = await fs35.stat(filePath);
35332
35477
  if (now - stat5.mtimeMs > cutoffMs) {
35333
- await fs34.unlink(filePath);
35478
+ await fs35.unlink(filePath);
35334
35479
  }
35335
35480
  } catch {}
35336
35481
  }
@@ -35755,18 +35900,18 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
35755
35900
  init_logger();
35756
35901
 
35757
35902
  // src/prm/replay.ts
35758
- import { promises as fs35 } from "fs";
35759
- import path68 from "path";
35903
+ import { promises as fs36 } from "fs";
35904
+ import path69 from "path";
35760
35905
  init_logger();
35761
35906
  function isPathSafe(targetPath, basePath) {
35762
- const resolvedTarget = path68.resolve(targetPath);
35763
- const resolvedBase = path68.resolve(basePath);
35764
- const rel = path68.relative(resolvedBase, resolvedTarget);
35765
- return !rel.startsWith("..") && !path68.isAbsolute(rel);
35907
+ const resolvedTarget = path69.resolve(targetPath);
35908
+ const resolvedBase = path69.resolve(basePath);
35909
+ const rel = path69.relative(resolvedBase, resolvedTarget);
35910
+ return !rel.startsWith("..") && !path69.isAbsolute(rel);
35766
35911
  }
35767
35912
  function isWithinReplaysDir(targetPath) {
35768
- const resolved = path68.resolve(targetPath);
35769
- const parts = resolved.split(path68.sep);
35913
+ const resolved = path69.resolve(targetPath);
35914
+ const parts = resolved.split(path69.sep);
35770
35915
  for (let i = 0;i < parts.length - 1; i++) {
35771
35916
  if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
35772
35917
  return true;
@@ -35779,15 +35924,15 @@ function sanitizeFilename(input) {
35779
35924
  }
35780
35925
  async function startReplayRecording(sessionID, directory) {
35781
35926
  try {
35782
- const replayDir = path68.join(directory, ".swarm", "replays");
35927
+ const replayDir = path69.join(directory, ".swarm", "replays");
35783
35928
  const safeSessionID = sanitizeFilename(sessionID);
35784
35929
  const filename = `${safeSessionID}-${Date.now()}.jsonl`;
35785
- const filepath = path68.join(replayDir, filename);
35930
+ const filepath = path69.join(replayDir, filename);
35786
35931
  if (!isPathSafe(filepath, replayDir)) {
35787
35932
  advisoryWarn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
35788
35933
  return null;
35789
35934
  }
35790
- await fs35.mkdir(replayDir, { recursive: true });
35935
+ await fs36.mkdir(replayDir, { recursive: true });
35791
35936
  return filepath;
35792
35937
  } catch (err) {
35793
35938
  log(`[replay] Failed to start recording for session ${sessionID}: ${err}`);
@@ -35807,14 +35952,14 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
35807
35952
  };
35808
35953
  const line = `${JSON.stringify(fullEntry)}
35809
35954
  `;
35810
- await fs35.appendFile(artifactPath, line, "utf-8");
35955
+ await fs36.appendFile(artifactPath, line, "utf-8");
35811
35956
  } catch (err) {
35812
35957
  log(`[replay] Failed to record entry: ${err}`);
35813
35958
  }
35814
35959
  }
35815
35960
 
35816
35961
  // src/prm/index.ts
35817
- var _internals52 = {
35962
+ var _internals53 = {
35818
35963
  getAgentSession,
35819
35964
  readTrajectory,
35820
35965
  getInMemoryTrajectory,
@@ -35837,13 +35982,14 @@ function resetPrmSessionState(session, sessionId) {
35837
35982
  session.prmTrajectoryStep = 0;
35838
35983
  session.replayArtifactPath = null;
35839
35984
  if (sessionId) {
35840
- _internals52.clearTrajectoryCache(sessionId);
35985
+ _internals53.clearTrajectoryCache(sessionId);
35841
35986
  }
35842
35987
  }
35843
35988
 
35844
35989
  // src/commands/reset-session.ts
35845
- var _internals53 = {
35846
- cleanupOrphanedBranches
35990
+ var _internals54 = {
35991
+ cleanupOrphanedBranches,
35992
+ backupSwarmStateBeforeReset
35847
35993
  };
35848
35994
  function errorMessage(err) {
35849
35995
  if (err instanceof Error)
@@ -35852,11 +35998,23 @@ function errorMessage(err) {
35852
35998
  }
35853
35999
  async function handleResetSessionCommand(directory, _args) {
35854
36000
  const results = [];
36001
+ try {
36002
+ const backup = _internals54.backupSwarmStateBeforeReset(directory, "reset-session", ["session"]);
36003
+ if (backup.backupDir && backup.copied.length > 0) {
36004
+ const rel = path70.relative(directory, backup.backupDir);
36005
+ results.push(`\uD83D\uDCE6 Backed up session state to ${rel}/ (restore by copying files back into .swarm/session/)`);
36006
+ }
36007
+ for (const w of backup.warnings) {
36008
+ results.push(`\u26A0\uFE0F Backup warning: ${w}`);
36009
+ }
36010
+ } catch (err) {
36011
+ results.push(`\u26A0\uFE0F Auto-backup failed (continuing with reset): ${err instanceof Error ? err.message : String(err)}`);
36012
+ }
35855
36013
  let statePath;
35856
36014
  try {
35857
36015
  statePath = validateSwarmPath(directory, "session/state.json");
35858
- if (fs36.existsSync(statePath)) {
35859
- fs36.unlinkSync(statePath);
36016
+ if (fs37.existsSync(statePath)) {
36017
+ fs37.unlinkSync(statePath);
35860
36018
  results.push("\u2705 Deleted .swarm/session/state.json");
35861
36019
  } else {
35862
36020
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -35864,11 +36022,11 @@ async function handleResetSessionCommand(directory, _args) {
35864
36022
  } catch {
35865
36023
  results.push("\u274C Failed to delete state.json");
35866
36024
  }
35867
- const sessionDir = statePath ? path69.dirname(statePath) : undefined;
36025
+ const sessionDir = statePath ? path70.dirname(statePath) : undefined;
35868
36026
  let sessionFiles = [];
35869
- if (sessionDir && fs36.existsSync(sessionDir)) {
36027
+ if (sessionDir && fs37.existsSync(sessionDir)) {
35870
36028
  try {
35871
- sessionFiles = fs36.readdirSync(sessionDir);
36029
+ sessionFiles = fs37.readdirSync(sessionDir);
35872
36030
  } catch (err) {
35873
36031
  results.push(`\u274C Failed to read session directory: ${errorMessage(err)}`);
35874
36032
  }
@@ -35876,13 +36034,13 @@ async function handleResetSessionCommand(directory, _args) {
35876
36034
  for (const file of sessionFiles) {
35877
36035
  if (file === "state.json")
35878
36036
  continue;
35879
- const filePath = path69.join(sessionDir, file);
36037
+ const filePath = path70.join(sessionDir, file);
35880
36038
  try {
35881
- if (!fs36.existsSync(filePath))
36039
+ if (!fs37.existsSync(filePath))
35882
36040
  continue;
35883
- if (!fs36.lstatSync(filePath).isFile())
36041
+ if (!fs37.lstatSync(filePath).isFile())
35884
36042
  continue;
35885
- fs36.unlinkSync(filePath);
36043
+ fs37.unlinkSync(filePath);
35886
36044
  results.push(`\u2713 Deleted ${file}`);
35887
36045
  } catch (err) {
35888
36046
  results.push(`\u274C Failed to delete ${file}: ${errorMessage(err)}`);
@@ -35898,17 +36056,17 @@ async function handleResetSessionCommand(directory, _args) {
35898
36056
  const chainCount = swarmState.delegationChains.size;
35899
36057
  swarmState.delegationChains.clear();
35900
36058
  results.push(`\u2705 Cleared ${chainCount} delegation chain(s)`);
35901
- const worktreesDir = path69.resolve(path69.dirname(directory), ".swarm-worktrees");
36059
+ const worktreesDir = path70.resolve(path70.dirname(directory), ".swarm-worktrees");
35902
36060
  try {
35903
- if (fs36.existsSync(worktreesDir)) {
35904
- fs36.rmSync(worktreesDir, { recursive: true, force: true });
36061
+ if (fs37.existsSync(worktreesDir)) {
36062
+ fs37.rmSync(worktreesDir, { recursive: true, force: true });
35905
36063
  results.push("\u2705 Removed .swarm-worktrees/ directory");
35906
36064
  }
35907
36065
  } catch (err) {
35908
36066
  results.push(`\u26A0\uFE0F Failed to remove .swarm-worktrees/: ${errorMessage(err)}`);
35909
36067
  }
35910
36068
  try {
35911
- const branchResult = await _internals53.cleanupOrphanedBranches(directory, []);
36069
+ const branchResult = await _internals54.cleanupOrphanedBranches(directory, []);
35912
36070
  if (branchResult.removed.length > 0) {
35913
36071
  results.push(`\u2705 Removed ${branchResult.removed.length} orphan swarm-lane branch(es)`);
35914
36072
  }
@@ -35931,7 +36089,7 @@ async function handleResetSessionCommand(directory, _args) {
35931
36089
  }
35932
36090
 
35933
36091
  // src/summaries/manager.ts
35934
- import * as path70 from "path";
36092
+ import * as path71 from "path";
35935
36093
  var SUMMARY_ID_REGEX = /^S\d+$/;
35936
36094
  function sanitizeSummaryId(id) {
35937
36095
  if (!id || id.length === 0) {
@@ -35955,7 +36113,7 @@ function sanitizeSummaryId(id) {
35955
36113
  }
35956
36114
  async function loadFullOutput(directory, id) {
35957
36115
  const sanitizedId = sanitizeSummaryId(id);
35958
- const relativePath2 = path70.join("summaries", `${sanitizedId}.json`);
36116
+ const relativePath2 = path71.join("summaries", `${sanitizedId}.json`);
35959
36117
  validateSwarmPath(directory, relativePath2);
35960
36118
  const content = await readSwarmFileAsync(directory, relativePath2);
35961
36119
  if (content === null) {
@@ -36007,8 +36165,8 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
36007
36165
  }
36008
36166
 
36009
36167
  // src/commands/rollback.ts
36010
- import * as fs37 from "fs";
36011
- import * as path71 from "path";
36168
+ import * as fs38 from "fs";
36169
+ import * as path72 from "path";
36012
36170
  function safeParseToolJson(result) {
36013
36171
  try {
36014
36172
  const jsonStr = typeof result === "string" ? result : result.output;
@@ -36071,7 +36229,7 @@ async function restoreGitCheckpoint(directory, selected) {
36071
36229
  source: "checkpoints.json"
36072
36230
  };
36073
36231
  try {
36074
- fs37.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
36232
+ fs38.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
36075
36233
  `);
36076
36234
  } catch (error2) {
36077
36235
  console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
@@ -36082,7 +36240,7 @@ async function handleRollbackCommand(directory, args) {
36082
36240
  const phaseArg = args[0];
36083
36241
  if (!phaseArg) {
36084
36242
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
36085
- if (!fs37.existsSync(manifestPath2)) {
36243
+ if (!fs38.existsSync(manifestPath2)) {
36086
36244
  const gitCheckpoints = await listGitCheckpoints(directory);
36087
36245
  if (gitCheckpoints) {
36088
36246
  return formatGitCheckpointList(gitCheckpoints);
@@ -36091,7 +36249,7 @@ async function handleRollbackCommand(directory, args) {
36091
36249
  }
36092
36250
  let manifest2;
36093
36251
  try {
36094
- manifest2 = JSON.parse(fs37.readFileSync(manifestPath2, "utf-8"));
36252
+ manifest2 = JSON.parse(fs38.readFileSync(manifestPath2, "utf-8"));
36095
36253
  } catch {
36096
36254
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
36097
36255
  }
@@ -36121,7 +36279,7 @@ async function handleRollbackCommand(directory, args) {
36121
36279
  return restoreGitCheckpoint(directory, selected);
36122
36280
  }
36123
36281
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
36124
- if (!fs37.existsSync(manifestPath)) {
36282
+ if (!fs38.existsSync(manifestPath)) {
36125
36283
  const gitCheckpoints = await listGitCheckpoints(directory);
36126
36284
  if (!gitCheckpoints) {
36127
36285
  return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
@@ -36134,7 +36292,7 @@ async function handleRollbackCommand(directory, args) {
36134
36292
  }
36135
36293
  let manifest;
36136
36294
  try {
36137
- manifest = JSON.parse(fs37.readFileSync(manifestPath, "utf-8"));
36295
+ manifest = JSON.parse(fs38.readFileSync(manifestPath, "utf-8"));
36138
36296
  } catch {
36139
36297
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
36140
36298
  }
@@ -36144,10 +36302,10 @@ async function handleRollbackCommand(directory, args) {
36144
36302
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
36145
36303
  }
36146
36304
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
36147
- if (!fs37.existsSync(checkpointDir)) {
36305
+ if (!fs38.existsSync(checkpointDir)) {
36148
36306
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
36149
36307
  }
36150
- const checkpointFiles = fs37.readdirSync(checkpointDir);
36308
+ const checkpointFiles = fs38.readdirSync(checkpointDir);
36151
36309
  if (checkpointFiles.length === 0) {
36152
36310
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
36153
36311
  }
@@ -36163,10 +36321,10 @@ async function handleRollbackCommand(directory, args) {
36163
36321
  if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
36164
36322
  continue;
36165
36323
  }
36166
- const src = path71.join(checkpointDir, file);
36167
- const dest = path71.join(swarmDir, file);
36324
+ const src = path72.join(checkpointDir, file);
36325
+ const dest = path72.join(swarmDir, file);
36168
36326
  try {
36169
- fs37.cpSync(src, dest, { recursive: true, force: true });
36327
+ fs38.cpSync(src, dest, { recursive: true, force: true });
36170
36328
  successes.push(file);
36171
36329
  } catch (error2) {
36172
36330
  failures.push({ file, error: error2.message });
@@ -36183,11 +36341,11 @@ async function handleRollbackCommand(directory, args) {
36183
36341
  ].join(`
36184
36342
  `);
36185
36343
  }
36186
- const existingLedgerPath = path71.join(swarmDir, "plan-ledger.jsonl");
36344
+ const existingLedgerPath = path72.join(swarmDir, "plan-ledger.jsonl");
36187
36345
  let ledgerDeletionFailed = false;
36188
- if (fs37.existsSync(existingLedgerPath)) {
36346
+ if (fs38.existsSync(existingLedgerPath)) {
36189
36347
  try {
36190
- fs37.unlinkSync(existingLedgerPath);
36348
+ fs38.unlinkSync(existingLedgerPath);
36191
36349
  } catch (err) {
36192
36350
  ledgerDeletionFailed = true;
36193
36351
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -36196,9 +36354,9 @@ async function handleRollbackCommand(directory, args) {
36196
36354
  }
36197
36355
  if (!ledgerDeletionFailed) {
36198
36356
  try {
36199
- const planJsonPath = path71.join(swarmDir, "plan.json");
36200
- if (fs37.existsSync(planJsonPath)) {
36201
- const planRaw = fs37.readFileSync(planJsonPath, "utf-8");
36357
+ const planJsonPath = path72.join(swarmDir, "plan.json");
36358
+ if (fs38.existsSync(planJsonPath)) {
36359
+ const planRaw = fs38.readFileSync(planJsonPath, "utf-8");
36202
36360
  const plan = PlanSchema.parse(JSON.parse(planRaw));
36203
36361
  const planId = derivePlanId(plan);
36204
36362
  const planHash = computePlanHash(plan);
@@ -36226,7 +36384,7 @@ async function handleRollbackCommand(directory, args) {
36226
36384
  timestamp: new Date().toISOString()
36227
36385
  };
36228
36386
  try {
36229
- fs37.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
36387
+ fs38.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
36230
36388
  `);
36231
36389
  } catch (error2) {
36232
36390
  console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
@@ -36243,12 +36401,12 @@ async function handleRollbackCommand(directory, args) {
36243
36401
  }
36244
36402
 
36245
36403
  // src/commands/sdd.ts
36246
- import * as fs38 from "fs";
36247
- import * as path72 from "path";
36248
- var _internals54 = {
36404
+ import * as fs39 from "fs";
36405
+ import * as path73 from "path";
36406
+ var _internals55 = {
36249
36407
  writeProjectedSpecSync
36250
36408
  };
36251
- var SWARM_SPEC_REL = path72.join(".swarm", "spec.md");
36409
+ var SWARM_SPEC_REL = path73.join(".swarm", "spec.md");
36252
36410
  var USAGE10 = `Usage:
36253
36411
  /swarm sdd status [--json] [--source <provider>]
36254
36412
  /swarm sdd validate [--json] [--change <id>] [--source <provider>] [--feature <id>]
@@ -36370,7 +36528,7 @@ ${USAGE10}`;
36370
36528
  }
36371
36529
  const speckitDetection = detectSpeckit(directory);
36372
36530
  const speckitPresent = speckitDetection.features.length > 0;
36373
- const nativeSpecExists = fs38.existsSync(path72.join(directory, SWARM_SPEC_REL));
36531
+ const nativeSpecExists = fs39.existsSync(path73.join(directory, SWARM_SPEC_REL));
36374
36532
  if (speckitPresent && !parsed.source && !nativeSpecExists) {
36375
36533
  const openspecProjection = buildOpenSpecProjectionSync(directory);
36376
36534
  if (openspecProjection !== null) {
@@ -36440,7 +36598,7 @@ ${USAGE10}`;
36440
36598
  ${USAGE10}`;
36441
36599
  }
36442
36600
  let useSpeckit = false;
36443
- const nativeSpecExists = fs38.existsSync(path72.join(directory, SWARM_SPEC_REL));
36601
+ const nativeSpecExists = fs39.existsSync(path73.join(directory, SWARM_SPEC_REL));
36444
36602
  if (parsed.source === "speckit") {
36445
36603
  useSpeckit = true;
36446
36604
  } else if (!parsed.source && !nativeSpecExists) {
@@ -36594,8 +36752,8 @@ ${USAGE10}`;
36594
36752
  ${USAGE10}`;
36595
36753
  }
36596
36754
  if (!parsed.dryRun) {
36597
- const nativeSpecPath = path72.join(directory, SWARM_SPEC_REL);
36598
- if (fs38.existsSync(nativeSpecPath)) {
36755
+ const nativeSpecPath = path73.join(directory, SWARM_SPEC_REL);
36756
+ if (fs39.existsSync(nativeSpecPath)) {
36599
36757
  if (!parsed.overwrite) {
36600
36758
  return [
36601
36759
  "Error: .swarm/spec.md already exists.",
@@ -36641,7 +36799,7 @@ ${USAGE10}`;
36641
36799
 
36642
36800
  ${USAGE10}`;
36643
36801
  }
36644
- const result2 = _internals54.writeProjectedSpecSync(directory, {
36802
+ const result2 = _internals55.writeProjectedSpecSync(directory, {
36645
36803
  source: "speckit",
36646
36804
  feature: resolution.feature,
36647
36805
  dryRun: parsed.dryRun,
@@ -36699,7 +36857,7 @@ ${formatList(result2.projection.warnings)}` : ""
36699
36857
  ].join(`
36700
36858
  `);
36701
36859
  }
36702
- const result = _internals54.writeProjectedSpecSync(directory, {
36860
+ const result = _internals55.writeProjectedSpecSync(directory, {
36703
36861
  changeId: parsed.changeId,
36704
36862
  dryRun: parsed.dryRun,
36705
36863
  overwrite: parsed.overwrite
@@ -36809,13 +36967,13 @@ Ensure this is a git repository with commit history.`;
36809
36967
  const report = reportLines.filter(Boolean).join(`
36810
36968
  `);
36811
36969
  try {
36812
- const fs39 = await import("fs/promises");
36813
- const path73 = await import("path");
36814
- const reportPath = path73.join(directory, ".swarm", "simulate-report.md");
36815
- await fs39.mkdir(path73.dirname(reportPath), { recursive: true });
36816
- const reportTempPath = path73.join(path73.dirname(reportPath), `${path73.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
36970
+ const fs40 = await import("fs/promises");
36971
+ const path74 = await import("path");
36972
+ const reportPath = path74.join(directory, ".swarm", "simulate-report.md");
36973
+ await fs40.mkdir(path74.dirname(reportPath), { recursive: true });
36974
+ const reportTempPath = path74.join(path74.dirname(reportPath), `${path74.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
36817
36975
  try {
36818
- await fs39.writeFile(reportTempPath, report, "utf-8");
36976
+ await fs40.writeFile(reportTempPath, report, "utf-8");
36819
36977
  renameSync11(reportTempPath, reportPath);
36820
36978
  } catch (err) {
36821
36979
  try {
@@ -36842,7 +37000,7 @@ async function handleSpecifyCommand(_directory, args) {
36842
37000
  // src/services/status-service.ts
36843
37001
  import * as fsSync2 from "fs";
36844
37002
  import { readFile as readFile17 } from "fs/promises";
36845
- import * as path74 from "path";
37003
+ import * as path75 from "path";
36846
37004
 
36847
37005
  // src/hooks/extractors.ts
36848
37006
  function extractCurrentPhase(planContent) {
@@ -36886,16 +37044,16 @@ function extractCurrentPhaseFromPlan2(plan) {
36886
37044
 
36887
37045
  // src/turbo/lean/state.ts
36888
37046
  init_logger();
36889
- import * as fs39 from "fs";
36890
- import * as path73 from "path";
37047
+ import * as fs40 from "fs";
37048
+ import * as path74 from "path";
36891
37049
  var STATE_FILE3 = "turbo-state.json";
36892
37050
  function nowISO3() {
36893
37051
  return new Date().toISOString();
36894
37052
  }
36895
37053
  function ensureSwarmDir2(directory) {
36896
- const swarmDir = path73.resolve(directory, ".swarm");
36897
- if (!fs39.existsSync(swarmDir)) {
36898
- fs39.mkdirSync(swarmDir, { recursive: true });
37054
+ const swarmDir = path74.resolve(directory, ".swarm");
37055
+ if (!fs40.existsSync(swarmDir)) {
37056
+ fs40.mkdirSync(swarmDir, { recursive: true });
36899
37057
  }
36900
37058
  return swarmDir;
36901
37059
  }
@@ -36938,17 +37096,17 @@ function markStateUnreadable2(directory, reason) {
36938
37096
  }
36939
37097
  function readPersisted2(directory) {
36940
37098
  try {
36941
- const filePath = path73.join(directory, ".swarm", STATE_FILE3);
36942
- if (!fs39.existsSync(filePath)) {
37099
+ const filePath = path74.join(directory, ".swarm", STATE_FILE3);
37100
+ if (!fs40.existsSync(filePath)) {
36943
37101
  const seed = emptyPersisted2();
36944
37102
  try {
36945
37103
  ensureSwarmDir2(directory);
36946
- fs39.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
37104
+ fs40.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
36947
37105
  `, "utf-8");
36948
37106
  } catch {}
36949
37107
  return seed;
36950
37108
  }
36951
- const raw = fs39.readFileSync(filePath, "utf-8");
37109
+ const raw = fs40.readFileSync(filePath, "utf-8");
36952
37110
  const parsed = JSON.parse(raw);
36953
37111
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
36954
37112
  markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -36974,7 +37132,7 @@ function writePersisted2(directory, persisted) {
36974
37132
  let payload;
36975
37133
  try {
36976
37134
  ensureSwarmDir2(directory);
36977
- filePath = path73.join(directory, ".swarm", STATE_FILE3);
37135
+ filePath = path74.join(directory, ".swarm", STATE_FILE3);
36978
37136
  tmpPath = `${filePath}.tmp.${Date.now()}`;
36979
37137
  persisted.updatedAt = nowISO3();
36980
37138
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -36985,14 +37143,14 @@ function writePersisted2(directory, persisted) {
36985
37143
  throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
36986
37144
  }
36987
37145
  try {
36988
- fs39.writeFileSync(tmpPath, payload, "utf-8");
36989
- fs39.renameSync(tmpPath, filePath);
37146
+ fs40.writeFileSync(tmpPath, payload, "utf-8");
37147
+ fs40.renameSync(tmpPath, filePath);
36990
37148
  } catch (error2) {
36991
37149
  const msg = error2 instanceof Error ? error2.message : String(error2);
36992
37150
  error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
36993
37151
  try {
36994
- if (fs39.existsSync(tmpPath)) {
36995
- fs39.unlinkSync(tmpPath);
37152
+ if (fs40.existsSync(tmpPath)) {
37153
+ fs40.unlinkSync(tmpPath);
36996
37154
  }
36997
37155
  } catch {}
36998
37156
  throw new Error(`Lean Turbo state persistence failed: ${msg}`);
@@ -37086,7 +37244,7 @@ var DEFAULT_CONTEXT_BUDGET_CONFIG = {
37086
37244
  };
37087
37245
 
37088
37246
  // src/services/status-service.ts
37089
- var _internals55 = {
37247
+ var _internals56 = {
37090
37248
  loadLeanTurboRunState,
37091
37249
  hasActiveLeanTurbo,
37092
37250
  hasActiveFullAuto,
@@ -37095,7 +37253,7 @@ var _internals55 = {
37095
37253
  };
37096
37254
  function readSpecStalenessSnapshot(directory) {
37097
37255
  try {
37098
- const p = path74.join(directory, ".swarm", "spec-staleness.json");
37256
+ const p = path75.join(directory, ".swarm", "spec-staleness.json");
37099
37257
  if (!fsSync2.existsSync(p))
37100
37258
  return { stale: false };
37101
37259
  const raw = fsSync2.readFileSync(p, "utf-8");
@@ -37189,11 +37347,11 @@ async function getStatusData(directory, agents) {
37189
37347
  status.pendingProposals = await countProposals(directory);
37190
37348
  status.unactionableQueueDepth = await safeLineCount(resolveUnactionablePath(directory));
37191
37349
  status.insightCandidatesPending = await safeLineCount(validateSwarmPath(directory, "insight-candidates.jsonl"));
37192
- status.fullAutoActive = _internals55.hasActiveFullAuto();
37350
+ status.fullAutoActive = _internals56.hasActiveFullAuto();
37193
37351
  if (status.fullAutoActive) {
37194
- const sid = _internals55.getActiveFullAutoSessionID();
37352
+ const sid = _internals56.getActiveFullAutoSessionID();
37195
37353
  if (sid) {
37196
- const runState = _internals55.loadFullAutoRunState(directory, sid);
37354
+ const runState = _internals56.loadFullAutoRunState(directory, sid);
37197
37355
  if (runState?.lastEscalation) {
37198
37356
  status.fullAutoEscalation = {
37199
37357
  reason: runState.lastEscalation.reason,
@@ -37208,7 +37366,7 @@ async function getStatusData(directory, agents) {
37208
37366
  }
37209
37367
  function enrichWithLeanTurbo(status, directory) {
37210
37368
  const turboMode = hasActiveTurboMode();
37211
- const leanActive = _internals55.hasActiveLeanTurbo();
37369
+ const leanActive = _internals56.hasActiveLeanTurbo();
37212
37370
  let turboStrategy = "off";
37213
37371
  if (leanActive) {
37214
37372
  turboStrategy = "lean";
@@ -37227,7 +37385,7 @@ function enrichWithLeanTurbo(status, directory) {
37227
37385
  }
37228
37386
  }
37229
37387
  if (leanSessionID) {
37230
- const runState = _internals55.loadLeanTurboRunState(directory, leanSessionID);
37388
+ const runState = _internals56.loadLeanTurboRunState(directory, leanSessionID);
37231
37389
  if (runState) {
37232
37390
  status.leanTurboPhase = runState.phase;
37233
37391
  status.leanMaxParallelCoders = runState.maxParallelCoders;
@@ -37418,7 +37576,7 @@ No active swarm plan found. Nothing to sync.`;
37418
37576
 
37419
37577
  // src/commands/turbo.ts
37420
37578
  init_logger();
37421
- var _internals56 = {
37579
+ var _internals57 = {
37422
37580
  loadPluginConfigWithMeta
37423
37581
  };
37424
37582
  async function handleTurboCommand(directory, args, sessionID) {
@@ -37478,7 +37636,7 @@ async function handleTurboCommand(directory, args, sessionID) {
37478
37636
  if (arg0 === "on") {
37479
37637
  let strategy = "standard";
37480
37638
  try {
37481
- const { config } = _internals56.loadPluginConfigWithMeta(directory);
37639
+ const { config } = _internals57.loadPluginConfigWithMeta(directory);
37482
37640
  if (config.turbo?.strategy === "lean") {
37483
37641
  strategy = "lean";
37484
37642
  }
@@ -37575,7 +37733,7 @@ function enableLeanTurbo(session, directory, sessionID) {
37575
37733
  let maxParallelCoders = 4;
37576
37734
  let conflictPolicy = "serialize";
37577
37735
  try {
37578
- const { config } = _internals56.loadPluginConfigWithMeta(directory);
37736
+ const { config } = _internals57.loadPluginConfigWithMeta(directory);
37579
37737
  const leanConfig = config.turbo?.lean;
37580
37738
  if (leanConfig) {
37581
37739
  maxParallelCoders = leanConfig.max_parallel_coders ?? 4;
@@ -37647,13 +37805,13 @@ function buildStatusMessage2(session, directory, sessionID) {
37647
37805
  }
37648
37806
 
37649
37807
  // src/commands/unlink.ts
37650
- import { existsSync as existsSync45 } from "fs";
37651
- import * as path75 from "path";
37808
+ import { existsSync as existsSync46 } from "fs";
37809
+ import * as path76 from "path";
37652
37810
  var DEDUP_THRESHOLD2 = 0.6;
37653
37811
  async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
37654
- const sharedPath = path75.join(linkDir, "knowledge.jsonl");
37655
- const localPath = path75.join(localSwarmDir, "knowledge.jsonl");
37656
- if (!existsSync45(sharedPath))
37812
+ const sharedPath = path76.join(linkDir, "knowledge.jsonl");
37813
+ const localPath = path76.join(localSwarmDir, "knowledge.jsonl");
37814
+ if (!existsSync46(sharedPath))
37657
37815
  return 0;
37658
37816
  const sharedEntries = await readKnowledge(sharedPath);
37659
37817
  if (sharedEntries.length === 0)
@@ -37687,7 +37845,7 @@ async function handleUnlinkCommand(directory, args) {
37687
37845
  let copied = 0;
37688
37846
  if (copyBack) {
37689
37847
  try {
37690
- copied = await copySharedKnowledgeToLocal(linkDir, path75.join(directory, ".swarm"));
37848
+ copied = await copySharedKnowledgeToLocal(linkDir, path76.join(directory, ".swarm"));
37691
37849
  } catch (error2) {
37692
37850
  return `\u274C Failed to copy shared knowledge back to local: ${error2 instanceof Error ? error2.message : String(error2)}`;
37693
37851
  }
@@ -37791,7 +37949,7 @@ function findSimilarCommands(query) {
37791
37949
  }
37792
37950
  const scored = VALID_COMMANDS.map((cmd) => {
37793
37951
  const cmdLower = cmd.toLowerCase();
37794
- const fullScore = _internals57.levenshteinDistance(q, cmdLower);
37952
+ const fullScore = _internals58.levenshteinDistance(q, cmdLower);
37795
37953
  let tokenScore = Infinity;
37796
37954
  if (cmd.includes(" ") || cmd.includes("-")) {
37797
37955
  const qTokens = q.split(/[\s-]+/);
@@ -37804,7 +37962,7 @@ function findSimilarCommands(query) {
37804
37962
  for (const ct of cmdTokens) {
37805
37963
  if (ct.length === 0)
37806
37964
  continue;
37807
- const dist = _internals57.levenshteinDistance(qt, ct);
37965
+ const dist = _internals58.levenshteinDistance(qt, ct);
37808
37966
  if (dist < minDist)
37809
37967
  minDist = dist;
37810
37968
  }
@@ -37814,7 +37972,7 @@ function findSimilarCommands(query) {
37814
37972
  }
37815
37973
  const dashStrippedQ = q.replace(/-/g, "");
37816
37974
  const dashStrippedCmd = cmdLower.replace(/-/g, "");
37817
- const dashScore = _internals57.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
37975
+ const dashScore = _internals58.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
37818
37976
  const score = Math.min(fullScore, tokenScore, dashScore);
37819
37977
  return { cmd, score };
37820
37978
  });
@@ -37849,16 +38007,16 @@ function buildDetailedHelp(commandName, entry) {
37849
38007
  async function handleHelpCommand(ctx) {
37850
38008
  const targetCommand = ctx.args.join(" ");
37851
38009
  if (!targetCommand) {
37852
- const { buildHelpText } = await import("./index-3b8n3dbd.js");
38010
+ const { buildHelpText } = await import("./index-p9jf8gt8.js");
37853
38011
  return buildHelpText();
37854
38012
  }
37855
38013
  const tokens = targetCommand.split(/\s+/);
37856
- const resolved = _internals57.resolveCommand(tokens);
38014
+ const resolved = _internals58.resolveCommand(tokens);
37857
38015
  if (resolved) {
37858
- return _internals57.buildDetailedHelp(resolved.key, resolved.entry);
38016
+ return _internals58.buildDetailedHelp(resolved.key, resolved.entry);
37859
38017
  }
37860
- const similar = _internals57.findSimilarCommands(targetCommand);
37861
- const { buildHelpText: fullHelp } = await import("./index-3b8n3dbd.js");
38018
+ const similar = _internals58.findSimilarCommands(targetCommand);
38019
+ const { buildHelpText: fullHelp } = await import("./index-p9jf8gt8.js");
37862
38020
  if (similar.length > 0) {
37863
38021
  return `Command '/swarm ${targetCommand}' not found.
37864
38022
 
@@ -37922,7 +38080,7 @@ var COMMAND_REGISTRY = {
37922
38080
  toolNoArgs: true
37923
38081
  },
37924
38082
  help: {
37925
- handler: (ctx) => _internals57.handleHelpCommand(ctx),
38083
+ handler: (ctx) => _internals58.handleHelpCommand(ctx),
37926
38084
  description: "Show help for swarm commands",
37927
38085
  category: "core",
37928
38086
  args: "[command]",
@@ -37991,7 +38149,7 @@ var COMMAND_REGISTRY = {
37991
38149
  },
37992
38150
  "guardrail explain": {
37993
38151
  handler: async (ctx) => {
37994
- const { handleGuardrailExplain } = await import("./guardrail-explain-kwqfkwch.js");
38152
+ const { handleGuardrailExplain } = await import("./guardrail-explain-xvyz2eag.js");
37995
38153
  return handleGuardrailExplain(ctx.directory, ctx.args);
37996
38154
  },
37997
38155
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -38001,7 +38159,7 @@ var COMMAND_REGISTRY = {
38001
38159
  },
38002
38160
  "guardrail-explain": {
38003
38161
  handler: async (ctx) => {
38004
- const { handleGuardrailExplain } = await import("./guardrail-explain-kwqfkwch.js");
38162
+ const { handleGuardrailExplain } = await import("./guardrail-explain-xvyz2eag.js");
38005
38163
  return handleGuardrailExplain(ctx.directory, ctx.args);
38006
38164
  },
38007
38165
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -38218,8 +38376,8 @@ var COMMAND_REGISTRY = {
38218
38376
  sessionID: ctx.sessionID
38219
38377
  }),
38220
38378
  description: "Use /swarm finalize to finalize the swarm project and archive evidence",
38221
- details: "Idempotent 4-stage terminal finalization: (1) finalize writes retrospectives for in-progress phases, (2) archive creates timestamped bundle of swarm artifacts and evidence, (3) clean removes active-state files for a clean slate, (4) align performs aggressive git reset --hard to the default remote branch, discarding uncommitted changes and gitignored build artifacts (user-created untracked files are preserved); falls back to a cautious reset that preserves uncommitted changes when the aggressive path cannot proceed. WARNING: alignment discards local changes and gitignored files. Resets agent sessions and delegation chains. Reads .swarm/close-lessons.md for explicit lessons and runs curation. Use --skill-review to run the quota-bounded skill_improver in proposal mode.",
38222
- args: "--prune-branches, --skill-review",
38379
+ details: "Idempotent 4-stage terminal finalization: (1) finalize writes retrospectives for in-progress phases, (2) archive creates timestamped bundle of swarm artifacts and evidence, (3) clean removes active-state files for a clean slate, (4) align performs aggressive git reset --hard to the default remote branch, discarding uncommitted changes and gitignored build artifacts (user-created untracked files are preserved); falls back to a cautious reset that preserves uncommitted changes when the aggressive path cannot proceed. WARNING: alignment discards local changes and gitignored files. Resets agent sessions and delegation chains. Reads .swarm/close-lessons.md for explicit lessons and runs curation. Use --skill-review to run the quota-bounded skill_improver in proposal mode. Use --dry-run to preview what finalize would archive, clean, and align without taking the lock or changing anything.",
38380
+ args: "--prune-branches, --skill-review, --dry-run",
38223
38381
  category: "core",
38224
38382
  toolPolicy: "none"
38225
38383
  },
@@ -38228,8 +38386,8 @@ var COMMAND_REGISTRY = {
38228
38386
  sessionID: ctx.sessionID
38229
38387
  }),
38230
38388
  description: "Use /swarm close (deprecated alias) to finalize and archive swarm state",
38231
- details: "Deprecated alias for /swarm finalize. Preserved for backward compatibility.",
38232
- args: "--prune-branches, --skill-review",
38389
+ details: "Deprecated alias for /swarm finalize. Preserved for backward compatibility. Supports the same flags, including --dry-run.",
38390
+ args: "--prune-branches, --skill-review, --dry-run",
38233
38391
  category: "core",
38234
38392
  aliasOf: "finalize",
38235
38393
  deprecated: true
@@ -38549,7 +38707,7 @@ Subcommands:
38549
38707
  reset: {
38550
38708
  handler: (ctx) => handleResetCommand(ctx.directory, ctx.args),
38551
38709
  description: "Clear swarm state files [--confirm]",
38552
- details: "DELETES plan.md, context.md, and summaries/ directory from .swarm/. Stops background automation and clears in-memory queues. SAFETY: requires --confirm flag \u2014 without it, displays a warning and tips to export first.",
38710
+ details: "DELETES plan.md, context.md, and summaries/ directory from .swarm/. Stops background automation and clears in-memory queues. SAFETY: requires --confirm flag \u2014 without it, displays a warning and tips to export first. Before deleting, auto-backs up the state it removes to .swarm/reset-backups/<timestamp>/ (newest 5 kept) so it can be restored by copying the files back.",
38553
38711
  args: "--confirm (required)",
38554
38712
  category: "utility",
38555
38713
  clashesWithNativeCcCommand: "/reset",
@@ -38558,7 +38716,7 @@ Subcommands:
38558
38716
  "reset-session": {
38559
38717
  handler: (ctx) => handleResetSessionCommand(ctx.directory, ctx.args),
38560
38718
  description: "Clear session state while preserving plan, evidence, and knowledge",
38561
- details: "Deletes only .swarm/session/state.json and any other session files. Clears in-memory agent sessions and delegation chains. Preserves plan, evidence, and knowledge for cross-session continuity.",
38719
+ details: "Deletes only .swarm/session/state.json and any other session files. Clears in-memory agent sessions and delegation chains. Preserves plan, evidence, and knowledge for cross-session continuity. Before deleting, auto-backs up the session files it removes to .swarm/reset-backups/<timestamp>/ (newest 5 kept).",
38562
38720
  args: "",
38563
38721
  category: "utility",
38564
38722
  toolPolicy: "restricted"
@@ -38826,24 +38984,24 @@ function validateAliases() {
38826
38984
  continue;
38827
38985
  }
38828
38986
  const visited = new Set;
38829
- const path76 = [];
38987
+ const path77 = [];
38830
38988
  let current = target;
38831
38989
  while (current) {
38832
38990
  const currentEntry = COMMAND_REGISTRY[current];
38833
38991
  if (!currentEntry)
38834
38992
  break;
38835
38993
  if (visited.has(current)) {
38836
- const cycleStart = path76.indexOf(current);
38994
+ const cycleStart = path77.indexOf(current);
38837
38995
  const fullChain = [
38838
38996
  name,
38839
- ...path76.slice(0, cycleStart > 0 ? cycleStart : path76.length),
38997
+ ...path77.slice(0, cycleStart > 0 ? cycleStart : path77.length),
38840
38998
  current
38841
38999
  ].join(" \u2192 ");
38842
39000
  errors.push(`Circular alias detected: ${fullChain}`);
38843
39001
  break;
38844
39002
  }
38845
39003
  visited.add(current);
38846
- path76.push(current);
39004
+ path77.push(current);
38847
39005
  current = currentEntry.aliasOf || "";
38848
39006
  }
38849
39007
  }
@@ -38862,7 +39020,7 @@ function validateToolPolicy() {
38862
39020
  }
38863
39021
  return { valid: warnings.length === 0, warnings };
38864
39022
  }
38865
- var _internals57 = {
39023
+ var _internals58 = {
38866
39024
  handleHelpCommand,
38867
39025
  validateAliases,
38868
39026
  validateToolPolicy,
@@ -38872,16 +39030,16 @@ var _internals57 = {
38872
39030
  findSimilarCommands,
38873
39031
  buildDetailedHelp
38874
39032
  };
38875
- var validation = _internals57.validateAliases();
39033
+ var validation = _internals58.validateAliases();
38876
39034
  if (!validation.valid) {
38877
39035
  throw new Error(`COMMAND_REGISTRY alias validation failed:
38878
39036
  ${validation.errors.join(`
38879
39037
  `)}`);
38880
39038
  }
38881
- _internals57.emitValidationWarnings("COMMAND_REGISTRY alias warnings", validation.warnings);
39039
+ _internals58.emitValidationWarnings("COMMAND_REGISTRY alias warnings", validation.warnings);
38882
39040
  try {
38883
- const toolPolicyValidation = _internals57.validateToolPolicy();
38884
- _internals57.emitValidationWarnings("COMMAND_REGISTRY toolPolicy warnings", toolPolicyValidation.warnings);
39041
+ const toolPolicyValidation = _internals58.validateToolPolicy();
39042
+ _internals58.emitValidationWarnings("COMMAND_REGISTRY toolPolicy warnings", toolPolicyValidation.warnings);
38885
39043
  } catch (e) {
38886
39044
  warn(`COMMAND_REGISTRY toolPolicy validation failed (non-fatal): ${e.message}`);
38887
39045
  }
@@ -41215,7 +41373,7 @@ init_logger();
41215
41373
 
41216
41374
  // src/hooks/guardrails/destructive-command.ts
41217
41375
  import * as fsSync3 from "fs";
41218
- import * as path76 from "path";
41376
+ import * as path77 from "path";
41219
41377
  var DC_MAX_UNWRAP_DEPTH = 5;
41220
41378
  var DC_SAFE_TARGETS = new Set([
41221
41379
  "node_modules",
@@ -41391,16 +41549,16 @@ function dcIsRemotePath(p) {
41391
41549
  return DC_REMOTE_PREFIXES.some((pfx) => p.startsWith(pfx));
41392
41550
  }
41393
41551
  function dcLstatAncestorWalk(targetPath, cwd) {
41394
- const normalizedTarget = path76.resolve(cwd, targetPath);
41395
- const normalizedCwd = path76.resolve(cwd);
41552
+ const normalizedTarget = path77.resolve(cwd, targetPath);
41553
+ const normalizedCwd = path77.resolve(cwd);
41396
41554
  const ancestors = [];
41397
41555
  let current = normalizedTarget;
41398
41556
  while (true) {
41399
41557
  ancestors.push(current);
41400
- const parent = path76.dirname(current);
41558
+ const parent = path77.dirname(current);
41401
41559
  if (parent === current)
41402
41560
  break;
41403
- const rel = path76.relative(normalizedCwd, current);
41561
+ const rel = path77.relative(normalizedCwd, current);
41404
41562
  if (rel === "" || rel.startsWith(".."))
41405
41563
  break;
41406
41564
  current = parent;
@@ -41439,14 +41597,14 @@ function dcValidateTargets(targets, cwd) {
41439
41597
  const lstatBlock = dcLstatAncestorWalk(t, cwd);
41440
41598
  if (lstatBlock)
41441
41599
  return lstatBlock;
41442
- const basename15 = path76.basename(t);
41600
+ const basename15 = path77.basename(t);
41443
41601
  if (t === basename15 && DC_SAFE_TARGETS.has(t)) {
41444
41602
  continue;
41445
41603
  }
41446
41604
  if (DC_FS_ROOTS.has(t) || DC_FS_ROOTS.has(t.replace(/\//g, "\\"))) {
41447
41605
  return `BLOCKED: Destructive command targets filesystem root "${t}"`;
41448
41606
  }
41449
- if (path76.isAbsolute(t) || /^[A-Za-z]:/.test(t)) {
41607
+ if (path77.isAbsolute(t) || /^[A-Za-z]:/.test(t)) {
41450
41608
  for (const blocked of DC_BLOCKED_ABSOLUTE_PREFIXES) {
41451
41609
  if (t.startsWith(blocked)) {
41452
41610
  return `BLOCKED: Destructive command targets system path "${t}" which is under protected prefix "${blocked}"`;
@@ -41461,9 +41619,9 @@ function dcCheckJunctionCreation(segment, cwd) {
41461
41619
  if (mklinkMatch) {
41462
41620
  const target = mklinkMatch[2].trim();
41463
41621
  if (!dcHasUnresolvableVars(target)) {
41464
- const resolved = path76.resolve(cwd, target);
41465
- const rel = path76.relative(cwd, resolved);
41466
- if (rel.startsWith("..") || path76.isAbsolute(rel)) {
41622
+ const resolved = path77.resolve(cwd, target);
41623
+ const rel = path77.relative(cwd, resolved);
41624
+ if (rel.startsWith("..") || path77.isAbsolute(rel)) {
41467
41625
  return `BLOCKED: Junction/symlink creation targeting path outside working directory: mklink target "${target}" resolves to "${resolved}" which is outside "${cwd}". Creating junctions to external paths and then deleting them recursively can destroy data.`;
41468
41626
  }
41469
41627
  }
@@ -41475,9 +41633,9 @@ function dcCheckJunctionCreation(segment, cwd) {
41475
41633
  if (newItemMatch) {
41476
41634
  const target = newItemMatch[1].trim();
41477
41635
  if (!dcHasUnresolvableVars(target)) {
41478
- const resolved = path76.resolve(cwd, target);
41479
- const rel = path76.relative(cwd, resolved);
41480
- if (rel.startsWith("..") || path76.isAbsolute(rel)) {
41636
+ const resolved = path77.resolve(cwd, target);
41637
+ const rel = path77.relative(cwd, resolved);
41638
+ if (rel.startsWith("..") || path77.isAbsolute(rel)) {
41481
41639
  return `BLOCKED: Junction/symlink creation targeting path outside working directory: New-Item target "${target}" resolves to "${resolved}" which is outside "${cwd}". This pattern caused the K2.6 data-loss incident.`;
41482
41640
  }
41483
41641
  }
@@ -41487,9 +41645,9 @@ function dcCheckJunctionCreation(segment, cwd) {
41487
41645
  if (lnMatch) {
41488
41646
  const target = lnMatch[1].trim();
41489
41647
  if (!dcHasUnresolvableVars(target)) {
41490
- const resolved = path76.resolve(cwd, target);
41491
- const rel = path76.relative(cwd, resolved);
41492
- if (rel.startsWith("..") || path76.isAbsolute(rel)) {
41648
+ const resolved = path77.resolve(cwd, target);
41649
+ const rel = path77.relative(cwd, resolved);
41650
+ if (rel.startsWith("..") || path77.isAbsolute(rel)) {
41493
41651
  return `BLOCKED: Symlink creation targeting path outside working directory: ln -s target "${target}" resolves to "${resolved}" which is outside "${cwd}". Symlinks to external paths combined with recursive deletion can destroy data.`;
41494
41652
  }
41495
41653
  }
@@ -41581,7 +41739,7 @@ function formatCommandNotFound(tokens) {
41581
41739
  const attemptedCommand = tokens[0] || "";
41582
41740
  const MAX_DISPLAY = 100;
41583
41741
  const displayCommand = attemptedCommand.length > MAX_DISPLAY ? `${attemptedCommand.slice(0, MAX_DISPLAY)}...` : attemptedCommand;
41584
- const similar = _internals57.findSimilarCommands(attemptedCommand);
41742
+ const similar = _internals58.findSimilarCommands(attemptedCommand);
41585
41743
  const header = `Command \`/swarm ${displayCommand}\` not found.`;
41586
41744
  const suggestions = similar.length > 0 ? `Did you mean:
41587
41745
  ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
@@ -41904,10 +42062,10 @@ function classifySwarmCommandChatFallbackUse(resolved) {
41904
42062
  init_executor();
41905
42063
 
41906
42064
  // src/hooks/shell-write-detect.ts
41907
- import * as path77 from "path";
42065
+ import * as path78 from "path";
41908
42066
  import parse from "bash-parser";
41909
- function buildDedupeKey(category, operator, path78) {
41910
- return `${category}|${operator}|${path78 ?? "null"}`;
42067
+ function buildDedupeKey(category, operator, path79) {
42068
+ return `${category}|${operator}|${path79 ?? "null"}`;
41911
42069
  }
41912
42070
  var REDIRECT_WRITE_TOKENS = new Set([
41913
42071
  "GREAT",
@@ -41967,16 +42125,16 @@ function detectProcessSubstitutionWrites(command) {
41967
42125
  results.push(builtinResult);
41968
42126
  const appendMatch = stage.match(/^\s*(.*?)\s*>>(\s*)(\S+)\s*$/);
41969
42127
  if (appendMatch) {
41970
- const path78 = appendMatch[3];
41971
- if (path78 && !isNullDevice(path78)) {
41972
- results.push({ category: "redirect", operator: ">>", path: path78 });
42128
+ const path79 = appendMatch[3];
42129
+ if (path79 && !isNullDevice(path79)) {
42130
+ results.push({ category: "redirect", operator: ">>", path: path79 });
41973
42131
  }
41974
42132
  } else {
41975
42133
  const writeMatch = stage.match(/^\s*(.*?)\s*>(?!>)(\s*)(\S+)\s*$/);
41976
42134
  if (writeMatch) {
41977
- const path78 = writeMatch[3];
41978
- if (path78 && !isNullDevice(path78)) {
41979
- results.push({ category: "redirect", operator: ">", path: path78 });
42135
+ const path79 = writeMatch[3];
42136
+ if (path79 && !isNullDevice(path79)) {
42137
+ results.push({ category: "redirect", operator: ">", path: path79 });
41980
42138
  }
41981
42139
  }
41982
42140
  }
@@ -42150,8 +42308,8 @@ function extractRedirectPath(fileNode) {
42150
42308
  return null;
42151
42309
  return text;
42152
42310
  }
42153
- function isNullDevice(path78) {
42154
- return path78 === "/dev/null" || path78 === "/dev/zero" || path78 === "/dev/urandom";
42311
+ function isNullDevice(path79) {
42312
+ return path79 === "/dev/null" || path79 === "/dev/zero" || path79 === "/dev/urandom";
42155
42313
  }
42156
42314
  function isNumeric(s) {
42157
42315
  return /^\d+$/.test(s);
@@ -42171,12 +42329,12 @@ function detectRedirects(cmd) {
42171
42329
  if (!opType || !REDIRECT_ALL_WRITE_TOKENS.has(opType))
42172
42330
  continue;
42173
42331
  const fileNode = r.file;
42174
- const path78 = extractRedirectPath(fileNode);
42332
+ const path79 = extractRedirectPath(fileNode);
42175
42333
  const opLabel = operatorLabel(opNode);
42176
42334
  if (REDIRECT_WRITE_TOKENS.has(opType)) {
42177
- results.push({ category: "redirect", operator: opLabel, path: path78 });
42335
+ results.push({ category: "redirect", operator: opLabel, path: path79 });
42178
42336
  } else if (REDIRECT_HERE_TOKENS.has(opType)) {
42179
- results.push({ category: "here_doc", operator: opLabel, path: path78 });
42337
+ results.push({ category: "here_doc", operator: opLabel, path: path79 });
42180
42338
  }
42181
42339
  }
42182
42340
  return results;
@@ -42219,9 +42377,9 @@ function detectBuiltinWrites(cmd) {
42219
42377
  const suffixWords2 = getSuffixWords(cmd);
42220
42378
  for (const word of suffixWords2) {
42221
42379
  if (word.startsWith("of=")) {
42222
- const path78 = word.slice(3);
42223
- if (path78 && !isNullDevice(path78)) {
42224
- results.push({ category: "builtin_write", operator: "dd of=", path: path78 });
42380
+ const path79 = word.slice(3);
42381
+ if (path79 && !isNullDevice(path79)) {
42382
+ results.push({ category: "builtin_write", operator: "dd of=", path: path79 });
42225
42383
  }
42226
42384
  }
42227
42385
  }
@@ -42340,12 +42498,12 @@ function detectNetworkDownloaders(cmd) {
42340
42498
  for (let i = 0;i < suffixWords.length; i++) {
42341
42499
  const word = suffixWords[i];
42342
42500
  if (word === "-o" && i + 1 < suffixWords.length) {
42343
- const path78 = suffixWords[i + 1];
42344
- if (!path78.startsWith("-")) {
42501
+ const path79 = suffixWords[i + 1];
42502
+ if (!path79.startsWith("-")) {
42345
42503
  results.push({
42346
42504
  category: "network_download",
42347
42505
  operator: "curl -o",
42348
- path: path78
42506
+ path: path79
42349
42507
  });
42350
42508
  }
42351
42509
  } else if (word.startsWith("-o") && word.length > 2) {
@@ -42360,12 +42518,12 @@ function detectNetworkDownloaders(cmd) {
42360
42518
  for (let i = 0;i < suffixWords.length; i++) {
42361
42519
  const word = suffixWords[i];
42362
42520
  if (word === "-O" && i + 1 < suffixWords.length) {
42363
- const path78 = suffixWords[i + 1];
42364
- if (!path78.startsWith("-")) {
42521
+ const path79 = suffixWords[i + 1];
42522
+ if (!path79.startsWith("-")) {
42365
42523
  results.push({
42366
42524
  category: "network_download",
42367
42525
  operator: "wget -O",
42368
- path: path78
42526
+ path: path79
42369
42527
  });
42370
42528
  }
42371
42529
  } else if (word.startsWith("-O") && word.length > 2) {
@@ -42474,9 +42632,9 @@ function detectGitDestructive(cmd) {
42474
42632
  if (first === "checkout") {
42475
42633
  const dashDashIdx = suffixWords.indexOf("--");
42476
42634
  if (dashDashIdx !== -1 && dashDashIdx + 1 < suffixWords.length) {
42477
- const path78 = suffixWords[dashDashIdx + 1];
42478
- const op = path78 === "." ? "git checkout -- ." : "git checkout --";
42479
- results.push({ category: "git_destructive", operator: op, path: path78 });
42635
+ const path79 = suffixWords[dashDashIdx + 1];
42636
+ const op = path79 === "." ? "git checkout -- ." : "git checkout --";
42637
+ results.push({ category: "git_destructive", operator: op, path: path79 });
42480
42638
  }
42481
42639
  } else if (first === "restore") {
42482
42640
  const hasHard = suffixWords.some((w) => w === "--hard" || w === "-H" || w.startsWith("-") && w.includes("H"));
@@ -42596,10 +42754,10 @@ function detectPowerShellWrites(command) {
42596
42754
  if (redirectMatch) {
42597
42755
  const beforeRedirect = redirectMatch[1];
42598
42756
  const op = redirectMatch[2];
42599
- const path78 = redirectMatch[3];
42757
+ const path79 = redirectMatch[3];
42600
42758
  const fdRedirectPattern = /\d>\s*$|\s\d>&$/;
42601
42759
  if (!fdRedirectPattern.test(`${beforeRedirect} ${op}`)) {
42602
- results.push({ category: "redirect", operator: op, path: path78 });
42760
+ results.push({ category: "redirect", operator: op, path: path79 });
42603
42761
  }
42604
42762
  }
42605
42763
  const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
@@ -42612,12 +42770,12 @@ function detectPowerShellWrites(command) {
42612
42770
  }
42613
42771
  const iwrMatch = trimmed.match(/^(?:Invoke-WebRequest|curl)\s.*?(?:-OutFile\s+(\S+)|-o\s+(\S+))/i);
42614
42772
  if (iwrMatch) {
42615
- const path78 = iwrMatch[1] || iwrMatch[2];
42616
- if (path78) {
42773
+ const path79 = iwrMatch[1] || iwrMatch[2];
42774
+ if (path79) {
42617
42775
  results.push({
42618
42776
  category: "network_download",
42619
42777
  operator: "Invoke-WebRequest -OutFile",
42620
- path: path78
42778
+ path: path79
42621
42779
  });
42622
42780
  }
42623
42781
  }
@@ -42629,15 +42787,15 @@ function detectPowerShellWrites(command) {
42629
42787
  const rest = cmd.slice(cmdletMatch[0].length).trim();
42630
42788
  const pathFlagMatch = rest.match(/(?:-Path|-FilePath|-LiteralPath)\s+("([^"]+)"|'([^']+)'|(\S+))/i);
42631
42789
  if (pathFlagMatch) {
42632
- const path78 = pathFlagMatch[2] ?? pathFlagMatch[3] ?? pathFlagMatch[4] ?? "";
42633
- return { category: "redirect", operator: cmdletName, path: path78 };
42790
+ const path79 = pathFlagMatch[2] ?? pathFlagMatch[3] ?? pathFlagMatch[4] ?? "";
42791
+ return { category: "redirect", operator: cmdletName, path: path79 };
42634
42792
  }
42635
42793
  const tokens = rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
42636
42794
  for (const token of tokens) {
42637
42795
  if (token.startsWith("-"))
42638
42796
  continue;
42639
- const path78 = token.replace(/^["']|["']$/g, "");
42640
- return { category: "redirect", operator: cmdletName, path: path78 };
42797
+ const path79 = token.replace(/^["']|["']$/g, "");
42798
+ return { category: "redirect", operator: cmdletName, path: path79 };
42641
42799
  }
42642
42800
  return null;
42643
42801
  }
@@ -42653,9 +42811,9 @@ function detectPowerShellWrites(command) {
42653
42811
  for (const token of tokens) {
42654
42812
  if (token.startsWith("-"))
42655
42813
  continue;
42656
- const path78 = token.replace(/^["']|["']$/g, "");
42657
- if (path78) {
42658
- results.push({ category: "redirect", operator: cmdletName, path: path78 });
42814
+ const path79 = token.replace(/^["']|["']$/g, "");
42815
+ if (path79) {
42816
+ results.push({ category: "redirect", operator: cmdletName, path: path79 });
42659
42817
  break;
42660
42818
  }
42661
42819
  }
@@ -42668,8 +42826,8 @@ function detectPowerShellWrites(command) {
42668
42826
  const rest = cmd.slice(opMatch[0].length).trim();
42669
42827
  const destFlagMatch = rest.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);
42670
42828
  if (destFlagMatch) {
42671
- const path78 = destFlagMatch[1].replace(/^["']|["']$/g, "");
42672
- return { category: "builtin_write", operator: cmdletName, path: path78 };
42829
+ const path79 = destFlagMatch[1].replace(/^["']|["']$/g, "");
42830
+ return { category: "builtin_write", operator: cmdletName, path: path79 };
42673
42831
  }
42674
42832
  const tokens = [];
42675
42833
  const flagTakingValue = new Set([
@@ -42708,11 +42866,11 @@ function detectPowerShellWrites(command) {
42708
42866
  }
42709
42867
  }
42710
42868
  if (tokens.length >= 2) {
42711
- const path78 = tokens[tokens.length - 1].replace(/^["']|["']$/g, "");
42712
- return { category: "builtin_write", operator: cmdletName, path: path78 };
42869
+ const path79 = tokens[tokens.length - 1].replace(/^["']|["']$/g, "");
42870
+ return { category: "builtin_write", operator: cmdletName, path: path79 };
42713
42871
  } else if (tokens.length === 1) {
42714
- const path78 = tokens[0].replace(/^["']|["']$/g, "");
42715
- return { category: "builtin_write", operator: cmdletName, path: path78 };
42872
+ const path79 = tokens[0].replace(/^["']|["']$/g, "");
42873
+ return { category: "builtin_write", operator: cmdletName, path: path79 };
42716
42874
  }
42717
42875
  return null;
42718
42876
  }
@@ -42726,14 +42884,14 @@ function detectPowerShellWrites(command) {
42726
42884
  const afterCmdlet = pipeFileOpMatch[2].trim();
42727
42885
  const destFlagMatch = afterCmdlet.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);
42728
42886
  if (destFlagMatch) {
42729
- const path78 = destFlagMatch[1].replace(/^["']|["']$/g, "");
42730
- results.push({ category: "builtin_write", operator: cmdletName, path: path78 });
42887
+ const path79 = destFlagMatch[1].replace(/^["']|["']$/g, "");
42888
+ results.push({ category: "builtin_write", operator: cmdletName, path: path79 });
42731
42889
  } else {
42732
42890
  const tokens = afterCmdlet.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
42733
42891
  const nonFlagTokens = tokens.filter((t) => !t.startsWith("-") && t.length > 0);
42734
42892
  if (nonFlagTokens.length > 0) {
42735
- const path78 = nonFlagTokens[nonFlagTokens.length - 1].replace(/^["']|["']$/g, "");
42736
- results.push({ category: "builtin_write", operator: cmdletName, path: path78 });
42893
+ const path79 = nonFlagTokens[nonFlagTokens.length - 1].replace(/^["']|["']$/g, "");
42894
+ results.push({ category: "builtin_write", operator: cmdletName, path: path79 });
42737
42895
  }
42738
42896
  }
42739
42897
  }
@@ -42786,10 +42944,10 @@ function detectCmdWrites(command) {
42786
42944
  if (redirectMatch) {
42787
42945
  const beforeRedirect = redirectMatch[1];
42788
42946
  const op = redirectMatch[2];
42789
- const path78 = redirectMatch[3];
42947
+ const path79 = redirectMatch[3];
42790
42948
  const fdRedirectPattern = /\d>&?$/;
42791
42949
  if (!fdRedirectPattern.test(beforeRedirect)) {
42792
- results.push({ category: "redirect", operator: op, path: path78 });
42950
+ results.push({ category: "redirect", operator: op, path: path79 });
42793
42951
  }
42794
42952
  }
42795
42953
  const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
@@ -42847,8 +43005,8 @@ function detectCmdWrites(command) {
42847
43005
  const rawTokens = rest.match(/(\/?[^\s]+|"[^"]*"|'[^']*')/g) ?? [];
42848
43006
  const tokens = rawTokens.filter((t) => !t.startsWith("/"));
42849
43007
  if (tokens.length > 0) {
42850
- const path78 = tokens[0].replace(/^["']|["']$/g, "");
42851
- return { category: "builtin_write", operator: "del", path: path78 };
43008
+ const path79 = tokens[0].replace(/^["']|["']$/g, "");
43009
+ return { category: "builtin_write", operator: "del", path: path79 };
42852
43010
  }
42853
43011
  return null;
42854
43012
  }
@@ -42858,16 +43016,16 @@ function detectCmdWrites(command) {
42858
43016
  }
42859
43017
  const rdMatch = innerCommand.match(/^rd\s+(?:\/s\s+|\/q\s+)*(\S+)/i);
42860
43018
  if (rdMatch) {
42861
- const path78 = rdMatch[1].replace(/^["']|["']$/g, "");
42862
- if (!path78.startsWith("/")) {
42863
- results.push({ category: "builtin_write", operator: "rd", path: path78 });
43019
+ const path79 = rdMatch[1].replace(/^["']|["']$/g, "");
43020
+ if (!path79.startsWith("/")) {
43021
+ results.push({ category: "builtin_write", operator: "rd", path: path79 });
42864
43022
  }
42865
43023
  }
42866
43024
  const mdMatch = trimmed.match(/^md\s+(\S+)/i);
42867
43025
  if (mdMatch) {
42868
- const path78 = mdMatch[1].replace(/^["']|["']$/g, "");
42869
- if (!path78.startsWith("/")) {
42870
- results.push({ category: "builtin_write", operator: "md", path: path78 });
43026
+ const path79 = mdMatch[1].replace(/^["']|["']$/g, "");
43027
+ if (!path79.startsWith("/")) {
43028
+ results.push({ category: "builtin_write", operator: "md", path: path79 });
42871
43029
  }
42872
43030
  }
42873
43031
  const echoMatch = trimmed.match(/^echo\s+(\S+.*?)\s+((?:>){1,2})\s*(\S+)$/i);
@@ -42983,10 +43141,10 @@ function resolvePath(pathText, cwd) {
42983
43141
  return null;
42984
43142
  const isWindowsPath = /^[a-zA-Z]:[\\\\/]/.test(cwd) || cwd.includes("\\");
42985
43143
  if (isWindowsPath) {
42986
- return path77.win32.resolve(cwd, pathText);
43144
+ return path78.win32.resolve(cwd, pathText);
42987
43145
  }
42988
- const normalizedRelativeWindowsPath = !path77.posix.isAbsolute(pathText) && !/^[a-zA-Z]:[\\/]/.test(pathText) ? pathText.replace(/\\/g, "/") : pathText;
42989
- return path77.posix.resolve(cwd, normalizedRelativeWindowsPath);
43146
+ const normalizedRelativeWindowsPath = !path78.posix.isAbsolute(pathText) && !/^[a-zA-Z]:[\\/]/.test(pathText) ? pathText.replace(/\\/g, "/") : pathText;
43147
+ return path78.posix.resolve(cwd, normalizedRelativeWindowsPath);
42990
43148
  }
42991
43149
  function getCdTarget(cmd) {
42992
43150
  if (!cmd || typeof cmd !== "object")
@@ -43053,7 +43211,7 @@ function collectWritesWithNodes(node, out, cwdStack) {
43053
43211
  for (const cmd of node.commands) {
43054
43212
  const cdTarget = getCdTarget(cmd);
43055
43213
  if (cdTarget) {
43056
- currentStack[0] = path77.posix.resolve(currentStack[0] ?? "/", cdTarget);
43214
+ currentStack[0] = path78.posix.resolve(currentStack[0] ?? "/", cdTarget);
43057
43215
  collectWritesWithNodes(cmd, out, currentStack);
43058
43216
  } else {
43059
43217
  collectWritesWithNodes(cmd, out, currentStack);
@@ -43099,7 +43257,7 @@ function collectWritesWithNodes(node, out, cwdStack) {
43099
43257
  const effectiveCwd = cwdStack[0] ?? "/";
43100
43258
  const cdTarget = getCdTarget(node);
43101
43259
  if (cdTarget) {
43102
- cwdStack[0] = path77.posix.resolve(cwdStack[0] ?? "/", cdTarget);
43260
+ cwdStack[0] = path78.posix.resolve(cwdStack[0] ?? "/", cdTarget);
43103
43261
  return;
43104
43262
  }
43105
43263
  const writesFromRedirs = getWritesFromCommandRedirs(node, effectiveCwd);
@@ -43145,12 +43303,12 @@ function getWritesFromRedirectNode(redirect, _context) {
43145
43303
  if (!opType || !REDIRECT_ALL_WRITE_TOKENS.has(opType))
43146
43304
  return [];
43147
43305
  const fileNode = r.file;
43148
- const path78 = extractRedirectPath(fileNode);
43306
+ const path79 = extractRedirectPath(fileNode);
43149
43307
  const opLabel = operatorLabel(opNode);
43150
43308
  if (REDIRECT_WRITE_TOKENS.has(opType)) {
43151
- return [{ category: "redirect", operator: opLabel, path: path78 }];
43309
+ return [{ category: "redirect", operator: opLabel, path: path79 }];
43152
43310
  } else if (REDIRECT_HERE_TOKENS.has(opType)) {
43153
- return [{ category: "here_doc", operator: opLabel, path: path78 }];
43311
+ return [{ category: "here_doc", operator: opLabel, path: path79 }];
43154
43312
  }
43155
43313
  return [];
43156
43314
  }
@@ -43541,10 +43699,10 @@ function startAgentSession(sessionId, agentName, staleDurationMs = STALE_SESSION
43541
43699
  }
43542
43700
  telemetry.sessionStarted(sessionId, agentName);
43543
43701
  swarmState.activeAgent.set(sessionId, agentName);
43544
- _internals60.applyRehydrationCache(sessionState);
43702
+ _internals61.applyRehydrationCache(sessionState);
43545
43703
  if (directory) {
43546
43704
  let rehydrationPromise;
43547
- rehydrationPromise = _internals60.rehydrateSessionFromDisk(directory, sessionState).then(async () => {
43705
+ rehydrationPromise = _internals61.rehydrateSessionFromDisk(directory, sessionState).then(async () => {
43548
43706
  try {
43549
43707
  sessionState.prSubscriptions = await rehydratePrSubscriptions(sessionId, directory);
43550
43708
  } catch (err) {
@@ -43725,7 +43883,7 @@ function ensureAgentSession(sessionId, agentName, directory) {
43725
43883
  maybeSweepStaleSessions();
43726
43884
  return session;
43727
43885
  }
43728
- _internals60.startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
43886
+ _internals61.startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
43729
43887
  session = swarmState.agentSessions.get(sessionId);
43730
43888
  if (!session) {
43731
43889
  throw new Error(`Failed to create guardrail session for ${sessionId}`);
@@ -43903,8 +44061,8 @@ function evidenceToWorkflowState(evidence) {
43903
44061
  }
43904
44062
  async function readPlanFromDisk(directory) {
43905
44063
  try {
43906
- const planPath = path78.join(directory, ".swarm", "plan.json");
43907
- const content = await fs40.readFile(planPath, "utf-8");
44064
+ const planPath = path79.join(directory, ".swarm", "plan.json");
44065
+ const content = await fs41.readFile(planPath, "utf-8");
43908
44066
  const parsed = JSON.parse(content);
43909
44067
  return PlanSchema.parse(parsed);
43910
44068
  } catch {
@@ -43914,8 +44072,8 @@ async function readPlanFromDisk(directory) {
43914
44072
  async function readGateEvidenceFromDisk(directory) {
43915
44073
  const evidenceMap = new Map;
43916
44074
  try {
43917
- const evidenceDir = path78.join(directory, ".swarm", "evidence");
43918
- const entries = await fs40.readdir(evidenceDir, { withFileTypes: true });
44075
+ const evidenceDir = path79.join(directory, ".swarm", "evidence");
44076
+ const entries = await fs41.readdir(evidenceDir, { withFileTypes: true });
43919
44077
  for (const entry of entries) {
43920
44078
  if (!entry.isFile() || !entry.name.endsWith(".json")) {
43921
44079
  continue;
@@ -43925,8 +44083,8 @@ async function readGateEvidenceFromDisk(directory) {
43925
44083
  continue;
43926
44084
  }
43927
44085
  try {
43928
- const filePath = path78.join(evidenceDir, entry.name);
43929
- const content = await fs40.readFile(filePath, "utf-8");
44086
+ const filePath = path79.join(evidenceDir, entry.name);
44087
+ const content = await fs41.readFile(filePath, "utf-8");
43930
44088
  const parsed = JSON.parse(content);
43931
44089
  if (parsed && typeof parsed.taskId === "string" && Array.isArray(parsed.required_gates)) {
43932
44090
  evidenceMap.set(taskId, parsed);
@@ -44013,8 +44171,8 @@ function applyRehydrationCache(session) {
44013
44171
  }
44014
44172
  }
44015
44173
  async function rehydrateSessionFromDisk(directory, session) {
44016
- await _internals60.buildRehydrationCache(directory);
44017
- _internals60.applyRehydrationCache(session);
44174
+ await _internals61.buildRehydrationCache(directory);
44175
+ _internals61.applyRehydrationCache(session);
44018
44176
  }
44019
44177
  function hasActiveTurboMode(sessionID) {
44020
44178
  if (sessionID) {
@@ -44081,7 +44239,7 @@ function hasActiveEpicMode(sessionID) {
44081
44239
  async function rehydratePrSubscriptions(sessionID, directory) {
44082
44240
  const map = new Map;
44083
44241
  try {
44084
- const { listActive: listActive2 } = await import("./pr-subscriptions-cny2jz2d.js");
44242
+ const { listActive: listActive2 } = await import("./pr-subscriptions-8a6jwek2.js");
44085
44243
  const records = await listActive2(directory);
44086
44244
  for (const record of records) {
44087
44245
  if (record.sessionID !== sessionID)
@@ -44102,7 +44260,7 @@ async function rehydratePrSubscriptions(sessionID, directory) {
44102
44260
  }
44103
44261
  return map;
44104
44262
  }
44105
- var _internals60 = {
44263
+ var _internals61 = {
44106
44264
  swarmState,
44107
44265
  resetSwarmState,
44108
44266
  ensureAgentSession,
@@ -44241,4 +44399,4 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
44241
44399
  };
44242
44400
  }
44243
44401
 
44244
- export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals13 as _internals, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, checkHivePromotions, _internals15 as _internals1, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleGateAuditCommand, handleGateStatsCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals57 as _internals2, resolveCommand };
44402
+ export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals13 as _internals, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, checkHivePromotions, _internals15 as _internals1, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleGateAuditCommand, handleGateStatsCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals58 as _internals2, resolveCommand };