opencode-swarm 7.92.0 → 7.93.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.
@@ -906,7 +906,7 @@ var init_executor = __esm(() => {
906
906
  // package.json
907
907
  var package_default = {
908
908
  name: "opencode-swarm",
909
- version: "7.92.0",
909
+ version: "7.93.1",
910
910
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
911
911
  main: "dist/index.js",
912
912
  types: "dist/index.d.ts",
@@ -5785,8 +5785,8 @@ async function handleClarifyCommand(_directory, args) {
5785
5785
  // src/commands/close.ts
5786
5786
  import { spawnSync as spawnSync5 } from "child_process";
5787
5787
  import * as fsSync2 from "fs";
5788
- import { promises as fs11 } from "fs";
5789
- import path24 from "path";
5788
+ import { promises as fs12 } from "fs";
5789
+ import path25 from "path";
5790
5790
 
5791
5791
  // src/hooks/abort-utils.ts
5792
5792
  function isAbortError(err) {
@@ -9903,10 +9903,9 @@ var _internals17 = {
9903
9903
  MAX_TRACKED_RETRO_SECTIONS
9904
9904
  };
9905
9905
 
9906
- // src/services/skill-improver.ts
9907
- import { existsSync as existsSync12 } from "fs";
9908
- import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as writeFile7 } from "fs/promises";
9909
- import * as path23 from "path";
9906
+ // src/services/session-reflection.ts
9907
+ import { promises as fs11 } from "fs";
9908
+ import * as path22 from "path";
9910
9909
 
9911
9910
  // src/hooks/skill-improver-llm-factory.ts
9912
9911
  function resolveSkillImproverAgentName(sessionId) {
@@ -10014,12 +10013,296 @@ ${userInput}` : userInput;
10014
10013
  };
10015
10014
  }
10016
10015
 
10016
+ // src/services/session-reflection.ts
10017
+ function gatherToolProblems(toolAggregates) {
10018
+ let totalCalls = 0;
10019
+ let totalFailures = 0;
10020
+ const problems = [];
10021
+ for (const [, agg] of toolAggregates) {
10022
+ totalCalls += agg.count;
10023
+ totalFailures += agg.failureCount;
10024
+ if (agg.failureCount > 0 && agg.count > 0) {
10025
+ const failureRate = agg.failureCount / agg.count;
10026
+ if (failureRate > 0.2 || agg.failureCount > 2) {
10027
+ problems.push({
10028
+ tool: agg.tool,
10029
+ failureCount: agg.failureCount,
10030
+ totalCalls: agg.count,
10031
+ failureRate: Math.round(failureRate * 100) / 100,
10032
+ avgDurationMs: Math.round(agg.totalDuration / agg.count)
10033
+ });
10034
+ }
10035
+ }
10036
+ }
10037
+ problems.sort((a, b) => b.failureCount - a.failureCount);
10038
+ return { problems, totalCalls, totalFailures };
10039
+ }
10040
+ function gatherAgentDispatches(agentSessions) {
10041
+ const agentCounts = new Map;
10042
+ for (const [, session] of agentSessions) {
10043
+ const name = session.agentName;
10044
+ const existing = agentCounts.get(name) ?? { count: 0 };
10045
+ existing.count++;
10046
+ if (session.lastDelegationReason) {
10047
+ existing.lastReason = session.lastDelegationReason;
10048
+ }
10049
+ agentCounts.set(name, existing);
10050
+ }
10051
+ return [...agentCounts.entries()].map(([agent, data]) => ({
10052
+ agent,
10053
+ delegationCount: data.count,
10054
+ lastDelegationReason: data.lastReason
10055
+ })).sort((a, b) => b.delegationCount - a.delegationCount);
10056
+ }
10057
+ async function gatherRetroLessonsAndTaxonomy(directory) {
10058
+ const lessons = [];
10059
+ const taxonomy = {};
10060
+ try {
10061
+ const evidenceDir = path22.join(directory, ".swarm", "evidence");
10062
+ const entries = await fs11.readdir(evidenceDir);
10063
+ const retroDirs = entries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
10064
+ for (const retroDir of retroDirs) {
10065
+ const evidencePath = path22.join(evidenceDir, retroDir, "evidence.json");
10066
+ try {
10067
+ const content = await fs11.readFile(evidencePath, "utf-8");
10068
+ const parsed = JSON.parse(content);
10069
+ const bundleEntries = parsed.entries ?? [parsed];
10070
+ for (const entry of bundleEntries) {
10071
+ if (Array.isArray(entry.lessons_learned)) {
10072
+ for (const lesson of entry.lessons_learned) {
10073
+ if (typeof lesson === "string" && lesson.trim().length > 0) {
10074
+ lessons.push(lesson.trim());
10075
+ }
10076
+ }
10077
+ }
10078
+ if (entry.error_taxonomy && typeof entry.error_taxonomy === "object") {
10079
+ for (const [key, val] of Object.entries(entry.error_taxonomy)) {
10080
+ if (typeof val === "number") {
10081
+ taxonomy[key] = (taxonomy[key] ?? 0) + val;
10082
+ }
10083
+ }
10084
+ }
10085
+ }
10086
+ } catch {}
10087
+ }
10088
+ } catch {}
10089
+ return { lessons: [...new Set(lessons)], taxonomy };
10090
+ }
10091
+ async function gatherGateFailures(directory) {
10092
+ const failures = new Map;
10093
+ try {
10094
+ const evidenceDir = path22.join(directory, ".swarm", "evidence");
10095
+ const entries = await fs11.readdir(evidenceDir);
10096
+ for (const entry of entries) {
10097
+ if (entry.startsWith("retro-"))
10098
+ continue;
10099
+ const evidencePath = path22.join(evidenceDir, entry, "evidence.json");
10100
+ try {
10101
+ const content = await fs11.readFile(evidencePath, "utf-8");
10102
+ const parsed = JSON.parse(content);
10103
+ const bundleEntries = parsed.entries ?? [parsed];
10104
+ for (const e of bundleEntries) {
10105
+ if (e.verdict === "fail" || e.verdict === "REJECT") {
10106
+ const gate = e.agent ?? e.type ?? "unknown";
10107
+ const taskId = entry;
10108
+ const key = `${gate}:${taskId}`;
10109
+ const existing = failures.get(key) ?? {
10110
+ gate,
10111
+ taskId,
10112
+ count: 0
10113
+ };
10114
+ existing.count++;
10115
+ failures.set(key, existing);
10116
+ }
10117
+ }
10118
+ } catch {}
10119
+ }
10120
+ } catch {}
10121
+ return [...failures.values()].sort((a, b) => b.count - a.count);
10122
+ }
10123
+ function buildReflectionDataSummary(data) {
10124
+ const lines = [];
10125
+ lines.push("SESSION DATA SNAPSHOT");
10126
+ lines.push(`Total tool calls: ${data.totalToolCalls}`);
10127
+ lines.push(`Total tool failures: ${data.totalToolFailures}`);
10128
+ if (data.totalToolCalls > 0) {
10129
+ lines.push(`Overall failure rate: ${Math.round(data.totalToolFailures / data.totalToolCalls * 100)}%`);
10130
+ }
10131
+ lines.push("");
10132
+ if (data.toolProblems.length > 0) {
10133
+ lines.push("TOOL PROBLEMS (tools with >20% failure rate or >2 failures):");
10134
+ for (const p of data.toolProblems) {
10135
+ lines.push(` - ${p.tool}: ${p.failureCount}/${p.totalCalls} failures (${Math.round(p.failureRate * 100)}%), avg ${p.avgDurationMs}ms`);
10136
+ }
10137
+ lines.push("");
10138
+ }
10139
+ if (data.agentDispatches.length > 0) {
10140
+ lines.push("AGENT DISPATCHES:");
10141
+ for (const a of data.agentDispatches) {
10142
+ const reason = a.lastDelegationReason ? ` (last reason: ${a.lastDelegationReason})` : "";
10143
+ lines.push(` - ${a.agent}: ${a.delegationCount} delegation(s)${reason}`);
10144
+ }
10145
+ lines.push("");
10146
+ }
10147
+ if (data.gateFailures.length > 0) {
10148
+ lines.push("GATE FAILURES:");
10149
+ for (const gf of data.gateFailures) {
10150
+ lines.push(` - ${gf.gate} on task ${gf.taskId}: ${gf.count} failure(s)`);
10151
+ }
10152
+ lines.push("");
10153
+ }
10154
+ const taxonomyEntries = Object.entries(data.errorTaxonomy).sort((a, b) => b[1] - a[1]);
10155
+ if (taxonomyEntries.length > 0) {
10156
+ lines.push("ERROR TAXONOMY (from phase retrospectives):");
10157
+ for (const [category, count] of taxonomyEntries) {
10158
+ lines.push(` - ${category}: ${count}`);
10159
+ }
10160
+ lines.push("");
10161
+ }
10162
+ if (data.lessonsFromRetros.length > 0) {
10163
+ lines.push("LESSONS FROM RETROSPECTIVES:");
10164
+ for (const lesson of data.lessonsFromRetros) {
10165
+ lines.push(` - ${lesson}`);
10166
+ }
10167
+ lines.push("");
10168
+ }
10169
+ return lines.join(`
10170
+ `);
10171
+ }
10172
+ var REFLECTION_SYSTEM_PROMPT = `You are the architect reviewing a completed swarm session. Your job is to analyze what happened and produce a concise, actionable report for the human operator.
10173
+
10174
+ You have been given the full session telemetry: tool call statistics, agent dispatches, gate failures, error taxonomy, and lessons from phase retrospectives.
10175
+
10176
+ Your report MUST include these sections (omit a section only if there is genuinely nothing to say):
10177
+
10178
+ ## Problems Encountered
10179
+ What went wrong during this session? Tool failures, repeated gate rejections, error patterns. Be specific \u2014 name the tools, the error categories, the tasks affected. If nothing went wrong, say so clearly.
10180
+
10181
+ ## Tools That Didn't Work
10182
+ Which tools had high failure rates or were slow? What was the likely cause? What should the operator or the swarm do differently next time?
10183
+
10184
+ ## Skill Recommendations
10185
+ Based on everything that happened in this session, should any existing skills be updated or new skills be created? Be specific: name the skill, describe the change, and explain why. Consider:
10186
+ - Patterns that repeated across multiple tasks or phases
10187
+ - Workarounds the agents had to use
10188
+ - Knowledge gaps the agents exposed
10189
+ - Conventions the session revealed that aren't captured in any skill
10190
+
10191
+ ## Process Improvements
10192
+ What should the swarm do differently next time? Dispatch patterns, gate configurations, agent routing, phase structure \u2014 anything the architect should learn from this session.
10193
+
10194
+ Keep the report under 3000 characters. Be direct. No filler. Every sentence should be actionable or provide specific evidence. If the session was clean with no issues, say so in 2-3 sentences and skip the detailed sections.`;
10195
+ function buildDeterministicReport(data) {
10196
+ const lines = [];
10197
+ lines.push("## Problems Encountered");
10198
+ lines.push("");
10199
+ if (data.totalToolFailures === 0 && data.gateFailures.length === 0) {
10200
+ lines.push("No tool failures or gate rejections recorded this session.");
10201
+ lines.push("");
10202
+ } else {
10203
+ if (data.totalToolFailures > 0) {
10204
+ const rate = data.totalToolCalls > 0 ? Math.round(data.totalToolFailures / data.totalToolCalls * 100) : 0;
10205
+ lines.push(`${data.totalToolFailures} tool failure(s) across ${data.totalToolCalls} calls (${rate}% failure rate).`);
10206
+ }
10207
+ if (data.gateFailures.length > 0) {
10208
+ lines.push(`${data.gateFailures.length} gate failure(s) recorded:`);
10209
+ for (const gf of data.gateFailures.slice(0, 5)) {
10210
+ lines.push(`- ${gf.gate} on task ${gf.taskId} (${gf.count}x)`);
10211
+ }
10212
+ }
10213
+ const taxonomyEntries = Object.entries(data.errorTaxonomy).sort((a, b) => b[1] - a[1]);
10214
+ if (taxonomyEntries.length > 0) {
10215
+ lines.push("");
10216
+ lines.push("Error patterns:");
10217
+ for (const [cat, count] of taxonomyEntries) {
10218
+ lines.push(`- ${cat}: ${count} occurrence(s)`);
10219
+ }
10220
+ }
10221
+ lines.push("");
10222
+ }
10223
+ if (data.toolProblems.length > 0) {
10224
+ lines.push("## Tools That Didn't Work");
10225
+ lines.push("");
10226
+ for (const p of data.toolProblems) {
10227
+ lines.push(`- **${p.tool}**: ${p.failureCount}/${p.totalCalls} failures (${Math.round(p.failureRate * 100)}%), avg ${p.avgDurationMs}ms per call`);
10228
+ }
10229
+ lines.push("");
10230
+ }
10231
+ if (data.lessonsFromRetros.length > 0) {
10232
+ lines.push("## Skill Recommendations");
10233
+ lines.push("");
10234
+ lines.push("The following lessons were captured during the session. Review them for skill creation/update opportunities:");
10235
+ for (const lesson of data.lessonsFromRetros) {
10236
+ lines.push(`- ${lesson}`);
10237
+ }
10238
+ lines.push("");
10239
+ }
10240
+ lines.push("## Process Improvements");
10241
+ lines.push("");
10242
+ if (data.totalToolFailures === 0 && data.gateFailures.length === 0 && data.lessonsFromRetros.length === 0) {
10243
+ lines.push("Session completed without notable issues.");
10244
+ } else {
10245
+ lines.push("_Deterministic fallback: no LLM client available for deep analysis. Review the data above manually._");
10246
+ }
10247
+ lines.push("");
10248
+ return lines.join(`
10249
+ `);
10250
+ }
10251
+ async function runSessionReflection(input) {
10252
+ const { problems, totalCalls, totalFailures } = gatherToolProblems(input.toolAggregates);
10253
+ const agentDispatches = gatherAgentDispatches(input.agentSessions);
10254
+ const { lessons, taxonomy } = await gatherRetroLessonsAndTaxonomy(input.directory);
10255
+ const gateFailures = await gatherGateFailures(input.directory);
10256
+ const data = {
10257
+ timestamp: new Date().toISOString(),
10258
+ totalToolCalls: totalCalls,
10259
+ totalToolFailures: totalFailures,
10260
+ toolProblems: problems,
10261
+ agentDispatches,
10262
+ gateFailures,
10263
+ lessonsFromRetros: lessons,
10264
+ errorTaxonomy: taxonomy
10265
+ };
10266
+ const delegate = input.delegate ?? createSkillImproverLLMDelegate(input.directory, input.sessionId);
10267
+ if (delegate && !input.signal?.aborted) {
10268
+ try {
10269
+ const dataSummary = buildReflectionDataSummary(data);
10270
+ const report = await delegate(REFLECTION_SYSTEM_PROMPT, dataSummary, input.signal);
10271
+ if (report && report.trim().length > 0) {
10272
+ return { data, architectReport: report.trim(), source: "llm" };
10273
+ }
10274
+ } catch {}
10275
+ }
10276
+ return {
10277
+ data,
10278
+ architectReport: buildDeterministicReport(data),
10279
+ source: "deterministic"
10280
+ };
10281
+ }
10282
+ async function writeSessionReflection(directory, result) {
10283
+ const reflectionPath = validateSwarmPath(directory, "session-reflection.md");
10284
+ const lines = [];
10285
+ lines.push("# Session Reflection");
10286
+ lines.push("");
10287
+ lines.push(`Generated: ${result.data.timestamp}`);
10288
+ lines.push(`Source: ${result.source}`);
10289
+ lines.push("");
10290
+ lines.push(result.architectReport);
10291
+ const content = lines.join(`
10292
+ `);
10293
+ await fs11.writeFile(reflectionPath, content, "utf-8");
10294
+ return reflectionPath;
10295
+ }
10296
+
10017
10297
  // src/services/skill-improver.ts
10298
+ import { existsSync as existsSync12 } from "fs";
10299
+ import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as writeFile7 } from "fs/promises";
10300
+ import * as path24 from "path";
10018
10301
  init_logger();
10019
10302
 
10020
10303
  // src/services/trajectory-cluster.ts
10021
10304
  import { mkdir as mkdir6, writeFile as writeFile6 } from "fs/promises";
10022
- import * as path22 from "path";
10305
+ import * as path23 from "path";
10023
10306
  init_logger();
10024
10307
  var MACRO_TRAJECTORY_WINDOW = 200;
10025
10308
  var MOTIF_MIN_TASKS = 2;
@@ -10151,11 +10434,11 @@ async function writeMotifProposals(directory, opts = {}) {
10151
10434
  if (motifs.length === 0)
10152
10435
  return result;
10153
10436
  const max = opts.maxProposals ?? 10;
10154
- const proposalsDir = validateSwarmPath(directory, path22.join("skills", "proposals"));
10437
+ const proposalsDir = validateSwarmPath(directory, path23.join("skills", "proposals"));
10155
10438
  await mkdir6(proposalsDir, { recursive: true });
10156
10439
  for (const motif of motifs.slice(0, max)) {
10157
10440
  const slug = `motif-${slugify(motif.signature)}`;
10158
- const filePath = path22.join(proposalsDir, `${slug}.md`);
10441
+ const filePath = path23.join(proposalsDir, `${slug}.md`);
10159
10442
  await writeFile6(filePath, buildMotifProposal(motif), "utf-8");
10160
10443
  result.proposalsWritten.push(filePath);
10161
10444
  }
@@ -10296,11 +10579,11 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
10296
10579
  if (motifs.length === 0)
10297
10580
  return result;
10298
10581
  const max = opts.maxProposals ?? 10;
10299
- const proposalsDir = validateSwarmPath(directory, path22.join("skills", "proposals"));
10582
+ const proposalsDir = validateSwarmPath(directory, path23.join("skills", "proposals"));
10300
10583
  await mkdir6(proposalsDir, { recursive: true });
10301
10584
  for (const motif of motifs.slice(0, max)) {
10302
10585
  const slug = workflowSlug(motif.signature);
10303
- const filePath = path22.join(proposalsDir, `${slug}.md`);
10586
+ const filePath = path23.join(proposalsDir, `${slug}.md`);
10304
10587
  await writeFile6(filePath, buildWorkflowProposal(motif), "utf-8");
10305
10588
  result.proposalsWritten.push(filePath);
10306
10589
  }
@@ -10423,7 +10706,7 @@ function timestampSlug(d) {
10423
10706
  return d.toISOString().replace(/[:.]/g, "-");
10424
10707
  }
10425
10708
  async function atomicWrite(p, content) {
10426
- await mkdir7(path23.dirname(p), { recursive: true });
10709
+ await mkdir7(path24.dirname(p), { recursive: true });
10427
10710
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
10428
10711
  await writeFile7(tmp, content, "utf-8");
10429
10712
  await rename3(tmp, p);
@@ -10826,8 +11109,8 @@ async function runSkillImprover(req) {
10826
11109
  }
10827
11110
  throw err;
10828
11111
  }
10829
- const proposalDir = path23.join(req.directory, ".swarm", "skill-improver", "proposals");
10830
- const proposalFile = path23.join(proposalDir, `${timestampSlug(now)}.md`);
11112
+ const proposalDir = path24.join(req.directory, ".swarm", "skill-improver", "proposals");
11113
+ const proposalFile = path24.join(proposalDir, `${timestampSlug(now)}.md`);
10831
11114
  const finalBody = source === "llm" ? buildLLMProposalFrame({
10832
11115
  body,
10833
11116
  targets,
@@ -11250,6 +11533,27 @@ var _internals19 = {
11250
11533
 
11251
11534
  // src/commands/close.ts
11252
11535
  var CLOSE_SKILL_REVIEW_TIMEOUT_MS = 120000;
11536
+ var CLOSE_REFLECTION_TIMEOUT_MS = 90000;
11537
+ async function runAbortableReflection(input, timeoutMs) {
11538
+ const controller = new AbortController;
11539
+ let timeout;
11540
+ const reflectionPromise = runSessionReflection({
11541
+ ...input,
11542
+ signal: controller.signal
11543
+ });
11544
+ const timeoutPromise = new Promise((_, reject) => {
11545
+ timeout = setTimeout(() => {
11546
+ reject(new Error(`session_reflection exceeded ${timeoutMs}ms budget`));
11547
+ controller.abort();
11548
+ }, timeoutMs);
11549
+ });
11550
+ try {
11551
+ return await Promise.race([reflectionPromise, timeoutPromise]);
11552
+ } finally {
11553
+ if (timeout)
11554
+ clearTimeout(timeout);
11555
+ }
11556
+ }
11253
11557
  async function runAbortableSkillReview(req, timeoutMs) {
11254
11558
  const controller = new AbortController;
11255
11559
  let timeout;
@@ -11289,20 +11593,20 @@ function countSessionKnowledgeEntries(entries, sessionStart, fallbackCount) {
11289
11593
  async function copyDirRecursiveWithFailures(src, dest) {
11290
11594
  let count = 0;
11291
11595
  const failures = [];
11292
- const entries = await fs11.readdir(src);
11293
- await fs11.mkdir(dest, { recursive: true });
11596
+ const entries = await fs12.readdir(src);
11597
+ await fs12.mkdir(dest, { recursive: true });
11294
11598
  for (const entry of entries) {
11295
- const srcEntry = path24.join(src, entry);
11296
- const destEntry = path24.join(dest, entry);
11599
+ const srcEntry = path25.join(src, entry);
11600
+ const destEntry = path25.join(dest, entry);
11297
11601
  try {
11298
- const stat4 = await fs11.stat(srcEntry);
11602
+ const stat4 = await fs12.stat(srcEntry);
11299
11603
  if (stat4.isDirectory()) {
11300
11604
  const subResult = await copyDirRecursiveWithFailures(srcEntry, destEntry);
11301
11605
  count += subResult.copied;
11302
11606
  failures.push(...subResult.failures);
11303
11607
  } else {
11304
11608
  try {
11305
- await fs11.copyFile(srcEntry, destEntry);
11609
+ await fs12.copyFile(srcEntry, destEntry);
11306
11610
  count++;
11307
11611
  } catch (err) {
11308
11612
  const errno = err?.code;
@@ -11345,6 +11649,7 @@ var ARCHIVE_ARTIFACTS = [
11345
11649
  "swarm.db-shm",
11346
11650
  "swarm.db-wal",
11347
11651
  "close-summary.md",
11652
+ "session-reflection.md",
11348
11653
  "spec.md"
11349
11654
  ];
11350
11655
  var ACTIVE_STATE_TO_CLEAN = [
@@ -11361,6 +11666,7 @@ var ACTIVE_STATE_TO_CLEAN = [
11361
11666
  "doc-manifest.json",
11362
11667
  "dark-matter.md",
11363
11668
  "telemetry.jsonl",
11669
+ "session-reflection.md",
11364
11670
  "swarm.db",
11365
11671
  "swarm.db-shm",
11366
11672
  "swarm.db-wal"
@@ -11475,20 +11781,20 @@ async function runFinalizeStage(ctx) {
11475
11781
  ctx.warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
11476
11782
  }
11477
11783
  }
11478
- const lessonsFilePath = path24.join(ctx.swarmDir, "close-lessons.md");
11784
+ const lessonsFilePath = path25.join(ctx.swarmDir, "close-lessons.md");
11479
11785
  try {
11480
- const lessonsText = await fs11.readFile(lessonsFilePath, "utf-8");
11786
+ const lessonsText = await fs12.readFile(lessonsFilePath, "utf-8");
11481
11787
  ctx.explicitLessons = lessonsText.split(`
11482
11788
  `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
11483
11789
  } catch {}
11484
11790
  try {
11485
- const evidenceDir = path24.join(ctx.swarmDir, "evidence");
11486
- const evidenceEntries = await fs11.readdir(evidenceDir);
11791
+ const evidenceDir = path25.join(ctx.swarmDir, "evidence");
11792
+ const evidenceEntries = await fs12.readdir(evidenceDir);
11487
11793
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
11488
11794
  for (const retroDir of retroDirs) {
11489
- const evidencePath = path24.join(evidenceDir, retroDir, "evidence.json");
11795
+ const evidencePath = path25.join(evidenceDir, retroDir, "evidence.json");
11490
11796
  try {
11491
- const content = await fs11.readFile(evidencePath, "utf-8");
11797
+ const content = await fs12.readFile(evidencePath, "utf-8");
11492
11798
  const parsed = JSON.parse(content);
11493
11799
  const entries = parsed.entries ?? [parsed];
11494
11800
  for (const entry of entries) {
@@ -11532,7 +11838,7 @@ async function runFinalizeStage(ctx) {
11532
11838
  console.warn("[close-command] curateAndStoreSwarm error:", error2);
11533
11839
  }
11534
11840
  if (ctx.curationSucceeded && ctx.allLessons.length > 0) {
11535
- await fs11.unlink(lessonsFilePath).catch(() => {});
11841
+ await fs12.unlink(lessonsFilePath).catch(() => {});
11536
11842
  }
11537
11843
  if (ctx.curationSucceeded) {
11538
11844
  if (ctx.config.hive_enabled === false) {} else {
@@ -11587,6 +11893,18 @@ async function runFinalizeStage(ctx) {
11587
11893
  ctx.warnings.push(ctx.skillReviewSummary);
11588
11894
  }
11589
11895
  }
11896
+ try {
11897
+ ctx.sessionReflection = await runAbortableReflection({
11898
+ directory: ctx.directory,
11899
+ toolAggregates: swarmState.toolAggregates,
11900
+ agentSessions: swarmState.agentSessions,
11901
+ sessionId: ctx.options.sessionID
11902
+ }, CLOSE_REFLECTION_TIMEOUT_MS);
11903
+ await writeSessionReflection(ctx.directory, ctx.sessionReflection);
11904
+ } catch (reflectionErr) {
11905
+ const msg = reflectionErr instanceof Error ? reflectionErr.message : String(reflectionErr);
11906
+ ctx.warnings.push(`Session reflection failed: ${msg}`);
11907
+ }
11590
11908
  if (ctx.planExists) {
11591
11909
  ctx.originalStatuses = new Map;
11592
11910
  for (const phase of ctx.planData.phases ?? []) {
@@ -11656,7 +11974,7 @@ async function copySqliteSafe(srcPath, destPath) {
11656
11974
  let checkpointVerified = false;
11657
11975
  try {
11658
11976
  const result = spawnSync5("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
11659
- cwd: path24.dirname(srcPath),
11977
+ cwd: path25.dirname(srcPath),
11660
11978
  encoding: "utf-8",
11661
11979
  stdio: ["ignore", "pipe", "pipe"],
11662
11980
  timeout: 1e4,
@@ -11667,7 +11985,7 @@ async function copySqliteSafe(srcPath, destPath) {
11667
11985
  const code = result.error.code;
11668
11986
  if (code === "ENOENT") {
11669
11987
  try {
11670
- await fs11.copyFile(srcPath, destPath);
11988
+ await fs12.copyFile(srcPath, destPath);
11671
11989
  return {
11672
11990
  success: true,
11673
11991
  reason: "copied without WAL checkpoint (sqlite3 CLI unavailable)"
@@ -11706,7 +12024,7 @@ async function copySqliteSafe(srcPath, destPath) {
11706
12024
  };
11707
12025
  }
11708
12026
  try {
11709
- await fs11.copyFile(srcPath, destPath);
12027
+ await fs12.copyFile(srcPath, destPath);
11710
12028
  if (checkpointVerified) {
11711
12029
  return { success: true };
11712
12030
  }
@@ -11724,9 +12042,9 @@ async function copySqliteSafe(srcPath, destPath) {
11724
12042
  async function runArchiveStage(ctx) {
11725
12043
  ctx.timestamp = new Date().toISOString().replace(/[:.]/g, "-");
11726
12044
  ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
11727
- ctx.archiveDir = path24.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
12045
+ ctx.archiveDir = path25.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
11728
12046
  try {
11729
- await fs11.mkdir(ctx.archiveDir, { recursive: true });
12047
+ await fs12.mkdir(ctx.archiveDir, { recursive: true });
11730
12048
  const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
11731
12049
  const linkedKnowledgeShared = isLinked(ctx.directory);
11732
12050
  if (linkedKnowledgeShared) {
@@ -11739,8 +12057,8 @@ async function runArchiveStage(ctx) {
11739
12057
  if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
11740
12058
  continue;
11741
12059
  }
11742
- const srcPath = path24.join(ctx.swarmDir, artifact);
11743
- const destPath = path24.join(ctx.archiveDir, artifact);
12060
+ const srcPath = path25.join(ctx.swarmDir, artifact);
12061
+ const destPath = path25.join(ctx.archiveDir, artifact);
11744
12062
  if (artifact === "swarm.db") {
11745
12063
  const result = await copySqliteSafe(srcPath, destPath);
11746
12064
  if (result.skipped) {} else if (result.success) {
@@ -11756,7 +12074,7 @@ async function runArchiveStage(ctx) {
11756
12074
  }
11757
12075
  } else {
11758
12076
  try {
11759
- await fs11.copyFile(srcPath, destPath);
12077
+ await fs12.copyFile(srcPath, destPath);
11760
12078
  ctx.archivedFileCount++;
11761
12079
  if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
11762
12080
  ctx.archivedActiveStateFiles.add(artifact);
@@ -11772,8 +12090,8 @@ async function runArchiveStage(ctx) {
11772
12090
  }
11773
12091
  }
11774
12092
  for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
11775
- const srcDir = path24.join(ctx.swarmDir, dirName);
11776
- const destDir = path24.join(ctx.archiveDir, dirName);
12093
+ const srcDir = path25.join(ctx.swarmDir, dirName);
12094
+ const destDir = path25.join(ctx.archiveDir, dirName);
11777
12095
  try {
11778
12096
  const result = await copyDirRecursiveWithFailures(srcDir, destDir);
11779
12097
  ctx.archivedFileCount += result.copied;
@@ -11846,9 +12164,9 @@ async function runCleanStage(ctx) {
11846
12164
  ctx.warnings.push(reason ? `Preserved ${artifact} because it was not successfully archived: ${reason}.` : `Preserved ${artifact} because it was not successfully archived.`);
11847
12165
  continue;
11848
12166
  }
11849
- const filePath = path24.join(ctx.swarmDir, artifact);
12167
+ const filePath = path25.join(ctx.swarmDir, artifact);
11850
12168
  try {
11851
- await fs11.unlink(filePath);
12169
+ await fs12.unlink(filePath);
11852
12170
  cleanedFiles.push(artifact);
11853
12171
  } catch (err) {
11854
12172
  const errno = err?.code;
@@ -11865,18 +12183,18 @@ async function runCleanStage(ctx) {
11865
12183
  if (!ctx.archivedActiveStateDirs.has(dirName)) {
11866
12184
  continue;
11867
12185
  }
11868
- const dirPath = path24.join(ctx.swarmDir, dirName);
12186
+ const dirPath = path25.join(ctx.swarmDir, dirName);
11869
12187
  try {
11870
- await fs11.rm(dirPath, { recursive: true, force: true });
12188
+ await fs12.rm(dirPath, { recursive: true, force: true });
11871
12189
  cleanedFiles.push(`${dirName}/`);
11872
12190
  } catch {}
11873
12191
  }
11874
12192
  try {
11875
- const swarmFiles = await fs11.readdir(ctx.swarmDir);
12193
+ const swarmFiles = await fs12.readdir(ctx.swarmDir);
11876
12194
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
11877
12195
  for (const backup of configBackups) {
11878
12196
  try {
11879
- await fs11.unlink(path24.join(ctx.swarmDir, backup));
12197
+ await fs12.unlink(path25.join(ctx.swarmDir, backup));
11880
12198
  configBackupsRemoved++;
11881
12199
  } catch (err) {
11882
12200
  const errno = err?.code;
@@ -11889,7 +12207,7 @@ async function runCleanStage(ctx) {
11889
12207
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
11890
12208
  for (const sibling of ledgerSiblings) {
11891
12209
  try {
11892
- await fs11.unlink(path24.join(ctx.swarmDir, sibling));
12210
+ await fs12.unlink(path25.join(ctx.swarmDir, sibling));
11893
12211
  } catch (err) {
11894
12212
  const errno = err?.code;
11895
12213
  if (errno === "ENOENT") {} else {
@@ -11907,14 +12225,14 @@ async function runCleanStage(ctx) {
11907
12225
  }
11908
12226
  let swarmPlanFilesRemoved = 0;
11909
12227
  const candidates = [
11910
- path24.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
11911
- path24.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
11912
- path24.join(ctx.directory, "SWARM_PLAN.json"),
11913
- path24.join(ctx.directory, "SWARM_PLAN.md")
12228
+ path25.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
12229
+ path25.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
12230
+ path25.join(ctx.directory, "SWARM_PLAN.json"),
12231
+ path25.join(ctx.directory, "SWARM_PLAN.md")
11914
12232
  ];
11915
12233
  for (const candidate of candidates) {
11916
12234
  try {
11917
- await fs11.unlink(candidate);
12235
+ await fs12.unlink(candidate);
11918
12236
  swarmPlanFilesRemoved++;
11919
12237
  } catch (err) {
11920
12238
  if (err?.code !== "ENOENT") {
@@ -11924,11 +12242,11 @@ async function runCleanStage(ctx) {
11924
12242
  }
11925
12243
  let tmpFilesRemoved = 0;
11926
12244
  try {
11927
- const swarmFiles = await fs11.readdir(ctx.swarmDir);
12245
+ const swarmFiles = await fs12.readdir(ctx.swarmDir);
11928
12246
  const tmpFiles = swarmFiles.filter((f) => f.startsWith(".tmp."));
11929
12247
  for (const tmp of tmpFiles) {
11930
12248
  try {
11931
- await fs11.unlink(path24.join(ctx.swarmDir, tmp));
12249
+ await fs12.unlink(path25.join(ctx.swarmDir, tmp));
11932
12250
  tmpFilesRemoved++;
11933
12251
  } catch (err) {
11934
12252
  const errno = err?.code;
@@ -11949,7 +12267,7 @@ async function runCleanStage(ctx) {
11949
12267
  cleanedFiles.push(`${tmpFilesRemoved} .tmp.* file(s)`);
11950
12268
  }
11951
12269
  clearAllScopes(ctx.directory);
11952
- const contextPath = path24.join(ctx.swarmDir, "context.md");
12270
+ const contextPath = path25.join(ctx.swarmDir, "context.md");
11953
12271
  const contextContent = [
11954
12272
  "# Context",
11955
12273
  "",
@@ -11961,9 +12279,9 @@ async function runCleanStage(ctx) {
11961
12279
  ""
11962
12280
  ].join(`
11963
12281
  `);
11964
- const contextTempPath = path24.join(path24.dirname(contextPath), `${path24.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
12282
+ const contextTempPath = path25.join(path25.dirname(contextPath), `${path25.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
11965
12283
  try {
11966
- await fs11.writeFile(contextTempPath, contextContent, "utf-8");
12284
+ await fs12.writeFile(contextTempPath, contextContent, "utf-8");
11967
12285
  fsSync2.renameSync(contextTempPath, contextPath);
11968
12286
  } catch (error2) {
11969
12287
  try {
@@ -12025,7 +12343,7 @@ async function runAlignStage(ctx) {
12025
12343
  return { gitAlignResult, prunedBranches };
12026
12344
  }
12027
12345
  async function handleCloseCommand(directory, args, options = {}) {
12028
- const swarmDir = path24.join(directory, ".swarm");
12346
+ const swarmDir = path25.join(directory, ".swarm");
12029
12347
  try {
12030
12348
  const stat4 = fsSync2.lstatSync(swarmDir);
12031
12349
  if (stat4.isSymbolicLink()) {
@@ -12039,18 +12357,18 @@ async function handleCloseCommand(directory, args, options = {}) {
12039
12357
  const planPath = validateSwarmPath(directory, "plan.json");
12040
12358
  let planExists = false;
12041
12359
  let planData = {
12042
- title: path24.basename(directory) || "Ad-hoc session",
12360
+ title: path25.basename(directory) || "Ad-hoc session",
12043
12361
  phases: []
12044
12362
  };
12045
12363
  try {
12046
- const content = await fs11.readFile(planPath, "utf-8");
12364
+ const content = await fs12.readFile(planPath, "utf-8");
12047
12365
  planData = JSON.parse(content);
12048
12366
  planExists = true;
12049
12367
  } catch (error2) {
12050
12368
  if (error2?.code !== "ENOENT") {
12051
12369
  return `\u274C Failed to read plan.json: ${error2 instanceof Error ? error2.message : String(error2)}`;
12052
12370
  }
12053
- const swarmDirExists = await fs11.access(swarmDir).then(() => true).catch(() => false);
12371
+ const swarmDirExists = await fs12.access(swarmDir).then(() => true).catch(() => false);
12054
12372
  if (!swarmDirExists) {
12055
12373
  return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
12056
12374
  }
@@ -12064,15 +12382,15 @@ async function handleCloseCommand(directory, args, options = {}) {
12064
12382
  }
12065
12383
  try {
12066
12384
  if (!planExists) {
12067
- const archiveDir = path24.join(swarmDir, "archive");
12385
+ const archiveDir = path25.join(swarmDir, "archive");
12068
12386
  try {
12069
- const archiveEntries = await fs11.readdir(archiveDir);
12387
+ const archiveEntries = await fs12.readdir(archiveDir);
12070
12388
  const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
12071
12389
  if (hasArchiveBundle) {
12072
12390
  const hasActiveState = [
12073
12391
  ...ACTIVE_STATE_TO_CLEAN,
12074
12392
  ...ACTIVE_STATE_DIRS_TO_CLEAN
12075
- ].some((entry) => fsSync2.existsSync(path24.join(swarmDir, entry)));
12393
+ ].some((entry) => fsSync2.existsSync(path25.join(swarmDir, entry)));
12076
12394
  if (!hasActiveState) {
12077
12395
  return `\u2705 Already finalized \u2014 nothing to do.
12078
12396
 
@@ -12116,6 +12434,7 @@ This project was already finalized in a previous /swarm close run. The plan has
12116
12434
  knowledgeSkillHint: "",
12117
12435
  skillReviewSummary: "",
12118
12436
  postMortemSummary: "",
12437
+ sessionReflection: undefined,
12119
12438
  hivePromoted: 0,
12120
12439
  sessionKnowledgeCreated: 0,
12121
12440
  fallbackKnowledgeCreated: 0,
@@ -12165,6 +12484,12 @@ This project was already finalized in a previous /swarm close run. The plan has
12165
12484
  "## Skill Review",
12166
12485
  ctx.skillReviewSummary || "Skill review completed without details."
12167
12486
  ] : [],
12487
+ ...ctx.sessionReflection ? [
12488
+ "",
12489
+ `## Session Reflection (${ctx.sessionReflection.source})`,
12490
+ "",
12491
+ ctx.sessionReflection.architectReport
12492
+ ] : [],
12168
12493
  "",
12169
12494
  "## Local Repo State",
12170
12495
  ...gitAlignResult ? [`- **Git:** ${gitAlignResult}`] : ["- Git alignment skipped"],
@@ -12188,9 +12513,9 @@ This project was already finalized in a previous /swarm close run. The plan has
12188
12513
  ...ctx.warnings.length > 0 ? ["## Warnings", ...ctx.warnings.map((w) => `- ${w}`), ""] : []
12189
12514
  ].join(`
12190
12515
  `);
12191
- const closeSummaryTempPath = path24.join(path24.dirname(closeSummaryPath), `${path24.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
12516
+ const closeSummaryTempPath = path25.join(path25.dirname(closeSummaryPath), `${path25.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
12192
12517
  try {
12193
- await fs11.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
12518
+ await fs12.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
12194
12519
  fsSync2.renameSync(closeSummaryTempPath, closeSummaryPath);
12195
12520
  } catch (error2) {
12196
12521
  try {
@@ -12230,16 +12555,30 @@ ${otherWarnings.map((w) => `- ${w}`).join(`
12230
12555
  const postMortemOutput = ctx.postMortemSummary ? `
12231
12556
 
12232
12557
  **Post-Mortem:** ${ctx.postMortemSummary}` : "";
12558
+ let reflectionOutput = "";
12559
+ if (ctx.sessionReflection) {
12560
+ const d = ctx.sessionReflection.data;
12561
+ const hasSignals = d.totalToolFailures > 0 || d.gateFailures.length > 0 || d.lessonsFromRetros.length > 0 || Object.keys(d.errorTaxonomy).length > 0 || d.agentDispatches.length > 0;
12562
+ if (hasSignals) {
12563
+ reflectionOutput = `
12564
+
12565
+ ---
12566
+
12567
+ **Architect Session Review** (${ctx.sessionReflection.source}):
12568
+
12569
+ ${ctx.sessionReflection.architectReport}`;
12570
+ }
12571
+ }
12233
12572
  if (ctx.planAlreadyDone) {
12234
12573
  return `\u2705 Session finalized. Plan was already in a terminal state \u2014 cleanup and archive applied.
12235
12574
 
12236
12575
  **Archive:** ${ctx.archiveResult}
12237
- **Git:** ${gitAlignResult}${lessonSummary}${knowledgeHintSummary}${skillReviewOutput}${postMortemOutput}${warningMsg}`;
12576
+ **Git:** ${gitAlignResult}${lessonSummary}${knowledgeHintSummary}${skillReviewOutput}${postMortemOutput}${reflectionOutput}${warningMsg}`;
12238
12577
  }
12239
12578
  return `\u2705 Swarm finalized. ${ctx.closedPhases.length} phase(s) closed, ${ctx.closedTasks.length} incomplete task(s) marked closed.
12240
12579
 
12241
12580
  **Archive:** ${ctx.archiveResult}
12242
- **Git:** ${gitAlignResult}${lessonSummary}${knowledgeHintSummary}${skillReviewOutput}${postMortemOutput}${warningMsg}`;
12581
+ **Git:** ${gitAlignResult}${lessonSummary}${knowledgeHintSummary}${skillReviewOutput}${postMortemOutput}${reflectionOutput}${warningMsg}`;
12243
12582
  } finally {
12244
12583
  if (finalizeLock.release) {
12245
12584
  try {
@@ -12259,6 +12598,7 @@ var _internals20 = {
12259
12598
  ACTIVE_STATE_DIRS_TO_CLEAN,
12260
12599
  countSessionKnowledgeEntries,
12261
12600
  CLOSE_SKILL_REVIEW_TIMEOUT_MS,
12601
+ CLOSE_REFLECTION_TIMEOUT_MS,
12262
12602
  guaranteeAllPlansComplete,
12263
12603
  getGitRepositoryStatus,
12264
12604
  resetToMainAfterMerge,
@@ -12511,14 +12851,14 @@ function buildStatusMessage(session, plan) {
12511
12851
 
12512
12852
  // src/commands/config.ts
12513
12853
  import * as os6 from "os";
12514
- import * as path25 from "path";
12854
+ import * as path26 from "path";
12515
12855
  function getUserConfigDir2() {
12516
- return process.env.XDG_CONFIG_HOME || path25.join(os6.homedir(), ".config");
12856
+ return process.env.XDG_CONFIG_HOME || path26.join(os6.homedir(), ".config");
12517
12857
  }
12518
12858
  async function handleConfigCommand(directory, _args) {
12519
12859
  const config = loadPluginConfig(directory);
12520
- const userConfigPath = path25.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
12521
- const projectConfigPath = path25.join(directory, ".opencode", "opencode-swarm.json");
12860
+ const userConfigPath = path26.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
12861
+ const projectConfigPath = path26.join(directory, ".opencode", "opencode-swarm.json");
12522
12862
  const lines = [
12523
12863
  "## Swarm Configuration",
12524
12864
  "",
@@ -12538,7 +12878,7 @@ async function handleConfigCommand(directory, _args) {
12538
12878
  // src/services/skill-consolidation.ts
12539
12879
  import { existsSync as existsSync14 } from "fs";
12540
12880
  import { mkdir as mkdir8, readFile as readFile8, rename as rename4, writeFile as writeFile8 } from "fs/promises";
12541
- import * as path26 from "path";
12881
+ import * as path27 from "path";
12542
12882
 
12543
12883
  // src/utils/timeout.ts
12544
12884
  async function withTimeout(promise, ms, timeoutError) {
@@ -12563,7 +12903,7 @@ var DEFAULT_CONSOLIDATION_MAX_CALLS_PER_RUN = 1;
12563
12903
  var CONSOLIDATION_RUN_TIMEOUT_MS = 5 * 60 * 1000;
12564
12904
  var runningByDirectory = new Map;
12565
12905
  function consolidationStatePath(directory) {
12566
- return path26.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
12906
+ return path27.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
12567
12907
  }
12568
12908
  async function readState2(directory) {
12569
12909
  const filePath = consolidationStatePath(directory);
@@ -12579,7 +12919,7 @@ async function readState2(directory) {
12579
12919
  }
12580
12920
  }
12581
12921
  async function atomicWrite2(filePath, content) {
12582
- await mkdir8(path26.dirname(filePath), { recursive: true });
12922
+ await mkdir8(path27.dirname(filePath), { recursive: true });
12583
12923
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
12584
12924
  await writeFile8(tmp, content, "utf-8");
12585
12925
  await rename4(tmp, filePath);
@@ -12659,7 +12999,7 @@ async function runSkillConsolidationInner(req) {
12659
12999
  };
12660
13000
  }
12661
13001
  async function runSkillConsolidation(req) {
12662
- const key = path26.resolve(req.directory);
13002
+ const key = path27.resolve(req.directory);
12663
13003
  const existing = runningByDirectory.get(key);
12664
13004
  if (existing) {
12665
13005
  return {
@@ -12811,8 +13151,8 @@ async function handleCouncilCommand(_directory, args) {
12811
13151
 
12812
13152
  // src/commands/coupling.ts
12813
13153
  import { randomBytes } from "crypto";
12814
- import * as fs12 from "fs";
12815
- import * as path28 from "path";
13154
+ import * as fs13 from "fs";
13155
+ import * as path29 from "path";
12816
13156
 
12817
13157
  // src/turbo/epic/cochange-source.ts
12818
13158
  import * as child_process3 from "child_process";
@@ -12822,7 +13162,7 @@ import { promisify as promisify2 } from "util";
12822
13162
  import * as child_process2 from "child_process";
12823
13163
  import { randomUUID as randomUUID3 } from "crypto";
12824
13164
  import { readdir as readdir4, readFile as readFile9, stat as stat4 } from "fs/promises";
12825
- import * as path27 from "path";
13165
+ import * as path28 from "path";
12826
13166
  import { promisify } from "util";
12827
13167
  function getExecFileAsync() {
12828
13168
  return promisify(child_process2.execFile);
@@ -12926,7 +13266,7 @@ async function scanSourceFiles(dir) {
12926
13266
  try {
12927
13267
  const entries = await readdir4(dir, { withFileTypes: true });
12928
13268
  for (const entry of entries) {
12929
- const fullPath = path27.join(dir, entry.name);
13269
+ const fullPath = path28.join(dir, entry.name);
12930
13270
  if (entry.isDirectory()) {
12931
13271
  if (skipDirs.has(entry.name)) {
12932
13272
  continue;
@@ -12934,7 +13274,7 @@ async function scanSourceFiles(dir) {
12934
13274
  const subFiles = await scanSourceFiles(fullPath);
12935
13275
  results.push(...subFiles);
12936
13276
  } else if (entry.isFile()) {
12937
- const ext = path27.extname(entry.name);
13277
+ const ext = path28.extname(entry.name);
12938
13278
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
12939
13279
  results.push(fullPath);
12940
13280
  }
@@ -12956,8 +13296,8 @@ async function getStaticEdges(directory) {
12956
13296
  continue;
12957
13297
  }
12958
13298
  try {
12959
- const sourceDir = path27.dirname(sourceFile);
12960
- const resolvedPath = path27.resolve(sourceDir, importPath);
13299
+ const sourceDir = path28.dirname(sourceFile);
13300
+ const resolvedPath = path28.resolve(sourceDir, importPath);
12961
13301
  const extensions = [
12962
13302
  "",
12963
13303
  ".ts",
@@ -12982,8 +13322,8 @@ async function getStaticEdges(directory) {
12982
13322
  if (!targetFile) {
12983
13323
  continue;
12984
13324
  }
12985
- const relSource = path27.relative(directory, sourceFile).replace(/\\/g, "/");
12986
- const relTarget = path27.relative(directory, targetFile).replace(/\\/g, "/");
13325
+ const relSource = path28.relative(directory, sourceFile).replace(/\\/g, "/");
13326
+ const relTarget = path28.relative(directory, targetFile).replace(/\\/g, "/");
12987
13327
  const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
12988
13328
  edges.add(key);
12989
13329
  } catch {}
@@ -12995,7 +13335,7 @@ async function getStaticEdges(directory) {
12995
13335
  function isTestImplementationPair(fileA, fileB) {
12996
13336
  const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
12997
13337
  const getBaseName = (filePath) => {
12998
- const base = path27.basename(filePath);
13338
+ const base = path28.basename(filePath);
12999
13339
  for (const pattern of testPatterns) {
13000
13340
  if (base.endsWith(pattern)) {
13001
13341
  return base.slice(0, -pattern.length);
@@ -13005,16 +13345,16 @@ function isTestImplementationPair(fileA, fileB) {
13005
13345
  };
13006
13346
  const baseA = getBaseName(fileA);
13007
13347
  const baseB = getBaseName(fileB);
13008
- return baseA === baseB && baseA !== path27.basename(fileA) && baseA !== path27.basename(fileB);
13348
+ return baseA === baseB && baseA !== path28.basename(fileA) && baseA !== path28.basename(fileB);
13009
13349
  }
13010
13350
  function hasSharedPrefix(fileA, fileB) {
13011
- const dirA = path27.dirname(fileA);
13012
- const dirB = path27.dirname(fileB);
13351
+ const dirA = path28.dirname(fileA);
13352
+ const dirB = path28.dirname(fileB);
13013
13353
  if (dirA !== dirB) {
13014
13354
  return false;
13015
13355
  }
13016
- const baseA = path27.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
13017
- const baseB = path27.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
13356
+ const baseA = path28.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
13357
+ const baseB = path28.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
13018
13358
  if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
13019
13359
  return true;
13020
13360
  }
@@ -13069,8 +13409,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
13069
13409
  const entries = [];
13070
13410
  const now = new Date().toISOString();
13071
13411
  for (const pair of pairs.slice(0, 10)) {
13072
- const baseA = path27.basename(pair.fileA);
13073
- const baseB = path27.basename(pair.fileB);
13412
+ const baseA = path28.basename(pair.fileA);
13413
+ const baseB = path28.basename(pair.fileB);
13074
13414
  let lesson = `Files ${pair.fileA} and ${pair.fileB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
13075
13415
  if (lesson.length > 280) {
13076
13416
  lesson = `Files ${baseA} and ${baseB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
@@ -13496,17 +13836,17 @@ function parseArgs3(args) {
13496
13836
  return parsed;
13497
13837
  }
13498
13838
  function persistReportJson(directory, report) {
13499
- const epicDir = path28.join(directory, ".swarm", "epic");
13500
- fs12.mkdirSync(epicDir, { recursive: true });
13501
- const filePath = path28.join(epicDir, "coupling-report.json");
13839
+ const epicDir = path29.join(directory, ".swarm", "epic");
13840
+ fs13.mkdirSync(epicDir, { recursive: true });
13841
+ const filePath = path29.join(epicDir, "coupling-report.json");
13502
13842
  const tmpPath = `${filePath}.tmp.${randomBytes(8).toString("hex")}`;
13503
- fs12.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
13843
+ fs13.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
13504
13844
  `, "utf-8");
13505
13845
  try {
13506
- fs12.renameSync(tmpPath, filePath);
13846
+ fs13.renameSync(tmpPath, filePath);
13507
13847
  } catch (err) {
13508
13848
  try {
13509
- fs12.unlinkSync(tmpPath);
13849
+ fs13.unlinkSync(tmpPath);
13510
13850
  } catch {}
13511
13851
  throw err;
13512
13852
  }
@@ -13557,7 +13897,7 @@ Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>
13557
13897
  persistStatus = {
13558
13898
  requested: true,
13559
13899
  written: true,
13560
- path: path28.relative(directory, writtenAt)
13900
+ path: path29.relative(directory, writtenAt)
13561
13901
  };
13562
13902
  } catch (err) {
13563
13903
  persistStatus = {
@@ -13616,7 +13956,7 @@ function formatCurationSummary(summary) {
13616
13956
  }
13617
13957
 
13618
13958
  // src/commands/dark-matter.ts
13619
- import path29 from "path";
13959
+ import path30 from "path";
13620
13960
  async function handleDarkMatterCommand(directory, args) {
13621
13961
  const options = {};
13622
13962
  for (let i = 0;i < args.length; i++) {
@@ -13648,7 +13988,7 @@ Ensure this is a git repository with commit history.`;
13648
13988
  const output = formatDarkMatterOutput(pairs);
13649
13989
  if (pairs.length > 0) {
13650
13990
  try {
13651
- const projectName = path29.basename(path29.resolve(directory));
13991
+ const projectName = path30.basename(path30.resolve(directory));
13652
13992
  const entries = darkMatterToKnowledgeEntries(pairs, projectName);
13653
13993
  if (entries.length > 0) {
13654
13994
  const knowledgePath = resolveSwarmKnowledgePath(directory);
@@ -14015,49 +14355,49 @@ ${USAGE5}`;
14015
14355
  // src/services/diagnose-service.ts
14016
14356
  import * as child_process4 from "child_process";
14017
14357
  import { existsSync as existsSync17, readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync6 } from "fs";
14018
- import path31 from "path";
14358
+ import path32 from "path";
14019
14359
  import { fileURLToPath } from "url";
14020
14360
 
14021
14361
  // src/config/cache-paths.ts
14022
14362
  import * as os7 from "os";
14023
- import * as path30 from "path";
14363
+ import * as path31 from "path";
14024
14364
  function getPluginConfigDir() {
14025
- return path30.join(process.env.XDG_CONFIG_HOME || path30.join(os7.homedir(), ".config"), "opencode");
14365
+ return path31.join(process.env.XDG_CONFIG_HOME || path31.join(os7.homedir(), ".config"), "opencode");
14026
14366
  }
14027
14367
  function getPluginCachePaths() {
14028
- const cacheBase = process.env.XDG_CACHE_HOME || path30.join(os7.homedir(), ".cache");
14368
+ const cacheBase = process.env.XDG_CACHE_HOME || path31.join(os7.homedir(), ".cache");
14029
14369
  const configDir = getPluginConfigDir();
14030
14370
  const paths = [
14031
- path30.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
14032
- path30.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
14033
- path30.join(configDir, "node_modules", "opencode-swarm")
14371
+ path31.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
14372
+ path31.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
14373
+ path31.join(configDir, "node_modules", "opencode-swarm")
14034
14374
  ];
14035
14375
  if (process.platform === "darwin") {
14036
- const libCaches = path30.join(os7.homedir(), "Library", "Caches");
14037
- paths.push(path30.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path30.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
14376
+ const libCaches = path31.join(os7.homedir(), "Library", "Caches");
14377
+ paths.push(path31.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path31.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
14038
14378
  }
14039
14379
  if (process.platform === "win32") {
14040
- const localAppData = process.env.LOCALAPPDATA || path30.join(os7.homedir(), "AppData", "Local");
14041
- const appData = process.env.APPDATA || path30.join(os7.homedir(), "AppData", "Roaming");
14042
- paths.push(path30.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path30.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path30.join(appData, "opencode", "node_modules", "opencode-swarm"));
14380
+ const localAppData = process.env.LOCALAPPDATA || path31.join(os7.homedir(), "AppData", "Local");
14381
+ const appData = process.env.APPDATA || path31.join(os7.homedir(), "AppData", "Roaming");
14382
+ paths.push(path31.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path31.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path31.join(appData, "opencode", "node_modules", "opencode-swarm"));
14043
14383
  }
14044
14384
  return paths;
14045
14385
  }
14046
14386
  function getPluginLockFilePaths() {
14047
- const cacheBase = process.env.XDG_CACHE_HOME || path30.join(os7.homedir(), ".cache");
14387
+ const cacheBase = process.env.XDG_CACHE_HOME || path31.join(os7.homedir(), ".cache");
14048
14388
  const configDir = getPluginConfigDir();
14049
14389
  const paths = [
14050
- path30.join(cacheBase, "opencode", "bun.lock"),
14051
- path30.join(cacheBase, "opencode", "bun.lockb"),
14052
- path30.join(configDir, "package-lock.json")
14390
+ path31.join(cacheBase, "opencode", "bun.lock"),
14391
+ path31.join(cacheBase, "opencode", "bun.lockb"),
14392
+ path31.join(configDir, "package-lock.json")
14053
14393
  ];
14054
14394
  if (process.platform === "darwin") {
14055
- const libCaches = path30.join(os7.homedir(), "Library", "Caches");
14056
- paths.push(path30.join(libCaches, "opencode", "bun.lock"), path30.join(libCaches, "opencode", "bun.lockb"));
14395
+ const libCaches = path31.join(os7.homedir(), "Library", "Caches");
14396
+ paths.push(path31.join(libCaches, "opencode", "bun.lock"), path31.join(libCaches, "opencode", "bun.lockb"));
14057
14397
  }
14058
14398
  if (process.platform === "win32") {
14059
- const localAppData = process.env.LOCALAPPDATA || path30.join(os7.homedir(), "AppData", "Local");
14060
- paths.push(path30.join(localAppData, "opencode", "bun.lock"), path30.join(localAppData, "opencode", "bun.lockb"));
14399
+ const localAppData = process.env.LOCALAPPDATA || path31.join(os7.homedir(), "AppData", "Local");
14400
+ paths.push(path31.join(localAppData, "opencode", "bun.lock"), path31.join(localAppData, "opencode", "bun.lockb"));
14061
14401
  }
14062
14402
  return paths;
14063
14403
  }
@@ -14073,22 +14413,22 @@ import { readFile as readFile10 } from "fs/promises";
14073
14413
  // src/services/version-check.ts
14074
14414
  import { existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "fs";
14075
14415
  import { homedir as homedir4 } from "os";
14076
- import { join as join25 } from "path";
14416
+ import { join as join26 } from "path";
14077
14417
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
14078
14418
  function cacheDir() {
14079
14419
  const xdg = process.env.XDG_CACHE_HOME;
14080
- const base = xdg && xdg.length > 0 ? xdg : join25(homedir4(), ".cache");
14081
- return join25(base, "opencode-swarm");
14420
+ const base = xdg && xdg.length > 0 ? xdg : join26(homedir4(), ".cache");
14421
+ return join26(base, "opencode-swarm");
14082
14422
  }
14083
14423
  function cacheFile() {
14084
- return join25(cacheDir(), "version-check.json");
14424
+ return join26(cacheDir(), "version-check.json");
14085
14425
  }
14086
14426
  function readVersionCache() {
14087
14427
  try {
14088
- const path31 = cacheFile();
14089
- if (!existsSync15(path31))
14428
+ const path32 = cacheFile();
14429
+ if (!existsSync15(path32))
14090
14430
  return null;
14091
- const raw = readFileSync8(path31, "utf-8");
14431
+ const raw = readFileSync8(path32, "utf-8");
14092
14432
  const parsed = JSON.parse(raw);
14093
14433
  if (typeof parsed?.checkedAt !== "number")
14094
14434
  return null;
@@ -14637,7 +14977,7 @@ async function checkSpecStaleness(directory, plan) {
14637
14977
  };
14638
14978
  }
14639
14979
  async function checkConfigParseability(directory) {
14640
- const configPath = path31.join(directory, ".opencode/opencode-swarm.json");
14980
+ const configPath = path32.join(directory, ".opencode/opencode-swarm.json");
14641
14981
  if (!existsSync17(configPath)) {
14642
14982
  return {
14643
14983
  name: "Config Parseability",
@@ -14666,7 +15006,7 @@ function resolveGrammarDir(thisDir) {
14666
15006
  const normalized = thisDir.replace(/\\/g, "/");
14667
15007
  const isSource = normalized.endsWith("/src/services");
14668
15008
  const isCliBundle = normalized.endsWith("/cli");
14669
- return isSource || isCliBundle ? path31.join(thisDir, "..", "lang", "grammars") : path31.join(thisDir, "lang", "grammars");
15009
+ return isSource || isCliBundle ? path32.join(thisDir, "..", "lang", "grammars") : path32.join(thisDir, "lang", "grammars");
14670
15010
  }
14671
15011
  async function checkGrammarWasmFiles() {
14672
15012
  const grammarFiles = [
@@ -14690,14 +15030,14 @@ async function checkGrammarWasmFiles() {
14690
15030
  "tree-sitter-ini.wasm",
14691
15031
  "tree-sitter-regex.wasm"
14692
15032
  ];
14693
- const thisDir = path31.dirname(fileURLToPath(import.meta.url));
15033
+ const thisDir = path32.dirname(fileURLToPath(import.meta.url));
14694
15034
  const grammarDir = resolveGrammarDir(thisDir);
14695
15035
  const missing = [];
14696
- if (!existsSync17(path31.join(grammarDir, "tree-sitter.wasm"))) {
15036
+ if (!existsSync17(path32.join(grammarDir, "tree-sitter.wasm"))) {
14697
15037
  missing.push("tree-sitter.wasm (core runtime)");
14698
15038
  }
14699
15039
  for (const file of grammarFiles) {
14700
- if (!existsSync17(path31.join(grammarDir, file))) {
15040
+ if (!existsSync17(path32.join(grammarDir, file))) {
14701
15041
  missing.push(file);
14702
15042
  }
14703
15043
  }
@@ -14715,7 +15055,7 @@ async function checkGrammarWasmFiles() {
14715
15055
  };
14716
15056
  }
14717
15057
  async function checkCheckpointManifest(directory) {
14718
- const manifestPath = path31.join(directory, ".swarm/checkpoints.json");
15058
+ const manifestPath = path32.join(directory, ".swarm/checkpoints.json");
14719
15059
  if (!existsSync17(manifestPath)) {
14720
15060
  return {
14721
15061
  name: "Checkpoint Manifest",
@@ -14767,7 +15107,7 @@ async function checkCheckpointManifest(directory) {
14767
15107
  }
14768
15108
  }
14769
15109
  async function checkEventStreamIntegrity(directory) {
14770
- const eventsPath = path31.join(directory, ".swarm/events.jsonl");
15110
+ const eventsPath = path32.join(directory, ".swarm/events.jsonl");
14771
15111
  if (!existsSync17(eventsPath)) {
14772
15112
  return {
14773
15113
  name: "Event Stream",
@@ -14808,7 +15148,7 @@ async function checkEventStreamIntegrity(directory) {
14808
15148
  }
14809
15149
  }
14810
15150
  async function checkSteeringDirectives(directory) {
14811
- const eventsPath = path31.join(directory, ".swarm/events.jsonl");
15151
+ const eventsPath = path32.join(directory, ".swarm/events.jsonl");
14812
15152
  if (!existsSync17(eventsPath)) {
14813
15153
  return {
14814
15154
  name: "Steering Directives",
@@ -14864,7 +15204,7 @@ async function checkCurator(directory) {
14864
15204
  detail: "Disabled (enable via curator.enabled)"
14865
15205
  };
14866
15206
  }
14867
- const summaryPath = path31.join(directory, ".swarm/curator-summary.json");
15207
+ const summaryPath = path32.join(directory, ".swarm/curator-summary.json");
14868
15208
  if (!existsSync17(summaryPath)) {
14869
15209
  return {
14870
15210
  name: "Curator",
@@ -15066,7 +15406,7 @@ async function getDiagnoseData(directory) {
15066
15406
  checks.push(await checkCurator(directory));
15067
15407
  checks.push(await checkKnowledgeHealth(directory));
15068
15408
  try {
15069
- const evidenceDir = path31.join(directory, ".swarm", "evidence");
15409
+ const evidenceDir = path32.join(directory, ".swarm", "evidence");
15070
15410
  const snapshotFiles = existsSync17(evidenceDir) ? readdirSync3(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
15071
15411
  if (snapshotFiles.length > 0) {
15072
15412
  const latest = snapshotFiles.sort().pop();
@@ -15104,7 +15444,7 @@ async function getDiagnoseData(directory) {
15104
15444
  cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
15105
15445
  continue;
15106
15446
  }
15107
- const pkgJsonPath = path31.join(cachePath, "package.json");
15447
+ const pkgJsonPath = path32.join(cachePath, "package.json");
15108
15448
  try {
15109
15449
  const raw = readFileSync9(pkgJsonPath, "utf-8");
15110
15450
  const parsed = JSON.parse(raw);
@@ -15475,10 +15815,10 @@ function decideEpicActivation(tasks, cochangePairs, commitsObserved, options) {
15475
15815
 
15476
15816
  // src/turbo/epic/calibration.ts
15477
15817
  init_logger();
15478
- import * as fs13 from "fs";
15479
- import * as path32 from "path";
15818
+ import * as fs14 from "fs";
15819
+ import * as path33 from "path";
15480
15820
  var STATE_FILE = "calibration.json";
15481
- var STATE_REL_DIR = path32.join(".swarm", "epic");
15821
+ var STATE_REL_DIR = path33.join(".swarm", "epic");
15482
15822
  function nowISO() {
15483
15823
  return new Date().toISOString();
15484
15824
  }
@@ -15500,13 +15840,13 @@ function markUnreadable(directory, reason) {
15500
15840
  error(`[epic/calibration] state file unreadable for ${directory}: ${reason} \u2014 failing closed`);
15501
15841
  }
15502
15842
  function repairCalibrationUnreadable(directory) {
15503
- const filePath = path32.join(directory, STATE_REL_DIR, STATE_FILE);
15504
- if (!fs13.existsSync(filePath)) {
15843
+ const filePath = path33.join(directory, STATE_REL_DIR, STATE_FILE);
15844
+ if (!fs14.existsSync(filePath)) {
15505
15845
  stateUnreadableMap.delete(directory);
15506
15846
  return;
15507
15847
  }
15508
15848
  try {
15509
- const raw = fs13.readFileSync(filePath, "utf-8");
15849
+ const raw = fs14.readFileSync(filePath, "utf-8");
15510
15850
  const parsed = JSON.parse(raw);
15511
15851
  if (!isValidCalibrationShape(parsed)) {
15512
15852
  stateUnreadableMap.set(directory, true);
@@ -15532,9 +15872,9 @@ function isValidCalibrationShape(candidate) {
15532
15872
  return true;
15533
15873
  }
15534
15874
  function ensureSwarmEpicDir(directory) {
15535
- const dir = path32.resolve(directory, STATE_REL_DIR);
15536
- if (!fs13.existsSync(dir)) {
15537
- fs13.mkdirSync(dir, { recursive: true });
15875
+ const dir = path33.resolve(directory, STATE_REL_DIR);
15876
+ if (!fs14.existsSync(dir)) {
15877
+ fs14.mkdirSync(dir, { recursive: true });
15538
15878
  }
15539
15879
  return dir;
15540
15880
  }
@@ -15544,18 +15884,18 @@ function loadCalibrationState(directory) {
15544
15884
  if (stateUnreadableMap.get(directory))
15545
15885
  return null;
15546
15886
  }
15547
- const filePath = path32.join(directory, STATE_REL_DIR, STATE_FILE);
15887
+ const filePath = path33.join(directory, STATE_REL_DIR, STATE_FILE);
15548
15888
  try {
15549
- if (!fs13.existsSync(filePath)) {
15889
+ if (!fs14.existsSync(filePath)) {
15550
15890
  const seed = emptyCalibrationState();
15551
15891
  try {
15552
15892
  ensureSwarmEpicDir(directory);
15553
- fs13.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
15893
+ fs14.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
15554
15894
  `, "utf-8");
15555
15895
  } catch {}
15556
15896
  return seed;
15557
15897
  }
15558
- const raw = fs13.readFileSync(filePath, "utf-8");
15898
+ const raw = fs14.readFileSync(filePath, "utf-8");
15559
15899
  const parsed = JSON.parse(raw);
15560
15900
  if (!isValidCalibrationShape(parsed)) {
15561
15901
  markUnreadable(directory, `malformed shape (version=${parsed?.version}, hotModuleAdditions type=${Array.isArray(parsed?.hotModuleAdditions) ? "array" : typeof parsed?.hotModuleAdditions})`);
@@ -15570,36 +15910,36 @@ function loadCalibrationState(directory) {
15570
15910
 
15571
15911
  // src/turbo/epic/divergence-recorder.ts
15572
15912
  init_logger();
15573
- import * as fs14 from "fs";
15574
- import * as path33 from "path";
15575
- var EVIDENCE_REL_DIR = path33.join(".swarm", "epic");
15913
+ import * as fs15 from "fs";
15914
+ import * as path34 from "path";
15915
+ var EVIDENCE_REL_DIR = path34.join(".swarm", "epic");
15576
15916
  var EVIDENCE_FILE = "divergence.jsonl";
15577
15917
  var MAX_TAIL_BYTES2 = 16 * 1024 * 1024;
15578
15918
  function readDivergenceHistory(directory, options) {
15579
- const filePath = path33.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
15580
- if (!fs14.existsSync(filePath)) {
15919
+ const filePath = path34.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
15920
+ if (!fs15.existsSync(filePath)) {
15581
15921
  return [];
15582
15922
  }
15583
15923
  const maxBytes = options?.maxBytes ?? MAX_TAIL_BYTES2;
15584
15924
  let raw;
15585
15925
  let tailTruncated = false;
15586
15926
  try {
15587
- const stat5 = fs14.statSync(filePath);
15927
+ const stat5 = fs15.statSync(filePath);
15588
15928
  if (Number.isFinite(maxBytes) && stat5.size > maxBytes) {
15589
- const fd = fs14.openSync(filePath, "r");
15929
+ const fd = fs15.openSync(filePath, "r");
15590
15930
  try {
15591
15931
  const buf = Buffer.alloc(maxBytes);
15592
15932
  const offset = stat5.size - maxBytes;
15593
- fs14.readSync(fd, buf, 0, maxBytes, offset);
15933
+ fs15.readSync(fd, buf, 0, maxBytes, offset);
15594
15934
  raw = buf.toString("utf-8");
15595
15935
  tailTruncated = true;
15596
15936
  } finally {
15597
15937
  try {
15598
- fs14.closeSync(fd);
15938
+ fs15.closeSync(fd);
15599
15939
  } catch {}
15600
15940
  }
15601
15941
  } else {
15602
- raw = fs14.readFileSync(filePath, "utf-8");
15942
+ raw = fs15.readFileSync(filePath, "utf-8");
15603
15943
  }
15604
15944
  } catch {
15605
15945
  return [];
@@ -15624,16 +15964,16 @@ function readDivergenceHistory(directory, options) {
15624
15964
  }
15625
15965
 
15626
15966
  // src/turbo/epic/promotion-evidence.ts
15627
- import * as fs15 from "fs";
15628
- import * as path34 from "path";
15629
- var EVIDENCE_REL_DIR2 = path34.join(".swarm", "evidence");
15967
+ import * as fs16 from "fs";
15968
+ import * as path35 from "path";
15969
+ var EVIDENCE_REL_DIR2 = path35.join(".swarm", "evidence");
15630
15970
  var EVIDENCE_FILE2 = "epic-promotions.jsonl";
15631
15971
  function readPromotionEvidence(directory) {
15632
- const filePath = path34.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
15633
- if (!fs15.existsSync(filePath)) {
15972
+ const filePath = path35.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
15973
+ if (!fs16.existsSync(filePath)) {
15634
15974
  return [];
15635
15975
  }
15636
- const raw = fs15.readFileSync(filePath, "utf-8");
15976
+ const raw = fs16.readFileSync(filePath, "utf-8");
15637
15977
  const lines = raw.split(`
15638
15978
  `).filter((l) => l.trim().length > 0);
15639
15979
  const records = [];
@@ -16202,8 +16542,8 @@ async function handleExportCommand(directory, _args) {
16202
16542
  }
16203
16543
  // src/full-auto/state.ts
16204
16544
  var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
16205
- import * as fs16 from "fs";
16206
- import * as path35 from "path";
16545
+ import * as fs17 from "fs";
16546
+ import * as path36 from "path";
16207
16547
  init_logger();
16208
16548
  var lockfile4 = import_proper_lockfile4.default;
16209
16549
  var STATE_FILE2 = "full-auto-state.json";
@@ -16211,9 +16551,9 @@ function nowISO2() {
16211
16551
  return new Date().toISOString();
16212
16552
  }
16213
16553
  function ensureSwarmDir(directory) {
16214
- const swarmDir = path35.resolve(directory, ".swarm");
16215
- if (!fs16.existsSync(swarmDir)) {
16216
- fs16.mkdirSync(swarmDir, { recursive: true });
16554
+ const swarmDir = path36.resolve(directory, ".swarm");
16555
+ if (!fs17.existsSync(swarmDir)) {
16556
+ fs17.mkdirSync(swarmDir, { recursive: true });
16217
16557
  }
16218
16558
  return swarmDir;
16219
16559
  }
@@ -16271,7 +16611,7 @@ function withStateLock(directory, fn) {
16271
16611
  let release;
16272
16612
  try {
16273
16613
  const lockTarget = validateSwarmPath(directory, STATE_FILE2);
16274
- if (!fs16.existsSync(lockTarget)) {
16614
+ if (!fs17.existsSync(lockTarget)) {
16275
16615
  ensureSwarmDir(directory);
16276
16616
  const seed = {
16277
16617
  version: 2,
@@ -16279,7 +16619,7 @@ function withStateLock(directory, fn) {
16279
16619
  oversightSequence: 0,
16280
16620
  sessions: {}
16281
16621
  };
16282
- fs16.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
16622
+ fs17.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
16283
16623
  `, "utf-8");
16284
16624
  }
16285
16625
  release = lockfile4.lockSync(lockTarget, {
@@ -16329,7 +16669,7 @@ function readPersisted(directory) {
16329
16669
  const filePath = validateSwarmPath(directory, STATE_FILE2);
16330
16670
  let stats;
16331
16671
  try {
16332
- stats = fs16.statSync(filePath);
16672
+ stats = fs17.statSync(filePath);
16333
16673
  } catch {
16334
16674
  clearStateUnreadable();
16335
16675
  readCache.delete(filePath);
@@ -16340,7 +16680,7 @@ function readPersisted(directory) {
16340
16680
  clearStateUnreadable();
16341
16681
  return structuredClone(cached.state);
16342
16682
  }
16343
- const raw = fs16.readFileSync(filePath, "utf-8");
16683
+ const raw = fs17.readFileSync(filePath, "utf-8");
16344
16684
  const parsed = JSON.parse(raw);
16345
16685
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 2 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
16346
16686
  markStateUnreadable(`malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -16365,8 +16705,8 @@ function readPersisted(directory) {
16365
16705
  error(`[full-auto/state] Failed to read ${STATE_FILE2}: ${reason} \u2014 attempting .bak recovery`);
16366
16706
  try {
16367
16707
  const bakPath = validateSwarmPath(directory, `${STATE_FILE2}.bak`);
16368
- if (fs16.existsSync(bakPath)) {
16369
- const raw = fs16.readFileSync(bakPath, "utf-8");
16708
+ if (fs17.existsSync(bakPath)) {
16709
+ const raw = fs17.readFileSync(bakPath, "utf-8");
16370
16710
  const parsed = JSON.parse(raw);
16371
16711
  if (parsed?.version === 2 && parsed.sessions && !Array.isArray(parsed.sessions)) {
16372
16712
  warn(`[full-auto/state] Recovered from ${STATE_FILE2}.bak`);
@@ -16406,23 +16746,23 @@ function writePersisted(directory, persisted) {
16406
16746
  throw new Error(`Full-Auto state persistence prepare failed: ${msg}`);
16407
16747
  }
16408
16748
  try {
16409
- if (fs16.existsSync(filePath)) {
16410
- fs16.copyFileSync(filePath, bakPath);
16749
+ if (fs17.existsSync(filePath)) {
16750
+ fs17.copyFileSync(filePath, bakPath);
16411
16751
  }
16412
16752
  } catch {}
16413
16753
  try {
16414
- fs16.writeFileSync(tmpPath, payload, "utf-8");
16754
+ fs17.writeFileSync(tmpPath, payload, "utf-8");
16415
16755
  try {
16416
- const fd = fs16.openSync(tmpPath, "r+");
16756
+ const fd = fs17.openSync(tmpPath, "r+");
16417
16757
  try {
16418
- fs16.fsyncSync(fd);
16758
+ fs17.fsyncSync(fd);
16419
16759
  } finally {
16420
- fs16.closeSync(fd);
16760
+ fs17.closeSync(fd);
16421
16761
  }
16422
16762
  } catch {}
16423
- fs16.renameSync(tmpPath, filePath);
16763
+ fs17.renameSync(tmpPath, filePath);
16424
16764
  readCache.delete(filePath);
16425
- const readback = fs16.readFileSync(filePath, "utf-8");
16765
+ const readback = fs17.readFileSync(filePath, "utf-8");
16426
16766
  const parsed = JSON.parse(readback);
16427
16767
  if (parsed?.version !== 2) {
16428
16768
  throw new Error("Round-trip readback returned wrong version");
@@ -17023,7 +17363,7 @@ var _internals27 = {
17023
17363
 
17024
17364
  // src/session/snapshot-writer.ts
17025
17365
  import { closeSync as closeSync6, fsyncSync as fsyncSync2, mkdirSync as mkdirSync14, openSync as openSync6, renameSync as renameSync8 } from "fs";
17026
- import * as path36 from "path";
17366
+ import * as path37 from "path";
17027
17367
  var _writeInFlight = Promise.resolve();
17028
17368
  function serializeAgentSession(s) {
17029
17369
  const gateLog = {};
@@ -17130,7 +17470,7 @@ async function writeSnapshot(directory, state) {
17130
17470
  }
17131
17471
  const content = JSON.stringify(snapshot, null, 2);
17132
17472
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
17133
- const dir = path36.dirname(resolvedPath);
17473
+ const dir = path37.dirname(resolvedPath);
17134
17474
  mkdirSync14(dir, { recursive: true });
17135
17475
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
17136
17476
  await bunWrite(tempPath, content);
@@ -17633,7 +17973,7 @@ ${USAGE6}`;
17633
17973
  }
17634
17974
 
17635
17975
  // src/commands/knowledge.ts
17636
- import { join as join30 } from "path";
17976
+ import { join as join31 } from "path";
17637
17977
 
17638
17978
  // src/hooks/knowledge-migrator.ts
17639
17979
  init_logger();
@@ -17641,7 +17981,7 @@ import { randomUUID as randomUUID4 } from "crypto";
17641
17981
  import { existsSync as existsSync22, readFileSync as readFileSync14 } from "fs";
17642
17982
  import { mkdir as mkdir9, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
17643
17983
  import * as os8 from "os";
17644
- import * as path37 from "path";
17984
+ import * as path38 from "path";
17645
17985
 
17646
17986
  // src/hooks/knowledge-types.ts
17647
17987
  var KNOWLEDGE_SCHEMA_VERSION = 2;
@@ -17671,8 +18011,8 @@ var _internals30 = {
17671
18011
  resolveLegacyHiveKnowledgePath
17672
18012
  };
17673
18013
  async function migrateContextToKnowledge(directory, config) {
17674
- const sentinelPath = path37.join(directory, ".swarm", ".knowledge-migrated");
17675
- const contextPath = path37.join(directory, ".swarm", "context.md");
18014
+ const sentinelPath = path38.join(directory, ".swarm", ".knowledge-migrated");
18015
+ const contextPath = path38.join(directory, ".swarm", "context.md");
17676
18016
  const knowledgePath = resolveSwarmKnowledgePath(directory);
17677
18017
  if (existsSync22(sentinelPath)) {
17678
18018
  return {
@@ -17774,7 +18114,7 @@ async function migrateContextToKnowledge(directory, config) {
17774
18114
  async function migrateHiveKnowledgeLegacy(config) {
17775
18115
  const legacyHivePath = _internals30.resolveLegacyHiveKnowledgePath();
17776
18116
  const canonicalHivePath = resolveHiveKnowledgePath();
17777
- const sentinelPath = path37.join(path37.dirname(canonicalHivePath), ".hive-knowledge-migrated");
18117
+ const sentinelPath = path38.join(path38.dirname(canonicalHivePath), ".hive-knowledge-migrated");
17778
18118
  if (existsSync22(sentinelPath)) {
17779
18119
  return {
17780
18120
  migrated: false,
@@ -17985,7 +18325,7 @@ function truncateLesson2(text) {
17985
18325
  return `${text.slice(0, 277)}...`;
17986
18326
  }
17987
18327
  function inferProjectName(directory) {
17988
- const packageJsonPath = path37.join(directory, "package.json");
18328
+ const packageJsonPath = path38.join(directory, "package.json");
17989
18329
  if (existsSync22(packageJsonPath)) {
17990
18330
  try {
17991
18331
  const pkg = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
@@ -17994,7 +18334,7 @@ function inferProjectName(directory) {
17994
18334
  }
17995
18335
  } catch {}
17996
18336
  }
17997
- return path37.basename(directory);
18337
+ return path38.basename(directory);
17998
18338
  }
17999
18339
  async function writeSentinel(sentinelPath, migrated, dropped) {
18000
18340
  const sentinel = {
@@ -18006,7 +18346,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
18006
18346
  schema_version: 1,
18007
18347
  migration_tool: "knowledge-migrator.ts"
18008
18348
  };
18009
- await mkdir9(path37.dirname(sentinelPath), { recursive: true });
18349
+ await mkdir9(path38.dirname(sentinelPath), { recursive: true });
18010
18350
  await writeFile9(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
18011
18351
  }
18012
18352
  function resolveLegacyHiveKnowledgePath() {
@@ -18014,13 +18354,13 @@ function resolveLegacyHiveKnowledgePath() {
18014
18354
  const home = process.env.HOME || os8.homedir();
18015
18355
  let dataDir;
18016
18356
  if (platform === "win32") {
18017
- dataDir = path37.join(process.env.LOCALAPPDATA || path37.join(home, "AppData", "Local"), "opencode-swarm", "Data");
18357
+ dataDir = path38.join(process.env.LOCALAPPDATA || path38.join(home, "AppData", "Local"), "opencode-swarm", "Data");
18018
18358
  } else if (platform === "darwin") {
18019
- dataDir = path37.join(home, "Library", "Application Support", "opencode-swarm");
18359
+ dataDir = path38.join(home, "Library", "Application Support", "opencode-swarm");
18020
18360
  } else {
18021
- dataDir = path37.join(process.env.XDG_DATA_HOME || path37.join(home, ".local", "share"), "opencode-swarm");
18361
+ dataDir = path38.join(process.env.XDG_DATA_HOME || path38.join(home, ".local", "share"), "opencode-swarm");
18022
18362
  }
18023
- return path37.join(dataDir, "hive-knowledge.jsonl");
18363
+ return path38.join(dataDir, "hive-knowledge.jsonl");
18024
18364
  }
18025
18365
 
18026
18366
  // src/commands/knowledge.ts
@@ -18074,7 +18414,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
18074
18414
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
18075
18415
  }
18076
18416
  try {
18077
- const quarantinePath = join30(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
18417
+ const quarantinePath = join31(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
18078
18418
  const entries = await readKnowledge(quarantinePath);
18079
18419
  const resolved = resolveEntryByPrefix(entries, inputId);
18080
18420
  if ("error" in resolved) {
@@ -18326,14 +18666,14 @@ var _internals31 = {
18326
18666
 
18327
18667
  // src/commands/link.ts
18328
18668
  import { existsSync as existsSync23 } from "fs";
18329
- import * as path39 from "path";
18669
+ import * as path40 from "path";
18330
18670
 
18331
18671
  // src/knowledge/identity.ts
18332
18672
  import * as child_process5 from "child_process";
18333
18673
  import { createHash as createHash4 } from "crypto";
18334
- import * as path38 from "path";
18674
+ import * as path39 from "path";
18335
18675
  function deriveProjectHash(directory) {
18336
- const absolutePath = path38.resolve(directory);
18676
+ const absolutePath = path39.resolve(directory);
18337
18677
  let hashInput;
18338
18678
  try {
18339
18679
  const remoteUrl = child_process5.execSync("git remote get-url origin", {
@@ -18353,8 +18693,8 @@ function deriveProjectHash(directory) {
18353
18693
  // src/commands/link.ts
18354
18694
  var DEDUP_THRESHOLD = 0.6;
18355
18695
  async function mergeLocalKnowledgeIntoLink(localSwarmDir, linkDir) {
18356
- const localPath = path39.join(localSwarmDir, "knowledge.jsonl");
18357
- const sharedPath = path39.join(linkDir, "knowledge.jsonl");
18696
+ const localPath = path40.join(localSwarmDir, "knowledge.jsonl");
18697
+ const sharedPath = path40.join(linkDir, "knowledge.jsonl");
18358
18698
  if (!existsSync23(localPath))
18359
18699
  return { merged: 0, skipped: 0 };
18360
18700
  let merged = 0;
@@ -18452,7 +18792,7 @@ ${formatStatus(directory)}`;
18452
18792
  const linkDir = resolveLinkDir(linkId);
18453
18793
  let merge;
18454
18794
  try {
18455
- merge = await mergeLocalKnowledgeIntoLink(path39.join(directory, ".swarm"), linkDir);
18795
+ merge = await mergeLocalKnowledgeIntoLink(path40.join(directory, ".swarm"), linkDir);
18456
18796
  } catch (error2) {
18457
18797
  return `\u274C Failed to merge local knowledge into the link store: ${error2 instanceof Error ? error2.message : String(error2)}`;
18458
18798
  }
@@ -18597,7 +18937,7 @@ ${USAGE7}`;
18597
18937
 
18598
18938
  // src/commands/memory.ts
18599
18939
  import { existsSync as existsSync26 } from "fs";
18600
- import * as path46 from "path";
18940
+ import * as path47 from "path";
18601
18941
  import { fileURLToPath as fileURLToPath2 } from "url";
18602
18942
 
18603
18943
  // src/memory/config.ts
@@ -18737,9 +19077,9 @@ class MemoryValidationError extends Error {
18737
19077
  }
18738
19078
  }
18739
19079
  // src/memory/evaluation.ts
18740
- import * as fs17 from "fs/promises";
19080
+ import * as fs18 from "fs/promises";
18741
19081
  import * as os9 from "os";
18742
- import * as path44 from "path";
19082
+ import * as path45 from "path";
18743
19083
 
18744
19084
  // src/memory/local-jsonl-provider.ts
18745
19085
  import { randomUUID as randomUUID5 } from "crypto";
@@ -18751,7 +19091,7 @@ import {
18751
19091
  rename as rename5,
18752
19092
  writeFile as writeFile10
18753
19093
  } from "fs/promises";
18754
- import * as path40 from "path";
19094
+ import * as path41 from "path";
18755
19095
 
18756
19096
  // src/memory/schema.ts
18757
19097
  import { createHash as createHash5 } from "crypto";
@@ -19612,7 +19952,7 @@ class LocalJsonlMemoryProvider {
19612
19952
  pathFor(file) {
19613
19953
  const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
19614
19954
  const filename = file === "memories" ? "memories.jsonl" : file === "proposals" ? "proposals.jsonl" : "audit.jsonl";
19615
- return validateSwarmPath(this.rootDirectory, path40.join(storageDir, filename));
19955
+ return validateSwarmPath(this.rootDirectory, path41.join(storageDir, filename));
19616
19956
  }
19617
19957
  async initialize() {
19618
19958
  if (this.initialized)
@@ -19995,12 +20335,12 @@ function parseRecallUsageEvent(event) {
19995
20335
  }
19996
20336
  }
19997
20337
  async function appendJsonl(filePath, value) {
19998
- await mkdir10(path40.dirname(filePath), { recursive: true });
20338
+ await mkdir10(path41.dirname(filePath), { recursive: true });
19999
20339
  await appendFile3(filePath, `${JSON.stringify(value)}
20000
20340
  `, "utf-8");
20001
20341
  }
20002
20342
  async function writeJsonlAtomic(filePath, values) {
20003
- await mkdir10(path40.dirname(filePath), { recursive: true });
20343
+ await mkdir10(path41.dirname(filePath), { recursive: true });
20004
20344
  const tmp = `${filePath}.tmp.${randomUUID5()}`;
20005
20345
  const content = values.map((value) => JSON.stringify(value)).join(`
20006
20346
  `) + (values.length > 0 ? `
@@ -20011,18 +20351,18 @@ async function writeJsonlAtomic(filePath, values) {
20011
20351
 
20012
20352
  // src/memory/provider-pool.ts
20013
20353
  import { realpathSync as realpathSync2 } from "fs";
20014
- import * as path43 from "path";
20354
+ import * as path44 from "path";
20015
20355
 
20016
20356
  // src/memory/sqlite-provider.ts
20017
20357
  import { randomUUID as randomUUID6 } from "crypto";
20018
20358
  import { mkdirSync as mkdirSync15 } from "fs";
20019
20359
  import { createRequire as createRequire2 } from "module";
20020
- import * as path42 from "path";
20360
+ import * as path43 from "path";
20021
20361
 
20022
20362
  // src/memory/jsonl-migration.ts
20023
20363
  import { existsSync as existsSync25, renameSync as renameSync10, unlinkSync as unlinkSync6 } from "fs";
20024
20364
  import { copyFile as copyFile2, mkdir as mkdir11, readFile as readFile13, stat as stat5, writeFile as writeFile11 } from "fs/promises";
20025
- import * as path41 from "path";
20365
+ import * as path42 from "path";
20026
20366
  var LEGACY_JSONL_MIGRATION_VERSION = 2;
20027
20367
  var LEGACY_JSONL_MIGRATION_NAME = "legacy_jsonl_import_complete";
20028
20368
  function resolveMemoryStorageDir(rootDirectory, config = {}) {
@@ -20038,8 +20378,8 @@ function resolveSqliteDatabasePath(rootDirectory, config = {}) {
20038
20378
  async function readLegacyJsonl(rootDirectory, config = {}) {
20039
20379
  const resolved = resolveConfig(config);
20040
20380
  const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
20041
- const memoryLoad = await readMemoryJsonl(path41.join(storageDir, "memories.jsonl"), resolved);
20042
- const proposalLoad = await readProposalJsonl(path41.join(storageDir, "proposals.jsonl"), resolved);
20381
+ const memoryLoad = await readMemoryJsonl(path42.join(storageDir, "memories.jsonl"), resolved);
20382
+ const proposalLoad = await readProposalJsonl(path42.join(storageDir, "proposals.jsonl"), resolved);
20043
20383
  return {
20044
20384
  memories: memoryLoad.records,
20045
20385
  proposals: proposalLoad.records,
@@ -20049,14 +20389,14 @@ async function readLegacyJsonl(rootDirectory, config = {}) {
20049
20389
  }
20050
20390
  async function backupLegacyJsonl(rootDirectory, config = {}) {
20051
20391
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
20052
- const backupDir = path41.join(storageDir, "backups");
20392
+ const backupDir = path42.join(storageDir, "backups");
20053
20393
  await mkdir11(backupDir, { recursive: true });
20054
20394
  const results = [];
20055
20395
  for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
20056
- const source = path41.join(storageDir, filename);
20396
+ const source = path42.join(storageDir, filename);
20057
20397
  if (!existsSync25(source))
20058
20398
  continue;
20059
- const backup = path41.join(backupDir, `${filename}.pre-sqlite-migration`);
20399
+ const backup = path42.join(backupDir, `${filename}.pre-sqlite-migration`);
20060
20400
  if (existsSync25(backup)) {
20061
20401
  results.push({ source, backup, created: false });
20062
20402
  continue;
@@ -20067,11 +20407,11 @@ async function backupLegacyJsonl(rootDirectory, config = {}) {
20067
20407
  return results;
20068
20408
  }
20069
20409
  async function writeJsonlExport(rootDirectory, config, memories, proposals) {
20070
- const exportDir = path41.join(resolveMemoryStorageDir(rootDirectory, config), "export");
20410
+ const exportDir = path42.join(resolveMemoryStorageDir(rootDirectory, config), "export");
20071
20411
  await mkdir11(exportDir, { recursive: true });
20072
- const memoriesPath = path41.join(exportDir, "memories.jsonl");
20073
- const proposalsPath = path41.join(exportDir, "proposals.jsonl");
20074
- const memoriesTempPath = path41.join(path41.dirname(memoriesPath), `${path41.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20412
+ const memoriesPath = path42.join(exportDir, "memories.jsonl");
20413
+ const proposalsPath = path42.join(exportDir, "proposals.jsonl");
20414
+ const memoriesTempPath = path42.join(path42.dirname(memoriesPath), `${path42.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20075
20415
  try {
20076
20416
  await writeFile11(memoriesTempPath, toJsonl(memories), "utf-8");
20077
20417
  renameSync10(memoriesTempPath, memoriesPath);
@@ -20081,7 +20421,7 @@ async function writeJsonlExport(rootDirectory, config, memories, proposals) {
20081
20421
  } catch {}
20082
20422
  throw err;
20083
20423
  }
20084
- const proposalsTempPath = path41.join(path41.dirname(proposalsPath), `${path41.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20424
+ const proposalsTempPath = path42.join(path42.dirname(proposalsPath), `${path42.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20085
20425
  try {
20086
20426
  await writeFile11(proposalsTempPath, toJsonl(proposals), "utf-8");
20087
20427
  renameSync10(proposalsTempPath, proposalsPath);
@@ -20094,9 +20434,9 @@ async function writeJsonlExport(rootDirectory, config, memories, proposals) {
20094
20434
  return { directory: exportDir, memoriesPath, proposalsPath };
20095
20435
  }
20096
20436
  async function writeMigrationReport(rootDirectory, report, config = {}) {
20097
- const reportPath = path41.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
20098
- await mkdir11(path41.dirname(reportPath), { recursive: true });
20099
- const reportTempPath = path41.join(path41.dirname(reportPath), `${path41.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20437
+ const reportPath = path42.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
20438
+ await mkdir11(path42.dirname(reportPath), { recursive: true });
20439
+ const reportTempPath = path42.join(path42.dirname(reportPath), `${path42.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20100
20440
  try {
20101
20441
  await writeFile11(reportTempPath, `${JSON.stringify(report, null, 2)}
20102
20442
  `, "utf-8");
@@ -20110,7 +20450,7 @@ async function writeMigrationReport(rootDirectory, report, config = {}) {
20110
20450
  return reportPath;
20111
20451
  }
20112
20452
  async function readMigrationReport(rootDirectory, config = {}) {
20113
- const reportPath = path41.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
20453
+ const reportPath = path42.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
20114
20454
  if (!existsSync25(reportPath))
20115
20455
  return null;
20116
20456
  try {
@@ -20123,7 +20463,7 @@ async function getLegacyJsonlFileStatus(rootDirectory, config = {}) {
20123
20463
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
20124
20464
  const statuses = [];
20125
20465
  for (const file of ["memories.jsonl", "proposals.jsonl"]) {
20126
- const filePath = path41.join(storageDir, file);
20466
+ const filePath = path42.join(storageDir, file);
20127
20467
  let sizeBytes = 0;
20128
20468
  if (existsSync25(filePath)) {
20129
20469
  sizeBytes = (await stat5(filePath)).size;
@@ -20431,7 +20771,7 @@ class SQLiteMemoryProvider {
20431
20771
  }
20432
20772
  async doInitialize() {
20433
20773
  const dbPath = this.databasePath();
20434
- mkdirSync15(path42.dirname(dbPath), { recursive: true });
20774
+ mkdirSync15(path43.dirname(dbPath), { recursive: true });
20435
20775
  const Db = loadDatabaseCtor2();
20436
20776
  this.db = new Db(dbPath);
20437
20777
  this.db.run("PRAGMA journal_mode = WAL;");
@@ -21460,7 +21800,7 @@ function resolvePoolKey(directory) {
21460
21800
  try {
21461
21801
  return realpathSync2(directory);
21462
21802
  } catch {
21463
- return path43.resolve(directory);
21803
+ return path44.resolve(directory);
21464
21804
  }
21465
21805
  }
21466
21806
 
@@ -21532,7 +21872,7 @@ var DEFAULT_MODES = [
21532
21872
  ];
21533
21873
  var DEFAULT_TIMESTAMP = "2026-05-26T12:00:00.000Z";
21534
21874
  async function evaluateMemoryRecallFixtures(options) {
21535
- const fixtureDirectory = path44.resolve(options.fixtureDirectory);
21875
+ const fixtureDirectory = path45.resolve(options.fixtureDirectory);
21536
21876
  const providers = options.providers ?? DEFAULT_PROVIDERS;
21537
21877
  const modes = options.modes ?? DEFAULT_MODES;
21538
21878
  const generatedAt = new Date().toISOString();
@@ -21541,7 +21881,7 @@ async function evaluateMemoryRecallFixtures(options) {
21541
21881
  for (const fixture of fixtures) {
21542
21882
  const materialized = materializeFixture(fixture);
21543
21883
  for (const providerName of providers) {
21544
- const tempRoot = await fs17.realpath(await fs17.mkdtemp(path44.join(os9.tmpdir(), "swarm-memory-eval-")));
21884
+ const tempRoot = await fs18.realpath(await fs18.mkdtemp(path45.join(os9.tmpdir(), "swarm-memory-eval-")));
21545
21885
  const provider = createEvaluationProvider(providerName, tempRoot);
21546
21886
  try {
21547
21887
  await provider.initialize?.();
@@ -21565,7 +21905,7 @@ async function evaluateMemoryRecallFixtures(options) {
21565
21905
  } finally {
21566
21906
  await provider.close?.();
21567
21907
  if (!options.keepTempRoots) {
21568
- await fs17.rm(tempRoot, { recursive: true, force: true });
21908
+ await fs18.rm(tempRoot, { recursive: true, force: true });
21569
21909
  }
21570
21910
  }
21571
21911
  }
@@ -21581,11 +21921,11 @@ async function evaluateMemoryRecallFixtures(options) {
21581
21921
  };
21582
21922
  }
21583
21923
  async function loadRecallEvaluationFixtures(fixtureDirectory) {
21584
- const entries = await fs17.readdir(fixtureDirectory, { withFileTypes: true });
21924
+ const entries = await fs18.readdir(fixtureDirectory, { withFileTypes: true });
21585
21925
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
21586
21926
  const fixtures = [];
21587
21927
  for (const file of files) {
21588
- const raw = await fs17.readFile(path44.join(fixtureDirectory, file), "utf-8");
21928
+ const raw = await fs18.readFile(path45.join(fixtureDirectory, file), "utf-8");
21589
21929
  fixtures.push(validateFixture(JSON.parse(raw), file));
21590
21930
  }
21591
21931
  return fixtures;
@@ -21862,8 +22202,8 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
21862
22202
  }).passthrough();
21863
22203
  // src/memory/consolidation-log.ts
21864
22204
  import { appendFile as appendFile4, mkdir as mkdir12, readFile as readFile15 } from "fs/promises";
21865
- import * as path45 from "path";
21866
- var LOG_RELATIVE_PATH = path45.join("memory", "consolidation-log.jsonl");
22205
+ import * as path46 from "path";
22206
+ var LOG_RELATIVE_PATH = path46.join("memory", "consolidation-log.jsonl");
21867
22207
  async function readConsolidationLog(directory) {
21868
22208
  const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
21869
22209
  let raw;
@@ -21886,7 +22226,7 @@ async function readConsolidationLog(directory) {
21886
22226
  }
21887
22227
 
21888
22228
  // src/commands/memory.ts
21889
- var PACKAGE_ROOT = path46.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
22229
+ var PACKAGE_ROOT = path47.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
21890
22230
  async function handleMemoryCommand(_directory, _args) {
21891
22231
  return [
21892
22232
  "## Swarm Memory",
@@ -22184,7 +22524,7 @@ function resolveCommandMemoryConfig(directory) {
22184
22524
  }
22185
22525
  function parseEvaluateArgs(directory, args) {
22186
22526
  let json = false;
22187
- let fixtureDirectory = path46.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
22527
+ let fixtureDirectory = path47.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
22188
22528
  for (let i = 0;i < args.length; i++) {
22189
22529
  const arg = args[i];
22190
22530
  if (arg === "--json") {
@@ -22198,10 +22538,10 @@ function parseEvaluateArgs(directory, args) {
22198
22538
  error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
22199
22539
  };
22200
22540
  }
22201
- const resolvedFixtures = path46.resolve(directory, next);
22202
- const canonical = path46.normalize(resolvedFixtures) + path46.sep;
22203
- const allowedRootA = path46.normalize(directory) + path46.sep;
22204
- const allowedRootB = path46.normalize(path46.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path46.sep;
22541
+ const resolvedFixtures = path47.resolve(directory, next);
22542
+ const canonical = path47.normalize(resolvedFixtures) + path47.sep;
22543
+ const allowedRootA = path47.normalize(directory) + path47.sep;
22544
+ const allowedRootB = path47.normalize(path47.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path47.sep;
22205
22545
  if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
22206
22546
  return {
22207
22547
  error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
@@ -22240,15 +22580,15 @@ function parseMaintenanceArgs(args, options) {
22240
22580
  return { limit, confirm };
22241
22581
  }
22242
22582
  function resolvePackageRootFromModule(modulePath) {
22243
- const moduleDir = path46.dirname(modulePath);
22244
- const leaf = path46.basename(moduleDir);
22583
+ const moduleDir = path47.dirname(modulePath);
22584
+ const leaf = path47.basename(moduleDir);
22245
22585
  if (leaf === "commands" || leaf === "cli") {
22246
- return path46.resolve(moduleDir, "..", "..");
22586
+ return path47.resolve(moduleDir, "..", "..");
22247
22587
  }
22248
22588
  if (leaf === "dist") {
22249
- return path46.resolve(moduleDir, "..");
22589
+ return path47.resolve(moduleDir, "..");
22250
22590
  }
22251
- return path46.resolve(moduleDir, "..");
22591
+ return path47.resolve(moduleDir, "..");
22252
22592
  }
22253
22593
  function formatMigrationResult(label, report) {
22254
22594
  if (!report) {
@@ -22942,12 +23282,12 @@ var _internals36 = {
22942
23282
  };
22943
23283
 
22944
23284
  // src/services/preflight-service.ts
22945
- import * as fs24 from "fs";
22946
- import * as path53 from "path";
23285
+ import * as fs25 from "fs";
23286
+ import * as path54 from "path";
22947
23287
 
22948
23288
  // src/tools/lint.ts
22949
- import * as fs18 from "fs";
22950
- import * as path47 from "path";
23289
+ import * as fs19 from "fs";
23290
+ import * as path48 from "path";
22951
23291
 
22952
23292
  // src/utils/path-security.ts
22953
23293
  function containsPathTraversal(str) {
@@ -23003,9 +23343,9 @@ function validateArgs(args) {
23003
23343
  }
23004
23344
  function getLinterCommand(linter, mode, projectDir) {
23005
23345
  const isWindows = process.platform === "win32";
23006
- const binDir = path47.join(projectDir, "node_modules", ".bin");
23007
- const biomeBin = isWindows ? path47.join(binDir, "biome.EXE") : path47.join(binDir, "biome");
23008
- const eslintBin = isWindows ? path47.join(binDir, "eslint.cmd") : path47.join(binDir, "eslint");
23346
+ const binDir = path48.join(projectDir, "node_modules", ".bin");
23347
+ const biomeBin = isWindows ? path48.join(binDir, "biome.EXE") : path48.join(binDir, "biome");
23348
+ const eslintBin = isWindows ? path48.join(binDir, "eslint.cmd") : path48.join(binDir, "eslint");
23009
23349
  switch (linter) {
23010
23350
  case "biome":
23011
23351
  if (mode === "fix") {
@@ -23021,7 +23361,7 @@ function getLinterCommand(linter, mode, projectDir) {
23021
23361
  }
23022
23362
  function getAdditionalLinterCommand(linter, mode, cwd) {
23023
23363
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
23024
- const gradlew = fs18.existsSync(path47.join(cwd, gradlewName)) ? path47.join(cwd, gradlewName) : null;
23364
+ const gradlew = fs19.existsSync(path48.join(cwd, gradlewName)) ? path48.join(cwd, gradlewName) : null;
23025
23365
  switch (linter) {
23026
23366
  case "ruff":
23027
23367
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -23055,12 +23395,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
23055
23395
  }
23056
23396
  }
23057
23397
  function detectRuff(cwd) {
23058
- if (fs18.existsSync(path47.join(cwd, "ruff.toml")))
23398
+ if (fs19.existsSync(path48.join(cwd, "ruff.toml")))
23059
23399
  return isCommandAvailable("ruff");
23060
23400
  try {
23061
- const pyproject = path47.join(cwd, "pyproject.toml");
23062
- if (fs18.existsSync(pyproject)) {
23063
- const content = fs18.readFileSync(pyproject, "utf-8");
23401
+ const pyproject = path48.join(cwd, "pyproject.toml");
23402
+ if (fs19.existsSync(pyproject)) {
23403
+ const content = fs19.readFileSync(pyproject, "utf-8");
23064
23404
  if (content.includes("[tool.ruff]"))
23065
23405
  return isCommandAvailable("ruff");
23066
23406
  }
@@ -23068,21 +23408,21 @@ function detectRuff(cwd) {
23068
23408
  return false;
23069
23409
  }
23070
23410
  function detectClippy(cwd) {
23071
- return fs18.existsSync(path47.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
23411
+ return fs19.existsSync(path48.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
23072
23412
  }
23073
23413
  function detectGolangciLint(cwd) {
23074
- return fs18.existsSync(path47.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
23414
+ return fs19.existsSync(path48.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
23075
23415
  }
23076
23416
  function detectCheckstyle(cwd) {
23077
- const hasMaven = fs18.existsSync(path47.join(cwd, "pom.xml"));
23078
- const hasGradle = fs18.existsSync(path47.join(cwd, "build.gradle")) || fs18.existsSync(path47.join(cwd, "build.gradle.kts"));
23079
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs18.existsSync(path47.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
23417
+ const hasMaven = fs19.existsSync(path48.join(cwd, "pom.xml"));
23418
+ const hasGradle = fs19.existsSync(path48.join(cwd, "build.gradle")) || fs19.existsSync(path48.join(cwd, "build.gradle.kts"));
23419
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs19.existsSync(path48.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
23080
23420
  return (hasMaven || hasGradle) && hasBinary;
23081
23421
  }
23082
23422
  function detectKtlint(cwd) {
23083
- const hasKotlin = fs18.existsSync(path47.join(cwd, "build.gradle.kts")) || fs18.existsSync(path47.join(cwd, "build.gradle")) || (() => {
23423
+ const hasKotlin = fs19.existsSync(path48.join(cwd, "build.gradle.kts")) || fs19.existsSync(path48.join(cwd, "build.gradle")) || (() => {
23084
23424
  try {
23085
- return fs18.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
23425
+ return fs19.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
23086
23426
  } catch {
23087
23427
  return false;
23088
23428
  }
@@ -23091,7 +23431,7 @@ function detectKtlint(cwd) {
23091
23431
  }
23092
23432
  function detectDotnetFormat(cwd) {
23093
23433
  try {
23094
- const files = fs18.readdirSync(cwd);
23434
+ const files = fs19.readdirSync(cwd);
23095
23435
  const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
23096
23436
  return hasCsproj && isCommandAvailable("dotnet");
23097
23437
  } catch {
@@ -23099,14 +23439,14 @@ function detectDotnetFormat(cwd) {
23099
23439
  }
23100
23440
  }
23101
23441
  function detectCppcheck(cwd) {
23102
- if (fs18.existsSync(path47.join(cwd, "CMakeLists.txt"))) {
23442
+ if (fs19.existsSync(path48.join(cwd, "CMakeLists.txt"))) {
23103
23443
  return isCommandAvailable("cppcheck");
23104
23444
  }
23105
23445
  try {
23106
- const dirsToCheck = [cwd, path47.join(cwd, "src")];
23446
+ const dirsToCheck = [cwd, path48.join(cwd, "src")];
23107
23447
  const hasCpp = dirsToCheck.some((dir) => {
23108
23448
  try {
23109
- return fs18.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
23449
+ return fs19.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
23110
23450
  } catch {
23111
23451
  return false;
23112
23452
  }
@@ -23117,13 +23457,13 @@ function detectCppcheck(cwd) {
23117
23457
  }
23118
23458
  }
23119
23459
  function detectSwiftlint(cwd) {
23120
- return fs18.existsSync(path47.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
23460
+ return fs19.existsSync(path48.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
23121
23461
  }
23122
23462
  function detectDartAnalyze(cwd) {
23123
- return fs18.existsSync(path47.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
23463
+ return fs19.existsSync(path48.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
23124
23464
  }
23125
23465
  function detectRubocop(cwd) {
23126
- return (fs18.existsSync(path47.join(cwd, "Gemfile")) || fs18.existsSync(path47.join(cwd, "gems.rb")) || fs18.existsSync(path47.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
23466
+ return (fs19.existsSync(path48.join(cwd, "Gemfile")) || fs19.existsSync(path48.join(cwd, "gems.rb")) || fs19.existsSync(path48.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
23127
23467
  }
23128
23468
  function detectAdditionalLinter(cwd) {
23129
23469
  if (detectRuff(cwd))
@@ -23151,10 +23491,10 @@ function detectAdditionalLinter(cwd) {
23151
23491
  function findBinInAncestors(startDir, binName) {
23152
23492
  let dir = startDir;
23153
23493
  while (true) {
23154
- const candidate = path47.join(dir, "node_modules", ".bin", binName);
23155
- if (fs18.existsSync(candidate))
23494
+ const candidate = path48.join(dir, "node_modules", ".bin", binName);
23495
+ if (fs19.existsSync(candidate))
23156
23496
  return candidate;
23157
- const parent = path47.dirname(dir);
23497
+ const parent = path48.dirname(dir);
23158
23498
  if (parent === dir)
23159
23499
  break;
23160
23500
  dir = parent;
@@ -23163,11 +23503,11 @@ function findBinInAncestors(startDir, binName) {
23163
23503
  }
23164
23504
  function findBinInEnvPath(binName) {
23165
23505
  const searchPath = process.env.PATH ?? "";
23166
- for (const dir of searchPath.split(path47.delimiter)) {
23506
+ for (const dir of searchPath.split(path48.delimiter)) {
23167
23507
  if (!dir)
23168
23508
  continue;
23169
- const candidate = path47.join(dir, binName);
23170
- if (fs18.existsSync(candidate))
23509
+ const candidate = path48.join(dir, binName);
23510
+ if (fs19.existsSync(candidate))
23171
23511
  return candidate;
23172
23512
  }
23173
23513
  return null;
@@ -23175,17 +23515,17 @@ function findBinInEnvPath(binName) {
23175
23515
  async function detectAvailableLinter(directory) {
23176
23516
  if (!directory)
23177
23517
  return null;
23178
- if (!fs18.existsSync(directory))
23518
+ if (!fs19.existsSync(directory))
23179
23519
  return null;
23180
23520
  const projectDir = directory;
23181
23521
  const isWindows = process.platform === "win32";
23182
- const biomeBin = isWindows ? path47.join(projectDir, "node_modules", ".bin", "biome.EXE") : path47.join(projectDir, "node_modules", ".bin", "biome");
23183
- const eslintBin = isWindows ? path47.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path47.join(projectDir, "node_modules", ".bin", "eslint");
23522
+ const biomeBin = isWindows ? path48.join(projectDir, "node_modules", ".bin", "biome.EXE") : path48.join(projectDir, "node_modules", ".bin", "biome");
23523
+ const eslintBin = isWindows ? path48.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path48.join(projectDir, "node_modules", ".bin", "eslint");
23184
23524
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
23185
23525
  if (localResult)
23186
23526
  return localResult;
23187
- const biomeAncestor = findBinInAncestors(path47.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
23188
- const eslintAncestor = findBinInAncestors(path47.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
23527
+ const biomeAncestor = findBinInAncestors(path48.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
23528
+ const eslintAncestor = findBinInAncestors(path48.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
23189
23529
  if (biomeAncestor || eslintAncestor) {
23190
23530
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
23191
23531
  }
@@ -23208,7 +23548,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
23208
23548
  const result = await Promise.race([biomeExit, timeout]);
23209
23549
  if (result === "timeout") {
23210
23550
  biomeProc.kill();
23211
- } else if (biomeProc.exitCode === 0 && fs18.existsSync(biomeBin)) {
23551
+ } else if (biomeProc.exitCode === 0 && fs19.existsSync(biomeBin)) {
23212
23552
  return "biome";
23213
23553
  }
23214
23554
  } catch {}
@@ -23222,7 +23562,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
23222
23562
  const result = await Promise.race([eslintExit, timeout]);
23223
23563
  if (result === "timeout") {
23224
23564
  eslintProc.kill();
23225
- } else if (eslintProc.exitCode === 0 && fs18.existsSync(eslintBin)) {
23565
+ } else if (eslintProc.exitCode === 0 && fs19.existsSync(eslintBin)) {
23226
23566
  return "eslint";
23227
23567
  }
23228
23568
  } catch {}
@@ -23398,8 +23738,8 @@ var _internals37 = {
23398
23738
  };
23399
23739
 
23400
23740
  // src/tools/secretscan.ts
23401
- import * as fs19 from "fs";
23402
- import * as path48 from "path";
23741
+ import * as fs20 from "fs";
23742
+ import * as path49 from "path";
23403
23743
  var MAX_FILE_PATH_LENGTH = 500;
23404
23744
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
23405
23745
  var MAX_FILES_SCANNED = 1000;
@@ -23626,11 +23966,11 @@ function isGlobOrPathPattern(pattern) {
23626
23966
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
23627
23967
  }
23628
23968
  function loadSecretScanIgnore(scanDir) {
23629
- const ignorePath = path48.join(scanDir, ".secretscanignore");
23969
+ const ignorePath = path49.join(scanDir, ".secretscanignore");
23630
23970
  try {
23631
- if (!fs19.existsSync(ignorePath))
23971
+ if (!fs20.existsSync(ignorePath))
23632
23972
  return [];
23633
- const content = fs19.readFileSync(ignorePath, "utf8");
23973
+ const content = fs20.readFileSync(ignorePath, "utf8");
23634
23974
  const patterns = [];
23635
23975
  for (const rawLine of content.split(/\r?\n/)) {
23636
23976
  const line = rawLine.trim();
@@ -23649,7 +23989,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
23649
23989
  if (exactNames.has(entry))
23650
23990
  return true;
23651
23991
  for (const pattern of globPatterns) {
23652
- if (path48.matchesGlob(relPath, pattern))
23992
+ if (path49.matchesGlob(relPath, pattern))
23653
23993
  return true;
23654
23994
  }
23655
23995
  return false;
@@ -23670,7 +24010,7 @@ function validateDirectoryInput(dir) {
23670
24010
  return null;
23671
24011
  }
23672
24012
  function isBinaryFile(filePath, buffer) {
23673
- const ext = path48.extname(filePath).toLowerCase();
24013
+ const ext = path49.extname(filePath).toLowerCase();
23674
24014
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
23675
24015
  return true;
23676
24016
  }
@@ -23745,11 +24085,11 @@ function createRedactedContext(line, findings) {
23745
24085
  result += line.slice(lastEnd);
23746
24086
  return result;
23747
24087
  }
23748
- var O_NOFOLLOW = process.platform !== "win32" ? fs19.constants.O_NOFOLLOW : undefined;
24088
+ var O_NOFOLLOW = process.platform !== "win32" ? fs20.constants.O_NOFOLLOW : undefined;
23749
24089
  function scanFileForSecrets(filePath) {
23750
24090
  const findings = [];
23751
24091
  try {
23752
- const lstat2 = fs19.lstatSync(filePath);
24092
+ const lstat2 = fs20.lstatSync(filePath);
23753
24093
  if (lstat2.isSymbolicLink()) {
23754
24094
  return findings;
23755
24095
  }
@@ -23758,14 +24098,14 @@ function scanFileForSecrets(filePath) {
23758
24098
  }
23759
24099
  let buffer;
23760
24100
  if (O_NOFOLLOW !== undefined) {
23761
- const fd = fs19.openSync(filePath, "r", O_NOFOLLOW);
24101
+ const fd = fs20.openSync(filePath, "r", O_NOFOLLOW);
23762
24102
  try {
23763
- buffer = fs19.readFileSync(fd);
24103
+ buffer = fs20.readFileSync(fd);
23764
24104
  } finally {
23765
- fs19.closeSync(fd);
24105
+ fs20.closeSync(fd);
23766
24106
  }
23767
24107
  } else {
23768
- buffer = fs19.readFileSync(filePath);
24108
+ buffer = fs20.readFileSync(filePath);
23769
24109
  }
23770
24110
  if (isBinaryFile(filePath, buffer)) {
23771
24111
  return findings;
@@ -23807,9 +24147,9 @@ function isSymlinkLoop(realPath, visited) {
23807
24147
  return false;
23808
24148
  }
23809
24149
  function isPathWithinScope(realPath, scanDir) {
23810
- const resolvedScanDir = path48.resolve(scanDir);
23811
- const resolvedRealPath = path48.resolve(realPath);
23812
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path48.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
24150
+ const resolvedScanDir = path49.resolve(scanDir);
24151
+ const resolvedRealPath = path49.resolve(realPath);
24152
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path49.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
23813
24153
  }
23814
24154
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
23815
24155
  skippedDirs: 0,
@@ -23820,7 +24160,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
23820
24160
  const files = [];
23821
24161
  let entries;
23822
24162
  try {
23823
- entries = fs19.readdirSync(dir);
24163
+ entries = fs20.readdirSync(dir);
23824
24164
  } catch {
23825
24165
  stats.fileErrors++;
23826
24166
  return files;
@@ -23835,15 +24175,15 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
23835
24175
  return a.localeCompare(b);
23836
24176
  });
23837
24177
  for (const entry of entries) {
23838
- const fullPath = path48.join(dir, entry);
23839
- const relPath = path48.relative(scanDir, fullPath).replace(/\\/g, "/");
24178
+ const fullPath = path49.join(dir, entry);
24179
+ const relPath = path49.relative(scanDir, fullPath).replace(/\\/g, "/");
23840
24180
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
23841
24181
  stats.skippedDirs++;
23842
24182
  continue;
23843
24183
  }
23844
24184
  let lstat2;
23845
24185
  try {
23846
- lstat2 = fs19.lstatSync(fullPath);
24186
+ lstat2 = fs20.lstatSync(fullPath);
23847
24187
  } catch {
23848
24188
  stats.fileErrors++;
23849
24189
  continue;
@@ -23855,7 +24195,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
23855
24195
  if (lstat2.isDirectory()) {
23856
24196
  let realPath;
23857
24197
  try {
23858
- realPath = fs19.realpathSync(fullPath);
24198
+ realPath = fs20.realpathSync(fullPath);
23859
24199
  } catch {
23860
24200
  stats.fileErrors++;
23861
24201
  continue;
@@ -23871,7 +24211,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
23871
24211
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
23872
24212
  files.push(...subFiles);
23873
24213
  } else if (lstat2.isFile()) {
23874
- const ext = path48.extname(fullPath).toLowerCase();
24214
+ const ext = path49.extname(fullPath).toLowerCase();
23875
24215
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
23876
24216
  files.push(fullPath);
23877
24217
  } else {
@@ -23937,15 +24277,15 @@ var secretscan = createSwarmTool({
23937
24277
  }
23938
24278
  }
23939
24279
  try {
23940
- const _scanDirRaw = path48.resolve(directory);
24280
+ const _scanDirRaw = path49.resolve(directory);
23941
24281
  const scanDir = (() => {
23942
24282
  try {
23943
- return fs19.realpathSync(_scanDirRaw);
24283
+ return fs20.realpathSync(_scanDirRaw);
23944
24284
  } catch {
23945
24285
  return _scanDirRaw;
23946
24286
  }
23947
24287
  })();
23948
- if (!fs19.existsSync(scanDir)) {
24288
+ if (!fs20.existsSync(scanDir)) {
23949
24289
  const errorResult = {
23950
24290
  error: "directory not found",
23951
24291
  scan_dir: directory,
@@ -23956,7 +24296,7 @@ var secretscan = createSwarmTool({
23956
24296
  };
23957
24297
  return JSON.stringify(errorResult, null, 2);
23958
24298
  }
23959
- const dirStat = fs19.statSync(scanDir);
24299
+ const dirStat = fs20.statSync(scanDir);
23960
24300
  if (!dirStat.isDirectory()) {
23961
24301
  const errorResult = {
23962
24302
  error: "target must be a directory, not a file",
@@ -24007,7 +24347,7 @@ var secretscan = createSwarmTool({
24007
24347
  break;
24008
24348
  const fileFindings = scanFileForSecrets(filePath);
24009
24349
  try {
24010
- const stat6 = fs19.statSync(filePath);
24350
+ const stat6 = fs20.statSync(filePath);
24011
24351
  if (stat6.size > MAX_FILE_SIZE_BYTES) {
24012
24352
  skippedFiles++;
24013
24353
  continue;
@@ -24099,12 +24439,12 @@ var _internals38 = {
24099
24439
  };
24100
24440
 
24101
24441
  // src/tools/test-runner.ts
24102
- import * as fs23 from "fs";
24103
- import * as path52 from "path";
24442
+ import * as fs24 from "fs";
24443
+ import * as path53 from "path";
24104
24444
 
24105
24445
  // src/test-impact/analyzer.ts
24106
- import fs20 from "fs";
24107
- import path49 from "path";
24446
+ import fs21 from "fs";
24447
+ import path50 from "path";
24108
24448
  var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
24109
24449
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
24110
24450
  var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
@@ -24131,7 +24471,7 @@ function sharedTrailingSegments(a, b) {
24131
24471
  function isCacheStale(impactMap, generatedAtMs) {
24132
24472
  for (const sourcePath of Object.keys(impactMap)) {
24133
24473
  try {
24134
- const stat6 = fs20.statSync(sourcePath);
24474
+ const stat6 = fs21.statSync(sourcePath);
24135
24475
  if (stat6.mtimeMs > generatedAtMs) {
24136
24476
  return true;
24137
24477
  }
@@ -24145,15 +24485,15 @@ function resolveRelativeImport(fromDir, importPath) {
24145
24485
  if (!importPath.startsWith(".")) {
24146
24486
  return null;
24147
24487
  }
24148
- const resolved = path49.resolve(fromDir, importPath);
24149
- if (path49.extname(resolved)) {
24150
- if (fs20.existsSync(resolved) && fs20.statSync(resolved).isFile()) {
24488
+ const resolved = path50.resolve(fromDir, importPath);
24489
+ if (path50.extname(resolved)) {
24490
+ if (fs21.existsSync(resolved) && fs21.statSync(resolved).isFile()) {
24151
24491
  return normalizePath2(resolved);
24152
24492
  }
24153
24493
  } else {
24154
24494
  for (const ext of EXTENSIONS_TO_TRY) {
24155
24495
  const withExt = resolved + ext;
24156
- if (fs20.existsSync(withExt) && fs20.statSync(withExt).isFile()) {
24496
+ if (fs21.existsSync(withExt) && fs21.statSync(withExt).isFile()) {
24157
24497
  return normalizePath2(withExt);
24158
24498
  }
24159
24499
  }
@@ -24166,30 +24506,30 @@ function resolvePythonImport(fromDir, module) {
24166
24506
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
24167
24507
  let baseDir = fromDir;
24168
24508
  for (let i = 1;i < leadingDots; i++) {
24169
- baseDir = path49.dirname(baseDir);
24509
+ baseDir = path50.dirname(baseDir);
24170
24510
  }
24171
24511
  const rest = module.slice(leadingDots);
24172
24512
  if (rest.length === 0) {
24173
- const initPath = path49.join(baseDir, "__init__.py");
24174
- if (fs20.existsSync(initPath) && fs20.statSync(initPath).isFile()) {
24513
+ const initPath = path50.join(baseDir, "__init__.py");
24514
+ if (fs21.existsSync(initPath) && fs21.statSync(initPath).isFile()) {
24175
24515
  return normalizePath2(initPath);
24176
24516
  }
24177
24517
  return null;
24178
24518
  }
24179
- const subpath = rest.replace(/\./g, path49.sep);
24519
+ const subpath = rest.replace(/\./g, path50.sep);
24180
24520
  const candidates = [
24181
- `${path49.join(baseDir, subpath)}.py`,
24182
- path49.join(baseDir, subpath, "__init__.py")
24521
+ `${path50.join(baseDir, subpath)}.py`,
24522
+ path50.join(baseDir, subpath, "__init__.py")
24183
24523
  ];
24184
24524
  for (const c of candidates) {
24185
- if (fs20.existsSync(c) && fs20.statSync(c).isFile())
24525
+ if (fs21.existsSync(c) && fs21.statSync(c).isFile())
24186
24526
  return normalizePath2(c);
24187
24527
  }
24188
24528
  return null;
24189
24529
  }
24190
24530
  var goModuleCache = new Map;
24191
24531
  function findGoModule(fromDir) {
24192
- const resolved = path49.resolve(fromDir);
24532
+ const resolved = path50.resolve(fromDir);
24193
24533
  let cur = resolved;
24194
24534
  const walked = [];
24195
24535
  for (let i = 0;i < 16; i++) {
@@ -24201,8 +24541,8 @@ function findGoModule(fromDir) {
24201
24541
  }
24202
24542
  walked.push(cur);
24203
24543
  try {
24204
- const goMod = path49.join(cur, "go.mod");
24205
- const content = fs20.readFileSync(goMod, "utf-8");
24544
+ const goMod = path50.join(cur, "go.mod");
24545
+ const content = fs21.readFileSync(goMod, "utf-8");
24206
24546
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
24207
24547
  if (moduleMatch) {
24208
24548
  const result = { moduleRoot: cur, modulePath: moduleMatch[1] };
@@ -24212,10 +24552,10 @@ function findGoModule(fromDir) {
24212
24552
  }
24213
24553
  } catch {}
24214
24554
  try {
24215
- fs20.accessSync(path49.join(cur, ".git"));
24555
+ fs21.accessSync(path50.join(cur, ".git"));
24216
24556
  break;
24217
24557
  } catch {}
24218
- const parent = path49.dirname(cur);
24558
+ const parent = path50.dirname(cur);
24219
24559
  if (parent === cur)
24220
24560
  break;
24221
24561
  cur = parent;
@@ -24227,20 +24567,20 @@ function findGoModule(fromDir) {
24227
24567
  function resolveGoImport(fromDir, importPath) {
24228
24568
  let dir = null;
24229
24569
  if (importPath.startsWith(".")) {
24230
- dir = path49.resolve(fromDir, importPath);
24570
+ dir = path50.resolve(fromDir, importPath);
24231
24571
  } else {
24232
24572
  const mod = findGoModule(fromDir);
24233
24573
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
24234
24574
  const subpath = importPath.slice(mod.modulePath.length);
24235
- dir = path49.join(mod.moduleRoot, subpath);
24575
+ dir = path50.join(mod.moduleRoot, subpath);
24236
24576
  }
24237
24577
  }
24238
24578
  if (dir === null)
24239
24579
  return [];
24240
- if (!fs20.existsSync(dir) || !fs20.statSync(dir).isDirectory())
24580
+ if (!fs21.existsSync(dir) || !fs21.statSync(dir).isDirectory())
24241
24581
  return [];
24242
24582
  try {
24243
- return fs20.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path49.join(dir, f)));
24583
+ return fs21.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path50.join(dir, f)));
24244
24584
  } catch {
24245
24585
  return [];
24246
24586
  }
@@ -24260,13 +24600,13 @@ function findTestFilesSync(cwd) {
24260
24600
  function walk(dir, visitedInodes) {
24261
24601
  let entries;
24262
24602
  try {
24263
- entries = fs20.readdirSync(dir, { withFileTypes: true });
24603
+ entries = fs21.readdirSync(dir, { withFileTypes: true });
24264
24604
  } catch {
24265
24605
  return;
24266
24606
  }
24267
24607
  let dirInode;
24268
24608
  try {
24269
- dirInode = fs20.statSync(dir).ino;
24609
+ dirInode = fs21.statSync(dir).ino;
24270
24610
  } catch {
24271
24611
  return;
24272
24612
  }
@@ -24279,15 +24619,15 @@ function findTestFilesSync(cwd) {
24279
24619
  for (const entry of entries) {
24280
24620
  if (entry.isDirectory()) {
24281
24621
  if (!skipDirs.has(entry.name)) {
24282
- walk(path49.join(dir, entry.name), visitedInodes);
24622
+ walk(path50.join(dir, entry.name), visitedInodes);
24283
24623
  }
24284
24624
  } else if (entry.isFile()) {
24285
24625
  const name = entry.name;
24286
24626
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
24287
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path49.sep}tests${path49.sep}`) && name.endsWith(".py");
24627
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path50.sep}tests${path50.sep}`) && name.endsWith(".py");
24288
24628
  const isGoTest = /.+_test\.go$/.test(name);
24289
24629
  if (isTsTest || isPyTest || isGoTest) {
24290
- testFiles.push(normalizePath2(path49.join(dir, entry.name)));
24630
+ testFiles.push(normalizePath2(path50.join(dir, entry.name)));
24291
24631
  }
24292
24632
  }
24293
24633
  }
@@ -24312,8 +24652,8 @@ function extractImports(content) {
24312
24652
  ];
24313
24653
  }
24314
24654
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
24315
- const ext = path49.extname(testFile).toLowerCase();
24316
- const testDir = path49.dirname(testFile);
24655
+ const ext = path50.extname(testFile).toLowerCase();
24656
+ const testDir = path50.dirname(testFile);
24317
24657
  function addEdge(source) {
24318
24658
  if (!impactMap[source])
24319
24659
  impactMap[source] = [];
@@ -24355,7 +24695,7 @@ async function buildImpactMapInternal(cwd) {
24355
24695
  for (const testFile of testFiles) {
24356
24696
  let content;
24357
24697
  try {
24358
- content = fs20.readFileSync(testFile, "utf-8");
24698
+ content = fs21.readFileSync(testFile, "utf-8");
24359
24699
  } catch {
24360
24700
  continue;
24361
24701
  }
@@ -24386,10 +24726,10 @@ async function buildImpactMap(cwd) {
24386
24726
  return impactMap;
24387
24727
  }
24388
24728
  async function loadImpactMap(cwd, options) {
24389
- const cachePath = path49.join(cwd, ".swarm", "cache", "impact-map.json");
24390
- if (fs20.existsSync(cachePath)) {
24729
+ const cachePath = path50.join(cwd, ".swarm", "cache", "impact-map.json");
24730
+ if (fs21.existsSync(cachePath)) {
24391
24731
  try {
24392
- const content = fs20.readFileSync(cachePath, "utf-8");
24732
+ const content = fs21.readFileSync(cachePath, "utf-8");
24393
24733
  const data = JSON.parse(content);
24394
24734
  if (data.map !== null && typeof data.map === "object" && !Array.isArray(data.map)) {
24395
24735
  const map = data.map;
@@ -24419,21 +24759,21 @@ async function loadImpactMap(cwd, options) {
24419
24759
  return _internals39.buildImpactMap(cwd);
24420
24760
  }
24421
24761
  async function saveImpactMap(cwd, impactMap) {
24422
- if (!path49.isAbsolute(cwd)) {
24762
+ if (!path50.isAbsolute(cwd)) {
24423
24763
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
24424
24764
  }
24425
24765
  _internals39.validateProjectRoot(cwd);
24426
- const cacheDir2 = path49.join(cwd, ".swarm", "cache");
24427
- const cachePath = path49.join(cacheDir2, "impact-map.json");
24428
- if (!fs20.existsSync(cacheDir2)) {
24429
- fs20.mkdirSync(cacheDir2, { recursive: true });
24766
+ const cacheDir2 = path50.join(cwd, ".swarm", "cache");
24767
+ const cachePath = path50.join(cacheDir2, "impact-map.json");
24768
+ if (!fs21.existsSync(cacheDir2)) {
24769
+ fs21.mkdirSync(cacheDir2, { recursive: true });
24430
24770
  }
24431
24771
  const data = {
24432
24772
  generatedAt: new Date().toISOString(),
24433
24773
  fileCount: Object.keys(impactMap).length,
24434
24774
  map: impactMap
24435
24775
  };
24436
- fs20.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
24776
+ fs21.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
24437
24777
  }
24438
24778
  async function analyzeImpact(changedFiles, cwd, budget) {
24439
24779
  if (!Array.isArray(changedFiles)) {
@@ -24456,7 +24796,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
24456
24796
  budgetExceeded = true;
24457
24797
  break;
24458
24798
  }
24459
- const normalizedChanged = normalizePath2(path49.resolve(changedFile));
24799
+ const normalizedChanged = normalizePath2(path50.resolve(changedFile));
24460
24800
  const tests = impactMap[normalizedChanged];
24461
24801
  if (tests && tests.length > 0) {
24462
24802
  for (const test of tests) {
@@ -24470,13 +24810,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
24470
24810
  if (budgetExceeded)
24471
24811
  break;
24472
24812
  } else {
24473
- const changedDir = normalizePath2(path49.dirname(normalizedChanged));
24474
- const changedInputDir = normalizePath2(path49.dirname(changedFile));
24813
+ const changedDir = normalizePath2(path50.dirname(normalizedChanged));
24814
+ const changedInputDir = normalizePath2(path50.dirname(changedFile));
24475
24815
  const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
24476
24816
  return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
24477
24817
  }).sort(([sourceA], [sourceB]) => {
24478
- const sourceDirA = normalizePath2(path49.dirname(sourceA));
24479
- const sourceDirB = normalizePath2(path49.dirname(sourceB));
24818
+ const sourceDirA = normalizePath2(path50.dirname(sourceA));
24819
+ const sourceDirB = normalizePath2(path50.dirname(sourceB));
24480
24820
  const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
24481
24821
  const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
24482
24822
  if (exactA !== exactB)
@@ -24802,8 +25142,8 @@ function detectFlakyTests(allHistory) {
24802
25142
  }
24803
25143
 
24804
25144
  // src/test-impact/history-store.ts
24805
- import fs21 from "fs";
24806
- import path50 from "path";
25145
+ import fs22 from "fs";
25146
+ import path51 from "path";
24807
25147
  var MAX_HISTORY_PER_TEST = 20;
24808
25148
  var MAX_ERROR_LENGTH = 500;
24809
25149
  var MAX_STACK_LENGTH = 200;
@@ -24815,10 +25155,10 @@ function getHistoryPath(workingDir) {
24815
25155
  if (!workingDir) {
24816
25156
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
24817
25157
  }
24818
- if (!path50.isAbsolute(workingDir)) {
25158
+ if (!path51.isAbsolute(workingDir)) {
24819
25159
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
24820
25160
  }
24821
- return path50.join(workingDir, ".swarm", "cache", "test-history.jsonl");
25161
+ return path51.join(workingDir, ".swarm", "cache", "test-history.jsonl");
24822
25162
  }
24823
25163
  function sanitizeErrorMessage(errorMessage) {
24824
25164
  if (errorMessage === undefined) {
@@ -24910,10 +25250,10 @@ function batchAppendTestRuns(records, workingDir) {
24910
25250
  }
24911
25251
  }
24912
25252
  const historyPath = getHistoryPath(workingDir);
24913
- const historyDir = path50.dirname(historyPath);
25253
+ const historyDir = path51.dirname(historyPath);
24914
25254
  _internals40.validateProjectRoot(workingDir);
24915
- if (!fs21.existsSync(historyDir)) {
24916
- fs21.mkdirSync(historyDir, { recursive: true });
25255
+ if (!fs22.existsSync(historyDir)) {
25256
+ fs22.mkdirSync(historyDir, { recursive: true });
24917
25257
  }
24918
25258
  withHistoryWriteLock(historyPath, () => {
24919
25259
  const existingRecords = readAllRecords(historyPath);
@@ -24947,13 +25287,13 @@ function batchAppendTestRuns(records, workingDir) {
24947
25287
  `)}
24948
25288
  `;
24949
25289
  const tempPath = `${historyPath}.tmp`;
24950
- fs21.writeFileSync(tempPath, content, "utf-8");
24951
- fs21.renameSync(tempPath, historyPath);
25290
+ fs22.writeFileSync(tempPath, content, "utf-8");
25291
+ fs22.renameSync(tempPath, historyPath);
24952
25292
  } catch (err) {
24953
25293
  try {
24954
25294
  const tempPath = `${historyPath}.tmp`;
24955
- if (fs21.existsSync(tempPath)) {
24956
- fs21.unlinkSync(tempPath);
25295
+ if (fs22.existsSync(tempPath)) {
25296
+ fs22.unlinkSync(tempPath);
24957
25297
  }
24958
25298
  } catch {}
24959
25299
  throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
@@ -24965,7 +25305,7 @@ function withHistoryWriteLock(historyPath, fn) {
24965
25305
  const deadline = Date.now() + HISTORY_WRITE_LOCK_TIMEOUT_MS;
24966
25306
  while (true) {
24967
25307
  try {
24968
- fs21.mkdirSync(lockPath);
25308
+ fs22.mkdirSync(lockPath);
24969
25309
  break;
24970
25310
  } catch (error2) {
24971
25311
  const code = error2 instanceof Error && "code" in error2 ? error2.code : undefined;
@@ -24976,9 +25316,9 @@ function withHistoryWriteLock(historyPath, fn) {
24976
25316
  throw new Error(`Timed out waiting for test history lock: ${historyPath}`);
24977
25317
  }
24978
25318
  try {
24979
- const lockStat = fs21.statSync(lockPath);
25319
+ const lockStat = fs22.statSync(lockPath);
24980
25320
  if (Date.now() - lockStat.mtimeMs >= HISTORY_WRITE_LOCK_STALE_MS) {
24981
- fs21.rmSync(lockPath, { recursive: true, force: true });
25321
+ fs22.rmSync(lockPath, { recursive: true, force: true });
24982
25322
  continue;
24983
25323
  }
24984
25324
  } catch {}
@@ -24993,7 +25333,7 @@ function withHistoryWriteLock(historyPath, fn) {
24993
25333
  return fn();
24994
25334
  } finally {
24995
25335
  try {
24996
- fs21.rmSync(lockPath, { recursive: true, force: true });
25336
+ fs22.rmSync(lockPath, { recursive: true, force: true });
24997
25337
  } catch {}
24998
25338
  }
24999
25339
  function sleepSync(ms) {
@@ -25002,11 +25342,11 @@ function withHistoryWriteLock(historyPath, fn) {
25002
25342
  }
25003
25343
  }
25004
25344
  function readAllRecords(historyPath) {
25005
- if (!fs21.existsSync(historyPath)) {
25345
+ if (!fs22.existsSync(historyPath)) {
25006
25346
  return [];
25007
25347
  }
25008
25348
  try {
25009
- const content = fs21.readFileSync(historyPath, "utf-8");
25349
+ const content = fs22.readFileSync(historyPath, "utf-8");
25010
25350
  const lines = content.split(`
25011
25351
  `);
25012
25352
  const records = [];
@@ -25039,8 +25379,8 @@ var _internals40 = {
25039
25379
  };
25040
25380
 
25041
25381
  // src/tools/resolve-working-directory.ts
25042
- import * as fs22 from "fs";
25043
- import * as path51 from "path";
25382
+ import * as fs23 from "fs";
25383
+ import * as path52 from "path";
25044
25384
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
25045
25385
  if (workingDirectory == null || workingDirectory === "") {
25046
25386
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
@@ -25072,18 +25412,18 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
25072
25412
  };
25073
25413
  }
25074
25414
  }
25075
- const rawPathParts = workingDirectory.split(path51.sep);
25415
+ const rawPathParts = workingDirectory.split(path52.sep);
25076
25416
  if (rawPathParts.includes("..")) {
25077
25417
  return {
25078
25418
  success: false,
25079
25419
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
25080
25420
  };
25081
25421
  }
25082
- const normalizedDir = path51.normalize(workingDirectory);
25083
- const resolvedDir = path51.resolve(normalizedDir);
25422
+ const normalizedDir = path52.normalize(workingDirectory);
25423
+ const resolvedDir = path52.resolve(normalizedDir);
25084
25424
  let statResult;
25085
25425
  try {
25086
- statResult = fs22.statSync(resolvedDir);
25426
+ statResult = fs23.statSync(resolvedDir);
25087
25427
  } catch {
25088
25428
  return {
25089
25429
  success: false,
@@ -25099,16 +25439,16 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
25099
25439
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
25100
25440
  return { success: true, directory: resolvedDir };
25101
25441
  }
25102
- const resolvedFallback = path51.resolve(fallbackDirectory);
25442
+ const resolvedFallback = path52.resolve(fallbackDirectory);
25103
25443
  let fallbackExists = false;
25104
25444
  try {
25105
- fs22.statSync(resolvedFallback);
25445
+ fs23.statSync(resolvedFallback);
25106
25446
  fallbackExists = true;
25107
25447
  } catch {
25108
25448
  fallbackExists = false;
25109
25449
  }
25110
25450
  if (fallbackExists) {
25111
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path51.sep);
25451
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path52.sep);
25112
25452
  if (isSubdirectory) {
25113
25453
  return {
25114
25454
  success: false,
@@ -25131,7 +25471,7 @@ async function estimateFanOut(sourceFiles, cwd) {
25131
25471
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
25132
25472
  const uniqueTestFiles = new Set;
25133
25473
  for (const sourceFile of sourceFiles) {
25134
- const resolvedPath = path52.resolve(cwd, sourceFile);
25474
+ const resolvedPath = path53.resolve(cwd, sourceFile);
25135
25475
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
25136
25476
  const testFiles = impactMap[normalizedPath];
25137
25477
  if (testFiles) {
@@ -25216,19 +25556,19 @@ function hasDevDependency(devDeps, ...patterns) {
25216
25556
  return hasPackageJsonDependency(devDeps, ...patterns);
25217
25557
  }
25218
25558
  function detectGoTest(cwd) {
25219
- return fs23.existsSync(path52.join(cwd, "go.mod")) && isCommandAvailable("go");
25559
+ return fs24.existsSync(path53.join(cwd, "go.mod")) && isCommandAvailable("go");
25220
25560
  }
25221
25561
  function detectJavaMaven(cwd) {
25222
- return fs23.existsSync(path52.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
25562
+ return fs24.existsSync(path53.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
25223
25563
  }
25224
25564
  function detectGradle(cwd) {
25225
- const hasBuildFile = fs23.existsSync(path52.join(cwd, "build.gradle")) || fs23.existsSync(path52.join(cwd, "build.gradle.kts"));
25226
- const hasGradlew = fs23.existsSync(path52.join(cwd, "gradlew")) || fs23.existsSync(path52.join(cwd, "gradlew.bat"));
25565
+ const hasBuildFile = fs24.existsSync(path53.join(cwd, "build.gradle")) || fs24.existsSync(path53.join(cwd, "build.gradle.kts"));
25566
+ const hasGradlew = fs24.existsSync(path53.join(cwd, "gradlew")) || fs24.existsSync(path53.join(cwd, "gradlew.bat"));
25227
25567
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
25228
25568
  }
25229
25569
  function detectDotnetTest(cwd) {
25230
25570
  try {
25231
- const files = fs23.readdirSync(cwd);
25571
+ const files = fs24.readdirSync(cwd);
25232
25572
  const hasCsproj = files.some((f) => f.endsWith(".csproj"));
25233
25573
  return hasCsproj && isCommandAvailable("dotnet");
25234
25574
  } catch {
@@ -25236,25 +25576,25 @@ function detectDotnetTest(cwd) {
25236
25576
  }
25237
25577
  }
25238
25578
  function detectCTest(cwd) {
25239
- const hasSource = fs23.existsSync(path52.join(cwd, "CMakeLists.txt"));
25240
- const hasBuildCache = fs23.existsSync(path52.join(cwd, "CMakeCache.txt")) || fs23.existsSync(path52.join(cwd, "build", "CMakeCache.txt"));
25579
+ const hasSource = fs24.existsSync(path53.join(cwd, "CMakeLists.txt"));
25580
+ const hasBuildCache = fs24.existsSync(path53.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path53.join(cwd, "build", "CMakeCache.txt"));
25241
25581
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
25242
25582
  }
25243
25583
  function detectSwiftTest(cwd) {
25244
- return fs23.existsSync(path52.join(cwd, "Package.swift")) && isCommandAvailable("swift");
25584
+ return fs24.existsSync(path53.join(cwd, "Package.swift")) && isCommandAvailable("swift");
25245
25585
  }
25246
25586
  function detectDartTest(cwd) {
25247
- return fs23.existsSync(path52.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
25587
+ return fs24.existsSync(path53.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
25248
25588
  }
25249
25589
  function detectRSpec(cwd) {
25250
- const hasRSpecFile = fs23.existsSync(path52.join(cwd, ".rspec"));
25251
- const hasGemfile = fs23.existsSync(path52.join(cwd, "Gemfile"));
25252
- const hasSpecDir = fs23.existsSync(path52.join(cwd, "spec"));
25590
+ const hasRSpecFile = fs24.existsSync(path53.join(cwd, ".rspec"));
25591
+ const hasGemfile = fs24.existsSync(path53.join(cwd, "Gemfile"));
25592
+ const hasSpecDir = fs24.existsSync(path53.join(cwd, "spec"));
25253
25593
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
25254
25594
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
25255
25595
  }
25256
25596
  function detectMinitest(cwd) {
25257
- return fs23.existsSync(path52.join(cwd, "test")) && (fs23.existsSync(path52.join(cwd, "Gemfile")) || fs23.existsSync(path52.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
25597
+ return fs24.existsSync(path53.join(cwd, "test")) && (fs24.existsSync(path53.join(cwd, "Gemfile")) || fs24.existsSync(path53.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
25258
25598
  }
25259
25599
  var DISPATCH_FRAMEWORK_MAP = {
25260
25600
  bun: "bun",
@@ -25339,9 +25679,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
25339
25679
  async function detectTestFramework(cwd) {
25340
25680
  const baseDir = cwd;
25341
25681
  try {
25342
- const packageJsonPath = path52.join(baseDir, "package.json");
25343
- if (fs23.existsSync(packageJsonPath)) {
25344
- const content = fs23.readFileSync(packageJsonPath, "utf-8");
25682
+ const packageJsonPath = path53.join(baseDir, "package.json");
25683
+ if (fs24.existsSync(packageJsonPath)) {
25684
+ const content = fs24.readFileSync(packageJsonPath, "utf-8");
25345
25685
  const pkg = JSON.parse(content);
25346
25686
  const _deps = pkg.dependencies || {};
25347
25687
  const devDeps = pkg.devDependencies || {};
@@ -25360,38 +25700,38 @@ async function detectTestFramework(cwd) {
25360
25700
  return "jest";
25361
25701
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
25362
25702
  return "mocha";
25363
- if (fs23.existsSync(path52.join(baseDir, "bun.lockb")) || fs23.existsSync(path52.join(baseDir, "bun.lock"))) {
25703
+ if (fs24.existsSync(path53.join(baseDir, "bun.lockb")) || fs24.existsSync(path53.join(baseDir, "bun.lock"))) {
25364
25704
  if (scripts.test?.includes("bun"))
25365
25705
  return "bun";
25366
25706
  }
25367
25707
  }
25368
25708
  } catch {}
25369
25709
  try {
25370
- const pyprojectTomlPath = path52.join(baseDir, "pyproject.toml");
25371
- const setupCfgPath = path52.join(baseDir, "setup.cfg");
25372
- const requirementsTxtPath = path52.join(baseDir, "requirements.txt");
25373
- if (fs23.existsSync(pyprojectTomlPath)) {
25374
- const content = fs23.readFileSync(pyprojectTomlPath, "utf-8");
25710
+ const pyprojectTomlPath = path53.join(baseDir, "pyproject.toml");
25711
+ const setupCfgPath = path53.join(baseDir, "setup.cfg");
25712
+ const requirementsTxtPath = path53.join(baseDir, "requirements.txt");
25713
+ if (fs24.existsSync(pyprojectTomlPath)) {
25714
+ const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
25375
25715
  if (content.includes("[tool.pytest"))
25376
25716
  return "pytest";
25377
25717
  if (content.includes("pytest"))
25378
25718
  return "pytest";
25379
25719
  }
25380
- if (fs23.existsSync(setupCfgPath)) {
25381
- const content = fs23.readFileSync(setupCfgPath, "utf-8");
25720
+ if (fs24.existsSync(setupCfgPath)) {
25721
+ const content = fs24.readFileSync(setupCfgPath, "utf-8");
25382
25722
  if (content.includes("[pytest]"))
25383
25723
  return "pytest";
25384
25724
  }
25385
- if (fs23.existsSync(requirementsTxtPath)) {
25386
- const content = fs23.readFileSync(requirementsTxtPath, "utf-8");
25725
+ if (fs24.existsSync(requirementsTxtPath)) {
25726
+ const content = fs24.readFileSync(requirementsTxtPath, "utf-8");
25387
25727
  if (content.includes("pytest"))
25388
25728
  return "pytest";
25389
25729
  }
25390
25730
  } catch {}
25391
25731
  try {
25392
- const cargoTomlPath = path52.join(baseDir, "Cargo.toml");
25393
- if (fs23.existsSync(cargoTomlPath)) {
25394
- const content = fs23.readFileSync(cargoTomlPath, "utf-8");
25732
+ const cargoTomlPath = path53.join(baseDir, "Cargo.toml");
25733
+ if (fs24.existsSync(cargoTomlPath)) {
25734
+ const content = fs24.readFileSync(cargoTomlPath, "utf-8");
25395
25735
  if (content.includes("[dev-dependencies]")) {
25396
25736
  if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
25397
25737
  return "cargo";
@@ -25400,10 +25740,10 @@ async function detectTestFramework(cwd) {
25400
25740
  }
25401
25741
  } catch {}
25402
25742
  try {
25403
- const pesterConfigPath = path52.join(baseDir, "pester.config.ps1");
25404
- const pesterConfigJsonPath = path52.join(baseDir, "pester.config.ps1.json");
25405
- const pesterPs1Path = path52.join(baseDir, "tests.ps1");
25406
- if (fs23.existsSync(pesterConfigPath) || fs23.existsSync(pesterConfigJsonPath) || fs23.existsSync(pesterPs1Path)) {
25743
+ const pesterConfigPath = path53.join(baseDir, "pester.config.ps1");
25744
+ const pesterConfigJsonPath = path53.join(baseDir, "pester.config.ps1.json");
25745
+ const pesterPs1Path = path53.join(baseDir, "tests.ps1");
25746
+ if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
25407
25747
  return "pester";
25408
25748
  }
25409
25749
  } catch {}
@@ -25445,12 +25785,12 @@ function isTestDirectoryPath(normalizedPath) {
25445
25785
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
25446
25786
  }
25447
25787
  function resolveWorkspacePath(file, workingDir) {
25448
- return path52.isAbsolute(file) ? path52.resolve(file) : path52.resolve(workingDir, file);
25788
+ return path53.isAbsolute(file) ? path53.resolve(file) : path53.resolve(workingDir, file);
25449
25789
  }
25450
25790
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
25451
25791
  if (!preferRelative)
25452
25792
  return absolutePath;
25453
- return path52.relative(workingDir, absolutePath);
25793
+ return path53.relative(workingDir, absolutePath);
25454
25794
  }
25455
25795
  function dedupePush(target, value) {
25456
25796
  if (!target.includes(value)) {
@@ -25487,18 +25827,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
25487
25827
  }
25488
25828
  }
25489
25829
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
25490
- const relativeDir = path52.dirname(relativePath);
25830
+ const relativeDir = path53.dirname(relativePath);
25491
25831
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
25492
25832
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
25493
- const rootDir = path52.join(workingDir, dirName);
25494
- return nestedRelativeDir ? [rootDir, path52.join(rootDir, nestedRelativeDir)] : [rootDir];
25833
+ const rootDir = path53.join(workingDir, dirName);
25834
+ return nestedRelativeDir ? [rootDir, path53.join(rootDir, nestedRelativeDir)] : [rootDir];
25495
25835
  });
25496
25836
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
25497
25837
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
25498
- directories.push(path52.join(workingDir, "src/test/java", path52.dirname(normalizedRelativePath.slice("src/main/java/".length))));
25838
+ directories.push(path53.join(workingDir, "src/test/java", path53.dirname(normalizedRelativePath.slice("src/main/java/".length))));
25499
25839
  }
25500
25840
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
25501
- directories.push(path52.join(workingDir, "src/test/kotlin", path52.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
25841
+ directories.push(path53.join(workingDir, "src/test/kotlin", path53.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
25502
25842
  }
25503
25843
  return [...new Set(directories)];
25504
25844
  }
@@ -25526,23 +25866,23 @@ function isLanguageSpecificTestFile(basename9) {
25526
25866
  }
25527
25867
  function isConventionTestFilePath(filePath) {
25528
25868
  const normalizedPath = filePath.replace(/\\/g, "/");
25529
- const basename9 = path52.basename(filePath);
25869
+ const basename9 = path53.basename(filePath);
25530
25870
  return hasCompoundTestExtension(basename9) || basename9.includes(".spec.") || basename9.includes(".test.") || isLanguageSpecificTestFile(basename9) || isTestDirectoryPath(normalizedPath);
25531
25871
  }
25532
25872
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
25533
25873
  const testFiles = [];
25534
25874
  for (const file of sourceFiles) {
25535
25875
  const absoluteFile = resolveWorkspacePath(file, workingDir);
25536
- const relativeFile = path52.relative(workingDir, absoluteFile);
25537
- const basename9 = path52.basename(absoluteFile);
25538
- const dirname25 = path52.dirname(absoluteFile);
25539
- const preferRelativeOutput = !path52.isAbsolute(file);
25876
+ const relativeFile = path53.relative(workingDir, absoluteFile);
25877
+ const basename9 = path53.basename(absoluteFile);
25878
+ const dirname25 = path53.dirname(absoluteFile);
25879
+ const preferRelativeOutput = !path53.isAbsolute(file);
25540
25880
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
25541
25881
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
25542
25882
  continue;
25543
25883
  }
25544
25884
  const nameWithoutExt = basename9.replace(/\.[^.]+$/, "");
25545
- const ext = path52.extname(basename9);
25885
+ const ext = path53.extname(basename9);
25546
25886
  const genericTestNames = [
25547
25887
  `${nameWithoutExt}.spec${ext}`,
25548
25888
  `${nameWithoutExt}.test${ext}`
@@ -25551,7 +25891,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
25551
25891
  const colocatedCandidates = [
25552
25892
  ...genericTestNames,
25553
25893
  ...languageSpecificTestNames
25554
- ].map((candidateName) => path52.join(dirname25, candidateName));
25894
+ ].map((candidateName) => path53.join(dirname25, candidateName));
25555
25895
  const testDirectoryNames = [
25556
25896
  basename9,
25557
25897
  ...genericTestNames,
@@ -25560,11 +25900,11 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
25560
25900
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
25561
25901
  const possibleTestFiles = [
25562
25902
  ...colocatedCandidates,
25563
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path52.join(dirname25, dirName, candidateName))),
25564
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path52.join(candidateDir, candidateName)))
25903
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path53.join(dirname25, dirName, candidateName))),
25904
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path53.join(candidateDir, candidateName)))
25565
25905
  ];
25566
25906
  for (const testFile of possibleTestFiles) {
25567
- if (fs23.existsSync(testFile)) {
25907
+ if (fs24.existsSync(testFile)) {
25568
25908
  dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
25569
25909
  }
25570
25910
  }
@@ -25581,8 +25921,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25581
25921
  for (const testFile of candidateTestFiles) {
25582
25922
  try {
25583
25923
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
25584
- const content = fs23.readFileSync(absoluteTestFile, "utf-8");
25585
- const testDir = path52.dirname(absoluteTestFile);
25924
+ const content = fs24.readFileSync(absoluteTestFile, "utf-8");
25925
+ const testDir = path53.dirname(absoluteTestFile);
25586
25926
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
25587
25927
  let match;
25588
25928
  match = importRegex.exec(content);
@@ -25590,8 +25930,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25590
25930
  const importPath = match[1];
25591
25931
  let resolvedImport;
25592
25932
  if (importPath.startsWith(".")) {
25593
- resolvedImport = path52.resolve(testDir, importPath);
25594
- const existingExt = path52.extname(resolvedImport);
25933
+ resolvedImport = path53.resolve(testDir, importPath);
25934
+ const existingExt = path53.extname(resolvedImport);
25595
25935
  if (!existingExt) {
25596
25936
  for (const extToTry of [
25597
25937
  ".ts",
@@ -25602,7 +25942,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25602
25942
  ".cjs"
25603
25943
  ]) {
25604
25944
  const withExt = resolvedImport + extToTry;
25605
- if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
25945
+ if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
25606
25946
  resolvedImport = withExt;
25607
25947
  break;
25608
25948
  }
@@ -25611,12 +25951,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25611
25951
  } else {
25612
25952
  continue;
25613
25953
  }
25614
- const importBasename = path52.basename(resolvedImport, path52.extname(resolvedImport));
25615
- const importDir = path52.dirname(resolvedImport);
25954
+ const importBasename = path53.basename(resolvedImport, path53.extname(resolvedImport));
25955
+ const importDir = path53.dirname(resolvedImport);
25616
25956
  for (const sourceFile of absoluteSourceFiles) {
25617
- const sourceDir = path52.dirname(sourceFile);
25618
- const sourceBasename = path52.basename(sourceFile, path52.extname(sourceFile));
25619
- const isRelatedDir = importDir === sourceDir || importDir === path52.join(sourceDir, "__tests__") || importDir === path52.join(sourceDir, "tests") || importDir === path52.join(sourceDir, "test") || importDir === path52.join(sourceDir, "spec");
25957
+ const sourceDir = path53.dirname(sourceFile);
25958
+ const sourceBasename = path53.basename(sourceFile, path53.extname(sourceFile));
25959
+ const isRelatedDir = importDir === sourceDir || importDir === path53.join(sourceDir, "__tests__") || importDir === path53.join(sourceDir, "tests") || importDir === path53.join(sourceDir, "test") || importDir === path53.join(sourceDir, "spec");
25620
25960
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
25621
25961
  dedupePush(testFiles, testFile);
25622
25962
  break;
@@ -25629,8 +25969,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25629
25969
  while (match !== null) {
25630
25970
  const importPath = match[1];
25631
25971
  if (importPath.startsWith(".")) {
25632
- let resolvedImport = path52.resolve(testDir, importPath);
25633
- const existingExt = path52.extname(resolvedImport);
25972
+ let resolvedImport = path53.resolve(testDir, importPath);
25973
+ const existingExt = path53.extname(resolvedImport);
25634
25974
  if (!existingExt) {
25635
25975
  for (const extToTry of [
25636
25976
  ".ts",
@@ -25641,18 +25981,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25641
25981
  ".cjs"
25642
25982
  ]) {
25643
25983
  const withExt = resolvedImport + extToTry;
25644
- if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
25984
+ if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
25645
25985
  resolvedImport = withExt;
25646
25986
  break;
25647
25987
  }
25648
25988
  }
25649
25989
  }
25650
- const importDir = path52.dirname(resolvedImport);
25651
- const importBasename = path52.basename(resolvedImport, path52.extname(resolvedImport));
25990
+ const importDir = path53.dirname(resolvedImport);
25991
+ const importBasename = path53.basename(resolvedImport, path53.extname(resolvedImport));
25652
25992
  for (const sourceFile of absoluteSourceFiles) {
25653
- const sourceDir = path52.dirname(sourceFile);
25654
- const sourceBasename = path52.basename(sourceFile, path52.extname(sourceFile));
25655
- const isRelatedDir = importDir === sourceDir || importDir === path52.join(sourceDir, "__tests__") || importDir === path52.join(sourceDir, "tests") || importDir === path52.join(sourceDir, "test") || importDir === path52.join(sourceDir, "spec");
25993
+ const sourceDir = path53.dirname(sourceFile);
25994
+ const sourceBasename = path53.basename(sourceFile, path53.extname(sourceFile));
25995
+ const isRelatedDir = importDir === sourceDir || importDir === path53.join(sourceDir, "__tests__") || importDir === path53.join(sourceDir, "tests") || importDir === path53.join(sourceDir, "test") || importDir === path53.join(sourceDir, "spec");
25656
25996
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
25657
25997
  dedupePush(testFiles, testFile);
25658
25998
  break;
@@ -25772,8 +26112,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
25772
26112
  return ["mvn", "test"];
25773
26113
  case "gradle": {
25774
26114
  const isWindows = process.platform === "win32";
25775
- const hasGradlewBat = fs23.existsSync(path52.join(baseDir, "gradlew.bat"));
25776
- const hasGradlew = fs23.existsSync(path52.join(baseDir, "gradlew"));
26115
+ const hasGradlewBat = fs24.existsSync(path53.join(baseDir, "gradlew.bat"));
26116
+ const hasGradlew = fs24.existsSync(path53.join(baseDir, "gradlew"));
25777
26117
  if (hasGradlewBat && isWindows)
25778
26118
  return ["gradlew.bat", "test"];
25779
26119
  if (hasGradlew)
@@ -25790,7 +26130,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
25790
26130
  "cmake-build-release",
25791
26131
  "out"
25792
26132
  ];
25793
- const actualBuildDir = buildDirCandidates.find((d) => fs23.existsSync(path52.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
26133
+ const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path53.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
25794
26134
  return ["ctest", "--test-dir", actualBuildDir];
25795
26135
  }
25796
26136
  case "swift-test":
@@ -26224,13 +26564,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
26224
26564
  };
26225
26565
  }
26226
26566
  const startTime = Date.now();
26227
- const vitestJsonOutputPath = framework === "vitest" ? path52.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
26567
+ const vitestJsonOutputPath = framework === "vitest" ? path53.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
26228
26568
  try {
26229
26569
  if (vitestJsonOutputPath) {
26230
26570
  try {
26231
- fs23.mkdirSync(path52.dirname(vitestJsonOutputPath), { recursive: true });
26232
- if (fs23.existsSync(vitestJsonOutputPath)) {
26233
- fs23.unlinkSync(vitestJsonOutputPath);
26571
+ fs24.mkdirSync(path53.dirname(vitestJsonOutputPath), { recursive: true });
26572
+ if (fs24.existsSync(vitestJsonOutputPath)) {
26573
+ fs24.unlinkSync(vitestJsonOutputPath);
26234
26574
  }
26235
26575
  } catch {}
26236
26576
  }
@@ -26256,8 +26596,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
26256
26596
  }
26257
26597
  if (vitestJsonOutputPath) {
26258
26598
  try {
26259
- if (fs23.existsSync(vitestJsonOutputPath)) {
26260
- const vitestJsonOutput = fs23.readFileSync(vitestJsonOutputPath, "utf-8");
26599
+ if (fs24.existsSync(vitestJsonOutputPath)) {
26600
+ const vitestJsonOutput = fs24.readFileSync(vitestJsonOutputPath, "utf-8");
26261
26601
  if (vitestJsonOutput.trim().length > 0) {
26262
26602
  output += (output ? `
26263
26603
  ` : "") + vitestJsonOutput;
@@ -26396,10 +26736,10 @@ var SKIP_DIRECTORIES = new Set([
26396
26736
  ]);
26397
26737
  function normalizeHistoryTestFile(testFile, workingDir) {
26398
26738
  const normalized = testFile.replace(/\\/g, "/");
26399
- if (!path52.isAbsolute(testFile))
26739
+ if (!path53.isAbsolute(testFile))
26400
26740
  return normalized;
26401
- const relative8 = path52.relative(workingDir, testFile);
26402
- if (relative8.startsWith("..") || path52.isAbsolute(relative8)) {
26741
+ const relative8 = path53.relative(workingDir, testFile);
26742
+ if (relative8.startsWith("..") || path53.isAbsolute(relative8)) {
26403
26743
  return normalized;
26404
26744
  }
26405
26745
  return relative8.replace(/\\/g, "/");
@@ -26638,7 +26978,7 @@ var test_runner = createSwarmTool({
26638
26978
  const sourceFiles = args.files.filter((file) => {
26639
26979
  if (directTestFiles.includes(file))
26640
26980
  return false;
26641
- const ext = path52.extname(file).toLowerCase();
26981
+ const ext = path53.extname(file).toLowerCase();
26642
26982
  return SOURCE_EXTENSIONS.has(ext);
26643
26983
  });
26644
26984
  const invalidFiles = args.files.filter((file) => !directTestFiles.includes(file) && !sourceFiles.includes(file));
@@ -26684,7 +27024,7 @@ var test_runner = createSwarmTool({
26684
27024
  if (isConventionTestFilePath(f)) {
26685
27025
  return false;
26686
27026
  }
26687
- const ext = path52.extname(f).toLowerCase();
27027
+ const ext = path53.extname(f).toLowerCase();
26688
27028
  return SOURCE_EXTENSIONS.has(ext);
26689
27029
  });
26690
27030
  if (sourceFiles.length === 0) {
@@ -26734,7 +27074,7 @@ var test_runner = createSwarmTool({
26734
27074
  if (isConventionTestFilePath(f)) {
26735
27075
  return false;
26736
27076
  }
26737
- const ext = path52.extname(f).toLowerCase();
27077
+ const ext = path53.extname(f).toLowerCase();
26738
27078
  return SOURCE_EXTENSIONS.has(ext);
26739
27079
  });
26740
27080
  if (sourceFiles.length === 0) {
@@ -26786,8 +27126,8 @@ var test_runner = createSwarmTool({
26786
27126
  }
26787
27127
  if (impactResult.impactedTests.length > 0) {
26788
27128
  testFiles = impactResult.impactedTests.map((absPath) => {
26789
- const relativePath = path52.relative(workingDir, absPath);
26790
- return path52.isAbsolute(relativePath) ? absPath : relativePath;
27129
+ const relativePath = path53.relative(workingDir, absPath);
27130
+ return path53.isAbsolute(relativePath) ? absPath : relativePath;
26791
27131
  });
26792
27132
  } else {
26793
27133
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -26882,8 +27222,8 @@ function validateDirectoryPath(dir) {
26882
27222
  if (dir.includes("..")) {
26883
27223
  throw new Error("Directory path must not contain path traversal sequences");
26884
27224
  }
26885
- const normalized = path53.normalize(dir);
26886
- const absolutePath = path53.isAbsolute(normalized) ? normalized : path53.resolve(normalized);
27225
+ const normalized = path54.normalize(dir);
27226
+ const absolutePath = path54.isAbsolute(normalized) ? normalized : path54.resolve(normalized);
26887
27227
  return absolutePath;
26888
27228
  }
26889
27229
  function validateTimeout(timeoutMs, defaultValue) {
@@ -26906,9 +27246,9 @@ function validateTimeout(timeoutMs, defaultValue) {
26906
27246
  }
26907
27247
  function getPackageVersion(dir) {
26908
27248
  try {
26909
- const packagePath = path53.join(dir, "package.json");
26910
- if (fs24.existsSync(packagePath)) {
26911
- const content = fs24.readFileSync(packagePath, "utf-8");
27249
+ const packagePath = path54.join(dir, "package.json");
27250
+ if (fs25.existsSync(packagePath)) {
27251
+ const content = fs25.readFileSync(packagePath, "utf-8");
26912
27252
  const pkg = JSON.parse(content);
26913
27253
  return pkg.version ?? null;
26914
27254
  }
@@ -26917,9 +27257,9 @@ function getPackageVersion(dir) {
26917
27257
  }
26918
27258
  function getChangelogVersion(dir) {
26919
27259
  try {
26920
- const changelogPath = path53.join(dir, "CHANGELOG.md");
26921
- if (fs24.existsSync(changelogPath)) {
26922
- const content = fs24.readFileSync(changelogPath, "utf-8");
27260
+ const changelogPath = path54.join(dir, "CHANGELOG.md");
27261
+ if (fs25.existsSync(changelogPath)) {
27262
+ const content = fs25.readFileSync(changelogPath, "utf-8");
26923
27263
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
26924
27264
  if (match) {
26925
27265
  return match[1];
@@ -26931,10 +27271,10 @@ function getChangelogVersion(dir) {
26931
27271
  function getVersionFileVersion(dir) {
26932
27272
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
26933
27273
  for (const file of possibleFiles) {
26934
- const filePath = path53.join(dir, file);
26935
- if (fs24.existsSync(filePath)) {
27274
+ const filePath = path54.join(dir, file);
27275
+ if (fs25.existsSync(filePath)) {
26936
27276
  try {
26937
- const content = fs24.readFileSync(filePath, "utf-8").trim();
27277
+ const content = fs25.readFileSync(filePath, "utf-8").trim();
26938
27278
  const match = content.match(/(\d+\.\d+\.\d+)/);
26939
27279
  if (match) {
26940
27280
  return match[1];
@@ -27668,8 +28008,8 @@ async function handleQaGatesCommand(directory, args, sessionID) {
27668
28008
  }
27669
28009
 
27670
28010
  // src/commands/reset.ts
27671
- import * as fs25 from "fs";
27672
- import * as path54 from "path";
28011
+ import * as fs26 from "fs";
28012
+ import * as path55 from "path";
27673
28013
 
27674
28014
  // src/background/circuit-breaker.ts
27675
28015
  class CircuitBreaker {
@@ -28374,8 +28714,8 @@ async function handleResetCommand(directory, args) {
28374
28714
  for (const filename of filesToReset) {
28375
28715
  try {
28376
28716
  const resolvedPath = validateSwarmPath(directory, filename);
28377
- if (fs25.existsSync(resolvedPath)) {
28378
- fs25.unlinkSync(resolvedPath);
28717
+ if (fs26.existsSync(resolvedPath)) {
28718
+ fs26.unlinkSync(resolvedPath);
28379
28719
  results.push(`- \u2705 Deleted ${filename}`);
28380
28720
  } else {
28381
28721
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -28386,9 +28726,9 @@ async function handleResetCommand(directory, args) {
28386
28726
  }
28387
28727
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
28388
28728
  try {
28389
- const rootPath = path54.join(directory, filename);
28390
- if (fs25.existsSync(rootPath)) {
28391
- fs25.unlinkSync(rootPath);
28729
+ const rootPath = path55.join(directory, filename);
28730
+ if (fs26.existsSync(rootPath)) {
28731
+ fs26.unlinkSync(rootPath);
28392
28732
  results.push(`- \u2705 Deleted ${filename} (root)`);
28393
28733
  }
28394
28734
  } catch (err) {
@@ -28403,8 +28743,8 @@ async function handleResetCommand(directory, args) {
28403
28743
  }
28404
28744
  try {
28405
28745
  const summariesPath = validateSwarmPath(directory, "summaries");
28406
- if (fs25.existsSync(summariesPath)) {
28407
- fs25.rmSync(summariesPath, { recursive: true, force: true });
28746
+ if (fs26.existsSync(summariesPath)) {
28747
+ fs26.rmSync(summariesPath, { recursive: true, force: true });
28408
28748
  results.push("- \u2705 Deleted summaries/ directory");
28409
28749
  } else {
28410
28750
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -28423,8 +28763,8 @@ async function handleResetCommand(directory, args) {
28423
28763
  }
28424
28764
 
28425
28765
  // src/commands/reset-session.ts
28426
- import * as fs27 from "fs";
28427
- import * as path56 from "path";
28766
+ import * as fs28 from "fs";
28767
+ import * as path57 from "path";
28428
28768
 
28429
28769
  // src/hooks/trajectory-logger.ts
28430
28770
  var callStartTimes = new Map;
@@ -28830,17 +29170,17 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
28830
29170
  };
28831
29171
  }
28832
29172
  // src/prm/replay.ts
28833
- import { promises as fs26 } from "fs";
28834
- import path55 from "path";
29173
+ import { promises as fs27 } from "fs";
29174
+ import path56 from "path";
28835
29175
  function isPathSafe(targetPath, basePath) {
28836
- const resolvedTarget = path55.resolve(targetPath);
28837
- const resolvedBase = path55.resolve(basePath);
28838
- const rel = path55.relative(resolvedBase, resolvedTarget);
28839
- return !rel.startsWith("..") && !path55.isAbsolute(rel);
29176
+ const resolvedTarget = path56.resolve(targetPath);
29177
+ const resolvedBase = path56.resolve(basePath);
29178
+ const rel = path56.relative(resolvedBase, resolvedTarget);
29179
+ return !rel.startsWith("..") && !path56.isAbsolute(rel);
28840
29180
  }
28841
29181
  function isWithinReplaysDir(targetPath) {
28842
- const resolved = path55.resolve(targetPath);
28843
- const parts = resolved.split(path55.sep);
29182
+ const resolved = path56.resolve(targetPath);
29183
+ const parts = resolved.split(path56.sep);
28844
29184
  for (let i = 0;i < parts.length - 1; i++) {
28845
29185
  if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
28846
29186
  return true;
@@ -28853,15 +29193,15 @@ function sanitizeFilename(input) {
28853
29193
  }
28854
29194
  async function startReplayRecording(sessionID, directory) {
28855
29195
  try {
28856
- const replayDir = path55.join(directory, ".swarm", "replays");
29196
+ const replayDir = path56.join(directory, ".swarm", "replays");
28857
29197
  const safeSessionID = sanitizeFilename(sessionID);
28858
29198
  const filename = `${safeSessionID}-${Date.now()}.jsonl`;
28859
- const filepath = path55.join(replayDir, filename);
29199
+ const filepath = path56.join(replayDir, filename);
28860
29200
  if (!isPathSafe(filepath, replayDir)) {
28861
29201
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
28862
29202
  return null;
28863
29203
  }
28864
- await fs26.mkdir(replayDir, { recursive: true });
29204
+ await fs27.mkdir(replayDir, { recursive: true });
28865
29205
  return filepath;
28866
29206
  } catch (err) {
28867
29207
  console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err}`);
@@ -28881,7 +29221,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
28881
29221
  };
28882
29222
  const line = `${JSON.stringify(fullEntry)}
28883
29223
  `;
28884
- await fs26.appendFile(artifactPath, line, "utf-8");
29224
+ await fs27.appendFile(artifactPath, line, "utf-8");
28885
29225
  } catch (err) {
28886
29226
  console.warn(`[replay] Failed to record entry: ${err}`);
28887
29227
  }
@@ -28925,8 +29265,8 @@ async function handleResetSessionCommand(directory, _args) {
28925
29265
  const results = [];
28926
29266
  try {
28927
29267
  const statePath = validateSwarmPath(directory, "session/state.json");
28928
- if (fs27.existsSync(statePath)) {
28929
- fs27.unlinkSync(statePath);
29268
+ if (fs28.existsSync(statePath)) {
29269
+ fs28.unlinkSync(statePath);
28930
29270
  results.push("\u2705 Deleted .swarm/session/state.json");
28931
29271
  } else {
28932
29272
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -28934,11 +29274,11 @@ async function handleResetSessionCommand(directory, _args) {
28934
29274
  } catch {
28935
29275
  results.push("\u274C Failed to delete state.json");
28936
29276
  }
28937
- const sessionDir = path56.dirname(validateSwarmPath(directory, "session/state.json"));
29277
+ const sessionDir = path57.dirname(validateSwarmPath(directory, "session/state.json"));
28938
29278
  let sessionFiles = [];
28939
- if (fs27.existsSync(sessionDir)) {
29279
+ if (fs28.existsSync(sessionDir)) {
28940
29280
  try {
28941
- sessionFiles = fs27.readdirSync(sessionDir);
29281
+ sessionFiles = fs28.readdirSync(sessionDir);
28942
29282
  } catch (err) {
28943
29283
  results.push(`\u274C Failed to read session directory: ${errorMessage(err)}`);
28944
29284
  }
@@ -28946,13 +29286,13 @@ async function handleResetSessionCommand(directory, _args) {
28946
29286
  for (const file of sessionFiles) {
28947
29287
  if (file === "state.json")
28948
29288
  continue;
28949
- const filePath = path56.join(sessionDir, file);
29289
+ const filePath = path57.join(sessionDir, file);
28950
29290
  try {
28951
- if (!fs27.existsSync(filePath))
29291
+ if (!fs28.existsSync(filePath))
28952
29292
  continue;
28953
- if (!fs27.lstatSync(filePath).isFile())
29293
+ if (!fs28.lstatSync(filePath).isFile())
28954
29294
  continue;
28955
- fs27.unlinkSync(filePath);
29295
+ fs28.unlinkSync(filePath);
28956
29296
  results.push(`\u2713 Deleted ${file}`);
28957
29297
  } catch (err) {
28958
29298
  results.push(`\u274C Failed to delete ${file}: ${errorMessage(err)}`);
@@ -28981,7 +29321,7 @@ async function handleResetSessionCommand(directory, _args) {
28981
29321
  }
28982
29322
 
28983
29323
  // src/summaries/manager.ts
28984
- import * as path57 from "path";
29324
+ import * as path58 from "path";
28985
29325
  var SUMMARY_ID_REGEX = /^S\d+$/;
28986
29326
  function sanitizeSummaryId(id) {
28987
29327
  if (!id || id.length === 0) {
@@ -29005,7 +29345,7 @@ function sanitizeSummaryId(id) {
29005
29345
  }
29006
29346
  async function loadFullOutput(directory, id) {
29007
29347
  const sanitizedId = sanitizeSummaryId(id);
29008
- const relativePath = path57.join("summaries", `${sanitizedId}.json`);
29348
+ const relativePath = path58.join("summaries", `${sanitizedId}.json`);
29009
29349
  validateSwarmPath(directory, relativePath);
29010
29350
  const content = await readSwarmFileAsync(directory, relativePath);
29011
29351
  if (content === null) {
@@ -29057,18 +29397,18 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
29057
29397
  }
29058
29398
 
29059
29399
  // src/commands/rollback.ts
29060
- import * as fs28 from "fs";
29061
- import * as path58 from "path";
29400
+ import * as fs29 from "fs";
29401
+ import * as path59 from "path";
29062
29402
  async function handleRollbackCommand(directory, args) {
29063
29403
  const phaseArg = args[0];
29064
29404
  if (!phaseArg) {
29065
29405
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
29066
- if (!fs28.existsSync(manifestPath2)) {
29406
+ if (!fs29.existsSync(manifestPath2)) {
29067
29407
  return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
29068
29408
  }
29069
29409
  let manifest2;
29070
29410
  try {
29071
- manifest2 = JSON.parse(fs28.readFileSync(manifestPath2, "utf-8"));
29411
+ manifest2 = JSON.parse(fs29.readFileSync(manifestPath2, "utf-8"));
29072
29412
  } catch {
29073
29413
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
29074
29414
  }
@@ -29090,12 +29430,12 @@ async function handleRollbackCommand(directory, args) {
29090
29430
  return "Error: Phase number must be a positive integer.";
29091
29431
  }
29092
29432
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
29093
- if (!fs28.existsSync(manifestPath)) {
29433
+ if (!fs29.existsSync(manifestPath)) {
29094
29434
  return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
29095
29435
  }
29096
29436
  let manifest;
29097
29437
  try {
29098
- manifest = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
29438
+ manifest = JSON.parse(fs29.readFileSync(manifestPath, "utf-8"));
29099
29439
  } catch {
29100
29440
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
29101
29441
  }
@@ -29105,10 +29445,10 @@ async function handleRollbackCommand(directory, args) {
29105
29445
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
29106
29446
  }
29107
29447
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
29108
- if (!fs28.existsSync(checkpointDir)) {
29448
+ if (!fs29.existsSync(checkpointDir)) {
29109
29449
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
29110
29450
  }
29111
- const checkpointFiles = fs28.readdirSync(checkpointDir);
29451
+ const checkpointFiles = fs29.readdirSync(checkpointDir);
29112
29452
  if (checkpointFiles.length === 0) {
29113
29453
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
29114
29454
  }
@@ -29124,10 +29464,10 @@ async function handleRollbackCommand(directory, args) {
29124
29464
  if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
29125
29465
  continue;
29126
29466
  }
29127
- const src = path58.join(checkpointDir, file);
29128
- const dest = path58.join(swarmDir, file);
29467
+ const src = path59.join(checkpointDir, file);
29468
+ const dest = path59.join(swarmDir, file);
29129
29469
  try {
29130
- fs28.cpSync(src, dest, { recursive: true, force: true });
29470
+ fs29.cpSync(src, dest, { recursive: true, force: true });
29131
29471
  successes.push(file);
29132
29472
  } catch (error2) {
29133
29473
  failures.push({ file, error: error2.message });
@@ -29144,11 +29484,11 @@ async function handleRollbackCommand(directory, args) {
29144
29484
  ].join(`
29145
29485
  `);
29146
29486
  }
29147
- const existingLedgerPath = path58.join(swarmDir, "plan-ledger.jsonl");
29487
+ const existingLedgerPath = path59.join(swarmDir, "plan-ledger.jsonl");
29148
29488
  let ledgerDeletionFailed = false;
29149
- if (fs28.existsSync(existingLedgerPath)) {
29489
+ if (fs29.existsSync(existingLedgerPath)) {
29150
29490
  try {
29151
- fs28.unlinkSync(existingLedgerPath);
29491
+ fs29.unlinkSync(existingLedgerPath);
29152
29492
  } catch (err) {
29153
29493
  ledgerDeletionFailed = true;
29154
29494
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -29157,9 +29497,9 @@ async function handleRollbackCommand(directory, args) {
29157
29497
  }
29158
29498
  if (!ledgerDeletionFailed) {
29159
29499
  try {
29160
- const planJsonPath = path58.join(swarmDir, "plan.json");
29161
- if (fs28.existsSync(planJsonPath)) {
29162
- const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
29500
+ const planJsonPath = path59.join(swarmDir, "plan.json");
29501
+ if (fs29.existsSync(planJsonPath)) {
29502
+ const planRaw = fs29.readFileSync(planJsonPath, "utf-8");
29163
29503
  const plan = PlanSchema.parse(JSON.parse(planRaw));
29164
29504
  const planId = derivePlanId(plan);
29165
29505
  const planHash = computePlanHash(plan);
@@ -29187,7 +29527,7 @@ async function handleRollbackCommand(directory, args) {
29187
29527
  timestamp: new Date().toISOString()
29188
29528
  };
29189
29529
  try {
29190
- fs28.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
29530
+ fs29.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
29191
29531
  `);
29192
29532
  } catch (error2) {
29193
29533
  console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
@@ -29417,13 +29757,13 @@ Ensure this is a git repository with commit history.`;
29417
29757
  const report = reportLines.filter(Boolean).join(`
29418
29758
  `);
29419
29759
  try {
29420
- const fs29 = await import("fs/promises");
29421
- const path59 = await import("path");
29422
- const reportPath = path59.join(directory, ".swarm", "simulate-report.md");
29423
- await fs29.mkdir(path59.dirname(reportPath), { recursive: true });
29424
- const reportTempPath = path59.join(path59.dirname(reportPath), `${path59.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
29760
+ const fs30 = await import("fs/promises");
29761
+ const path60 = await import("path");
29762
+ const reportPath = path60.join(directory, ".swarm", "simulate-report.md");
29763
+ await fs30.mkdir(path60.dirname(reportPath), { recursive: true });
29764
+ const reportTempPath = path60.join(path60.dirname(reportPath), `${path60.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
29425
29765
  try {
29426
- await fs29.writeFile(reportTempPath, report, "utf-8");
29766
+ await fs30.writeFile(reportTempPath, report, "utf-8");
29427
29767
  renameSync11(reportTempPath, reportPath);
29428
29768
  } catch (err) {
29429
29769
  try {
@@ -29450,20 +29790,20 @@ async function handleSpecifyCommand(_directory, args) {
29450
29790
  // src/services/status-service.ts
29451
29791
  import * as fsSync3 from "fs";
29452
29792
  import { readFile as readFile16 } from "fs/promises";
29453
- import * as path60 from "path";
29793
+ import * as path61 from "path";
29454
29794
 
29455
29795
  // src/turbo/lean/state.ts
29456
29796
  init_logger();
29457
- import * as fs29 from "fs";
29458
- import * as path59 from "path";
29797
+ import * as fs30 from "fs";
29798
+ import * as path60 from "path";
29459
29799
  var STATE_FILE3 = "turbo-state.json";
29460
29800
  function nowISO3() {
29461
29801
  return new Date().toISOString();
29462
29802
  }
29463
29803
  function ensureSwarmDir2(directory) {
29464
- const swarmDir = path59.resolve(directory, ".swarm");
29465
- if (!fs29.existsSync(swarmDir)) {
29466
- fs29.mkdirSync(swarmDir, { recursive: true });
29804
+ const swarmDir = path60.resolve(directory, ".swarm");
29805
+ if (!fs30.existsSync(swarmDir)) {
29806
+ fs30.mkdirSync(swarmDir, { recursive: true });
29467
29807
  }
29468
29808
  return swarmDir;
29469
29809
  }
@@ -29506,17 +29846,17 @@ function markStateUnreadable2(directory, reason) {
29506
29846
  }
29507
29847
  function readPersisted2(directory) {
29508
29848
  try {
29509
- const filePath = path59.join(directory, ".swarm", STATE_FILE3);
29510
- if (!fs29.existsSync(filePath)) {
29849
+ const filePath = path60.join(directory, ".swarm", STATE_FILE3);
29850
+ if (!fs30.existsSync(filePath)) {
29511
29851
  const seed = emptyPersisted2();
29512
29852
  try {
29513
29853
  ensureSwarmDir2(directory);
29514
- fs29.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
29854
+ fs30.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
29515
29855
  `, "utf-8");
29516
29856
  } catch {}
29517
29857
  return seed;
29518
29858
  }
29519
- const raw = fs29.readFileSync(filePath, "utf-8");
29859
+ const raw = fs30.readFileSync(filePath, "utf-8");
29520
29860
  const parsed = JSON.parse(raw);
29521
29861
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
29522
29862
  markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -29542,7 +29882,7 @@ function writePersisted2(directory, persisted) {
29542
29882
  let payload;
29543
29883
  try {
29544
29884
  ensureSwarmDir2(directory);
29545
- filePath = path59.join(directory, ".swarm", STATE_FILE3);
29885
+ filePath = path60.join(directory, ".swarm", STATE_FILE3);
29546
29886
  tmpPath = `${filePath}.tmp.${Date.now()}`;
29547
29887
  persisted.updatedAt = nowISO3();
29548
29888
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -29553,14 +29893,14 @@ function writePersisted2(directory, persisted) {
29553
29893
  throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
29554
29894
  }
29555
29895
  try {
29556
- fs29.writeFileSync(tmpPath, payload, "utf-8");
29557
- fs29.renameSync(tmpPath, filePath);
29896
+ fs30.writeFileSync(tmpPath, payload, "utf-8");
29897
+ fs30.renameSync(tmpPath, filePath);
29558
29898
  } catch (error2) {
29559
29899
  const msg = error2 instanceof Error ? error2.message : String(error2);
29560
29900
  error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
29561
29901
  try {
29562
- if (fs29.existsSync(tmpPath)) {
29563
- fs29.unlinkSync(tmpPath);
29902
+ if (fs30.existsSync(tmpPath)) {
29903
+ fs30.unlinkSync(tmpPath);
29564
29904
  }
29565
29905
  } catch {}
29566
29906
  throw new Error(`Lean Turbo state persistence failed: ${msg}`);
@@ -29660,7 +30000,7 @@ var _internals43 = {
29660
30000
  };
29661
30001
  function readSpecStalenessSnapshot(directory) {
29662
30002
  try {
29663
- const p = path60.join(directory, ".swarm", "spec-staleness.json");
30003
+ const p = path61.join(directory, ".swarm", "spec-staleness.json");
29664
30004
  if (!fsSync3.existsSync(p))
29665
30005
  return { stale: false };
29666
30006
  const raw = fsSync3.readFileSync(p, "utf-8");
@@ -30193,11 +30533,11 @@ function buildStatusMessage2(session, directory, sessionID) {
30193
30533
 
30194
30534
  // src/commands/unlink.ts
30195
30535
  import { existsSync as existsSync36 } from "fs";
30196
- import * as path61 from "path";
30536
+ import * as path62 from "path";
30197
30537
  var DEDUP_THRESHOLD2 = 0.6;
30198
30538
  async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
30199
- const sharedPath = path61.join(linkDir, "knowledge.jsonl");
30200
- const localPath = path61.join(localSwarmDir, "knowledge.jsonl");
30539
+ const sharedPath = path62.join(linkDir, "knowledge.jsonl");
30540
+ const localPath = path62.join(localSwarmDir, "knowledge.jsonl");
30201
30541
  if (!existsSync36(sharedPath))
30202
30542
  return 0;
30203
30543
  const sharedEntries = await readKnowledge(sharedPath);
@@ -30232,7 +30572,7 @@ async function handleUnlinkCommand(directory, args) {
30232
30572
  let copied = 0;
30233
30573
  if (copyBack) {
30234
30574
  try {
30235
- copied = await copySharedKnowledgeToLocal(linkDir, path61.join(directory, ".swarm"));
30575
+ copied = await copySharedKnowledgeToLocal(linkDir, path62.join(directory, ".swarm"));
30236
30576
  } catch (error2) {
30237
30577
  return `\u274C Failed to copy shared knowledge back to local: ${error2 instanceof Error ? error2.message : String(error2)}`;
30238
30578
  }
@@ -30387,7 +30727,7 @@ function buildDetailedHelp(commandName, entry) {
30387
30727
  async function handleHelpCommand(ctx) {
30388
30728
  const targetCommand = ctx.args.join(" ");
30389
30729
  if (!targetCommand) {
30390
- const { buildHelpText } = await import("./index-ary5jkky.js");
30730
+ const { buildHelpText } = await import("./index-dy6zs70b.js");
30391
30731
  return buildHelpText();
30392
30732
  }
30393
30733
  const tokens = targetCommand.split(/\s+/);
@@ -30396,7 +30736,7 @@ async function handleHelpCommand(ctx) {
30396
30736
  return _internals45.buildDetailedHelp(resolved.key, resolved.entry);
30397
30737
  }
30398
30738
  const similar = _internals45.findSimilarCommands(targetCommand);
30399
- const { buildHelpText: fullHelp } = await import("./index-ary5jkky.js");
30739
+ const { buildHelpText: fullHelp } = await import("./index-dy6zs70b.js");
30400
30740
  if (similar.length > 0) {
30401
30741
  return `Command '/swarm ${targetCommand}' not found.
30402
30742
 
@@ -30529,7 +30869,7 @@ var COMMAND_REGISTRY = {
30529
30869
  },
30530
30870
  "guardrail explain": {
30531
30871
  handler: async (ctx) => {
30532
- const { handleGuardrailExplain } = await import("./guardrail-explain-ygfy1qg9.js");
30872
+ const { handleGuardrailExplain } = await import("./guardrail-explain-bjsc2ydm.js");
30533
30873
  return handleGuardrailExplain(ctx.directory, ctx.args);
30534
30874
  },
30535
30875
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -31300,24 +31640,24 @@ function validateAliases() {
31300
31640
  }
31301
31641
  aliasTargets.get(target).push(name);
31302
31642
  const visited = new Set;
31303
- const path62 = [];
31643
+ const path63 = [];
31304
31644
  let current = target;
31305
31645
  while (current) {
31306
31646
  const currentEntry = COMMAND_REGISTRY[current];
31307
31647
  if (!currentEntry)
31308
31648
  break;
31309
31649
  if (visited.has(current)) {
31310
- const cycleStart = path62.indexOf(current);
31650
+ const cycleStart = path63.indexOf(current);
31311
31651
  const fullChain = [
31312
31652
  name,
31313
- ...path62.slice(0, cycleStart > 0 ? cycleStart : path62.length),
31653
+ ...path63.slice(0, cycleStart > 0 ? cycleStart : path63.length),
31314
31654
  current
31315
31655
  ].join(" \u2192 ");
31316
31656
  errors.push(`Circular alias detected: ${fullChain}`);
31317
31657
  break;
31318
31658
  }
31319
31659
  visited.add(current);
31320
- path62.push(current);
31660
+ path63.push(current);
31321
31661
  current = currentEntry.aliasOf || "";
31322
31662
  }
31323
31663
  }