opencode-swarm 7.98.1 → 7.99.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +1 -0
  2. package/dist/cli/{config-doctor-7yrxfa6b.js → config-doctor-9fhfy6p7.js} +2 -2
  3. package/dist/cli/{evidence-summary-service-g4x5e3e3.js → evidence-summary-service-4hs44n2c.js} +6 -6
  4. package/dist/cli/{gate-evidence-nphg8hay.js → gate-evidence-ywys9vfs.js} +4 -4
  5. package/dist/cli/guardrail-explain-ktm6szbm.js +30 -0
  6. package/dist/cli/{guardrail-log-53z1cf46.js → guardrail-log-ya49kpwn.js} +3 -3
  7. package/dist/cli/{index-91qtsbce.js → index-3naa2ajc.js} +1 -1
  8. package/dist/cli/{index-attgb1ma.js → index-4pt2py5p.js} +17 -15
  9. package/dist/cli/{index-sf08zj91.js → index-5fxjagjt.js} +2 -2
  10. package/dist/cli/{index-471qxz9g.js → index-7hnwnw5g.js} +11 -1
  11. package/dist/cli/{index-kv4dd5c5.js → index-9b7qp18e.js} +1 -1
  12. package/dist/cli/{index-hb10a2g8.js → index-f7nma02k.js} +2 -2
  13. package/dist/cli/{index-0rgde8qc.js → index-ft4gehk1.js} +2 -2
  14. package/dist/cli/{index-gnd1280x.js → index-h9ptj4b1.js} +1 -1
  15. package/dist/cli/{index-zgba613y.js → index-hw8r3e5p.js} +1108 -792
  16. package/dist/cli/{index-mh1ej70w.js → index-r8f89sm9.js} +2 -2
  17. package/dist/cli/{index-zy22fg5h.js → index-svf2zjxs.js} +5 -1
  18. package/dist/cli/{index-xchgryg4.js → index-vn263hqt.js} +16 -2
  19. package/dist/cli/{index-fjxjb66n.js → index-vwyjkzgs.js} +3 -3
  20. package/dist/cli/{index-gn8n22th.js → index-we94wkty.js} +19 -3
  21. package/dist/cli/{index-4c5jpmn9.js → index-wwnjw0fb.js} +11 -11
  22. package/dist/cli/{index-5z2e78tv.js → index-xsswhy6k.js} +1 -1
  23. package/dist/cli/index.js +13 -13
  24. package/dist/cli/{knowledge-store-pa58msy5.js → knowledge-store-tsa8ezka.js} +4 -4
  25. package/dist/cli/{pending-delegations-shqbvfjc.js → pending-delegations-c785p5n2.js} +3 -3
  26. package/dist/cli/{pr-subscriptions-2565fpsc.js → pr-subscriptions-fqrzm0tv.js} +4 -4
  27. package/dist/cli/{schema-mygkbbe9.js → schema-nz638xc3.js} +5 -1
  28. package/dist/cli/{skill-generator-3tkwcg4x.js → skill-generator-99rrfwae.js} +5 -5
  29. package/dist/cli/{telemetry-aa1ma1dr.js → telemetry-jm7t8031.js} +1 -1
  30. package/dist/commands/close.d.ts +2 -1
  31. package/dist/commands/costs.d.ts +4 -0
  32. package/dist/commands/index.d.ts +1 -0
  33. package/dist/commands/registry.d.ts +9 -2
  34. package/dist/config/evidence-schema.d.ts +44 -44
  35. package/dist/config/index.d.ts +2 -2
  36. package/dist/config/schema.d.ts +24 -0
  37. package/dist/hooks/system-enhancer.d.ts +1 -1
  38. package/dist/hooks/utils.d.ts +3 -1
  39. package/dist/index.js +2978 -2337
  40. package/dist/plan/manager.d.ts +1 -1
  41. package/dist/services/cost-accounting.d.ts +65 -0
  42. package/dist/state.d.ts +3 -3
  43. package/dist/telemetry.d.ts +2 -1
  44. package/package.json +1 -1
  45. package/dist/cli/guardrail-explain-cm08h4mt.js +0 -30
@@ -23,7 +23,7 @@ import {
23
23
  validateActionability,
24
24
  validateActionableFields,
25
25
  validateLesson
26
- } from "./index-fjxjb66n.js";
26
+ } from "./index-vwyjkzgs.js";
27
27
  import {
28
28
  appendKnowledge,
29
29
  appendRejectedLesson,
@@ -51,13 +51,13 @@ import {
51
51
  transactFile,
52
52
  transactKnowledge,
53
53
  writeLinkPointer
54
- } from "./index-hb10a2g8.js";
54
+ } from "./index-f7nma02k.js";
55
55
  import {
56
56
  detectStraySwarmDirs,
57
57
  readDoctorArtifact,
58
58
  removeStraySwarmDir,
59
59
  runConfigDoctor
60
- } from "./index-zy22fg5h.js";
60
+ } from "./index-svf2zjxs.js";
61
61
  import {
62
62
  AGENT_TOOL_MAP,
63
63
  ALL_SUBAGENT_NAMES,
@@ -70,7 +70,7 @@ import {
70
70
  TOOL_NAME_SET,
71
71
  resolveExternalSkillsConfig,
72
72
  stripKnownSwarmPrefix
73
- } from "./index-471qxz9g.js";
73
+ } from "./index-7hnwnw5g.js";
74
74
  import {
75
75
  MAX_TRANSIENT_RETRIES,
76
76
  PlanSchema,
@@ -114,7 +114,7 @@ import {
114
114
  transientBackoff,
115
115
  validateProjectRoot,
116
116
  writeProjectedSpecSync
117
- } from "./index-4c5jpmn9.js";
117
+ } from "./index-wwnjw0fb.js";
118
118
  import {
119
119
  _internals as _internals2,
120
120
  _internals1 as _internals3,
@@ -132,18 +132,18 @@ import {
132
132
  } from "./index-v4fcn4tr.js";
133
133
  import {
134
134
  atomicWriteFile
135
- } from "./index-kv4dd5c5.js";
135
+ } from "./index-9b7qp18e.js";
136
136
  import {
137
137
  buildCorrelationId,
138
138
  listActive,
139
139
  subscribe,
140
140
  unsubscribe
141
- } from "./index-sf08zj91.js";
141
+ } from "./index-5fxjagjt.js";
142
142
  import {
143
143
  readSwarmFileAsync,
144
144
  safeHook,
145
145
  validateSwarmPath
146
- } from "./index-gn8n22th.js";
146
+ } from "./index-we94wkty.js";
147
147
  import {
148
148
  deepMerge
149
149
  } from "./index-p0arc26j.js";
@@ -156,7 +156,7 @@ import {
156
156
  import {
157
157
  require_proper_lockfile,
158
158
  tryAcquireLock
159
- } from "./index-91qtsbce.js";
159
+ } from "./index-3naa2ajc.js";
160
160
  import {
161
161
  exports_external
162
162
  } from "./index-293f68mj.js";
@@ -166,7 +166,7 @@ import {
166
166
  } from "./index-b9v501fr.js";
167
167
  import {
168
168
  telemetry
169
- } from "./index-xchgryg4.js";
169
+ } from "./index-vn263hqt.js";
170
170
  import {
171
171
  __esm,
172
172
  __export,
@@ -909,7 +909,7 @@ var init_executor = __esm(() => {
909
909
  // package.json
910
910
  var package_default = {
911
911
  name: "opencode-swarm",
912
- version: "7.98.1",
912
+ version: "7.99.0",
913
913
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
914
914
  main: "dist/index.js",
915
915
  types: "dist/index.d.ts",
@@ -3624,15 +3624,30 @@ function classifySwarmCommandToolUse(resolved) {
3624
3624
  }
3625
3625
  }
3626
3626
  if (canonicalKey === "benchmark") {
3627
- const allowedFlags = new Set(["--cumulative", "--ci-gate"]);
3628
- const invalid = args.filter((arg) => !allowedFlags.has(arg));
3629
- if (invalid.length > 0) {
3627
+ for (let i = 0;i < args.length; i++) {
3628
+ const arg = args[i];
3629
+ if (arg === "--cumulative" || arg === "--ci-gate")
3630
+ continue;
3631
+ if (arg === "--max-cost-usd" && i + 1 < args.length && /^\d+(\.\d+)?$/.test(args[i + 1])) {
3632
+ i++;
3633
+ continue;
3634
+ }
3630
3635
  return {
3631
3636
  allowed: false,
3632
- message: "Only `--cumulative` and `--ci-gate` are supported for `/swarm benchmark` through swarm_command."
3637
+ message: "Only `--cumulative`, `--ci-gate`, and `--max-cost-usd <n>` are supported for `/swarm benchmark` through swarm_command."
3633
3638
  };
3634
3639
  }
3635
3640
  }
3641
+ if (canonicalKey === "costs") {
3642
+ if (args.length === 0)
3643
+ return { allowed: true };
3644
+ if (args.length === 1 && args[0] === "--json")
3645
+ return { allowed: true };
3646
+ return {
3647
+ allowed: false,
3648
+ message: "Usage through swarm_command: `/swarm costs` or `/swarm costs --json`."
3649
+ };
3650
+ }
3636
3651
  if (canonicalKey === "show-plan") {
3637
3652
  if (args.length > 1 || args[0] && !/^\d+$/.test(args[0])) {
3638
3653
  return {
@@ -5474,6 +5489,9 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, dire
5474
5489
  swarmState.pendingRehydrations.add(rehydrationPromise);
5475
5490
  }
5476
5491
  }
5492
+ function endAgentSession(sessionId) {
5493
+ swarmState.agentSessions.delete(sessionId);
5494
+ }
5477
5495
  function getAgentSession(sessionId) {
5478
5496
  return swarmState.agentSessions.get(sessionId);
5479
5497
  }
@@ -5978,7 +5996,7 @@ function hasActiveEpicMode(sessionID) {
5978
5996
  async function rehydratePrSubscriptions(sessionID, directory) {
5979
5997
  const map = new Map;
5980
5998
  try {
5981
- const { listActive: listActive2 } = await import("./pr-subscriptions-2565fpsc.js");
5999
+ const { listActive: listActive2 } = await import("./pr-subscriptions-fqrzm0tv.js");
5982
6000
  const records = await listActive2(directory);
5983
6001
  for (const record of records) {
5984
6002
  if (record.sessionID !== sessionID)
@@ -6055,6 +6073,199 @@ async function handleAutoProceedCommand(_directory, args, sessionID) {
6055
6073
  }
6056
6074
  }
6057
6075
 
6076
+ // src/services/cost-accounting.ts
6077
+ import * as fs7 from "fs";
6078
+ import * as os6 from "os";
6079
+ import * as path12 from "path";
6080
+ function summarizeTelemetryCosts(directory) {
6081
+ const summary = createEmptySummary();
6082
+ for (const event of readTelemetryEvents(directory)) {
6083
+ if (event.event !== "delegation_end")
6084
+ continue;
6085
+ addDelegationEvent(summary, event);
6086
+ }
6087
+ return finalizeSummary(summary);
6088
+ }
6089
+ function readTelemetryEvents(directory) {
6090
+ const swarmDir = path12.join(directory, ".swarm");
6091
+ const files = [
6092
+ path12.join(swarmDir, "telemetry.jsonl.1"),
6093
+ path12.join(swarmDir, "telemetry.jsonl")
6094
+ ];
6095
+ const tmpDir = fs7.mkdtempSync(path12.join(os6.tmpdir(), "telemetry-snapshot-"));
6096
+ const snapshotFiles = [];
6097
+ try {
6098
+ for (const file of files) {
6099
+ if (!fs7.existsSync(file))
6100
+ continue;
6101
+ const snap = path12.join(tmpDir, path12.basename(file));
6102
+ try {
6103
+ fs7.copyFileSync(file, snap);
6104
+ snapshotFiles.push(snap);
6105
+ } catch {}
6106
+ }
6107
+ } catch {}
6108
+ const events = [];
6109
+ for (const file of snapshotFiles) {
6110
+ let content = "";
6111
+ try {
6112
+ content = fs7.readFileSync(file, "utf-8");
6113
+ } catch {
6114
+ continue;
6115
+ }
6116
+ for (const line of content.split(/\r?\n/)) {
6117
+ const trimmed = line.trim();
6118
+ if (!trimmed)
6119
+ continue;
6120
+ try {
6121
+ const parsed = JSON.parse(trimmed);
6122
+ if (isRecord(parsed))
6123
+ events.push(parsed);
6124
+ } catch {}
6125
+ }
6126
+ }
6127
+ try {
6128
+ for (const f of snapshotFiles) {
6129
+ try {
6130
+ fs7.unlinkSync(f);
6131
+ } catch {}
6132
+ }
6133
+ fs7.rmdirSync(tmpDir);
6134
+ } catch {}
6135
+ return events;
6136
+ }
6137
+ function readNumber(record, keys) {
6138
+ for (const key of keys) {
6139
+ const value = record[key];
6140
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0)
6141
+ return value;
6142
+ if (typeof value === "string" && value.trim() !== "") {
6143
+ const parsed = Number(value);
6144
+ if (Number.isFinite(parsed) && parsed >= 0)
6145
+ return parsed;
6146
+ }
6147
+ }
6148
+ return null;
6149
+ }
6150
+ function isRecord(value) {
6151
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6152
+ }
6153
+ function createEmptySummary() {
6154
+ return {
6155
+ total_cost_usd: 0,
6156
+ total_reported_usd: 0,
6157
+ total_estimated_usd: 0,
6158
+ total_input_tokens: 0,
6159
+ total_output_tokens: 0,
6160
+ total_reasoning_tokens: 0,
6161
+ total_cache_tokens: 0,
6162
+ delegations: 0,
6163
+ unavailable_delegations: 0,
6164
+ by_agent: [],
6165
+ by_task: [],
6166
+ by_gate: [],
6167
+ by_retry: [],
6168
+ by_source: {
6169
+ reported: { delegations: 0, cost_usd: 0 },
6170
+ estimated: { delegations: 0, cost_usd: 0 },
6171
+ unavailable: { delegations: 0, cost_usd: 0 }
6172
+ }
6173
+ };
6174
+ }
6175
+ function addDelegationEvent(summary, event) {
6176
+ const costSource = parseCostSource(event.cost_source);
6177
+ const cost = readNumber(event, ["cost_usd"]) ?? 0;
6178
+ const usage = {
6179
+ tokens_input: readNumber(event, ["tokens_input"]) ?? 0,
6180
+ tokens_output: readNumber(event, ["tokens_output"]) ?? 0,
6181
+ tokens_reasoning: readNumber(event, ["tokens_reasoning"]) ?? 0,
6182
+ tokens_cache: readNumber(event, ["tokens_cache"]) ?? 0
6183
+ };
6184
+ summary.delegations++;
6185
+ summary.total_cost_usd += cost;
6186
+ summary.total_input_tokens += usage.tokens_input;
6187
+ summary.total_output_tokens += usage.tokens_output;
6188
+ summary.total_reasoning_tokens += usage.tokens_reasoning;
6189
+ summary.total_cache_tokens += usage.tokens_cache;
6190
+ summary.by_source[costSource].delegations++;
6191
+ summary.by_source[costSource].cost_usd += cost;
6192
+ if (costSource === "reported")
6193
+ summary.total_reported_usd += cost;
6194
+ if (costSource === "estimated")
6195
+ summary.total_estimated_usd += cost;
6196
+ if (costSource === "unavailable")
6197
+ summary.unavailable_delegations++;
6198
+ addRow(summary.by_agent, String(event.agentName ?? event.agent ?? "unknown"), {
6199
+ cost,
6200
+ costSource,
6201
+ usage
6202
+ });
6203
+ addRow(summary.by_task, String(event.taskId ?? event.task_id ?? "unknown"), {
6204
+ cost,
6205
+ costSource,
6206
+ usage
6207
+ });
6208
+ addRow(summary.by_gate, String(event.gate ?? "unknown"), {
6209
+ cost,
6210
+ costSource,
6211
+ usage
6212
+ });
6213
+ addRow(summary.by_retry, String(readNumber(event, ["retry_index", "retryIndex"]) ?? 0), {
6214
+ cost,
6215
+ costSource,
6216
+ usage
6217
+ });
6218
+ }
6219
+ function addRow(rows, name, input) {
6220
+ let row = rows.find((candidate) => candidate.name === name);
6221
+ if (!row) {
6222
+ row = {
6223
+ name,
6224
+ delegations: 0,
6225
+ cost_usd: 0,
6226
+ input_tokens: 0,
6227
+ output_tokens: 0,
6228
+ reasoning_tokens: 0,
6229
+ cache_tokens: 0,
6230
+ unavailable_delegations: 0
6231
+ };
6232
+ rows.push(row);
6233
+ }
6234
+ row.delegations++;
6235
+ row.cost_usd += input.cost;
6236
+ row.input_tokens += input.usage.tokens_input;
6237
+ row.output_tokens += input.usage.tokens_output;
6238
+ row.reasoning_tokens += input.usage.tokens_reasoning;
6239
+ row.cache_tokens += input.usage.tokens_cache;
6240
+ if (input.costSource === "unavailable")
6241
+ row.unavailable_delegations++;
6242
+ }
6243
+ function finalizeSummary(summary) {
6244
+ summary.total_cost_usd = roundUsd(summary.total_cost_usd);
6245
+ summary.total_reported_usd = roundUsd(summary.total_reported_usd);
6246
+ summary.total_estimated_usd = roundUsd(summary.total_estimated_usd);
6247
+ for (const source of Object.values(summary.by_source)) {
6248
+ source.cost_usd = roundUsd(source.cost_usd);
6249
+ }
6250
+ for (const rows of [
6251
+ summary.by_agent,
6252
+ summary.by_task,
6253
+ summary.by_gate,
6254
+ summary.by_retry
6255
+ ]) {
6256
+ for (const row of rows)
6257
+ row.cost_usd = roundUsd(row.cost_usd);
6258
+ rows.sort((a, b) => b.cost_usd - a.cost_usd || b.delegations - a.delegations);
6259
+ }
6260
+ return summary;
6261
+ }
6262
+ function parseCostSource(value) {
6263
+ return value === "reported" || value === "estimated" || value === "unavailable" ? value : "unavailable";
6264
+ }
6265
+ function roundUsd(value) {
6266
+ return Math.round(value * 1e6) / 1e6;
6267
+ }
6268
+
6058
6269
  // src/commands/benchmark.ts
6059
6270
  var CI = {
6060
6271
  review_pass_rate: 70,
@@ -6070,7 +6281,9 @@ async function handleBenchmarkCommand(directory, args) {
6070
6281
  let cumulative = args.includes("--cumulative");
6071
6282
  if (args.includes("--ci-gate"))
6072
6283
  cumulative = true;
6284
+ const maxCostUsd = parseMaxCostUsd(args);
6073
6285
  const mode = cumulative ? "cumulative" : "in-memory";
6286
+ const costSummary = cumulative ? summarizeTelemetryCosts(directory) : undefined;
6074
6287
  const agentMap = new Map;
6075
6288
  for (const [, s] of swarmState.agentSessions) {
6076
6289
  const e = agentMap.get(s.agentName) || {
@@ -6262,6 +6475,15 @@ async function handleBenchmarkCommand(directory, args) {
6262
6475
  passed: !hasQualityEvidence || testToCodeRatio >= CI.min_test_to_code_ratio
6263
6476
  }
6264
6477
  ];
6478
+ if (maxCostUsd !== null) {
6479
+ checks.push({
6480
+ name: "Total cost",
6481
+ value: costSummary?.total_cost_usd ?? 0,
6482
+ threshold: maxCostUsd,
6483
+ operator: "<=",
6484
+ passed: (costSummary?.total_cost_usd ?? 0) <= maxCostUsd
6485
+ });
6486
+ }
6265
6487
  ciGate = { passed: checks.every((c) => c.passed), checks };
6266
6488
  }
6267
6489
  const lines = [
@@ -6313,16 +6535,23 @@ async function handleBenchmarkCommand(directory, args) {
6313
6535
  lines.push(`- Test-to-Code Ratio: ${qualityMetrics.testToCodeRatio}% (min: ${qualityMetrics.thresholds.minTestToCodeRatio}%) ${qualityMetrics.testToCodeRatio >= qualityMetrics.thresholds.minTestToCodeRatio ? "\u2705" : "\u274C"}`);
6314
6536
  lines.push("");
6315
6537
  }
6538
+ if (costSummary) {
6539
+ lines.push("### Cost Signals");
6540
+ lines.push(`- Total tracked cost: $${costSummary.total_cost_usd.toFixed(6)} (${costSummary.delegations} delegations)`, `- Reported: $${costSummary.total_reported_usd.toFixed(6)}; estimated: $${costSummary.total_estimated_usd.toFixed(6)}; unavailable: ${costSummary.unavailable_delegations}`);
6541
+ lines.push("");
6542
+ }
6316
6543
  if (ciGate) {
6317
6544
  lines.push("### CI Gate", ciGate.passed ? "\u2705 PASSED" : "\u274C FAILED");
6318
6545
  for (const c of ciGate.checks) {
6319
6546
  let valueStr;
6320
6547
  if (c.name === "Complexity Delta" || c.name === "Public API Delta") {
6321
6548
  valueStr = `${c.value}`;
6549
+ } else if (c.name === "Total cost") {
6550
+ valueStr = `$${c.value.toFixed(6)}`;
6322
6551
  } else {
6323
6552
  valueStr = `${c.value}%`;
6324
6553
  }
6325
- const thresholdStr = c.name === "Complexity Delta" || c.name === "Public API Delta" ? `${c.threshold}` : `${c.threshold}%`;
6554
+ const thresholdStr = c.name === "Complexity Delta" || c.name === "Public API Delta" ? `${c.threshold}` : c.name === "Total cost" ? `$${c.threshold.toFixed(6)}` : `${c.threshold}%`;
6326
6555
  lines.push(`- ${c.name}: ${valueStr} ${c.operator} ${thresholdStr} ${c.passed ? "\u2705" : "\u274C"}`);
6327
6556
  }
6328
6557
  lines.push("");
@@ -6363,6 +6592,18 @@ async function handleBenchmarkCommand(directory, args) {
6363
6592
  thresholds: qualityMetrics.thresholds,
6364
6593
  has_evidence: qualityMetrics.hasEvidence
6365
6594
  };
6595
+ if (costSummary)
6596
+ json.costs = {
6597
+ total_cost_usd: costSummary.total_cost_usd,
6598
+ total_reported_usd: costSummary.total_reported_usd,
6599
+ total_estimated_usd: costSummary.total_estimated_usd,
6600
+ total_input_tokens: costSummary.total_input_tokens,
6601
+ total_output_tokens: costSummary.total_output_tokens,
6602
+ total_reasoning_tokens: costSummary.total_reasoning_tokens,
6603
+ total_cache_tokens: costSummary.total_cache_tokens,
6604
+ delegations: costSummary.delegations,
6605
+ unavailable_delegations: costSummary.unavailable_delegations
6606
+ };
6366
6607
  if (ciGate)
6367
6608
  json.ci_gate = {
6368
6609
  passed: ciGate.passed,
@@ -6378,6 +6619,20 @@ async function handleBenchmarkCommand(directory, args) {
6378
6619
  return lines.join(`
6379
6620
  `);
6380
6621
  }
6622
+ function parseMaxCostUsd(args) {
6623
+ const index = args.indexOf("--max-cost-usd");
6624
+ if (index === -1)
6625
+ return null;
6626
+ const raw = args[index + 1];
6627
+ if (!raw || raw.startsWith("--")) {
6628
+ throw new Error("Invalid --max-cost-usd value: expected a non-negative number.");
6629
+ }
6630
+ const parsed = Number(raw);
6631
+ if (!Number.isFinite(parsed) || parsed < 0) {
6632
+ throw new Error("Invalid --max-cost-usd value: expected a non-negative number.");
6633
+ }
6634
+ return parsed;
6635
+ }
6381
6636
 
6382
6637
  // src/commands/brainstorm.ts
6383
6638
  function sanitizeTopic(raw) {
@@ -6399,8 +6654,8 @@ async function handleBrainstormCommand(_directory, args) {
6399
6654
 
6400
6655
  // src/tools/checkpoint.ts
6401
6656
  import * as child_process from "child_process";
6402
- import * as fs7 from "fs";
6403
- import * as path12 from "path";
6657
+ import * as fs8 from "fs";
6658
+ import * as path13 from "path";
6404
6659
 
6405
6660
  // src/tools/create-tool.ts
6406
6661
  function classifyToolError(error2) {
@@ -6487,13 +6742,13 @@ function validateLabel(label) {
6487
6742
  return null;
6488
6743
  }
6489
6744
  function getCheckpointLogPath(directory) {
6490
- return path12.join(directory, CHECKPOINT_LOG_PATH);
6745
+ return path13.join(directory, CHECKPOINT_LOG_PATH);
6491
6746
  }
6492
6747
  function readCheckpointLog(directory) {
6493
6748
  const logPath = getCheckpointLogPath(directory);
6494
6749
  try {
6495
- if (fs7.existsSync(logPath)) {
6496
- const content = fs7.readFileSync(logPath, "utf-8");
6750
+ if (fs8.existsSync(logPath)) {
6751
+ const content = fs8.readFileSync(logPath, "utf-8");
6497
6752
  const parsed = JSON.parse(content);
6498
6753
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
6499
6754
  return { version: 1, checkpoints: [] };
@@ -6505,13 +6760,13 @@ function readCheckpointLog(directory) {
6505
6760
  }
6506
6761
  function writeCheckpointLog(log2, directory) {
6507
6762
  const logPath = getCheckpointLogPath(directory);
6508
- const dir = path12.dirname(logPath);
6509
- if (!fs7.existsSync(dir)) {
6510
- fs7.mkdirSync(dir, { recursive: true });
6763
+ const dir = path13.dirname(logPath);
6764
+ if (!fs8.existsSync(dir)) {
6765
+ fs8.mkdirSync(dir, { recursive: true });
6511
6766
  }
6512
6767
  const tempPath = `${logPath}.tmp`;
6513
- fs7.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
6514
- fs7.renameSync(tempPath, logPath);
6768
+ fs8.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
6769
+ fs8.renameSync(tempPath, logPath);
6515
6770
  }
6516
6771
  function gitExec(args, cwd) {
6517
6772
  for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
@@ -6542,10 +6797,10 @@ function gitExec(args, cwd) {
6542
6797
  }
6543
6798
  function appendRetentionEvent(directory, event) {
6544
6799
  try {
6545
- const eventsPath = path12.join(directory, ".swarm", "events.jsonl");
6800
+ const eventsPath = path13.join(directory, ".swarm", "events.jsonl");
6546
6801
  const line = `${JSON.stringify({ ...event, timestamp: new Date().toISOString() })}
6547
6802
  `;
6548
- fs7.appendFileSync(eventsPath, line);
6803
+ fs8.appendFileSync(eventsPath, line);
6549
6804
  } catch {}
6550
6805
  }
6551
6806
  function getCurrentSha(directory) {
@@ -6907,8 +7162,8 @@ async function handleClarifyCommand(_directory, args) {
6907
7162
  // src/commands/close.ts
6908
7163
  import { spawnSync as spawnSync5 } from "child_process";
6909
7164
  import * as fsSync2 from "fs";
6910
- import { promises as fs12 } from "fs";
6911
- import path25 from "path";
7165
+ import { promises as fs13 } from "fs";
7166
+ import path26 from "path";
6912
7167
 
6913
7168
  // src/hooks/abort-utils.ts
6914
7169
  function isAbortError(err) {
@@ -7037,8 +7292,8 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
7037
7292
  }
7038
7293
 
7039
7294
  // src/hooks/curator-postmortem.ts
7040
- import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync5 } from "fs";
7041
- import * as path13 from "path";
7295
+ import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync6 } from "fs";
7296
+ import * as path14 from "path";
7042
7297
  var MAX_INPUT_TEXT_CHARS = 500;
7043
7298
  var MAX_KNOWLEDGE_ENTRIES = 500;
7044
7299
  var MAX_PROPOSALS = 50;
@@ -7083,9 +7338,9 @@ async function collectKnowledgeSummary(directory) {
7083
7338
  }
7084
7339
  function readJsonlFile(filePath, maxLines) {
7085
7340
  try {
7086
- if (!existsSync5(filePath))
7341
+ if (!existsSync6(filePath))
7087
7342
  return [];
7088
- const content = readFileSync5(filePath, "utf-8");
7343
+ const content = readFileSync6(filePath, "utf-8");
7089
7344
  const results = [];
7090
7345
  const max = maxLines !== undefined && maxLines > 0 ? maxLines : Infinity;
7091
7346
  for (const line of content.split(`
@@ -7105,16 +7360,16 @@ function readJsonlFile(filePath, maxLines) {
7105
7360
  }
7106
7361
  function collectRetrospectives(directory) {
7107
7362
  const results = [];
7108
- const evidenceDir = path13.join(directory, ".swarm", "evidence");
7363
+ const evidenceDir = path14.join(directory, ".swarm", "evidence");
7109
7364
  try {
7110
- if (!existsSync5(evidenceDir))
7365
+ if (!existsSync6(evidenceDir))
7111
7366
  return results;
7112
7367
  const retroDirs = readdirSync(evidenceDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("retro-")).slice(0, MAX_RETROSPECTIVES);
7113
7368
  for (const entry of retroDirs) {
7114
- const retroPath = path13.join(evidenceDir, entry.name, "evidence.json");
7115
- if (existsSync5(retroPath)) {
7369
+ const retroPath = path14.join(evidenceDir, entry.name, "evidence.json");
7370
+ if (existsSync6(retroPath)) {
7116
7371
  try {
7117
- results.push(readFileSync5(retroPath, "utf-8"));
7372
+ results.push(readFileSync6(retroPath, "utf-8"));
7118
7373
  } catch {}
7119
7374
  }
7120
7375
  }
@@ -7123,14 +7378,14 @@ function collectRetrospectives(directory) {
7123
7378
  }
7124
7379
  function collectDriftReports(directory) {
7125
7380
  const results = [];
7126
- const swarmDir = path13.join(directory, ".swarm");
7381
+ const swarmDir = path14.join(directory, ".swarm");
7127
7382
  try {
7128
- if (!existsSync5(swarmDir))
7383
+ if (!existsSync6(swarmDir))
7129
7384
  return results;
7130
7385
  const driftFiles = readdirSync(swarmDir).filter((e) => e.startsWith("drift-report-phase-") && e.endsWith(".json")).slice(0, MAX_DRIFT_REPORTS);
7131
7386
  for (const entry of driftFiles) {
7132
7387
  try {
7133
- results.push(readFileSync5(path13.join(swarmDir, entry), "utf-8"));
7388
+ results.push(readFileSync6(path14.join(swarmDir, entry), "utf-8"));
7134
7389
  } catch {}
7135
7390
  }
7136
7391
  } catch {}
@@ -7138,24 +7393,24 @@ function collectDriftReports(directory) {
7138
7393
  }
7139
7394
  function collectPendingProposals(directory) {
7140
7395
  const results = [];
7141
- const insightPath = path13.join(directory, ".swarm", "insight-candidates.jsonl");
7142
- if (existsSync5(insightPath)) {
7396
+ const insightPath = path14.join(directory, ".swarm", "insight-candidates.jsonl");
7397
+ if (existsSync6(insightPath)) {
7143
7398
  try {
7144
7399
  results.push({
7145
7400
  source: "insight-candidates",
7146
- content: readFileSync5(insightPath, "utf-8")
7401
+ content: readFileSync6(insightPath, "utf-8")
7147
7402
  });
7148
7403
  } catch {}
7149
7404
  }
7150
- const proposalsDir = path13.join(directory, ".swarm", "skills", "proposals");
7405
+ const proposalsDir = path14.join(directory, ".swarm", "skills", "proposals");
7151
7406
  try {
7152
- if (existsSync5(proposalsDir)) {
7407
+ if (existsSync6(proposalsDir)) {
7153
7408
  const proposalFiles = readdirSync(proposalsDir).filter((e) => e.endsWith(".md") || e.endsWith(".json")).slice(0, MAX_PROPOSALS);
7154
7409
  for (const entry of proposalFiles) {
7155
7410
  try {
7156
7411
  results.push({
7157
7412
  source: `proposals/${entry}`,
7158
- content: readFileSync5(path13.join(proposalsDir, entry), "utf-8")
7413
+ content: readFileSync6(path14.join(proposalsDir, entry), "utf-8")
7159
7414
  });
7160
7415
  } catch {}
7161
7416
  }
@@ -7165,9 +7420,9 @@ function collectPendingProposals(directory) {
7165
7420
  }
7166
7421
  function isReportValid(reportPath) {
7167
7422
  try {
7168
- if (!existsSync5(reportPath))
7423
+ if (!existsSync6(reportPath))
7169
7424
  return false;
7170
- const content = readFileSync5(reportPath, "utf-8").trim();
7425
+ const content = readFileSync6(reportPath, "utf-8").trim();
7171
7426
  if (content.length === 0)
7172
7427
  return false;
7173
7428
  if (!content.startsWith("# Post-Mortem Report:"))
@@ -7376,7 +7631,7 @@ async function runCuratorPostMortem(directory, options = {}) {
7376
7631
  warnings.push(`Pending proposals capped at ${MAX_PROPOSALS} (had ${proposals.length}); older entries truncated.`);
7377
7632
  proposals = proposals.slice(0, MAX_PROPOSALS);
7378
7633
  }
7379
- const unactionablePath = path13.join(resolveKnowledgeStoreDir(directory), "knowledge-unactionable.jsonl");
7634
+ const unactionablePath = path14.join(resolveKnowledgeStoreDir(directory), "knowledge-unactionable.jsonl");
7380
7635
  let unactionable = readJsonlFile(unactionablePath, MAX_UNACTIONABLE);
7381
7636
  if (unactionable.length > MAX_UNACTIONABLE) {
7382
7637
  warnings.push(`Unactionable entries capped at ${MAX_UNACTIONABLE} (had ${unactionable.length}); older entries truncated.`);
@@ -7426,7 +7681,7 @@ ${llmOutput}`;
7426
7681
  }
7427
7682
  try {
7428
7683
  const { mkdirSync: mkdirSync6 } = await import("fs");
7429
- mkdirSync6(path13.dirname(reportPath), { recursive: true });
7684
+ mkdirSync6(path14.dirname(reportPath), { recursive: true });
7430
7685
  await atomicWriteFile(reportPath, reportContent);
7431
7686
  } catch (err) {
7432
7687
  const msg = err instanceof Error ? err.message : String(err);
@@ -7474,7 +7729,7 @@ var _internals13 = {
7474
7729
  };
7475
7730
 
7476
7731
  // src/hooks/hive-promoter.ts
7477
- import path16 from "path";
7732
+ import path17 from "path";
7478
7733
 
7479
7734
  // src/background/event-bus.ts
7480
7735
  class AutomationEventBus {
@@ -7978,9 +8233,9 @@ init_logger();
7978
8233
 
7979
8234
  // src/services/skill-improver-quota.ts
7980
8235
  var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
7981
- import { existsSync as existsSync6 } from "fs";
8236
+ import { existsSync as existsSync7 } from "fs";
7982
8237
  import { mkdir as mkdir3, readFile as readFile3, rename, writeFile as writeFile2 } from "fs/promises";
7983
- import * as path14 from "path";
8238
+ import * as path15 from "path";
7984
8239
  var LOCK_ACQUIRE_TIMEOUT_MS = 1e4;
7985
8240
  var LOCK_RETRY_OPTS = {
7986
8241
  retries: {
@@ -8009,7 +8264,7 @@ async function acquireLock(dir) {
8009
8264
  }
8010
8265
  function resolveQuotaPath(directory, scope = "skill-improver") {
8011
8266
  const fileName = scope === "knowledge-enrichment" ? "knowledge-enrichment-quota.json" : "skill-improver-quota.json";
8012
- return path14.join(directory, ".swarm", fileName);
8267
+ return path15.join(directory, ".swarm", fileName);
8013
8268
  }
8014
8269
  function todayKey(window, now = new Date) {
8015
8270
  if (window === "utc") {
@@ -8021,7 +8276,7 @@ function todayKey(window, now = new Date) {
8021
8276
  return `${yr}-${m}-${d}`;
8022
8277
  }
8023
8278
  async function readState(filePath) {
8024
- if (!existsSync6(filePath))
8279
+ if (!existsSync7(filePath))
8025
8280
  return null;
8026
8281
  try {
8027
8282
  const raw = await readFile3(filePath, "utf-8");
@@ -8035,7 +8290,7 @@ async function readState(filePath) {
8035
8290
  }
8036
8291
  }
8037
8292
  async function writeState(filePath, state) {
8038
- await mkdir3(path14.dirname(filePath), { recursive: true });
8293
+ await mkdir3(path15.dirname(filePath), { recursive: true });
8039
8294
  const tmp = `${filePath}.tmp-${process.pid}`;
8040
8295
  await writeFile2(tmp, JSON.stringify(state, null, 2), "utf-8");
8041
8296
  await rename(tmp, filePath);
@@ -8058,10 +8313,10 @@ async function getQuotaState(directory, opts) {
8058
8313
  }
8059
8314
  async function reserveQuota(directory, opts) {
8060
8315
  const filePath = resolveQuotaPath(directory, opts.scope);
8061
- await mkdir3(path14.dirname(filePath), { recursive: true });
8316
+ await mkdir3(path15.dirname(filePath), { recursive: true });
8062
8317
  let release = null;
8063
8318
  try {
8064
- release = await acquireLock(path14.dirname(filePath));
8319
+ release = await acquireLock(path15.dirname(filePath));
8065
8320
  const state = await getQuotaState(directory, opts);
8066
8321
  if (state.calls_used + opts.nCalls > opts.maxCalls) {
8067
8322
  return {
@@ -8088,10 +8343,10 @@ async function reserveQuota(directory, opts) {
8088
8343
  }
8089
8344
  async function releaseQuota(directory, opts) {
8090
8345
  const filePath = resolveQuotaPath(directory, opts.scope);
8091
- await mkdir3(path14.dirname(filePath), { recursive: true });
8346
+ await mkdir3(path15.dirname(filePath), { recursive: true });
8092
8347
  let release = null;
8093
8348
  try {
8094
- release = await acquireLock(path14.dirname(filePath));
8349
+ release = await acquireLock(path15.dirname(filePath));
8095
8350
  const state = await getQuotaState(directory, opts);
8096
8351
  const next = {
8097
8352
  ...state,
@@ -8114,8 +8369,8 @@ init_logger();
8114
8369
 
8115
8370
  // src/hooks/skill-usage-log.ts
8116
8371
  import * as crypto3 from "crypto";
8117
- import * as fs8 from "fs";
8118
- import * as path15 from "path";
8372
+ import * as fs9 from "fs";
8373
+ import * as path16 from "path";
8119
8374
  function resolveLogPath(directory) {
8120
8375
  return validateSwarmPath(directory, "skill-usage.jsonl");
8121
8376
  }
@@ -8124,16 +8379,16 @@ function normalizeComplianceVerdict(verdict) {
8124
8379
  }
8125
8380
  var _internals14 = {
8126
8381
  generateId: () => crypto3.randomUUID(),
8127
- appendFileSync: fs8.appendFileSync.bind(fs8),
8128
- readFileSync: fs8.readFileSync.bind(fs8),
8129
- writeFileSync: fs8.writeFileSync.bind(fs8),
8130
- renameSync: fs8.renameSync.bind(fs8),
8131
- mkdirSync: fs8.mkdirSync.bind(fs8),
8132
- existsSync: fs8.existsSync.bind(fs8),
8133
- statSync: fs8.statSync.bind(fs8),
8134
- openSync: fs8.openSync.bind(fs8),
8135
- readSync: fs8.readSync.bind(fs8),
8136
- closeSync: fs8.closeSync.bind(fs8),
8382
+ appendFileSync: fs9.appendFileSync.bind(fs9),
8383
+ readFileSync: fs9.readFileSync.bind(fs9),
8384
+ writeFileSync: fs9.writeFileSync.bind(fs9),
8385
+ renameSync: fs9.renameSync.bind(fs9),
8386
+ mkdirSync: fs9.mkdirSync.bind(fs9),
8387
+ existsSync: fs9.existsSync.bind(fs9),
8388
+ statSync: fs9.statSync.bind(fs9),
8389
+ openSync: fs9.openSync.bind(fs9),
8390
+ readSync: fs9.readSync.bind(fs9),
8391
+ closeSync: fs9.closeSync.bind(fs9),
8137
8392
  pruneSkillUsageLog,
8138
8393
  resolveSourceKnowledgeIds,
8139
8394
  applySkillUsageFeedback,
@@ -8214,7 +8469,7 @@ function appendFeedbackAppliedMarker(directory, processedEntryIds) {
8214
8469
  if (processedEntryIds.length === 0)
8215
8470
  return;
8216
8471
  const resolved = resolveLogPath(directory);
8217
- const dir = path15.dirname(resolved);
8472
+ const dir = path16.dirname(resolved);
8218
8473
  if (!_internals14.existsSync(dir)) {
8219
8474
  _internals14.mkdirSync(dir, { recursive: true });
8220
8475
  }
@@ -8259,7 +8514,7 @@ function appendSkillUsageEntry(directory, entry) {
8259
8514
  throw new Error("sessionID is required and must be a non-empty string");
8260
8515
  }
8261
8516
  const resolved = validateSwarmPath(directory, "skill-usage.jsonl");
8262
- const dir = path15.dirname(resolved);
8517
+ const dir = path16.dirname(resolved);
8263
8518
  if (!_internals14.existsSync(dir)) {
8264
8519
  _internals14.mkdirSync(dir, { recursive: true });
8265
8520
  }
@@ -8435,8 +8690,8 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8435
8690
  }
8436
8691
  if (entries.length === 0) {
8437
8692
  if (preservedMarkers.length > 0) {
8438
- const dir2 = path15.dirname(resolved);
8439
- const tmpPath2 = path15.join(dir2, `skill-usage-${Date.now()}.tmp`);
8693
+ const dir2 = path16.dirname(resolved);
8694
+ const tmpPath2 = path16.join(dir2, `skill-usage-${Date.now()}.tmp`);
8440
8695
  const content2 = preservedMarkers.join(`
8441
8696
  `).concat(preservedMarkers.length > 0 ? `
8442
8697
  ` : "");
@@ -8478,8 +8733,8 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8478
8733
  if (pruned === 0) {
8479
8734
  return { pruned: 0, remaining: entries.length };
8480
8735
  }
8481
- const dir = path15.dirname(resolved);
8482
- const tmpPath = path15.join(dir, `skill-usage-${Date.now()}.tmp`);
8736
+ const dir = path16.dirname(resolved);
8737
+ const tmpPath = path16.join(dir, `skill-usage-${Date.now()}.tmp`);
8483
8738
  const entryLines = surviving.map((e) => JSON.stringify(e));
8484
8739
  const allLines = [...entryLines, ...preservedMarkers];
8485
8740
  const content = allLines.join(`
@@ -8508,9 +8763,9 @@ async function resolveSourceKnowledgeIds(directory, skillPath) {
8508
8763
  if (/\.\.[/\\]/.test(cleanPath)) {
8509
8764
  return [];
8510
8765
  }
8511
- const absolute = path15.normalize(path15.isAbsolute(cleanPath) ? cleanPath : path15.resolve(directory, cleanPath));
8512
- const baseDir = path15.normalize(path15.resolve(directory));
8513
- const isContained = process.platform === "win32" ? absolute.toLowerCase().startsWith((baseDir + path15.sep).toLowerCase()) : absolute.startsWith(baseDir + path15.sep);
8766
+ const absolute = path16.normalize(path16.isAbsolute(cleanPath) ? cleanPath : path16.resolve(directory, cleanPath));
8767
+ const baseDir = path16.normalize(path16.resolve(directory));
8768
+ const isContained = process.platform === "win32" ? absolute.toLowerCase().startsWith((baseDir + path16.sep).toLowerCase()) : absolute.startsWith(baseDir + path16.sep);
8514
8769
  if (!isContained) {
8515
8770
  return [];
8516
8771
  }
@@ -8822,7 +9077,7 @@ async function promoteToHive(directory, lesson, category) {
8822
9077
  schema_version: 1,
8823
9078
  created_at: new Date().toISOString(),
8824
9079
  updated_at: new Date().toISOString(),
8825
- source_project: path16.basename(directory) || "unknown",
9080
+ source_project: path17.basename(directory) || "unknown",
8826
9081
  encounter_score: 1
8827
9082
  };
8828
9083
  await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
@@ -8874,9 +9129,9 @@ async function promoteFromSwarm(directory, lessonId) {
8874
9129
 
8875
9130
  // src/hooks/knowledge-curator.ts
8876
9131
  import { createHash as createHash3 } from "crypto";
8877
- import { existsSync as existsSync10 } from "fs";
9132
+ import { existsSync as existsSync11 } from "fs";
8878
9133
  import { appendFile as appendFile2, mkdir as mkdir5, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
8879
- import * as path21 from "path";
9134
+ import * as path22 from "path";
8880
9135
 
8881
9136
  // src/services/synonym-map.ts
8882
9137
  var import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
@@ -8888,7 +9143,7 @@ import {
8888
9143
  unlink as unlink2,
8889
9144
  writeFile as writeFile3
8890
9145
  } from "fs/promises";
8891
- import * as path17 from "path";
9146
+ import * as path18 from "path";
8892
9147
  var SYNONYM_MAP_FILENAME = "synonym-map.json";
8893
9148
  var MAX_TOKEN_LENGTH = 64;
8894
9149
  var DEFAULT_MAX_PAIRS = 500;
@@ -9043,7 +9298,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
9043
9298
  }
9044
9299
  }
9045
9300
  async function writeSynonymMapAtomic(filePath, map) {
9046
- await mkdir4(path17.dirname(filePath), { recursive: true });
9301
+ await mkdir4(path18.dirname(filePath), { recursive: true });
9047
9302
  const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
9048
9303
  try {
9049
9304
  await writeFile3(tmp, JSON.stringify(map, null, 2), "utf-8");
@@ -9056,7 +9311,7 @@ async function writeSynonymMapAtomic(filePath, map) {
9056
9311
  }
9057
9312
  async function rebuildSynonymMap(directory, entries, maxPairs = DEFAULT_MAX_PAIRS) {
9058
9313
  const filePath = resolveSynonymMapPath(directory);
9059
- const dir = path17.dirname(filePath);
9314
+ const dir = path18.dirname(filePath);
9060
9315
  await mkdir4(dir, { recursive: true });
9061
9316
  let release = null;
9062
9317
  try {
@@ -9119,19 +9374,19 @@ function reinforceSwarmKnowledgeEntry(entry, confirmation) {
9119
9374
  }
9120
9375
 
9121
9376
  // src/hooks/micro-reflector.ts
9122
- import { existsSync as existsSync9 } from "fs";
9377
+ import { existsSync as existsSync10 } from "fs";
9123
9378
  import { readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
9124
- import * as path20 from "path";
9379
+ import * as path21 from "path";
9125
9380
  init_logger();
9126
9381
 
9127
9382
  // src/hooks/skill-propagation-gate.ts
9128
- import * as fs10 from "fs";
9129
- import * as path19 from "path";
9383
+ import * as fs11 from "fs";
9384
+ import * as path20 from "path";
9130
9385
  init_logger();
9131
9386
 
9132
9387
  // src/hooks/skill-scoring.ts
9133
- import * as fs9 from "fs";
9134
- import * as path18 from "path";
9388
+ import * as fs10 from "fs";
9389
+ import * as path19 from "path";
9135
9390
  var FREQUENCY_CAP = 10;
9136
9391
  var FREQUENCY_WEIGHT = 0.3;
9137
9392
  var COMPLIANCE_WEIGHT = 0.3;
@@ -9159,10 +9414,10 @@ var _internals15 = {
9159
9414
  computeTriggerMatchBoost: null
9160
9415
  };
9161
9416
  function extractSkillName(skillPath) {
9162
- const base = path18.basename(skillPath, path18.extname(skillPath));
9417
+ const base = path19.basename(skillPath, path19.extname(skillPath));
9163
9418
  if (base !== "SKILL")
9164
9419
  return base;
9165
- const parent = path18.basename(path18.dirname(skillPath));
9420
+ const parent = path19.basename(path19.dirname(skillPath));
9166
9421
  return parent;
9167
9422
  }
9168
9423
  function stripQuotes(value) {
@@ -9304,25 +9559,25 @@ function parseSkillFrontmatter(content, skillPath) {
9304
9559
  return meta;
9305
9560
  }
9306
9561
  function readFilePrefix(filePath) {
9307
- const fd = fs9.openSync(filePath, "r");
9562
+ const fd = fs10.openSync(filePath, "r");
9308
9563
  try {
9309
9564
  const buffer = Buffer.alloc(SKILL_FRONTMATTER_READ_BYTES);
9310
- const bytesRead = fs9.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
9565
+ const bytesRead = fs10.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
9311
9566
  return buffer.toString("utf-8", 0, bytesRead);
9312
9567
  } finally {
9313
- fs9.closeSync(fd);
9568
+ fs10.closeSync(fd);
9314
9569
  }
9315
9570
  }
9316
9571
  function readSkillMetadata(skillPath, directory) {
9317
9572
  const normalizedPath = skillPath.replace(/^file:/, "").replace(/\\/g, "/");
9318
9573
  const fallback = parseSkillFrontmatter("", normalizedPath);
9319
9574
  try {
9320
- if (path18.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
9575
+ if (path19.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
9321
9576
  return fallback;
9322
9577
  }
9323
- const root = path18.resolve(directory);
9324
- const absolutePath = path18.resolve(directory, normalizedPath);
9325
- if (absolutePath !== root && !absolutePath.startsWith(root + path18.sep)) {
9578
+ const root = path19.resolve(directory);
9579
+ const absolutePath = path19.resolve(directory, normalizedPath);
9580
+ if (absolutePath !== root && !absolutePath.startsWith(root + path19.sep)) {
9326
9581
  return fallback;
9327
9582
  }
9328
9583
  const content = readFilePrefix(absolutePath);
@@ -9456,10 +9711,10 @@ function getSkillStats(skillPath, directory) {
9456
9711
  };
9457
9712
  }
9458
9713
  function formatSkillIndexWithContext(skills, directory) {
9459
- const usageLogPath = path18.join(directory, ".swarm", "skill-usage.jsonl");
9714
+ const usageLogPath = path19.join(directory, ".swarm", "skill-usage.jsonl");
9460
9715
  let hasHistory = false;
9461
9716
  try {
9462
- const stat4 = fs9.statSync(usageLogPath);
9717
+ const stat4 = fs10.statSync(usageLogPath);
9463
9718
  hasHistory = stat4.size > 0;
9464
9719
  } catch {}
9465
9720
  if (!hasHistory) {
@@ -9590,7 +9845,7 @@ function parseYamlValue(value) {
9590
9845
  return trimmed;
9591
9846
  }
9592
9847
  function loadRoutingSkills(directory, targetAgent) {
9593
- const routingPath = path19.join(directory, ".opencode", "skill-routing.yaml");
9848
+ const routingPath = path20.join(directory, ".opencode", "skill-routing.yaml");
9594
9849
  if (!_internals16.existsSync(routingPath))
9595
9850
  return [];
9596
9851
  try {
@@ -9622,13 +9877,13 @@ var SKILL_SEARCH_ROOTS = [
9622
9877
  ];
9623
9878
  var MAX_SCORING_SESSION_ENTRIES = 500;
9624
9879
  var _internals16 = {
9625
- readdirSync: fs10.readdirSync.bind(fs10),
9626
- existsSync: fs10.existsSync.bind(fs10),
9627
- statSync: fs10.statSync.bind(fs10),
9628
- mkdirSync: fs10.mkdirSync.bind(fs10),
9629
- appendFileSync: fs10.appendFileSync.bind(fs10),
9630
- readFileSync: fs10.readFileSync.bind(fs10),
9631
- writeFileSync: fs10.writeFileSync.bind(fs10),
9880
+ readdirSync: fs11.readdirSync.bind(fs11),
9881
+ existsSync: fs11.existsSync.bind(fs11),
9882
+ statSync: fs11.statSync.bind(fs11),
9883
+ mkdirSync: fs11.mkdirSync.bind(fs11),
9884
+ appendFileSync: fs11.appendFileSync.bind(fs11),
9885
+ readFileSync: fs11.readFileSync.bind(fs11),
9886
+ writeFileSync: fs11.writeFileSync.bind(fs11),
9632
9887
  skillPropagationGateBefore: null,
9633
9888
  skillPropagationTransformScan: null,
9634
9889
  SKILL_CAPABLE_AGENTS,
@@ -9650,7 +9905,7 @@ var _internals16 = {
9650
9905
  function discoverAvailableSkills(directory) {
9651
9906
  const results = [];
9652
9907
  for (const root of SKILL_SEARCH_ROOTS) {
9653
- const rootPath = path19.join(directory, root);
9908
+ const rootPath = path20.join(directory, root);
9654
9909
  if (!_internals16.existsSync(rootPath))
9655
9910
  continue;
9656
9911
  let entries;
@@ -9662,13 +9917,13 @@ function discoverAvailableSkills(directory) {
9662
9917
  for (const entry of entries) {
9663
9918
  if (entry.startsWith("."))
9664
9919
  continue;
9665
- const skillDir = path19.join(rootPath, entry);
9666
- if (_internals16.existsSync(path19.join(skillDir, "retired.marker")) || _internals16.existsSync(path19.join(skillDir, "stale.marker")))
9920
+ const skillDir = path20.join(rootPath, entry);
9921
+ if (_internals16.existsSync(path20.join(skillDir, "retired.marker")) || _internals16.existsSync(path20.join(skillDir, "stale.marker")))
9667
9922
  continue;
9668
- const skillFile = path19.join(skillDir, "SKILL.md");
9923
+ const skillFile = path20.join(skillDir, "SKILL.md");
9669
9924
  try {
9670
9925
  if (_internals16.statSync(skillDir).isDirectory() && _internals16.existsSync(skillFile)) {
9671
- results.push(path19.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
9926
+ results.push(path20.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
9672
9927
  }
9673
9928
  } catch (err) {
9674
9929
  warn(`[skill-propagation-gate] failed to stat skill directory ${entry}: ${err instanceof Error ? err.message : String(err)}`);
@@ -9737,9 +9992,9 @@ function extractSkillsFieldFromPrompt(prompt) {
9737
9992
  return "";
9738
9993
  }
9739
9994
  function writeWarnEvent(directory, record) {
9740
- const filePath = path19.join(directory, ".swarm", "events.jsonl");
9995
+ const filePath = path20.join(directory, ".swarm", "events.jsonl");
9741
9996
  try {
9742
- const dir = path19.dirname(filePath);
9997
+ const dir = path20.dirname(filePath);
9743
9998
  if (!_internals16.existsSync(dir)) {
9744
9999
  _internals16.mkdirSync(dir, { recursive: true });
9745
10000
  }
@@ -9868,8 +10123,8 @@ async function skillPropagationGateBefore(directory, input, config) {
9868
10123
  if (routingPaths.length > 0) {
9869
10124
  const existingPaths = new Set(scored.map((s) => s.skillPath));
9870
10125
  for (const routingPath of routingPaths) {
9871
- const routedSkillDir = path19.dirname(path19.join(directory, routingPath));
9872
- if (_internals16.existsSync(path19.join(routedSkillDir, "retired.marker")) || _internals16.existsSync(path19.join(routedSkillDir, "stale.marker")))
10126
+ const routedSkillDir = path20.dirname(path20.join(directory, routingPath));
10127
+ if (_internals16.existsSync(path20.join(routedSkillDir, "retired.marker")) || _internals16.existsSync(path20.join(routedSkillDir, "stale.marker")))
9873
10128
  continue;
9874
10129
  if (!existingPaths.has(routingPath)) {
9875
10130
  scored.push({
@@ -9888,8 +10143,8 @@ async function skillPropagationGateBefore(directory, input, config) {
9888
10143
  let skillsForIndex = availableSkills;
9889
10144
  if (scoringSkipped) {
9890
10145
  skillsForIndex = [...availableSkills].sort((a, b) => {
9891
- const nameA = path19.basename(path19.dirname(a));
9892
- const nameB = path19.basename(path19.dirname(b));
10146
+ const nameA = path20.basename(path20.dirname(a));
10147
+ const nameB = path20.basename(path20.dirname(b));
9893
10148
  return nameA.localeCompare(nameB);
9894
10149
  });
9895
10150
  } else if (typeof scored !== "undefined" && scored.length > 0) {
@@ -9897,7 +10152,7 @@ async function skillPropagationGateBefore(directory, input, config) {
9897
10152
  }
9898
10153
  const formattedIndex = _internals16.formatSkillIndexWithContext(skillsForIndex, directory);
9899
10154
  if (formattedIndex.length > 0) {
9900
- const contextPath = path19.join(directory, ".swarm", "context.md");
10155
+ const contextPath = path20.join(directory, ".swarm", "context.md");
9901
10156
  let existingContent = "";
9902
10157
  if (_internals16.existsSync(contextPath)) {
9903
10158
  existingContent = _internals16.readFileSync(contextPath, "utf-8");
@@ -9919,7 +10174,7 @@ ${newSection}`;
9919
10174
  updatedContent = existingContent + newSection;
9920
10175
  }
9921
10176
  }
9922
- const swarmDir = path19.dirname(contextPath);
10177
+ const swarmDir = path20.dirname(contextPath);
9923
10178
  if (!_internals16.existsSync(swarmDir)) {
9924
10179
  _internals16.mkdirSync(swarmDir, { recursive: true });
9925
10180
  }
@@ -10145,9 +10400,9 @@ function resolveInsightCandidatesPath(directory) {
10145
10400
  }
10146
10401
  async function readTaskTrajectory(directory, taskId) {
10147
10402
  try {
10148
- const rel = path20.join("evidence", sanitizeTaskId(taskId), "trajectory.jsonl");
10403
+ const rel = path21.join("evidence", sanitizeTaskId(taskId), "trajectory.jsonl");
10149
10404
  const filePath = validateSwarmPath(directory, rel);
10150
- if (!existsSync9(filePath))
10405
+ if (!existsSync10(filePath))
10151
10406
  return [];
10152
10407
  const content = await readFile5(filePath, "utf-8");
10153
10408
  const out = [];
@@ -10203,7 +10458,7 @@ var WRITE_TOOLS = new Set([
10203
10458
  "apply_patch",
10204
10459
  "swarm_apply_patch"
10205
10460
  ]);
10206
- function isRecord(value) {
10461
+ function isRecord2(value) {
10207
10462
  return typeof value === "object" && value !== null;
10208
10463
  }
10209
10464
  function normalizePathField(value) {
@@ -10213,13 +10468,13 @@ function firstPathFromRecord(record) {
10213
10468
  return normalizePathField(record.path) ?? normalizePathField(record.filePath) ?? normalizePathField(record.file);
10214
10469
  }
10215
10470
  function normalizeWriteTrigger(input, output) {
10216
- if (!isRecord(input))
10471
+ if (!isRecord2(input))
10217
10472
  return null;
10218
10473
  const toolName = typeof input.toolName === "string" ? input.toolName : typeof input.tool === "string" ? input.tool : null;
10219
10474
  if (!toolName || !WRITE_TOOLS.has(toolName))
10220
10475
  return null;
10221
- const inputArgs = isRecord(input.args) ? input.args : null;
10222
- const outputArgs = isRecord(output) && isRecord(output.args) ? output.args : null;
10476
+ const inputArgs = isRecord2(input.args) ? input.args : null;
10477
+ const outputArgs = isRecord2(output) && isRecord2(output.args) ? output.args : null;
10223
10478
  const filePath = firstPathFromRecord(input) ?? (inputArgs ? firstPathFromRecord(inputArgs) : null) ?? (outputArgs ? firstPathFromRecord(outputArgs) : null);
10224
10479
  if (!filePath)
10225
10480
  return null;
@@ -10575,8 +10830,8 @@ RETRY: your last output was missing ${result.missing.join("; ")}; produce valid
10575
10830
  }
10576
10831
  async function appendCuratorSkippedEvent(directory, record) {
10577
10832
  try {
10578
- const filePath = path21.join(directory, ".swarm", "events.jsonl");
10579
- await mkdir5(path21.dirname(filePath), { recursive: true });
10833
+ const filePath = path22.join(directory, ".swarm", "events.jsonl");
10834
+ await mkdir5(path22.dirname(filePath), { recursive: true });
10580
10835
  await appendFile2(filePath, `${JSON.stringify({
10581
10836
  timestamp: new Date().toISOString(),
10582
10837
  event: "curator_skipped",
@@ -10616,7 +10871,7 @@ function readInsightJsonl(content) {
10616
10871
  async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BATCH_LIMIT) {
10617
10872
  try {
10618
10873
  const filePath = resolveInsightCandidatesPath(directory);
10619
- if (!existsSync10(filePath))
10874
+ if (!existsSync11(filePath))
10620
10875
  return [];
10621
10876
  const consumed = [];
10622
10877
  await transactFile(filePath, async (p) => readInsightJsonl(await readFile6(p, "utf-8").catch(() => "")), async (p, data) => {
@@ -11029,8 +11284,8 @@ var _internals17 = {
11029
11284
  };
11030
11285
 
11031
11286
  // src/services/session-reflection.ts
11032
- import { promises as fs11 } from "fs";
11033
- import * as path22 from "path";
11287
+ import { promises as fs12 } from "fs";
11288
+ import * as path23 from "path";
11034
11289
 
11035
11290
  // src/hooks/skill-improver-llm-factory.ts
11036
11291
  function resolveSkillImproverAgentName(sessionId) {
@@ -11183,13 +11438,13 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
11183
11438
  const lessons = [];
11184
11439
  const taxonomy = {};
11185
11440
  try {
11186
- const evidenceDir = path22.join(directory, ".swarm", "evidence");
11187
- const entries = await fs11.readdir(evidenceDir);
11441
+ const evidenceDir = path23.join(directory, ".swarm", "evidence");
11442
+ const entries = await fs12.readdir(evidenceDir);
11188
11443
  const retroDirs = entries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
11189
11444
  for (const retroDir of retroDirs) {
11190
- const evidencePath = path22.join(evidenceDir, retroDir, "evidence.json");
11445
+ const evidencePath = path23.join(evidenceDir, retroDir, "evidence.json");
11191
11446
  try {
11192
- const content = await fs11.readFile(evidencePath, "utf-8");
11447
+ const content = await fs12.readFile(evidencePath, "utf-8");
11193
11448
  const parsed = JSON.parse(content);
11194
11449
  const bundleEntries = parsed.entries ?? [parsed];
11195
11450
  for (const entry of bundleEntries) {
@@ -11216,14 +11471,14 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
11216
11471
  async function gatherGateFailures(directory) {
11217
11472
  const failures = new Map;
11218
11473
  try {
11219
- const evidenceDir = path22.join(directory, ".swarm", "evidence");
11220
- const entries = await fs11.readdir(evidenceDir);
11474
+ const evidenceDir = path23.join(directory, ".swarm", "evidence");
11475
+ const entries = await fs12.readdir(evidenceDir);
11221
11476
  for (const entry of entries) {
11222
11477
  if (entry.startsWith("retro-"))
11223
11478
  continue;
11224
- const evidencePath = path22.join(evidenceDir, entry, "evidence.json");
11479
+ const evidencePath = path23.join(evidenceDir, entry, "evidence.json");
11225
11480
  try {
11226
- const content = await fs11.readFile(evidencePath, "utf-8");
11481
+ const content = await fs12.readFile(evidencePath, "utf-8");
11227
11482
  const parsed = JSON.parse(content);
11228
11483
  const bundleEntries = parsed.entries ?? [parsed];
11229
11484
  for (const e of bundleEntries) {
@@ -11415,19 +11670,19 @@ async function writeSessionReflection(directory, result) {
11415
11670
  lines.push(result.architectReport);
11416
11671
  const content = lines.join(`
11417
11672
  `);
11418
- await fs11.writeFile(reflectionPath, content, "utf-8");
11673
+ await fs12.writeFile(reflectionPath, content, "utf-8");
11419
11674
  return reflectionPath;
11420
11675
  }
11421
11676
 
11422
11677
  // src/services/skill-improver.ts
11423
- import { existsSync as existsSync12 } from "fs";
11678
+ import { existsSync as existsSync13 } from "fs";
11424
11679
  import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as writeFile7 } from "fs/promises";
11425
- import * as path24 from "path";
11680
+ import * as path25 from "path";
11426
11681
  init_logger();
11427
11682
 
11428
11683
  // src/services/trajectory-cluster.ts
11429
11684
  import { mkdir as mkdir6, writeFile as writeFile6 } from "fs/promises";
11430
- import * as path23 from "path";
11685
+ import * as path24 from "path";
11431
11686
  init_logger();
11432
11687
  var MACRO_TRAJECTORY_WINDOW = 200;
11433
11688
  var MOTIF_MIN_TASKS = 2;
@@ -11559,11 +11814,11 @@ async function writeMotifProposals(directory, opts = {}) {
11559
11814
  if (motifs.length === 0)
11560
11815
  return result;
11561
11816
  const max = opts.maxProposals ?? 10;
11562
- const proposalsDir = validateSwarmPath(directory, path23.join("skills", "proposals"));
11817
+ const proposalsDir = validateSwarmPath(directory, path24.join("skills", "proposals"));
11563
11818
  await mkdir6(proposalsDir, { recursive: true });
11564
11819
  for (const motif of motifs.slice(0, max)) {
11565
11820
  const slug = `motif-${slugify(motif.signature)}`;
11566
- const filePath = path23.join(proposalsDir, `${slug}.md`);
11821
+ const filePath = path24.join(proposalsDir, `${slug}.md`);
11567
11822
  await writeFile6(filePath, buildMotifProposal(motif), "utf-8");
11568
11823
  result.proposalsWritten.push(filePath);
11569
11824
  }
@@ -11704,11 +11959,11 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
11704
11959
  if (motifs.length === 0)
11705
11960
  return result;
11706
11961
  const max = opts.maxProposals ?? 10;
11707
- const proposalsDir = validateSwarmPath(directory, path23.join("skills", "proposals"));
11962
+ const proposalsDir = validateSwarmPath(directory, path24.join("skills", "proposals"));
11708
11963
  await mkdir6(proposalsDir, { recursive: true });
11709
11964
  for (const motif of motifs.slice(0, max)) {
11710
11965
  const slug = workflowSlug(motif.signature);
11711
- const filePath = path23.join(proposalsDir, `${slug}.md`);
11966
+ const filePath = path24.join(proposalsDir, `${slug}.md`);
11712
11967
  await writeFile6(filePath, buildWorkflowProposal(motif), "utf-8");
11713
11968
  result.proposalsWritten.push(filePath);
11714
11969
  }
@@ -11720,14 +11975,14 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
11720
11975
  }
11721
11976
 
11722
11977
  // src/services/unactionable-hardening.ts
11723
- import { existsSync as existsSync11 } from "fs";
11978
+ import { existsSync as existsSync12 } from "fs";
11724
11979
  init_logger();
11725
11980
  var HARDENING_BATCH_LIMIT = 5;
11726
11981
  async function hardenUnactionableEntries(params) {
11727
11982
  const result = { hardened: 0, retired: 0, remaining: 0 };
11728
11983
  try {
11729
11984
  const queuePath = resolveUnactionablePath(params.directory);
11730
- if (!existsSync11(queuePath))
11985
+ if (!existsSync12(queuePath))
11731
11986
  return result;
11732
11987
  const limit = params.batchLimit ?? HARDENING_BATCH_LIMIT;
11733
11988
  const dedupThreshold = params.dedupThreshold ?? 0.6;
@@ -11831,7 +12086,7 @@ function timestampSlug(d) {
11831
12086
  return d.toISOString().replace(/[:.]/g, "-");
11832
12087
  }
11833
12088
  async function atomicWrite(p, content) {
11834
- await mkdir7(path24.dirname(p), { recursive: true });
12089
+ await mkdir7(path25.dirname(p), { recursive: true });
11835
12090
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
11836
12091
  await writeFile7(tmp, content, "utf-8");
11837
12092
  await rename3(tmp, p);
@@ -11839,7 +12094,7 @@ async function atomicWrite(p, content) {
11839
12094
  async function gatherInventory(directory) {
11840
12095
  const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
11841
12096
  const hivePath = resolveHiveKnowledgePath();
11842
- const hive = existsSync12(hivePath) ? await readKnowledge(hivePath) : [];
12097
+ const hive = existsSync13(hivePath) ? await readKnowledge(hivePath) : [];
11843
12098
  const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
11844
12099
  const skills = await listSkills(directory);
11845
12100
  const knowledgeById = new Map([...swarm, ...hive].map((entry) => [entry.id, entry]));
@@ -12234,8 +12489,8 @@ async function runSkillImprover(req) {
12234
12489
  }
12235
12490
  throw err;
12236
12491
  }
12237
- const proposalDir = path24.join(req.directory, ".swarm", "skill-improver", "proposals");
12238
- const proposalFile = path24.join(proposalDir, `${timestampSlug(now)}.md`);
12492
+ const proposalDir = path25.join(req.directory, ".swarm", "skill-improver", "proposals");
12493
+ const proposalFile = path25.join(proposalDir, `${timestampSlug(now)}.md`);
12239
12494
  const finalBody = source === "llm" ? buildLLMProposalFrame({
12240
12495
  body,
12241
12496
  targets,
@@ -12718,20 +12973,20 @@ function countSessionKnowledgeEntries(entries, sessionStart, fallbackCount) {
12718
12973
  async function copyDirRecursiveWithFailures(src, dest) {
12719
12974
  let count = 0;
12720
12975
  const failures = [];
12721
- const entries = await fs12.readdir(src);
12722
- await fs12.mkdir(dest, { recursive: true });
12976
+ const entries = await fs13.readdir(src);
12977
+ await fs13.mkdir(dest, { recursive: true });
12723
12978
  for (const entry of entries) {
12724
- const srcEntry = path25.join(src, entry);
12725
- const destEntry = path25.join(dest, entry);
12979
+ const srcEntry = path26.join(src, entry);
12980
+ const destEntry = path26.join(dest, entry);
12726
12981
  try {
12727
- const stat4 = await fs12.stat(srcEntry);
12982
+ const stat4 = await fs13.stat(srcEntry);
12728
12983
  if (stat4.isDirectory()) {
12729
12984
  const subResult = await copyDirRecursiveWithFailures(srcEntry, destEntry);
12730
12985
  count += subResult.copied;
12731
12986
  failures.push(...subResult.failures);
12732
12987
  } else {
12733
12988
  try {
12734
- await fs12.copyFile(srcEntry, destEntry);
12989
+ await fs13.copyFile(srcEntry, destEntry);
12735
12990
  count++;
12736
12991
  } catch (err) {
12737
12992
  const errno = err?.code;
@@ -12906,20 +13161,20 @@ async function runFinalizeStage(ctx) {
12906
13161
  ctx.warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
12907
13162
  }
12908
13163
  }
12909
- const lessonsFilePath = path25.join(ctx.swarmDir, "close-lessons.md");
13164
+ const lessonsFilePath = path26.join(ctx.swarmDir, "close-lessons.md");
12910
13165
  try {
12911
- const lessonsText = await fs12.readFile(lessonsFilePath, "utf-8");
13166
+ const lessonsText = await fs13.readFile(lessonsFilePath, "utf-8");
12912
13167
  ctx.explicitLessons = lessonsText.split(`
12913
13168
  `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
12914
13169
  } catch {}
12915
13170
  try {
12916
- const evidenceDir = path25.join(ctx.swarmDir, "evidence");
12917
- const evidenceEntries = await fs12.readdir(evidenceDir);
13171
+ const evidenceDir = path26.join(ctx.swarmDir, "evidence");
13172
+ const evidenceEntries = await fs13.readdir(evidenceDir);
12918
13173
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
12919
13174
  for (const retroDir of retroDirs) {
12920
- const evidencePath = path25.join(evidenceDir, retroDir, "evidence.json");
13175
+ const evidencePath = path26.join(evidenceDir, retroDir, "evidence.json");
12921
13176
  try {
12922
- const content = await fs12.readFile(evidencePath, "utf-8");
13177
+ const content = await fs13.readFile(evidencePath, "utf-8");
12923
13178
  const parsed = JSON.parse(content);
12924
13179
  const entries = parsed.entries ?? [parsed];
12925
13180
  for (const entry of entries) {
@@ -12963,7 +13218,7 @@ async function runFinalizeStage(ctx) {
12963
13218
  console.warn("[close-command] curateAndStoreSwarm error:", error2);
12964
13219
  }
12965
13220
  if (ctx.curationSucceeded && ctx.allLessons.length > 0) {
12966
- await fs12.unlink(lessonsFilePath).catch(() => {});
13221
+ await fs13.unlink(lessonsFilePath).catch(() => {});
12967
13222
  }
12968
13223
  if (ctx.curationSucceeded) {
12969
13224
  if (ctx.config.hive_enabled === false) {} else {
@@ -13069,7 +13324,7 @@ async function runFinalizeStage(ctx) {
13069
13324
  }
13070
13325
  }
13071
13326
  try {
13072
- const { CuratorConfigSchema: CCS } = await import("./schema-mygkbbe9.js");
13327
+ const { CuratorConfigSchema: CCS } = await import("./schema-nz638xc3.js");
13073
13328
  const { config: pmLoadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
13074
13329
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
13075
13330
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -13099,7 +13354,7 @@ async function copySqliteSafe(srcPath, destPath) {
13099
13354
  let checkpointVerified = false;
13100
13355
  try {
13101
13356
  const result = spawnSync5("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
13102
- cwd: path25.dirname(srcPath),
13357
+ cwd: path26.dirname(srcPath),
13103
13358
  encoding: "utf-8",
13104
13359
  stdio: ["ignore", "pipe", "pipe"],
13105
13360
  timeout: 1e4,
@@ -13110,7 +13365,7 @@ async function copySqliteSafe(srcPath, destPath) {
13110
13365
  const code = result.error.code;
13111
13366
  if (code === "ENOENT") {
13112
13367
  try {
13113
- await fs12.copyFile(srcPath, destPath);
13368
+ await fs13.copyFile(srcPath, destPath);
13114
13369
  return {
13115
13370
  success: true,
13116
13371
  reason: "copied without WAL checkpoint (sqlite3 CLI unavailable)"
@@ -13149,7 +13404,7 @@ async function copySqliteSafe(srcPath, destPath) {
13149
13404
  };
13150
13405
  }
13151
13406
  try {
13152
- await fs12.copyFile(srcPath, destPath);
13407
+ await fs13.copyFile(srcPath, destPath);
13153
13408
  if (checkpointVerified) {
13154
13409
  return { success: true };
13155
13410
  }
@@ -13167,9 +13422,9 @@ async function copySqliteSafe(srcPath, destPath) {
13167
13422
  async function runArchiveStage(ctx) {
13168
13423
  ctx.timestamp = new Date().toISOString().replace(/[:.]/g, "-");
13169
13424
  ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
13170
- ctx.archiveDir = path25.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
13425
+ ctx.archiveDir = path26.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
13171
13426
  try {
13172
- await fs12.mkdir(ctx.archiveDir, { recursive: true });
13427
+ await fs13.mkdir(ctx.archiveDir, { recursive: true });
13173
13428
  const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
13174
13429
  const linkedKnowledgeShared = isLinked(ctx.directory);
13175
13430
  if (linkedKnowledgeShared) {
@@ -13182,8 +13437,8 @@ async function runArchiveStage(ctx) {
13182
13437
  if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
13183
13438
  continue;
13184
13439
  }
13185
- const srcPath = path25.join(ctx.swarmDir, artifact);
13186
- const destPath = path25.join(ctx.archiveDir, artifact);
13440
+ const srcPath = path26.join(ctx.swarmDir, artifact);
13441
+ const destPath = path26.join(ctx.archiveDir, artifact);
13187
13442
  if (artifact === "swarm.db") {
13188
13443
  const result = await copySqliteSafe(srcPath, destPath);
13189
13444
  if (result.skipped) {} else if (result.success) {
@@ -13199,7 +13454,7 @@ async function runArchiveStage(ctx) {
13199
13454
  }
13200
13455
  } else {
13201
13456
  try {
13202
- await fs12.copyFile(srcPath, destPath);
13457
+ await fs13.copyFile(srcPath, destPath);
13203
13458
  ctx.archivedFileCount++;
13204
13459
  if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
13205
13460
  ctx.archivedActiveStateFiles.add(artifact);
@@ -13215,8 +13470,8 @@ async function runArchiveStage(ctx) {
13215
13470
  }
13216
13471
  }
13217
13472
  for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
13218
- const srcDir = path25.join(ctx.swarmDir, dirName);
13219
- const destDir = path25.join(ctx.archiveDir, dirName);
13473
+ const srcDir = path26.join(ctx.swarmDir, dirName);
13474
+ const destDir = path26.join(ctx.archiveDir, dirName);
13220
13475
  try {
13221
13476
  const result = await copyDirRecursiveWithFailures(srcDir, destDir);
13222
13477
  ctx.archivedFileCount += result.copied;
@@ -13289,9 +13544,9 @@ async function runCleanStage(ctx) {
13289
13544
  ctx.warnings.push(reason ? `Preserved ${artifact} because it was not successfully archived: ${reason}.` : `Preserved ${artifact} because it was not successfully archived.`);
13290
13545
  continue;
13291
13546
  }
13292
- const filePath = path25.join(ctx.swarmDir, artifact);
13547
+ const filePath = path26.join(ctx.swarmDir, artifact);
13293
13548
  try {
13294
- await fs12.unlink(filePath);
13549
+ await fs13.unlink(filePath);
13295
13550
  cleanedFiles.push(artifact);
13296
13551
  } catch (err) {
13297
13552
  const errno = err?.code;
@@ -13308,18 +13563,18 @@ async function runCleanStage(ctx) {
13308
13563
  if (!ctx.archivedActiveStateDirs.has(dirName)) {
13309
13564
  continue;
13310
13565
  }
13311
- const dirPath = path25.join(ctx.swarmDir, dirName);
13566
+ const dirPath = path26.join(ctx.swarmDir, dirName);
13312
13567
  try {
13313
- await fs12.rm(dirPath, { recursive: true, force: true });
13568
+ await fs13.rm(dirPath, { recursive: true, force: true });
13314
13569
  cleanedFiles.push(`${dirName}/`);
13315
13570
  } catch {}
13316
13571
  }
13317
13572
  try {
13318
- const swarmFiles = await fs12.readdir(ctx.swarmDir);
13573
+ const swarmFiles = await fs13.readdir(ctx.swarmDir);
13319
13574
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
13320
13575
  for (const backup of configBackups) {
13321
13576
  try {
13322
- await fs12.unlink(path25.join(ctx.swarmDir, backup));
13577
+ await fs13.unlink(path26.join(ctx.swarmDir, backup));
13323
13578
  configBackupsRemoved++;
13324
13579
  } catch (err) {
13325
13580
  const errno = err?.code;
@@ -13332,7 +13587,7 @@ async function runCleanStage(ctx) {
13332
13587
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
13333
13588
  for (const sibling of ledgerSiblings) {
13334
13589
  try {
13335
- await fs12.unlink(path25.join(ctx.swarmDir, sibling));
13590
+ await fs13.unlink(path26.join(ctx.swarmDir, sibling));
13336
13591
  } catch (err) {
13337
13592
  const errno = err?.code;
13338
13593
  if (errno === "ENOENT") {} else {
@@ -13350,16 +13605,16 @@ async function runCleanStage(ctx) {
13350
13605
  }
13351
13606
  let swarmPlanFilesRemoved = 0;
13352
13607
  const candidates = [
13353
- path25.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
13354
- path25.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
13355
- path25.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
13356
- path25.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
13357
- path25.join(ctx.directory, "SWARM_PLAN.json"),
13358
- path25.join(ctx.directory, "SWARM_PLAN.md")
13608
+ path26.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
13609
+ path26.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
13610
+ path26.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
13611
+ path26.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
13612
+ path26.join(ctx.directory, "SWARM_PLAN.json"),
13613
+ path26.join(ctx.directory, "SWARM_PLAN.md")
13359
13614
  ];
13360
13615
  for (const candidate of candidates) {
13361
13616
  try {
13362
- await fs12.unlink(candidate);
13617
+ await fs13.unlink(candidate);
13363
13618
  swarmPlanFilesRemoved++;
13364
13619
  } catch (err) {
13365
13620
  if (err?.code !== "ENOENT") {
@@ -13369,11 +13624,11 @@ async function runCleanStage(ctx) {
13369
13624
  }
13370
13625
  let tmpFilesRemoved = 0;
13371
13626
  try {
13372
- const swarmFiles = await fs12.readdir(ctx.swarmDir);
13627
+ const swarmFiles = await fs13.readdir(ctx.swarmDir);
13373
13628
  const tmpFiles = swarmFiles.filter((f) => f.startsWith(".tmp."));
13374
13629
  for (const tmp of tmpFiles) {
13375
13630
  try {
13376
- await fs12.unlink(path25.join(ctx.swarmDir, tmp));
13631
+ await fs13.unlink(path26.join(ctx.swarmDir, tmp));
13377
13632
  tmpFilesRemoved++;
13378
13633
  } catch (err) {
13379
13634
  const errno = err?.code;
@@ -13394,7 +13649,7 @@ async function runCleanStage(ctx) {
13394
13649
  cleanedFiles.push(`${tmpFilesRemoved} .tmp.* file(s)`);
13395
13650
  }
13396
13651
  clearAllScopes(ctx.directory);
13397
- const contextPath = path25.join(ctx.swarmDir, "context.md");
13652
+ const contextPath = path26.join(ctx.swarmDir, "context.md");
13398
13653
  const contextContent = [
13399
13654
  "# Context",
13400
13655
  "",
@@ -13406,9 +13661,9 @@ async function runCleanStage(ctx) {
13406
13661
  ""
13407
13662
  ].join(`
13408
13663
  `);
13409
- const contextTempPath = path25.join(path25.dirname(contextPath), `${path25.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
13664
+ const contextTempPath = path26.join(path26.dirname(contextPath), `${path26.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
13410
13665
  try {
13411
- await fs12.writeFile(contextTempPath, contextContent, "utf-8");
13666
+ await fs13.writeFile(contextTempPath, contextContent, "utf-8");
13412
13667
  fsSync2.renameSync(contextTempPath, contextPath);
13413
13668
  } catch (error2) {
13414
13669
  try {
@@ -13470,7 +13725,7 @@ async function runAlignStage(ctx) {
13470
13725
  return { gitAlignResult, prunedBranches };
13471
13726
  }
13472
13727
  async function handleCloseCommand(directory, args, options = {}) {
13473
- const swarmDir = path25.join(directory, ".swarm");
13728
+ const swarmDir = path26.join(directory, ".swarm");
13474
13729
  try {
13475
13730
  const stat4 = fsSync2.lstatSync(swarmDir);
13476
13731
  if (stat4.isSymbolicLink()) {
@@ -13484,18 +13739,18 @@ async function handleCloseCommand(directory, args, options = {}) {
13484
13739
  const planPath = validateSwarmPath(directory, "plan.json");
13485
13740
  let planExists = false;
13486
13741
  let planData = {
13487
- title: path25.basename(directory) || "Ad-hoc session",
13742
+ title: path26.basename(directory) || "Ad-hoc session",
13488
13743
  phases: []
13489
13744
  };
13490
13745
  try {
13491
- const content = await fs12.readFile(planPath, "utf-8");
13746
+ const content = await fs13.readFile(planPath, "utf-8");
13492
13747
  planData = JSON.parse(content);
13493
13748
  planExists = true;
13494
13749
  } catch (error2) {
13495
13750
  if (error2?.code !== "ENOENT") {
13496
13751
  return `\u274C Failed to read plan.json: ${error2 instanceof Error ? error2.message : String(error2)}`;
13497
13752
  }
13498
- const swarmDirExists = await fs12.access(swarmDir).then(() => true).catch(() => false);
13753
+ const swarmDirExists = await fs13.access(swarmDir).then(() => true).catch(() => false);
13499
13754
  if (!swarmDirExists) {
13500
13755
  return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
13501
13756
  }
@@ -13509,15 +13764,15 @@ async function handleCloseCommand(directory, args, options = {}) {
13509
13764
  }
13510
13765
  try {
13511
13766
  if (!planExists) {
13512
- const archiveDir = path25.join(swarmDir, "archive");
13767
+ const archiveDir = path26.join(swarmDir, "archive");
13513
13768
  try {
13514
- const archiveEntries = await fs12.readdir(archiveDir);
13769
+ const archiveEntries = await fs13.readdir(archiveDir);
13515
13770
  const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
13516
13771
  if (hasArchiveBundle) {
13517
13772
  const hasActiveState = [
13518
13773
  ...ACTIVE_STATE_TO_CLEAN,
13519
13774
  ...ACTIVE_STATE_DIRS_TO_CLEAN
13520
- ].some((entry) => fsSync2.existsSync(path25.join(swarmDir, entry)));
13775
+ ].some((entry) => fsSync2.existsSync(path26.join(swarmDir, entry)));
13521
13776
  if (!hasActiveState) {
13522
13777
  return `\u2705 Already finalized \u2014 nothing to do.
13523
13778
 
@@ -13640,9 +13895,9 @@ This project was already finalized in a previous /swarm close run. The plan has
13640
13895
  ...ctx.warnings.length > 0 ? ["## Warnings", ...ctx.warnings.map((w) => `- ${w}`), ""] : []
13641
13896
  ].join(`
13642
13897
  `);
13643
- const closeSummaryTempPath = path25.join(path25.dirname(closeSummaryPath), `${path25.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
13898
+ const closeSummaryTempPath = path26.join(path26.dirname(closeSummaryPath), `${path26.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
13644
13899
  try {
13645
- await fs12.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
13900
+ await fs13.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
13646
13901
  fsSync2.renameSync(closeSummaryTempPath, closeSummaryPath);
13647
13902
  } catch (error2) {
13648
13903
  try {
@@ -13652,6 +13907,10 @@ This project was already finalized in a previous /swarm close run. The plan has
13652
13907
  ctx.warnings.push(`Failed to write close-summary.md: ${msg}`);
13653
13908
  console.warn("[close-command] Failed to write close-summary.md:", error2);
13654
13909
  }
13910
+ const sessionIdsToEnd = [...swarmState.agentSessions.keys()];
13911
+ for (const sessionId of sessionIdsToEnd) {
13912
+ _internals20.endAgentSession(sessionId);
13913
+ }
13655
13914
  _internals20.resetSwarmStatePreservingSingletons();
13656
13915
  const retroWarnings = ctx.warnings.filter((w) => w.includes("Retrospective write") || w.includes("retrospective write") || w.includes("Session retrospective"));
13657
13916
  const otherWarnings = ctx.warnings.filter((w) => !w.includes("Retrospective write") && !w.includes("retrospective write") && !w.includes("Session retrospective"));
@@ -13744,7 +14003,8 @@ var _internals20 = {
13744
14003
  runCleanStage,
13745
14004
  runAlignStage,
13746
14005
  archiveEvidence,
13747
- closePlanTerminalState
14006
+ closePlanTerminalState,
14007
+ endAgentSession
13748
14008
  };
13749
14009
 
13750
14010
  // src/commands/codebase-review.ts
@@ -13977,15 +14237,15 @@ function buildStatusMessage(session, plan) {
13977
14237
  }
13978
14238
 
13979
14239
  // src/commands/config.ts
13980
- import * as os6 from "os";
13981
- import * as path26 from "path";
14240
+ import * as os7 from "os";
14241
+ import * as path27 from "path";
13982
14242
  function getUserConfigDir2() {
13983
- return process.env.XDG_CONFIG_HOME || path26.join(os6.homedir(), ".config");
14243
+ return process.env.XDG_CONFIG_HOME || path27.join(os7.homedir(), ".config");
13984
14244
  }
13985
14245
  async function handleConfigCommand(directory, _args) {
13986
14246
  const config = loadPluginConfig(directory);
13987
- const userConfigPath = path26.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
13988
- const projectConfigPath = path26.join(directory, ".opencode", "opencode-swarm.json");
14247
+ const userConfigPath = path27.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
14248
+ const projectConfigPath = path27.join(directory, ".opencode", "opencode-swarm.json");
13989
14249
  const lines = [
13990
14250
  "## Swarm Configuration",
13991
14251
  "",
@@ -14003,9 +14263,9 @@ async function handleConfigCommand(directory, _args) {
14003
14263
  }
14004
14264
 
14005
14265
  // src/services/skill-consolidation.ts
14006
- import { existsSync as existsSync14 } from "fs";
14266
+ import { existsSync as existsSync15 } from "fs";
14007
14267
  import { mkdir as mkdir8, readFile as readFile8, rename as rename4, writeFile as writeFile8 } from "fs/promises";
14008
- import * as path27 from "path";
14268
+ import * as path28 from "path";
14009
14269
 
14010
14270
  // src/utils/timeout.ts
14011
14271
  async function withTimeout(promise, ms, timeoutError) {
@@ -14030,11 +14290,11 @@ var DEFAULT_CONSOLIDATION_MAX_CALLS_PER_RUN = 1;
14030
14290
  var CONSOLIDATION_RUN_TIMEOUT_MS = 5 * 60 * 1000;
14031
14291
  var runningByDirectory = new Map;
14032
14292
  function consolidationStatePath(directory) {
14033
- return path27.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
14293
+ return path28.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
14034
14294
  }
14035
14295
  async function readState2(directory) {
14036
14296
  const filePath = consolidationStatePath(directory);
14037
- if (!existsSync14(filePath))
14297
+ if (!existsSync15(filePath))
14038
14298
  return {};
14039
14299
  try {
14040
14300
  const parsed = JSON.parse(await readFile8(filePath, "utf-8"));
@@ -14046,7 +14306,7 @@ async function readState2(directory) {
14046
14306
  }
14047
14307
  }
14048
14308
  async function atomicWrite2(filePath, content) {
14049
- await mkdir8(path27.dirname(filePath), { recursive: true });
14309
+ await mkdir8(path28.dirname(filePath), { recursive: true });
14050
14310
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
14051
14311
  await writeFile8(tmp, content, "utf-8");
14052
14312
  await rename4(tmp, filePath);
@@ -14126,7 +14386,7 @@ async function runSkillConsolidationInner(req) {
14126
14386
  };
14127
14387
  }
14128
14388
  async function runSkillConsolidation(req) {
14129
- const key = path27.resolve(req.directory);
14389
+ const key = path28.resolve(req.directory);
14130
14390
  const existing = runningByDirectory.get(key);
14131
14391
  if (existing) {
14132
14392
  return {
@@ -14208,6 +14468,55 @@ async function handleConsolidateCommand(directory, args, options = {}) {
14208
14468
  }
14209
14469
  }
14210
14470
 
14471
+ // src/commands/costs.ts
14472
+ async function handleCostsCommand(directory, args) {
14473
+ const summary = summarizeTelemetryCosts(directory);
14474
+ const json = args.includes("--json");
14475
+ if (json) {
14476
+ return [
14477
+ "[COSTS_JSON]",
14478
+ JSON.stringify(summary, null, 2),
14479
+ "[/COSTS_JSON]"
14480
+ ].join(`
14481
+ `);
14482
+ }
14483
+ return renderCostSummary(summary);
14484
+ }
14485
+ function renderCostSummary(summary) {
14486
+ const lines = [
14487
+ "## Swarm Costs",
14488
+ "",
14489
+ `Total tracked cost: ${formatUsd(summary.total_cost_usd)}`,
14490
+ `Delegations: ${summary.delegations}`,
14491
+ `Tokens: input ${summary.total_input_tokens.toLocaleString()}, output ${summary.total_output_tokens.toLocaleString()}, reasoning ${summary.total_reasoning_tokens.toLocaleString()}, cache ${summary.total_cache_tokens.toLocaleString()}`,
14492
+ `Cost source: reported ${formatUsd(summary.total_reported_usd)}, estimated ${formatUsd(summary.total_estimated_usd)}, unavailable ${summary.unavailable_delegations}`,
14493
+ "",
14494
+ "### By Agent"
14495
+ ];
14496
+ appendCostRows(lines, "Agent", summary.by_agent, "No delegation cost telemetry recorded.");
14497
+ lines.push("", "### By Task");
14498
+ appendCostRows(lines, "Task", summary.by_task, "No task cost telemetry recorded.");
14499
+ lines.push("", "### By Gate");
14500
+ appendCostRows(lines, "Gate", summary.by_gate, "No gate cost telemetry recorded.");
14501
+ lines.push("", "### By Retry Loop");
14502
+ appendCostRows(lines, "Retry", summary.by_retry, "No retry-loop cost telemetry recorded.");
14503
+ return lines.join(`
14504
+ `);
14505
+ }
14506
+ function appendCostRows(lines, label, rows, emptyMessage) {
14507
+ if (rows.length === 0) {
14508
+ lines.push(emptyMessage);
14509
+ return;
14510
+ }
14511
+ lines.push(`| ${label} | Delegations | Cost | Input | Output | Reasoning | Cache | Unavailable |`, "|------|-------------|------|-------|--------|-----------|-------|-------------|");
14512
+ for (const row of rows) {
14513
+ lines.push(`| ${row.name} | ${row.delegations} | ${formatUsd(row.cost_usd)} | ${row.input_tokens.toLocaleString()} | ${row.output_tokens.toLocaleString()} | ${row.reasoning_tokens.toLocaleString()} | ${row.cache_tokens.toLocaleString()} | ${row.unavailable_delegations} |`);
14514
+ }
14515
+ }
14516
+ function formatUsd(value) {
14517
+ return `$${value.toFixed(6)}`;
14518
+ }
14519
+
14211
14520
  // src/commands/council.ts
14212
14521
  var MAX_QUESTION_LEN = 2000;
14213
14522
  function sanitizeQuestion(raw) {
@@ -14278,8 +14587,8 @@ async function handleCouncilCommand(_directory, args) {
14278
14587
 
14279
14588
  // src/commands/coupling.ts
14280
14589
  import { randomBytes } from "crypto";
14281
- import * as fs13 from "fs";
14282
- import * as path29 from "path";
14590
+ import * as fs14 from "fs";
14591
+ import * as path30 from "path";
14283
14592
 
14284
14593
  // src/turbo/epic/cochange-source.ts
14285
14594
  import * as child_process3 from "child_process";
@@ -14289,7 +14598,7 @@ import { promisify as promisify2 } from "util";
14289
14598
  import * as child_process2 from "child_process";
14290
14599
  import { randomUUID as randomUUID3 } from "crypto";
14291
14600
  import { readdir as readdir4, readFile as readFile9, stat as stat4 } from "fs/promises";
14292
- import * as path28 from "path";
14601
+ import * as path29 from "path";
14293
14602
  import { promisify } from "util";
14294
14603
  function getExecFileAsync() {
14295
14604
  return promisify(child_process2.execFile);
@@ -14393,7 +14702,7 @@ async function scanSourceFiles(dir) {
14393
14702
  try {
14394
14703
  const entries = await readdir4(dir, { withFileTypes: true });
14395
14704
  for (const entry of entries) {
14396
- const fullPath = path28.join(dir, entry.name);
14705
+ const fullPath = path29.join(dir, entry.name);
14397
14706
  if (entry.isDirectory()) {
14398
14707
  if (skipDirs.has(entry.name)) {
14399
14708
  continue;
@@ -14401,7 +14710,7 @@ async function scanSourceFiles(dir) {
14401
14710
  const subFiles = await scanSourceFiles(fullPath);
14402
14711
  results.push(...subFiles);
14403
14712
  } else if (entry.isFile()) {
14404
- const ext = path28.extname(entry.name);
14713
+ const ext = path29.extname(entry.name);
14405
14714
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
14406
14715
  results.push(fullPath);
14407
14716
  }
@@ -14423,8 +14732,8 @@ async function getStaticEdges(directory) {
14423
14732
  continue;
14424
14733
  }
14425
14734
  try {
14426
- const sourceDir = path28.dirname(sourceFile);
14427
- const resolvedPath = path28.resolve(sourceDir, importPath);
14735
+ const sourceDir = path29.dirname(sourceFile);
14736
+ const resolvedPath = path29.resolve(sourceDir, importPath);
14428
14737
  const extensions = [
14429
14738
  "",
14430
14739
  ".ts",
@@ -14449,8 +14758,8 @@ async function getStaticEdges(directory) {
14449
14758
  if (!targetFile) {
14450
14759
  continue;
14451
14760
  }
14452
- const relSource = path28.relative(directory, sourceFile).replace(/\\/g, "/");
14453
- const relTarget = path28.relative(directory, targetFile).replace(/\\/g, "/");
14761
+ const relSource = path29.relative(directory, sourceFile).replace(/\\/g, "/");
14762
+ const relTarget = path29.relative(directory, targetFile).replace(/\\/g, "/");
14454
14763
  const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
14455
14764
  edges.add(key);
14456
14765
  } catch {}
@@ -14462,7 +14771,7 @@ async function getStaticEdges(directory) {
14462
14771
  function isTestImplementationPair(fileA, fileB) {
14463
14772
  const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
14464
14773
  const getBaseName = (filePath) => {
14465
- const base = path28.basename(filePath);
14774
+ const base = path29.basename(filePath);
14466
14775
  for (const pattern of testPatterns) {
14467
14776
  if (base.endsWith(pattern)) {
14468
14777
  return base.slice(0, -pattern.length);
@@ -14472,16 +14781,16 @@ function isTestImplementationPair(fileA, fileB) {
14472
14781
  };
14473
14782
  const baseA = getBaseName(fileA);
14474
14783
  const baseB = getBaseName(fileB);
14475
- return baseA === baseB && baseA !== path28.basename(fileA) && baseA !== path28.basename(fileB);
14784
+ return baseA === baseB && baseA !== path29.basename(fileA) && baseA !== path29.basename(fileB);
14476
14785
  }
14477
14786
  function hasSharedPrefix(fileA, fileB) {
14478
- const dirA = path28.dirname(fileA);
14479
- const dirB = path28.dirname(fileB);
14787
+ const dirA = path29.dirname(fileA);
14788
+ const dirB = path29.dirname(fileB);
14480
14789
  if (dirA !== dirB) {
14481
14790
  return false;
14482
14791
  }
14483
- const baseA = path28.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
14484
- const baseB = path28.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
14792
+ const baseA = path29.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
14793
+ const baseB = path29.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
14485
14794
  if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
14486
14795
  return true;
14487
14796
  }
@@ -14536,8 +14845,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
14536
14845
  const entries = [];
14537
14846
  const now = new Date().toISOString();
14538
14847
  for (const pair of pairs.slice(0, 10)) {
14539
- const baseA = path28.basename(pair.fileA);
14540
- const baseB = path28.basename(pair.fileB);
14848
+ const baseA = path29.basename(pair.fileA);
14849
+ const baseB = path29.basename(pair.fileB);
14541
14850
  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.`;
14542
14851
  if (lesson.length > 280) {
14543
14852
  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.`;
@@ -14963,17 +15272,17 @@ function parseArgs3(args) {
14963
15272
  return parsed;
14964
15273
  }
14965
15274
  function persistReportJson(directory, report) {
14966
- const epicDir = path29.join(directory, ".swarm", "epic");
14967
- fs13.mkdirSync(epicDir, { recursive: true });
14968
- const filePath = path29.join(epicDir, "coupling-report.json");
15275
+ const epicDir = path30.join(directory, ".swarm", "epic");
15276
+ fs14.mkdirSync(epicDir, { recursive: true });
15277
+ const filePath = path30.join(epicDir, "coupling-report.json");
14969
15278
  const tmpPath = `${filePath}.tmp.${randomBytes(8).toString("hex")}`;
14970
- fs13.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
15279
+ fs14.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
14971
15280
  `, "utf-8");
14972
15281
  try {
14973
- fs13.renameSync(tmpPath, filePath);
15282
+ fs14.renameSync(tmpPath, filePath);
14974
15283
  } catch (err) {
14975
15284
  try {
14976
- fs13.unlinkSync(tmpPath);
15285
+ fs14.unlinkSync(tmpPath);
14977
15286
  } catch {}
14978
15287
  throw err;
14979
15288
  }
@@ -15024,7 +15333,7 @@ Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>
15024
15333
  persistStatus = {
15025
15334
  requested: true,
15026
15335
  written: true,
15027
- path: path29.relative(directory, writtenAt)
15336
+ path: path30.relative(directory, writtenAt)
15028
15337
  };
15029
15338
  } catch (err) {
15030
15339
  persistStatus = {
@@ -15083,7 +15392,7 @@ function formatCurationSummary(summary) {
15083
15392
  }
15084
15393
 
15085
15394
  // src/commands/dark-matter.ts
15086
- import path30 from "path";
15395
+ import path31 from "path";
15087
15396
  async function handleDarkMatterCommand(directory, args) {
15088
15397
  const options = {};
15089
15398
  for (let i = 0;i < args.length; i++) {
@@ -15115,7 +15424,7 @@ Ensure this is a git repository with commit history.`;
15115
15424
  const output = formatDarkMatterOutput(pairs);
15116
15425
  if (pairs.length > 0) {
15117
15426
  try {
15118
- const projectName = path30.basename(path30.resolve(directory));
15427
+ const projectName = path31.basename(path31.resolve(directory));
15119
15428
  const entries = darkMatterToKnowledgeEntries(pairs, projectName);
15120
15429
  if (entries.length > 0) {
15121
15430
  const knowledgePath = resolveSwarmKnowledgePath(directory);
@@ -15481,50 +15790,50 @@ ${USAGE5}`;
15481
15790
 
15482
15791
  // src/services/diagnose-service.ts
15483
15792
  import * as child_process4 from "child_process";
15484
- import { existsSync as existsSync17, readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync6 } from "fs";
15485
- import path32 from "path";
15793
+ import { existsSync as existsSync18, readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
15794
+ import path33 from "path";
15486
15795
  import { fileURLToPath } from "url";
15487
15796
 
15488
15797
  // src/config/cache-paths.ts
15489
- import * as os7 from "os";
15490
- import * as path31 from "path";
15798
+ import * as os8 from "os";
15799
+ import * as path32 from "path";
15491
15800
  function getPluginConfigDir() {
15492
- return path31.join(process.env.XDG_CONFIG_HOME || path31.join(os7.homedir(), ".config"), "opencode");
15801
+ return path32.join(process.env.XDG_CONFIG_HOME || path32.join(os8.homedir(), ".config"), "opencode");
15493
15802
  }
15494
15803
  function getPluginCachePaths() {
15495
- const cacheBase = process.env.XDG_CACHE_HOME || path31.join(os7.homedir(), ".cache");
15804
+ const cacheBase = process.env.XDG_CACHE_HOME || path32.join(os8.homedir(), ".cache");
15496
15805
  const configDir = getPluginConfigDir();
15497
15806
  const paths = [
15498
- path31.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
15499
- path31.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
15500
- path31.join(configDir, "node_modules", "opencode-swarm")
15807
+ path32.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
15808
+ path32.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
15809
+ path32.join(configDir, "node_modules", "opencode-swarm")
15501
15810
  ];
15502
15811
  if (process.platform === "darwin") {
15503
- const libCaches = path31.join(os7.homedir(), "Library", "Caches");
15504
- paths.push(path31.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path31.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
15812
+ const libCaches = path32.join(os8.homedir(), "Library", "Caches");
15813
+ paths.push(path32.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path32.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
15505
15814
  }
15506
15815
  if (process.platform === "win32") {
15507
- const localAppData = process.env.LOCALAPPDATA || path31.join(os7.homedir(), "AppData", "Local");
15508
- const appData = process.env.APPDATA || path31.join(os7.homedir(), "AppData", "Roaming");
15509
- 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"));
15816
+ const localAppData = process.env.LOCALAPPDATA || path32.join(os8.homedir(), "AppData", "Local");
15817
+ const appData = process.env.APPDATA || path32.join(os8.homedir(), "AppData", "Roaming");
15818
+ paths.push(path32.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path32.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path32.join(appData, "opencode", "node_modules", "opencode-swarm"));
15510
15819
  }
15511
15820
  return paths;
15512
15821
  }
15513
15822
  function getPluginLockFilePaths() {
15514
- const cacheBase = process.env.XDG_CACHE_HOME || path31.join(os7.homedir(), ".cache");
15823
+ const cacheBase = process.env.XDG_CACHE_HOME || path32.join(os8.homedir(), ".cache");
15515
15824
  const configDir = getPluginConfigDir();
15516
15825
  const paths = [
15517
- path31.join(cacheBase, "opencode", "bun.lock"),
15518
- path31.join(cacheBase, "opencode", "bun.lockb"),
15519
- path31.join(configDir, "package-lock.json")
15826
+ path32.join(cacheBase, "opencode", "bun.lock"),
15827
+ path32.join(cacheBase, "opencode", "bun.lockb"),
15828
+ path32.join(configDir, "package-lock.json")
15520
15829
  ];
15521
15830
  if (process.platform === "darwin") {
15522
- const libCaches = path31.join(os7.homedir(), "Library", "Caches");
15523
- paths.push(path31.join(libCaches, "opencode", "bun.lock"), path31.join(libCaches, "opencode", "bun.lockb"));
15831
+ const libCaches = path32.join(os8.homedir(), "Library", "Caches");
15832
+ paths.push(path32.join(libCaches, "opencode", "bun.lock"), path32.join(libCaches, "opencode", "bun.lockb"));
15524
15833
  }
15525
15834
  if (process.platform === "win32") {
15526
- const localAppData = process.env.LOCALAPPDATA || path31.join(os7.homedir(), "AppData", "Local");
15527
- paths.push(path31.join(localAppData, "opencode", "bun.lock"), path31.join(localAppData, "opencode", "bun.lockb"));
15835
+ const localAppData = process.env.LOCALAPPDATA || path32.join(os8.homedir(), "AppData", "Local");
15836
+ paths.push(path32.join(localAppData, "opencode", "bun.lock"), path32.join(localAppData, "opencode", "bun.lockb"));
15528
15837
  }
15529
15838
  return paths;
15530
15839
  }
@@ -15534,28 +15843,28 @@ init_capability_probe();
15534
15843
  init_executor();
15535
15844
 
15536
15845
  // src/services/knowledge-diagnostics.ts
15537
- import { existsSync as existsSync16 } from "fs";
15846
+ import { existsSync as existsSync17 } from "fs";
15538
15847
  import { readFile as readFile10 } from "fs/promises";
15539
15848
 
15540
15849
  // src/services/version-check.ts
15541
- import { existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "fs";
15850
+ import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "fs";
15542
15851
  import { homedir as homedir4 } from "os";
15543
- import { join as join26 } from "path";
15852
+ import { join as join27 } from "path";
15544
15853
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
15545
15854
  function cacheDir() {
15546
15855
  const xdg = process.env.XDG_CACHE_HOME;
15547
- const base = xdg && xdg.length > 0 ? xdg : join26(homedir4(), ".cache");
15548
- return join26(base, "opencode-swarm");
15856
+ const base = xdg && xdg.length > 0 ? xdg : join27(homedir4(), ".cache");
15857
+ return join27(base, "opencode-swarm");
15549
15858
  }
15550
15859
  function cacheFile() {
15551
- return join26(cacheDir(), "version-check.json");
15860
+ return join27(cacheDir(), "version-check.json");
15552
15861
  }
15553
15862
  function readVersionCache() {
15554
15863
  try {
15555
- const path32 = cacheFile();
15556
- if (!existsSync15(path32))
15864
+ const path33 = cacheFile();
15865
+ if (!existsSync16(path33))
15557
15866
  return null;
15558
- const raw = readFileSync8(path32, "utf-8");
15867
+ const raw = readFileSync9(path33, "utf-8");
15559
15868
  const parsed = JSON.parse(raw);
15560
15869
  if (typeof parsed?.checkedAt !== "number")
15561
15870
  return null;
@@ -15594,7 +15903,7 @@ var SEVEN_DAYS_MS2 = 7 * 24 * 60 * 60 * 1000;
15594
15903
  var UNACTIONABLE_BACKLOG_WARN = 100;
15595
15904
  var INSIGHT_BACKLOG_WARN = 50;
15596
15905
  async function readRawLines(filePath) {
15597
- if (!existsSync16(filePath))
15906
+ if (!existsSync17(filePath))
15598
15907
  return { entries: [], corrupt: 0 };
15599
15908
  const content = await readFile10(filePath, "utf-8");
15600
15909
  const entries = [];
@@ -15719,7 +16028,7 @@ async function computeKnowledgeDebug(directory) {
15719
16028
  };
15720
16029
  }
15721
16030
  async function safeJsonlCount(filePath) {
15722
- if (!filePath || !existsSync16(filePath))
16031
+ if (!filePath || !existsSync17(filePath))
15723
16032
  return 0;
15724
16033
  try {
15725
16034
  const content = await readFile10(filePath, "utf-8");
@@ -16040,7 +16349,7 @@ async function checkConfigBackups(directory) {
16040
16349
  }
16041
16350
  async function checkGitRepository(directory) {
16042
16351
  try {
16043
- if (!existsSync17(directory) || !statSync6(directory).isDirectory()) {
16352
+ if (!existsSync18(directory) || !statSync6(directory).isDirectory()) {
16044
16353
  return {
16045
16354
  name: "Git Repository",
16046
16355
  status: "\u274C",
@@ -16104,8 +16413,8 @@ async function checkSpecStaleness(directory, plan) {
16104
16413
  };
16105
16414
  }
16106
16415
  async function checkConfigParseability(directory) {
16107
- const configPath = path32.join(directory, ".opencode/opencode-swarm.json");
16108
- if (!existsSync17(configPath)) {
16416
+ const configPath = path33.join(directory, ".opencode/opencode-swarm.json");
16417
+ if (!existsSync18(configPath)) {
16109
16418
  return {
16110
16419
  name: "Config Parseability",
16111
16420
  status: "\u2705",
@@ -16113,7 +16422,7 @@ async function checkConfigParseability(directory) {
16113
16422
  };
16114
16423
  }
16115
16424
  try {
16116
- const content = readFileSync9(configPath, "utf-8");
16425
+ const content = readFileSync10(configPath, "utf-8");
16117
16426
  JSON.parse(content);
16118
16427
  return {
16119
16428
  name: "Config Parseability",
@@ -16133,7 +16442,7 @@ function resolveGrammarDir(thisDir) {
16133
16442
  const normalized = thisDir.replace(/\\/g, "/");
16134
16443
  const isSource = normalized.endsWith("/src/services");
16135
16444
  const isCliBundle = normalized.endsWith("/cli");
16136
- return isSource || isCliBundle ? path32.join(thisDir, "..", "lang", "grammars") : path32.join(thisDir, "lang", "grammars");
16445
+ return isSource || isCliBundle ? path33.join(thisDir, "..", "lang", "grammars") : path33.join(thisDir, "lang", "grammars");
16137
16446
  }
16138
16447
  async function checkGrammarWasmFiles() {
16139
16448
  const grammarFiles = [
@@ -16157,14 +16466,14 @@ async function checkGrammarWasmFiles() {
16157
16466
  "tree-sitter-ini.wasm",
16158
16467
  "tree-sitter-regex.wasm"
16159
16468
  ];
16160
- const thisDir = path32.dirname(fileURLToPath(import.meta.url));
16469
+ const thisDir = path33.dirname(fileURLToPath(import.meta.url));
16161
16470
  const grammarDir = resolveGrammarDir(thisDir);
16162
16471
  const missing = [];
16163
- if (!existsSync17(path32.join(grammarDir, "tree-sitter.wasm"))) {
16472
+ if (!existsSync18(path33.join(grammarDir, "tree-sitter.wasm"))) {
16164
16473
  missing.push("tree-sitter.wasm (core runtime)");
16165
16474
  }
16166
16475
  for (const file of grammarFiles) {
16167
- if (!existsSync17(path32.join(grammarDir, file))) {
16476
+ if (!existsSync18(path33.join(grammarDir, file))) {
16168
16477
  missing.push(file);
16169
16478
  }
16170
16479
  }
@@ -16182,8 +16491,8 @@ async function checkGrammarWasmFiles() {
16182
16491
  };
16183
16492
  }
16184
16493
  async function checkCheckpointManifest(directory) {
16185
- const manifestPath = path32.join(directory, ".swarm/checkpoints.json");
16186
- if (!existsSync17(manifestPath)) {
16494
+ const manifestPath = path33.join(directory, ".swarm/checkpoints.json");
16495
+ if (!existsSync18(manifestPath)) {
16187
16496
  return {
16188
16497
  name: "Checkpoint Manifest",
16189
16498
  status: "\u2705",
@@ -16191,7 +16500,7 @@ async function checkCheckpointManifest(directory) {
16191
16500
  };
16192
16501
  }
16193
16502
  try {
16194
- const content = readFileSync9(manifestPath, "utf-8");
16503
+ const content = readFileSync10(manifestPath, "utf-8");
16195
16504
  const parsed = JSON.parse(content);
16196
16505
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
16197
16506
  return {
@@ -16234,8 +16543,8 @@ async function checkCheckpointManifest(directory) {
16234
16543
  }
16235
16544
  }
16236
16545
  async function checkEventStreamIntegrity(directory) {
16237
- const eventsPath = path32.join(directory, ".swarm/events.jsonl");
16238
- if (!existsSync17(eventsPath)) {
16546
+ const eventsPath = path33.join(directory, ".swarm/events.jsonl");
16547
+ if (!existsSync18(eventsPath)) {
16239
16548
  return {
16240
16549
  name: "Event Stream",
16241
16550
  status: "\u2705",
@@ -16243,7 +16552,7 @@ async function checkEventStreamIntegrity(directory) {
16243
16552
  };
16244
16553
  }
16245
16554
  try {
16246
- const content = readFileSync9(eventsPath, "utf-8");
16555
+ const content = readFileSync10(eventsPath, "utf-8");
16247
16556
  const lines = content.split(`
16248
16557
  `).filter((line) => line.trim() !== "");
16249
16558
  let malformedCount = 0;
@@ -16275,8 +16584,8 @@ async function checkEventStreamIntegrity(directory) {
16275
16584
  }
16276
16585
  }
16277
16586
  async function checkSteeringDirectives(directory) {
16278
- const eventsPath = path32.join(directory, ".swarm/events.jsonl");
16279
- if (!existsSync17(eventsPath)) {
16587
+ const eventsPath = path33.join(directory, ".swarm/events.jsonl");
16588
+ if (!existsSync18(eventsPath)) {
16280
16589
  return {
16281
16590
  name: "Steering Directives",
16282
16591
  status: "\u2705",
@@ -16284,7 +16593,7 @@ async function checkSteeringDirectives(directory) {
16284
16593
  };
16285
16594
  }
16286
16595
  try {
16287
- const content = readFileSync9(eventsPath, "utf-8");
16596
+ const content = readFileSync10(eventsPath, "utf-8");
16288
16597
  const lines = content.split(`
16289
16598
  `).filter((line) => line.trim() !== "");
16290
16599
  const directivesIssued = [];
@@ -16331,8 +16640,8 @@ async function checkCurator(directory) {
16331
16640
  detail: "Disabled (enable via curator.enabled)"
16332
16641
  };
16333
16642
  }
16334
- const summaryPath = path32.join(directory, ".swarm/curator-summary.json");
16335
- if (!existsSync17(summaryPath)) {
16643
+ const summaryPath = path33.join(directory, ".swarm/curator-summary.json");
16644
+ if (!existsSync18(summaryPath)) {
16336
16645
  return {
16337
16646
  name: "Curator",
16338
16647
  status: "\u2705",
@@ -16340,7 +16649,7 @@ async function checkCurator(directory) {
16340
16649
  };
16341
16650
  }
16342
16651
  try {
16343
- const content = readFileSync9(summaryPath, "utf-8");
16652
+ const content = readFileSync10(summaryPath, "utf-8");
16344
16653
  const parsed = JSON.parse(content);
16345
16654
  if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
16346
16655
  return {
@@ -16533,8 +16842,8 @@ async function getDiagnoseData(directory) {
16533
16842
  checks.push(await checkCurator(directory));
16534
16843
  checks.push(await checkKnowledgeHealth(directory));
16535
16844
  try {
16536
- const evidenceDir = path32.join(directory, ".swarm", "evidence");
16537
- const snapshotFiles = existsSync17(evidenceDir) ? readdirSync3(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
16845
+ const evidenceDir = path33.join(directory, ".swarm", "evidence");
16846
+ const snapshotFiles = existsSync18(evidenceDir) ? readdirSync3(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
16538
16847
  if (snapshotFiles.length > 0) {
16539
16848
  const latest = snapshotFiles.sort().pop();
16540
16849
  checks.push({
@@ -16567,13 +16876,13 @@ async function getDiagnoseData(directory) {
16567
16876
  const cacheRows = [];
16568
16877
  for (const cachePath of cachePaths) {
16569
16878
  try {
16570
- if (!existsSync17(cachePath)) {
16879
+ if (!existsSync18(cachePath)) {
16571
16880
  cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
16572
16881
  continue;
16573
16882
  }
16574
- const pkgJsonPath = path32.join(cachePath, "package.json");
16883
+ const pkgJsonPath = path33.join(cachePath, "package.json");
16575
16884
  try {
16576
- const raw = readFileSync9(pkgJsonPath, "utf-8");
16885
+ const raw = readFileSync10(pkgJsonPath, "utf-8");
16577
16886
  const parsed = JSON.parse(raw);
16578
16887
  const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
16579
16888
  cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
@@ -16792,7 +17101,7 @@ async function handleDoctorCommand(directory, args) {
16792
17101
  const result = runConfigDoctor(config, directory);
16793
17102
  let output;
16794
17103
  if (enableAutoFix && result.hasAutoFixableIssues) {
16795
- const { runConfigDoctorWithFixes } = await import("./config-doctor-7yrxfa6b.js");
17104
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-9fhfy6p7.js");
16796
17105
  const fixResult = await runConfigDoctorWithFixes(directory, config, true);
16797
17106
  output = formatDoctorMarkdown(fixResult.result);
16798
17107
  } else {
@@ -16942,10 +17251,10 @@ function decideEpicActivation(tasks, cochangePairs, commitsObserved, options) {
16942
17251
 
16943
17252
  // src/turbo/epic/calibration.ts
16944
17253
  init_logger();
16945
- import * as fs14 from "fs";
16946
- import * as path33 from "path";
17254
+ import * as fs15 from "fs";
17255
+ import * as path34 from "path";
16947
17256
  var STATE_FILE = "calibration.json";
16948
- var STATE_REL_DIR = path33.join(".swarm", "epic");
17257
+ var STATE_REL_DIR = path34.join(".swarm", "epic");
16949
17258
  function nowISO() {
16950
17259
  return new Date().toISOString();
16951
17260
  }
@@ -16967,13 +17276,13 @@ function markUnreadable(directory, reason) {
16967
17276
  error(`[epic/calibration] state file unreadable for ${directory}: ${reason} \u2014 failing closed`);
16968
17277
  }
16969
17278
  function repairCalibrationUnreadable(directory) {
16970
- const filePath = path33.join(directory, STATE_REL_DIR, STATE_FILE);
16971
- if (!fs14.existsSync(filePath)) {
17279
+ const filePath = path34.join(directory, STATE_REL_DIR, STATE_FILE);
17280
+ if (!fs15.existsSync(filePath)) {
16972
17281
  stateUnreadableMap.delete(directory);
16973
17282
  return;
16974
17283
  }
16975
17284
  try {
16976
- const raw = fs14.readFileSync(filePath, "utf-8");
17285
+ const raw = fs15.readFileSync(filePath, "utf-8");
16977
17286
  const parsed = JSON.parse(raw);
16978
17287
  if (!isValidCalibrationShape(parsed)) {
16979
17288
  stateUnreadableMap.set(directory, true);
@@ -16999,9 +17308,9 @@ function isValidCalibrationShape(candidate) {
16999
17308
  return true;
17000
17309
  }
17001
17310
  function ensureSwarmEpicDir(directory) {
17002
- const dir = path33.resolve(directory, STATE_REL_DIR);
17003
- if (!fs14.existsSync(dir)) {
17004
- fs14.mkdirSync(dir, { recursive: true });
17311
+ const dir = path34.resolve(directory, STATE_REL_DIR);
17312
+ if (!fs15.existsSync(dir)) {
17313
+ fs15.mkdirSync(dir, { recursive: true });
17005
17314
  }
17006
17315
  return dir;
17007
17316
  }
@@ -17011,18 +17320,18 @@ function loadCalibrationState(directory) {
17011
17320
  if (stateUnreadableMap.get(directory))
17012
17321
  return null;
17013
17322
  }
17014
- const filePath = path33.join(directory, STATE_REL_DIR, STATE_FILE);
17323
+ const filePath = path34.join(directory, STATE_REL_DIR, STATE_FILE);
17015
17324
  try {
17016
- if (!fs14.existsSync(filePath)) {
17325
+ if (!fs15.existsSync(filePath)) {
17017
17326
  const seed = emptyCalibrationState();
17018
17327
  try {
17019
17328
  ensureSwarmEpicDir(directory);
17020
- fs14.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
17329
+ fs15.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
17021
17330
  `, "utf-8");
17022
17331
  } catch {}
17023
17332
  return seed;
17024
17333
  }
17025
- const raw = fs14.readFileSync(filePath, "utf-8");
17334
+ const raw = fs15.readFileSync(filePath, "utf-8");
17026
17335
  const parsed = JSON.parse(raw);
17027
17336
  if (!isValidCalibrationShape(parsed)) {
17028
17337
  markUnreadable(directory, `malformed shape (version=${parsed?.version}, hotModuleAdditions type=${Array.isArray(parsed?.hotModuleAdditions) ? "array" : typeof parsed?.hotModuleAdditions})`);
@@ -17037,36 +17346,36 @@ function loadCalibrationState(directory) {
17037
17346
 
17038
17347
  // src/turbo/epic/divergence-recorder.ts
17039
17348
  init_logger();
17040
- import * as fs15 from "fs";
17041
- import * as path34 from "path";
17042
- var EVIDENCE_REL_DIR = path34.join(".swarm", "epic");
17349
+ import * as fs16 from "fs";
17350
+ import * as path35 from "path";
17351
+ var EVIDENCE_REL_DIR = path35.join(".swarm", "epic");
17043
17352
  var EVIDENCE_FILE = "divergence.jsonl";
17044
17353
  var MAX_TAIL_BYTES2 = 16 * 1024 * 1024;
17045
17354
  function readDivergenceHistory(directory, options) {
17046
- const filePath = path34.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
17047
- if (!fs15.existsSync(filePath)) {
17355
+ const filePath = path35.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
17356
+ if (!fs16.existsSync(filePath)) {
17048
17357
  return [];
17049
17358
  }
17050
17359
  const maxBytes = options?.maxBytes ?? MAX_TAIL_BYTES2;
17051
17360
  let raw;
17052
17361
  let tailTruncated = false;
17053
17362
  try {
17054
- const stat5 = fs15.statSync(filePath);
17363
+ const stat5 = fs16.statSync(filePath);
17055
17364
  if (Number.isFinite(maxBytes) && stat5.size > maxBytes) {
17056
- const fd = fs15.openSync(filePath, "r");
17365
+ const fd = fs16.openSync(filePath, "r");
17057
17366
  try {
17058
17367
  const buf = Buffer.alloc(maxBytes);
17059
17368
  const offset = stat5.size - maxBytes;
17060
- fs15.readSync(fd, buf, 0, maxBytes, offset);
17369
+ fs16.readSync(fd, buf, 0, maxBytes, offset);
17061
17370
  raw = buf.toString("utf-8");
17062
17371
  tailTruncated = true;
17063
17372
  } finally {
17064
17373
  try {
17065
- fs15.closeSync(fd);
17374
+ fs16.closeSync(fd);
17066
17375
  } catch {}
17067
17376
  }
17068
17377
  } else {
17069
- raw = fs15.readFileSync(filePath, "utf-8");
17378
+ raw = fs16.readFileSync(filePath, "utf-8");
17070
17379
  }
17071
17380
  } catch {
17072
17381
  return [];
@@ -17091,16 +17400,16 @@ function readDivergenceHistory(directory, options) {
17091
17400
  }
17092
17401
 
17093
17402
  // src/turbo/epic/promotion-evidence.ts
17094
- import * as fs16 from "fs";
17095
- import * as path35 from "path";
17096
- var EVIDENCE_REL_DIR2 = path35.join(".swarm", "evidence");
17403
+ import * as fs17 from "fs";
17404
+ import * as path36 from "path";
17405
+ var EVIDENCE_REL_DIR2 = path36.join(".swarm", "evidence");
17097
17406
  var EVIDENCE_FILE2 = "epic-promotions.jsonl";
17098
17407
  function readPromotionEvidence(directory) {
17099
- const filePath = path35.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
17100
- if (!fs16.existsSync(filePath)) {
17408
+ const filePath = path36.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
17409
+ if (!fs17.existsSync(filePath)) {
17101
17410
  return [];
17102
17411
  }
17103
- const raw = fs16.readFileSync(filePath, "utf-8");
17412
+ const raw = fs17.readFileSync(filePath, "utf-8");
17104
17413
  const lines = raw.split(`
17105
17414
  `).filter((l) => l.trim().length > 0);
17106
17415
  const records = [];
@@ -17605,7 +17914,7 @@ async function handleEvidenceCommand(directory, args) {
17605
17914
  return formatTaskEvidenceMarkdown(evidenceData);
17606
17915
  }
17607
17916
  async function handleEvidenceSummaryCommand(directory) {
17608
- const { buildEvidenceSummary } = await import("./evidence-summary-service-g4x5e3e3.js");
17917
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-4hs44n2c.js");
17609
17918
  const artifact = await buildEvidenceSummary(directory);
17610
17919
  if (!artifact) {
17611
17920
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -17669,8 +17978,8 @@ async function handleExportCommand(directory, _args) {
17669
17978
  }
17670
17979
  // src/full-auto/state.ts
17671
17980
  var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
17672
- import * as fs17 from "fs";
17673
- import * as path36 from "path";
17981
+ import * as fs18 from "fs";
17982
+ import * as path37 from "path";
17674
17983
  init_logger();
17675
17984
  var lockfile4 = import_proper_lockfile4.default;
17676
17985
  var STATE_FILE2 = "full-auto-state.json";
@@ -17678,9 +17987,9 @@ function nowISO2() {
17678
17987
  return new Date().toISOString();
17679
17988
  }
17680
17989
  function ensureSwarmDir(directory) {
17681
- const swarmDir = path36.resolve(directory, ".swarm");
17682
- if (!fs17.existsSync(swarmDir)) {
17683
- fs17.mkdirSync(swarmDir, { recursive: true });
17990
+ const swarmDir = path37.resolve(directory, ".swarm");
17991
+ if (!fs18.existsSync(swarmDir)) {
17992
+ fs18.mkdirSync(swarmDir, { recursive: true });
17684
17993
  }
17685
17994
  return swarmDir;
17686
17995
  }
@@ -17738,7 +18047,7 @@ function withStateLock(directory, fn) {
17738
18047
  let release;
17739
18048
  try {
17740
18049
  const lockTarget = validateSwarmPath(directory, STATE_FILE2);
17741
- if (!fs17.existsSync(lockTarget)) {
18050
+ if (!fs18.existsSync(lockTarget)) {
17742
18051
  ensureSwarmDir(directory);
17743
18052
  const seed = {
17744
18053
  version: 2,
@@ -17746,7 +18055,7 @@ function withStateLock(directory, fn) {
17746
18055
  oversightSequence: 0,
17747
18056
  sessions: {}
17748
18057
  };
17749
- fs17.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
18058
+ fs18.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
17750
18059
  `, "utf-8");
17751
18060
  }
17752
18061
  release = lockfile4.lockSync(lockTarget, {
@@ -17796,7 +18105,7 @@ function readPersisted(directory) {
17796
18105
  const filePath = validateSwarmPath(directory, STATE_FILE2);
17797
18106
  let stats;
17798
18107
  try {
17799
- stats = fs17.statSync(filePath);
18108
+ stats = fs18.statSync(filePath);
17800
18109
  } catch {
17801
18110
  clearStateUnreadable();
17802
18111
  readCache.delete(filePath);
@@ -17807,7 +18116,7 @@ function readPersisted(directory) {
17807
18116
  clearStateUnreadable();
17808
18117
  return structuredClone(cached.state);
17809
18118
  }
17810
- const raw = fs17.readFileSync(filePath, "utf-8");
18119
+ const raw = fs18.readFileSync(filePath, "utf-8");
17811
18120
  const parsed = JSON.parse(raw);
17812
18121
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 2 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
17813
18122
  markStateUnreadable(`malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -17832,8 +18141,8 @@ function readPersisted(directory) {
17832
18141
  error(`[full-auto/state] Failed to read ${STATE_FILE2}: ${reason} \u2014 attempting .bak recovery`);
17833
18142
  try {
17834
18143
  const bakPath = validateSwarmPath(directory, `${STATE_FILE2}.bak`);
17835
- if (fs17.existsSync(bakPath)) {
17836
- const raw = fs17.readFileSync(bakPath, "utf-8");
18144
+ if (fs18.existsSync(bakPath)) {
18145
+ const raw = fs18.readFileSync(bakPath, "utf-8");
17837
18146
  const parsed = JSON.parse(raw);
17838
18147
  if (parsed?.version === 2 && parsed.sessions && !Array.isArray(parsed.sessions)) {
17839
18148
  warn(`[full-auto/state] Recovered from ${STATE_FILE2}.bak`);
@@ -17873,23 +18182,23 @@ function writePersisted(directory, persisted) {
17873
18182
  throw new Error(`Full-Auto state persistence prepare failed: ${msg}`);
17874
18183
  }
17875
18184
  try {
17876
- if (fs17.existsSync(filePath)) {
17877
- fs17.copyFileSync(filePath, bakPath);
18185
+ if (fs18.existsSync(filePath)) {
18186
+ fs18.copyFileSync(filePath, bakPath);
17878
18187
  }
17879
18188
  } catch {}
17880
18189
  try {
17881
- fs17.writeFileSync(tmpPath, payload, "utf-8");
18190
+ fs18.writeFileSync(tmpPath, payload, "utf-8");
17882
18191
  try {
17883
- const fd = fs17.openSync(tmpPath, "r+");
18192
+ const fd = fs18.openSync(tmpPath, "r+");
17884
18193
  try {
17885
- fs17.fsyncSync(fd);
18194
+ fs18.fsyncSync(fd);
17886
18195
  } finally {
17887
- fs17.closeSync(fd);
18196
+ fs18.closeSync(fd);
17888
18197
  }
17889
18198
  } catch {}
17890
- fs17.renameSync(tmpPath, filePath);
18199
+ fs18.renameSync(tmpPath, filePath);
17891
18200
  readCache.delete(filePath);
17892
- const readback = fs17.readFileSync(filePath, "utf-8");
18201
+ const readback = fs18.readFileSync(filePath, "utf-8");
17893
18202
  const parsed = JSON.parse(readback);
17894
18203
  if (parsed?.version !== 2) {
17895
18204
  throw new Error("Round-trip readback returned wrong version");
@@ -18109,7 +18418,7 @@ function buildStatusReport(directory, sessionID, sessionFlag) {
18109
18418
 
18110
18419
  // src/commands/handoff.ts
18111
18420
  import crypto4 from "crypto";
18112
- import { renameSync as renameSync9, unlinkSync as unlinkSync5 } from "fs";
18421
+ import { renameSync as renameSync9, unlinkSync as unlinkSync6 } from "fs";
18113
18422
 
18114
18423
  // src/services/handoff-service.ts
18115
18424
  var RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
@@ -18490,7 +18799,7 @@ var _internals27 = {
18490
18799
 
18491
18800
  // src/session/snapshot-writer.ts
18492
18801
  import { closeSync as closeSync6, fsyncSync as fsyncSync2, mkdirSync as mkdirSync14, openSync as openSync6, renameSync as renameSync8 } from "fs";
18493
- import * as path37 from "path";
18802
+ import * as path38 from "path";
18494
18803
  var _writeInFlight = Promise.resolve();
18495
18804
  function serializeAgentSession(s) {
18496
18805
  const gateLog = {};
@@ -18597,7 +18906,7 @@ async function writeSnapshot(directory, state) {
18597
18906
  }
18598
18907
  const content = JSON.stringify(snapshot, null, 2);
18599
18908
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
18600
- const dir = path37.dirname(resolvedPath);
18909
+ const dir = path38.dirname(resolvedPath);
18601
18910
  mkdirSync14(dir, { recursive: true });
18602
18911
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
18603
18912
  await bunWrite(tempPath, content);
@@ -18644,7 +18953,7 @@ async function handleHandoffCommand(directory, _args) {
18644
18953
  renameSync9(tempPath, resolvedPath);
18645
18954
  } catch (renameErr) {
18646
18955
  try {
18647
- unlinkSync5(tempPath);
18956
+ unlinkSync6(tempPath);
18648
18957
  } catch {}
18649
18958
  throw renameErr;
18650
18959
  }
@@ -18656,7 +18965,7 @@ async function handleHandoffCommand(directory, _args) {
18656
18965
  renameSync9(promptTempPath, promptPath);
18657
18966
  } catch (renameErr) {
18658
18967
  try {
18659
- unlinkSync5(promptTempPath);
18968
+ unlinkSync6(promptTempPath);
18660
18969
  } catch {}
18661
18970
  throw renameErr;
18662
18971
  }
@@ -19100,15 +19409,15 @@ ${USAGE6}`;
19100
19409
  }
19101
19410
 
19102
19411
  // src/commands/knowledge.ts
19103
- import { join as join31 } from "path";
19412
+ import { join as join32 } from "path";
19104
19413
 
19105
19414
  // src/hooks/knowledge-migrator.ts
19106
19415
  init_logger();
19107
19416
  import { randomUUID as randomUUID4 } from "crypto";
19108
- import { existsSync as existsSync22, readFileSync as readFileSync14 } from "fs";
19417
+ import { existsSync as existsSync23, readFileSync as readFileSync15 } from "fs";
19109
19418
  import { mkdir as mkdir9, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
19110
- import * as os8 from "os";
19111
- import * as path38 from "path";
19419
+ import * as os9 from "os";
19420
+ import * as path39 from "path";
19112
19421
 
19113
19422
  // src/hooks/knowledge-types.ts
19114
19423
  var KNOWLEDGE_SCHEMA_VERSION = 2;
@@ -19138,10 +19447,10 @@ var _internals30 = {
19138
19447
  resolveLegacyHiveKnowledgePath
19139
19448
  };
19140
19449
  async function migrateContextToKnowledge(directory, config) {
19141
- const sentinelPath = path38.join(directory, ".swarm", ".knowledge-migrated");
19142
- const contextPath = path38.join(directory, ".swarm", "context.md");
19450
+ const sentinelPath = path39.join(directory, ".swarm", ".knowledge-migrated");
19451
+ const contextPath = path39.join(directory, ".swarm", "context.md");
19143
19452
  const knowledgePath = resolveSwarmKnowledgePath(directory);
19144
- if (existsSync22(sentinelPath)) {
19453
+ if (existsSync23(sentinelPath)) {
19145
19454
  return {
19146
19455
  migrated: false,
19147
19456
  entriesMigrated: 0,
@@ -19150,7 +19459,7 @@ async function migrateContextToKnowledge(directory, config) {
19150
19459
  skippedReason: "sentinel-exists"
19151
19460
  };
19152
19461
  }
19153
- if (!existsSync22(contextPath)) {
19462
+ if (!existsSync23(contextPath)) {
19154
19463
  return {
19155
19464
  migrated: false,
19156
19465
  entriesMigrated: 0,
@@ -19241,8 +19550,8 @@ async function migrateContextToKnowledge(directory, config) {
19241
19550
  async function migrateHiveKnowledgeLegacy(config) {
19242
19551
  const legacyHivePath = _internals30.resolveLegacyHiveKnowledgePath();
19243
19552
  const canonicalHivePath = resolveHiveKnowledgePath();
19244
- const sentinelPath = path38.join(path38.dirname(canonicalHivePath), ".hive-knowledge-migrated");
19245
- if (existsSync22(sentinelPath)) {
19553
+ const sentinelPath = path39.join(path39.dirname(canonicalHivePath), ".hive-knowledge-migrated");
19554
+ if (existsSync23(sentinelPath)) {
19246
19555
  return {
19247
19556
  migrated: false,
19248
19557
  entriesMigrated: 0,
@@ -19251,7 +19560,7 @@ async function migrateHiveKnowledgeLegacy(config) {
19251
19560
  skippedReason: "sentinel-exists"
19252
19561
  };
19253
19562
  }
19254
- if (!existsSync22(legacyHivePath)) {
19563
+ if (!existsSync23(legacyHivePath)) {
19255
19564
  return {
19256
19565
  migrated: false,
19257
19566
  entriesMigrated: 0,
@@ -19452,16 +19761,16 @@ function truncateLesson2(text) {
19452
19761
  return `${text.slice(0, 277)}...`;
19453
19762
  }
19454
19763
  function inferProjectName(directory) {
19455
- const packageJsonPath = path38.join(directory, "package.json");
19456
- if (existsSync22(packageJsonPath)) {
19764
+ const packageJsonPath = path39.join(directory, "package.json");
19765
+ if (existsSync23(packageJsonPath)) {
19457
19766
  try {
19458
- const pkg = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
19767
+ const pkg = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
19459
19768
  if (pkg.name && typeof pkg.name === "string") {
19460
19769
  return pkg.name;
19461
19770
  }
19462
19771
  } catch {}
19463
19772
  }
19464
- return path38.basename(directory);
19773
+ return path39.basename(directory);
19465
19774
  }
19466
19775
  async function writeSentinel(sentinelPath, migrated, dropped) {
19467
19776
  const sentinel = {
@@ -19473,21 +19782,21 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
19473
19782
  schema_version: 1,
19474
19783
  migration_tool: "knowledge-migrator.ts"
19475
19784
  };
19476
- await mkdir9(path38.dirname(sentinelPath), { recursive: true });
19785
+ await mkdir9(path39.dirname(sentinelPath), { recursive: true });
19477
19786
  await writeFile9(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
19478
19787
  }
19479
19788
  function resolveLegacyHiveKnowledgePath() {
19480
19789
  const platform = process.platform;
19481
- const home = process.env.HOME || os8.homedir();
19790
+ const home = process.env.HOME || os9.homedir();
19482
19791
  let dataDir;
19483
19792
  if (platform === "win32") {
19484
- dataDir = path38.join(process.env.LOCALAPPDATA || path38.join(home, "AppData", "Local"), "opencode-swarm", "Data");
19793
+ dataDir = path39.join(process.env.LOCALAPPDATA || path39.join(home, "AppData", "Local"), "opencode-swarm", "Data");
19485
19794
  } else if (platform === "darwin") {
19486
- dataDir = path38.join(home, "Library", "Application Support", "opencode-swarm");
19795
+ dataDir = path39.join(home, "Library", "Application Support", "opencode-swarm");
19487
19796
  } else {
19488
- dataDir = path38.join(process.env.XDG_DATA_HOME || path38.join(home, ".local", "share"), "opencode-swarm");
19797
+ dataDir = path39.join(process.env.XDG_DATA_HOME || path39.join(home, ".local", "share"), "opencode-swarm");
19489
19798
  }
19490
- return path38.join(dataDir, "hive-knowledge.jsonl");
19799
+ return path39.join(dataDir, "hive-knowledge.jsonl");
19491
19800
  }
19492
19801
 
19493
19802
  // src/commands/knowledge.ts
@@ -19541,7 +19850,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
19541
19850
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
19542
19851
  }
19543
19852
  try {
19544
- const quarantinePath = join31(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
19853
+ const quarantinePath = join32(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
19545
19854
  const entries = await readKnowledge(quarantinePath);
19546
19855
  const resolved = resolveEntryByPrefix(entries, inputId);
19547
19856
  if ("error" in resolved) {
@@ -19792,15 +20101,15 @@ var _internals31 = {
19792
20101
  };
19793
20102
 
19794
20103
  // src/commands/link.ts
19795
- import { existsSync as existsSync23 } from "fs";
19796
- import * as path40 from "path";
20104
+ import { existsSync as existsSync24 } from "fs";
20105
+ import * as path41 from "path";
19797
20106
 
19798
20107
  // src/knowledge/identity.ts
19799
20108
  import * as child_process5 from "child_process";
19800
20109
  import { createHash as createHash4 } from "crypto";
19801
- import * as path39 from "path";
20110
+ import * as path40 from "path";
19802
20111
  function deriveProjectHash(directory) {
19803
- const absolutePath = path39.resolve(directory);
20112
+ const absolutePath = path40.resolve(directory);
19804
20113
  let hashInput;
19805
20114
  try {
19806
20115
  const remoteUrl = child_process5.execSync("git remote get-url origin", {
@@ -19820,18 +20129,18 @@ function deriveProjectHash(directory) {
19820
20129
  // src/commands/link.ts
19821
20130
  var DEDUP_THRESHOLD = 0.6;
19822
20131
  async function mergeLocalKnowledgeIntoLink(localSwarmDir, linkDir) {
19823
- const localPath = path40.join(localSwarmDir, "knowledge.jsonl");
19824
- const sharedPath = path40.join(linkDir, "knowledge.jsonl");
19825
- if (!existsSync23(localPath))
20132
+ const localPath = path41.join(localSwarmDir, "knowledge.jsonl");
20133
+ const sharedPath = path41.join(linkDir, "knowledge.jsonl");
20134
+ if (!existsSync24(localPath))
19826
20135
  return { merged: 0, skipped: 0 };
19827
20136
  let merged = 0;
19828
20137
  let skipped = 0;
19829
- const { readFileSync: readFileSync15 } = await import("fs");
20138
+ const { readFileSync: readFileSync16 } = await import("fs");
19830
20139
  let changed = false;
19831
20140
  await transactKnowledge(sharedPath, (sharedEntries) => {
19832
20141
  const localEntries = [];
19833
20142
  try {
19834
- const content = readFileSync15(localPath, "utf-8");
20143
+ const content = readFileSync16(localPath, "utf-8");
19835
20144
  for (const line of content.split(`
19836
20145
  `)) {
19837
20146
  if (line.trim()) {
@@ -19919,7 +20228,7 @@ ${formatStatus(directory)}`;
19919
20228
  const linkDir = resolveLinkDir(linkId);
19920
20229
  let merge;
19921
20230
  try {
19922
- merge = await mergeLocalKnowledgeIntoLink(path40.join(directory, ".swarm"), linkDir);
20231
+ merge = await mergeLocalKnowledgeIntoLink(path41.join(directory, ".swarm"), linkDir);
19923
20232
  } catch (error2) {
19924
20233
  return `\u274C Failed to merge local knowledge into the link store: ${error2 instanceof Error ? error2.message : String(error2)}`;
19925
20234
  }
@@ -20063,8 +20372,8 @@ ${USAGE7}`;
20063
20372
  }
20064
20373
 
20065
20374
  // src/commands/memory.ts
20066
- import { existsSync as existsSync26 } from "fs";
20067
- import * as path47 from "path";
20375
+ import { existsSync as existsSync27 } from "fs";
20376
+ import * as path48 from "path";
20068
20377
  import { fileURLToPath as fileURLToPath2 } from "url";
20069
20378
 
20070
20379
  // src/memory/config.ts
@@ -20204,13 +20513,13 @@ class MemoryValidationError extends Error {
20204
20513
  }
20205
20514
  }
20206
20515
  // src/memory/evaluation.ts
20207
- import * as fs18 from "fs/promises";
20208
- import * as os9 from "os";
20209
- import * as path45 from "path";
20516
+ import * as fs19 from "fs/promises";
20517
+ import * as os10 from "os";
20518
+ import * as path46 from "path";
20210
20519
 
20211
20520
  // src/memory/local-jsonl-provider.ts
20212
20521
  import { randomUUID as randomUUID5 } from "crypto";
20213
- import { existsSync as existsSync24 } from "fs";
20522
+ import { existsSync as existsSync25 } from "fs";
20214
20523
  import {
20215
20524
  appendFile as appendFile3,
20216
20525
  mkdir as mkdir10,
@@ -20218,7 +20527,7 @@ import {
20218
20527
  rename as rename5,
20219
20528
  writeFile as writeFile10
20220
20529
  } from "fs/promises";
20221
- import * as path41 from "path";
20530
+ import * as path42 from "path";
20222
20531
 
20223
20532
  // src/memory/schema.ts
20224
20533
  import { createHash as createHash5 } from "crypto";
@@ -21079,7 +21388,7 @@ class LocalJsonlMemoryProvider {
21079
21388
  pathFor(file) {
21080
21389
  const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
21081
21390
  const filename = file === "memories" ? "memories.jsonl" : file === "proposals" ? "proposals.jsonl" : "audit.jsonl";
21082
- return validateSwarmPath(this.rootDirectory, path41.join(storageDir, filename));
21391
+ return validateSwarmPath(this.rootDirectory, path42.join(storageDir, filename));
21083
21392
  }
21084
21393
  async initialize() {
21085
21394
  if (this.initialized)
@@ -21406,7 +21715,7 @@ function validateLoadedProposals(values, config) {
21406
21715
  return { records, invalidCount };
21407
21716
  }
21408
21717
  async function readJsonl(filePath) {
21409
- if (!existsSync24(filePath))
21718
+ if (!existsSync25(filePath))
21410
21719
  return [];
21411
21720
  const content = await readFile12(filePath, "utf-8");
21412
21721
  const records = [];
@@ -21462,12 +21771,12 @@ function parseRecallUsageEvent(event) {
21462
21771
  }
21463
21772
  }
21464
21773
  async function appendJsonl(filePath, value) {
21465
- await mkdir10(path41.dirname(filePath), { recursive: true });
21774
+ await mkdir10(path42.dirname(filePath), { recursive: true });
21466
21775
  await appendFile3(filePath, `${JSON.stringify(value)}
21467
21776
  `, "utf-8");
21468
21777
  }
21469
21778
  async function writeJsonlAtomic(filePath, values) {
21470
- await mkdir10(path41.dirname(filePath), { recursive: true });
21779
+ await mkdir10(path42.dirname(filePath), { recursive: true });
21471
21780
  const tmp = `${filePath}.tmp.${randomUUID5()}`;
21472
21781
  const content = values.map((value) => JSON.stringify(value)).join(`
21473
21782
  `) + (values.length > 0 ? `
@@ -21478,18 +21787,18 @@ async function writeJsonlAtomic(filePath, values) {
21478
21787
 
21479
21788
  // src/memory/provider-pool.ts
21480
21789
  import { realpathSync as realpathSync2 } from "fs";
21481
- import * as path44 from "path";
21790
+ import * as path45 from "path";
21482
21791
 
21483
21792
  // src/memory/sqlite-provider.ts
21484
21793
  import { randomUUID as randomUUID6 } from "crypto";
21485
21794
  import { mkdirSync as mkdirSync15 } from "fs";
21486
21795
  import { createRequire as createRequire2 } from "module";
21487
- import * as path43 from "path";
21796
+ import * as path44 from "path";
21488
21797
 
21489
21798
  // src/memory/jsonl-migration.ts
21490
- import { existsSync as existsSync25, renameSync as renameSync10, unlinkSync as unlinkSync6 } from "fs";
21799
+ import { existsSync as existsSync26, renameSync as renameSync10, unlinkSync as unlinkSync7 } from "fs";
21491
21800
  import { copyFile as copyFile2, mkdir as mkdir11, readFile as readFile13, stat as stat5, writeFile as writeFile11 } from "fs/promises";
21492
- import * as path42 from "path";
21801
+ import * as path43 from "path";
21493
21802
  var LEGACY_JSONL_MIGRATION_VERSION = 2;
21494
21803
  var LEGACY_JSONL_MIGRATION_NAME = "legacy_jsonl_import_complete";
21495
21804
  function resolveMemoryStorageDir(rootDirectory, config = {}) {
@@ -21505,8 +21814,8 @@ function resolveSqliteDatabasePath(rootDirectory, config = {}) {
21505
21814
  async function readLegacyJsonl(rootDirectory, config = {}) {
21506
21815
  const resolved = resolveConfig(config);
21507
21816
  const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
21508
- const memoryLoad = await readMemoryJsonl(path42.join(storageDir, "memories.jsonl"), resolved);
21509
- const proposalLoad = await readProposalJsonl(path42.join(storageDir, "proposals.jsonl"), resolved);
21817
+ const memoryLoad = await readMemoryJsonl(path43.join(storageDir, "memories.jsonl"), resolved);
21818
+ const proposalLoad = await readProposalJsonl(path43.join(storageDir, "proposals.jsonl"), resolved);
21510
21819
  return {
21511
21820
  memories: memoryLoad.records,
21512
21821
  proposals: proposalLoad.records,
@@ -21516,15 +21825,15 @@ async function readLegacyJsonl(rootDirectory, config = {}) {
21516
21825
  }
21517
21826
  async function backupLegacyJsonl(rootDirectory, config = {}) {
21518
21827
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
21519
- const backupDir = path42.join(storageDir, "backups");
21828
+ const backupDir = path43.join(storageDir, "backups");
21520
21829
  await mkdir11(backupDir, { recursive: true });
21521
21830
  const results = [];
21522
21831
  for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
21523
- const source = path42.join(storageDir, filename);
21524
- if (!existsSync25(source))
21832
+ const source = path43.join(storageDir, filename);
21833
+ if (!existsSync26(source))
21525
21834
  continue;
21526
- const backup = path42.join(backupDir, `${filename}.pre-sqlite-migration`);
21527
- if (existsSync25(backup)) {
21835
+ const backup = path43.join(backupDir, `${filename}.pre-sqlite-migration`);
21836
+ if (existsSync26(backup)) {
21528
21837
  results.push({ source, backup, created: false });
21529
21838
  continue;
21530
21839
  }
@@ -21534,51 +21843,51 @@ async function backupLegacyJsonl(rootDirectory, config = {}) {
21534
21843
  return results;
21535
21844
  }
21536
21845
  async function writeJsonlExport(rootDirectory, config, memories, proposals) {
21537
- const exportDir = path42.join(resolveMemoryStorageDir(rootDirectory, config), "export");
21846
+ const exportDir = path43.join(resolveMemoryStorageDir(rootDirectory, config), "export");
21538
21847
  await mkdir11(exportDir, { recursive: true });
21539
- const memoriesPath = path42.join(exportDir, "memories.jsonl");
21540
- const proposalsPath = path42.join(exportDir, "proposals.jsonl");
21541
- const memoriesTempPath = path42.join(path42.dirname(memoriesPath), `${path42.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
21848
+ const memoriesPath = path43.join(exportDir, "memories.jsonl");
21849
+ const proposalsPath = path43.join(exportDir, "proposals.jsonl");
21850
+ const memoriesTempPath = path43.join(path43.dirname(memoriesPath), `${path43.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
21542
21851
  try {
21543
21852
  await writeFile11(memoriesTempPath, toJsonl(memories), "utf-8");
21544
21853
  renameSync10(memoriesTempPath, memoriesPath);
21545
21854
  } catch (err) {
21546
21855
  try {
21547
- unlinkSync6(memoriesTempPath);
21856
+ unlinkSync7(memoriesTempPath);
21548
21857
  } catch {}
21549
21858
  throw err;
21550
21859
  }
21551
- const proposalsTempPath = path42.join(path42.dirname(proposalsPath), `${path42.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
21860
+ const proposalsTempPath = path43.join(path43.dirname(proposalsPath), `${path43.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
21552
21861
  try {
21553
21862
  await writeFile11(proposalsTempPath, toJsonl(proposals), "utf-8");
21554
21863
  renameSync10(proposalsTempPath, proposalsPath);
21555
21864
  } catch (err) {
21556
21865
  try {
21557
- unlinkSync6(proposalsTempPath);
21866
+ unlinkSync7(proposalsTempPath);
21558
21867
  } catch {}
21559
21868
  throw err;
21560
21869
  }
21561
21870
  return { directory: exportDir, memoriesPath, proposalsPath };
21562
21871
  }
21563
21872
  async function writeMigrationReport(rootDirectory, report, config = {}) {
21564
- const reportPath = path42.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
21565
- await mkdir11(path42.dirname(reportPath), { recursive: true });
21566
- const reportTempPath = path42.join(path42.dirname(reportPath), `${path42.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
21873
+ const reportPath = path43.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
21874
+ await mkdir11(path43.dirname(reportPath), { recursive: true });
21875
+ const reportTempPath = path43.join(path43.dirname(reportPath), `${path43.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
21567
21876
  try {
21568
21877
  await writeFile11(reportTempPath, `${JSON.stringify(report, null, 2)}
21569
21878
  `, "utf-8");
21570
21879
  renameSync10(reportTempPath, reportPath);
21571
21880
  } catch (err) {
21572
21881
  try {
21573
- unlinkSync6(reportTempPath);
21882
+ unlinkSync7(reportTempPath);
21574
21883
  } catch {}
21575
21884
  throw err;
21576
21885
  }
21577
21886
  return reportPath;
21578
21887
  }
21579
21888
  async function readMigrationReport(rootDirectory, config = {}) {
21580
- const reportPath = path42.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
21581
- if (!existsSync25(reportPath))
21889
+ const reportPath = path43.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
21890
+ if (!existsSync26(reportPath))
21582
21891
  return null;
21583
21892
  try {
21584
21893
  return JSON.parse(await readFile13(reportPath, "utf-8"));
@@ -21590,15 +21899,15 @@ async function getLegacyJsonlFileStatus(rootDirectory, config = {}) {
21590
21899
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
21591
21900
  const statuses = [];
21592
21901
  for (const file of ["memories.jsonl", "proposals.jsonl"]) {
21593
- const filePath = path42.join(storageDir, file);
21902
+ const filePath = path43.join(storageDir, file);
21594
21903
  let sizeBytes = 0;
21595
- if (existsSync25(filePath)) {
21904
+ if (existsSync26(filePath)) {
21596
21905
  sizeBytes = (await stat5(filePath)).size;
21597
21906
  }
21598
21907
  statuses.push({
21599
21908
  file,
21600
21909
  path: filePath,
21601
- exists: existsSync25(filePath),
21910
+ exists: existsSync26(filePath),
21602
21911
  sizeBytes
21603
21912
  });
21604
21913
  }
@@ -21679,7 +21988,7 @@ async function readProposalJsonl(filePath, config) {
21679
21988
  return { records, invalidRows, totalRows: rows.totalRows };
21680
21989
  }
21681
21990
  async function readJsonlRows(filePath) {
21682
- if (!existsSync25(filePath)) {
21991
+ if (!existsSync26(filePath)) {
21683
21992
  return { rows: [], invalidRows: [], totalRows: 0 };
21684
21993
  }
21685
21994
  const content = await readFile13(filePath, "utf-8");
@@ -21898,7 +22207,7 @@ class SQLiteMemoryProvider {
21898
22207
  }
21899
22208
  async doInitialize() {
21900
22209
  const dbPath = this.databasePath();
21901
- mkdirSync15(path43.dirname(dbPath), { recursive: true });
22210
+ mkdirSync15(path44.dirname(dbPath), { recursive: true });
21902
22211
  const Db = loadDatabaseCtor2();
21903
22212
  this.db = new Db(dbPath);
21904
22213
  this.db.run("PRAGMA journal_mode = WAL;");
@@ -22927,7 +23236,7 @@ function resolvePoolKey(directory) {
22927
23236
  try {
22928
23237
  return realpathSync2(directory);
22929
23238
  } catch {
22930
- return path44.resolve(directory);
23239
+ return path45.resolve(directory);
22931
23240
  }
22932
23241
  }
22933
23242
 
@@ -22999,7 +23308,7 @@ var DEFAULT_MODES = [
22999
23308
  ];
23000
23309
  var DEFAULT_TIMESTAMP = "2026-05-26T12:00:00.000Z";
23001
23310
  async function evaluateMemoryRecallFixtures(options) {
23002
- const fixtureDirectory = path45.resolve(options.fixtureDirectory);
23311
+ const fixtureDirectory = path46.resolve(options.fixtureDirectory);
23003
23312
  const providers = options.providers ?? DEFAULT_PROVIDERS;
23004
23313
  const modes = options.modes ?? DEFAULT_MODES;
23005
23314
  const generatedAt = new Date().toISOString();
@@ -23008,7 +23317,7 @@ async function evaluateMemoryRecallFixtures(options) {
23008
23317
  for (const fixture of fixtures) {
23009
23318
  const materialized = materializeFixture(fixture);
23010
23319
  for (const providerName of providers) {
23011
- const tempRoot = await fs18.realpath(await fs18.mkdtemp(path45.join(os9.tmpdir(), "swarm-memory-eval-")));
23320
+ const tempRoot = await fs19.realpath(await fs19.mkdtemp(path46.join(os10.tmpdir(), "swarm-memory-eval-")));
23012
23321
  const provider = createEvaluationProvider(providerName, tempRoot);
23013
23322
  try {
23014
23323
  await provider.initialize?.();
@@ -23032,7 +23341,7 @@ async function evaluateMemoryRecallFixtures(options) {
23032
23341
  } finally {
23033
23342
  await provider.close?.();
23034
23343
  if (!options.keepTempRoots) {
23035
- await fs18.rm(tempRoot, { recursive: true, force: true });
23344
+ await fs19.rm(tempRoot, { recursive: true, force: true });
23036
23345
  }
23037
23346
  }
23038
23347
  }
@@ -23048,11 +23357,11 @@ async function evaluateMemoryRecallFixtures(options) {
23048
23357
  };
23049
23358
  }
23050
23359
  async function loadRecallEvaluationFixtures(fixtureDirectory) {
23051
- const entries = await fs18.readdir(fixtureDirectory, { withFileTypes: true });
23360
+ const entries = await fs19.readdir(fixtureDirectory, { withFileTypes: true });
23052
23361
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
23053
23362
  const fixtures = [];
23054
23363
  for (const file of files) {
23055
- const raw = await fs18.readFile(path45.join(fixtureDirectory, file), "utf-8");
23364
+ const raw = await fs19.readFile(path46.join(fixtureDirectory, file), "utf-8");
23056
23365
  fixtures.push(validateFixture(JSON.parse(raw), file));
23057
23366
  }
23058
23367
  return fixtures;
@@ -23329,8 +23638,8 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
23329
23638
  }).passthrough();
23330
23639
  // src/memory/consolidation-log.ts
23331
23640
  import { appendFile as appendFile4, mkdir as mkdir12, readFile as readFile15 } from "fs/promises";
23332
- import * as path46 from "path";
23333
- var LOG_RELATIVE_PATH = path46.join("memory", "consolidation-log.jsonl");
23641
+ import * as path47 from "path";
23642
+ var LOG_RELATIVE_PATH = path47.join("memory", "consolidation-log.jsonl");
23334
23643
  async function readConsolidationLog(directory) {
23335
23644
  const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
23336
23645
  let raw;
@@ -23353,7 +23662,7 @@ async function readConsolidationLog(directory) {
23353
23662
  }
23354
23663
 
23355
23664
  // src/commands/memory.ts
23356
- var PACKAGE_ROOT = path47.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
23665
+ var PACKAGE_ROOT = path48.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
23357
23666
  async function handleMemoryCommand(_directory, _args) {
23358
23667
  return [
23359
23668
  "## Swarm Memory",
@@ -23411,7 +23720,7 @@ async function handleMemoryStatusCommand(directory, _args) {
23411
23720
  `- Provider: \`${config.provider}\``,
23412
23721
  `- Storage: \`${storageDir}\``,
23413
23722
  `- SQLite path: \`${sqlitePath}\``,
23414
- `- SQLite database exists: \`${existsSync26(sqlitePath)}\``,
23723
+ `- SQLite database exists: \`${existsSync27(sqlitePath)}\``,
23415
23724
  `- Automatic destructive cleanup: \`disabled\``,
23416
23725
  "",
23417
23726
  "### Legacy JSONL"
@@ -23651,7 +23960,7 @@ function resolveCommandMemoryConfig(directory) {
23651
23960
  }
23652
23961
  function parseEvaluateArgs(directory, args) {
23653
23962
  let json = false;
23654
- let fixtureDirectory = path47.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
23963
+ let fixtureDirectory = path48.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
23655
23964
  for (let i = 0;i < args.length; i++) {
23656
23965
  const arg = args[i];
23657
23966
  if (arg === "--json") {
@@ -23665,10 +23974,10 @@ function parseEvaluateArgs(directory, args) {
23665
23974
  error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
23666
23975
  };
23667
23976
  }
23668
- const resolvedFixtures = path47.resolve(directory, next);
23669
- const canonical = path47.normalize(resolvedFixtures) + path47.sep;
23670
- const allowedRootA = path47.normalize(directory) + path47.sep;
23671
- const allowedRootB = path47.normalize(path47.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path47.sep;
23977
+ const resolvedFixtures = path48.resolve(directory, next);
23978
+ const canonical = path48.normalize(resolvedFixtures) + path48.sep;
23979
+ const allowedRootA = path48.normalize(directory) + path48.sep;
23980
+ const allowedRootB = path48.normalize(path48.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path48.sep;
23672
23981
  if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
23673
23982
  return {
23674
23983
  error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
@@ -23707,15 +24016,15 @@ function parseMaintenanceArgs(args, options) {
23707
24016
  return { limit, confirm };
23708
24017
  }
23709
24018
  function resolvePackageRootFromModule(modulePath) {
23710
- const moduleDir = path47.dirname(modulePath);
23711
- const leaf = path47.basename(moduleDir);
24019
+ const moduleDir = path48.dirname(modulePath);
24020
+ const leaf = path48.basename(moduleDir);
23712
24021
  if (leaf === "commands" || leaf === "cli") {
23713
- return path47.resolve(moduleDir, "..", "..");
24022
+ return path48.resolve(moduleDir, "..", "..");
23714
24023
  }
23715
24024
  if (leaf === "dist") {
23716
- return path47.resolve(moduleDir, "..");
24025
+ return path48.resolve(moduleDir, "..");
23717
24026
  }
23718
- return path47.resolve(moduleDir, "..");
24027
+ return path48.resolve(moduleDir, "..");
23719
24028
  }
23720
24029
  function formatMigrationResult(label, report) {
23721
24030
  if (!report) {
@@ -24409,12 +24718,12 @@ var _internals36 = {
24409
24718
  };
24410
24719
 
24411
24720
  // src/services/preflight-service.ts
24412
- import * as fs25 from "fs";
24413
- import * as path54 from "path";
24721
+ import * as fs26 from "fs";
24722
+ import * as path55 from "path";
24414
24723
 
24415
24724
  // src/tools/lint.ts
24416
- import * as fs19 from "fs";
24417
- import * as path48 from "path";
24725
+ import * as fs20 from "fs";
24726
+ import * as path49 from "path";
24418
24727
 
24419
24728
  // src/utils/path-security.ts
24420
24729
  function containsPathTraversal(str) {
@@ -24470,9 +24779,9 @@ function validateArgs(args) {
24470
24779
  }
24471
24780
  function getLinterCommand(linter, mode, projectDir) {
24472
24781
  const isWindows = process.platform === "win32";
24473
- const binDir = path48.join(projectDir, "node_modules", ".bin");
24474
- const biomeBin = isWindows ? path48.join(binDir, "biome.EXE") : path48.join(binDir, "biome");
24475
- const eslintBin = isWindows ? path48.join(binDir, "eslint.cmd") : path48.join(binDir, "eslint");
24782
+ const binDir = path49.join(projectDir, "node_modules", ".bin");
24783
+ const biomeBin = isWindows ? path49.join(binDir, "biome.EXE") : path49.join(binDir, "biome");
24784
+ const eslintBin = isWindows ? path49.join(binDir, "eslint.cmd") : path49.join(binDir, "eslint");
24476
24785
  switch (linter) {
24477
24786
  case "biome":
24478
24787
  if (mode === "fix") {
@@ -24488,7 +24797,7 @@ function getLinterCommand(linter, mode, projectDir) {
24488
24797
  }
24489
24798
  function getAdditionalLinterCommand(linter, mode, cwd) {
24490
24799
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
24491
- const gradlew = fs19.existsSync(path48.join(cwd, gradlewName)) ? path48.join(cwd, gradlewName) : null;
24800
+ const gradlew = fs20.existsSync(path49.join(cwd, gradlewName)) ? path49.join(cwd, gradlewName) : null;
24492
24801
  switch (linter) {
24493
24802
  case "ruff":
24494
24803
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -24522,12 +24831,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
24522
24831
  }
24523
24832
  }
24524
24833
  function detectRuff(cwd) {
24525
- if (fs19.existsSync(path48.join(cwd, "ruff.toml")))
24834
+ if (fs20.existsSync(path49.join(cwd, "ruff.toml")))
24526
24835
  return isCommandAvailable("ruff");
24527
24836
  try {
24528
- const pyproject = path48.join(cwd, "pyproject.toml");
24529
- if (fs19.existsSync(pyproject)) {
24530
- const content = fs19.readFileSync(pyproject, "utf-8");
24837
+ const pyproject = path49.join(cwd, "pyproject.toml");
24838
+ if (fs20.existsSync(pyproject)) {
24839
+ const content = fs20.readFileSync(pyproject, "utf-8");
24531
24840
  if (content.includes("[tool.ruff]"))
24532
24841
  return isCommandAvailable("ruff");
24533
24842
  }
@@ -24535,21 +24844,21 @@ function detectRuff(cwd) {
24535
24844
  return false;
24536
24845
  }
24537
24846
  function detectClippy(cwd) {
24538
- return fs19.existsSync(path48.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
24847
+ return fs20.existsSync(path49.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
24539
24848
  }
24540
24849
  function detectGolangciLint(cwd) {
24541
- return fs19.existsSync(path48.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24850
+ return fs20.existsSync(path49.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24542
24851
  }
24543
24852
  function detectCheckstyle(cwd) {
24544
- const hasMaven = fs19.existsSync(path48.join(cwd, "pom.xml"));
24545
- const hasGradle = fs19.existsSync(path48.join(cwd, "build.gradle")) || fs19.existsSync(path48.join(cwd, "build.gradle.kts"));
24546
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs19.existsSync(path48.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
24853
+ const hasMaven = fs20.existsSync(path49.join(cwd, "pom.xml"));
24854
+ const hasGradle = fs20.existsSync(path49.join(cwd, "build.gradle")) || fs20.existsSync(path49.join(cwd, "build.gradle.kts"));
24855
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs20.existsSync(path49.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
24547
24856
  return (hasMaven || hasGradle) && hasBinary;
24548
24857
  }
24549
24858
  function detectKtlint(cwd) {
24550
- const hasKotlin = fs19.existsSync(path48.join(cwd, "build.gradle.kts")) || fs19.existsSync(path48.join(cwd, "build.gradle")) || (() => {
24859
+ const hasKotlin = fs20.existsSync(path49.join(cwd, "build.gradle.kts")) || fs20.existsSync(path49.join(cwd, "build.gradle")) || (() => {
24551
24860
  try {
24552
- return fs19.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
24861
+ return fs20.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
24553
24862
  } catch {
24554
24863
  return false;
24555
24864
  }
@@ -24558,7 +24867,7 @@ function detectKtlint(cwd) {
24558
24867
  }
24559
24868
  function detectDotnetFormat(cwd) {
24560
24869
  try {
24561
- const files = fs19.readdirSync(cwd);
24870
+ const files = fs20.readdirSync(cwd);
24562
24871
  const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
24563
24872
  return hasCsproj && isCommandAvailable("dotnet");
24564
24873
  } catch {
@@ -24566,14 +24875,14 @@ function detectDotnetFormat(cwd) {
24566
24875
  }
24567
24876
  }
24568
24877
  function detectCppcheck(cwd) {
24569
- if (fs19.existsSync(path48.join(cwd, "CMakeLists.txt"))) {
24878
+ if (fs20.existsSync(path49.join(cwd, "CMakeLists.txt"))) {
24570
24879
  return isCommandAvailable("cppcheck");
24571
24880
  }
24572
24881
  try {
24573
- const dirsToCheck = [cwd, path48.join(cwd, "src")];
24882
+ const dirsToCheck = [cwd, path49.join(cwd, "src")];
24574
24883
  const hasCpp = dirsToCheck.some((dir) => {
24575
24884
  try {
24576
- return fs19.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
24885
+ return fs20.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
24577
24886
  } catch {
24578
24887
  return false;
24579
24888
  }
@@ -24584,13 +24893,13 @@ function detectCppcheck(cwd) {
24584
24893
  }
24585
24894
  }
24586
24895
  function detectSwiftlint(cwd) {
24587
- return fs19.existsSync(path48.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
24896
+ return fs20.existsSync(path49.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
24588
24897
  }
24589
24898
  function detectDartAnalyze(cwd) {
24590
- return fs19.existsSync(path48.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
24899
+ return fs20.existsSync(path49.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
24591
24900
  }
24592
24901
  function detectRubocop(cwd) {
24593
- 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"));
24902
+ return (fs20.existsSync(path49.join(cwd, "Gemfile")) || fs20.existsSync(path49.join(cwd, "gems.rb")) || fs20.existsSync(path49.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
24594
24903
  }
24595
24904
  function detectAdditionalLinter(cwd) {
24596
24905
  if (detectRuff(cwd))
@@ -24618,10 +24927,10 @@ function detectAdditionalLinter(cwd) {
24618
24927
  function findBinInAncestors(startDir, binName) {
24619
24928
  let dir = startDir;
24620
24929
  while (true) {
24621
- const candidate = path48.join(dir, "node_modules", ".bin", binName);
24622
- if (fs19.existsSync(candidate))
24930
+ const candidate = path49.join(dir, "node_modules", ".bin", binName);
24931
+ if (fs20.existsSync(candidate))
24623
24932
  return candidate;
24624
- const parent = path48.dirname(dir);
24933
+ const parent = path49.dirname(dir);
24625
24934
  if (parent === dir)
24626
24935
  break;
24627
24936
  dir = parent;
@@ -24630,11 +24939,11 @@ function findBinInAncestors(startDir, binName) {
24630
24939
  }
24631
24940
  function findBinInEnvPath(binName) {
24632
24941
  const searchPath = process.env.PATH ?? "";
24633
- for (const dir of searchPath.split(path48.delimiter)) {
24942
+ for (const dir of searchPath.split(path49.delimiter)) {
24634
24943
  if (!dir)
24635
24944
  continue;
24636
- const candidate = path48.join(dir, binName);
24637
- if (fs19.existsSync(candidate))
24945
+ const candidate = path49.join(dir, binName);
24946
+ if (fs20.existsSync(candidate))
24638
24947
  return candidate;
24639
24948
  }
24640
24949
  return null;
@@ -24642,17 +24951,17 @@ function findBinInEnvPath(binName) {
24642
24951
  async function detectAvailableLinter(directory) {
24643
24952
  if (!directory)
24644
24953
  return null;
24645
- if (!fs19.existsSync(directory))
24954
+ if (!fs20.existsSync(directory))
24646
24955
  return null;
24647
24956
  const projectDir = directory;
24648
24957
  const isWindows = process.platform === "win32";
24649
- const biomeBin = isWindows ? path48.join(projectDir, "node_modules", ".bin", "biome.EXE") : path48.join(projectDir, "node_modules", ".bin", "biome");
24650
- const eslintBin = isWindows ? path48.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path48.join(projectDir, "node_modules", ".bin", "eslint");
24958
+ const biomeBin = isWindows ? path49.join(projectDir, "node_modules", ".bin", "biome.EXE") : path49.join(projectDir, "node_modules", ".bin", "biome");
24959
+ const eslintBin = isWindows ? path49.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path49.join(projectDir, "node_modules", ".bin", "eslint");
24651
24960
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
24652
24961
  if (localResult)
24653
24962
  return localResult;
24654
- const biomeAncestor = findBinInAncestors(path48.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
24655
- const eslintAncestor = findBinInAncestors(path48.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
24963
+ const biomeAncestor = findBinInAncestors(path49.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
24964
+ const eslintAncestor = findBinInAncestors(path49.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
24656
24965
  if (biomeAncestor || eslintAncestor) {
24657
24966
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
24658
24967
  }
@@ -24675,7 +24984,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24675
24984
  const result = await Promise.race([biomeExit, timeout]);
24676
24985
  if (result === "timeout") {
24677
24986
  biomeProc.kill();
24678
- } else if (biomeProc.exitCode === 0 && fs19.existsSync(biomeBin)) {
24987
+ } else if (biomeProc.exitCode === 0 && fs20.existsSync(biomeBin)) {
24679
24988
  return "biome";
24680
24989
  }
24681
24990
  } catch {}
@@ -24689,7 +24998,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24689
24998
  const result = await Promise.race([eslintExit, timeout]);
24690
24999
  if (result === "timeout") {
24691
25000
  eslintProc.kill();
24692
- } else if (eslintProc.exitCode === 0 && fs19.existsSync(eslintBin)) {
25001
+ } else if (eslintProc.exitCode === 0 && fs20.existsSync(eslintBin)) {
24693
25002
  return "eslint";
24694
25003
  }
24695
25004
  } catch {}
@@ -24865,8 +25174,8 @@ var _internals37 = {
24865
25174
  };
24866
25175
 
24867
25176
  // src/tools/secretscan.ts
24868
- import * as fs20 from "fs";
24869
- import * as path49 from "path";
25177
+ import * as fs21 from "fs";
25178
+ import * as path50 from "path";
24870
25179
  var MAX_FILE_PATH_LENGTH = 500;
24871
25180
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
24872
25181
  var MAX_FILES_SCANNED = 1000;
@@ -25093,11 +25402,11 @@ function isGlobOrPathPattern(pattern) {
25093
25402
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
25094
25403
  }
25095
25404
  function loadSecretScanIgnore(scanDir) {
25096
- const ignorePath = path49.join(scanDir, ".secretscanignore");
25405
+ const ignorePath = path50.join(scanDir, ".secretscanignore");
25097
25406
  try {
25098
- if (!fs20.existsSync(ignorePath))
25407
+ if (!fs21.existsSync(ignorePath))
25099
25408
  return [];
25100
- const content = fs20.readFileSync(ignorePath, "utf8");
25409
+ const content = fs21.readFileSync(ignorePath, "utf8");
25101
25410
  const patterns = [];
25102
25411
  for (const rawLine of content.split(/\r?\n/)) {
25103
25412
  const line = rawLine.trim();
@@ -25116,7 +25425,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
25116
25425
  if (exactNames.has(entry))
25117
25426
  return true;
25118
25427
  for (const pattern of globPatterns) {
25119
- if (path49.matchesGlob(relPath, pattern))
25428
+ if (path50.matchesGlob(relPath, pattern))
25120
25429
  return true;
25121
25430
  }
25122
25431
  return false;
@@ -25137,7 +25446,7 @@ function validateDirectoryInput(dir) {
25137
25446
  return null;
25138
25447
  }
25139
25448
  function isBinaryFile(filePath, buffer) {
25140
- const ext = path49.extname(filePath).toLowerCase();
25449
+ const ext = path50.extname(filePath).toLowerCase();
25141
25450
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
25142
25451
  return true;
25143
25452
  }
@@ -25212,11 +25521,11 @@ function createRedactedContext(line, findings) {
25212
25521
  result += line.slice(lastEnd);
25213
25522
  return result;
25214
25523
  }
25215
- var O_NOFOLLOW = process.platform !== "win32" ? fs20.constants.O_NOFOLLOW : undefined;
25524
+ var O_NOFOLLOW = process.platform !== "win32" ? fs21.constants.O_NOFOLLOW : undefined;
25216
25525
  function scanFileForSecrets(filePath) {
25217
25526
  const findings = [];
25218
25527
  try {
25219
- const lstat2 = fs20.lstatSync(filePath);
25528
+ const lstat2 = fs21.lstatSync(filePath);
25220
25529
  if (lstat2.isSymbolicLink()) {
25221
25530
  return findings;
25222
25531
  }
@@ -25225,14 +25534,14 @@ function scanFileForSecrets(filePath) {
25225
25534
  }
25226
25535
  let buffer;
25227
25536
  if (O_NOFOLLOW !== undefined) {
25228
- const fd = fs20.openSync(filePath, "r", O_NOFOLLOW);
25537
+ const fd = fs21.openSync(filePath, "r", O_NOFOLLOW);
25229
25538
  try {
25230
- buffer = fs20.readFileSync(fd);
25539
+ buffer = fs21.readFileSync(fd);
25231
25540
  } finally {
25232
- fs20.closeSync(fd);
25541
+ fs21.closeSync(fd);
25233
25542
  }
25234
25543
  } else {
25235
- buffer = fs20.readFileSync(filePath);
25544
+ buffer = fs21.readFileSync(filePath);
25236
25545
  }
25237
25546
  if (isBinaryFile(filePath, buffer)) {
25238
25547
  return findings;
@@ -25274,9 +25583,9 @@ function isSymlinkLoop(realPath, visited) {
25274
25583
  return false;
25275
25584
  }
25276
25585
  function isPathWithinScope(realPath, scanDir) {
25277
- const resolvedScanDir = path49.resolve(scanDir);
25278
- const resolvedRealPath = path49.resolve(realPath);
25279
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path49.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
25586
+ const resolvedScanDir = path50.resolve(scanDir);
25587
+ const resolvedRealPath = path50.resolve(realPath);
25588
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path50.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
25280
25589
  }
25281
25590
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
25282
25591
  skippedDirs: 0,
@@ -25287,7 +25596,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
25287
25596
  const files = [];
25288
25597
  let entries;
25289
25598
  try {
25290
- entries = fs20.readdirSync(dir);
25599
+ entries = fs21.readdirSync(dir);
25291
25600
  } catch {
25292
25601
  stats.fileErrors++;
25293
25602
  return files;
@@ -25302,15 +25611,15 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
25302
25611
  return a.localeCompare(b);
25303
25612
  });
25304
25613
  for (const entry of entries) {
25305
- const fullPath = path49.join(dir, entry);
25306
- const relPath = path49.relative(scanDir, fullPath).replace(/\\/g, "/");
25614
+ const fullPath = path50.join(dir, entry);
25615
+ const relPath = path50.relative(scanDir, fullPath).replace(/\\/g, "/");
25307
25616
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
25308
25617
  stats.skippedDirs++;
25309
25618
  continue;
25310
25619
  }
25311
25620
  let lstat2;
25312
25621
  try {
25313
- lstat2 = fs20.lstatSync(fullPath);
25622
+ lstat2 = fs21.lstatSync(fullPath);
25314
25623
  } catch {
25315
25624
  stats.fileErrors++;
25316
25625
  continue;
@@ -25322,7 +25631,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
25322
25631
  if (lstat2.isDirectory()) {
25323
25632
  let realPath;
25324
25633
  try {
25325
- realPath = fs20.realpathSync(fullPath);
25634
+ realPath = fs21.realpathSync(fullPath);
25326
25635
  } catch {
25327
25636
  stats.fileErrors++;
25328
25637
  continue;
@@ -25338,7 +25647,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
25338
25647
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
25339
25648
  files.push(...subFiles);
25340
25649
  } else if (lstat2.isFile()) {
25341
- const ext = path49.extname(fullPath).toLowerCase();
25650
+ const ext = path50.extname(fullPath).toLowerCase();
25342
25651
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
25343
25652
  files.push(fullPath);
25344
25653
  } else {
@@ -25404,15 +25713,15 @@ var secretscan = createSwarmTool({
25404
25713
  }
25405
25714
  }
25406
25715
  try {
25407
- const _scanDirRaw = path49.resolve(directory);
25716
+ const _scanDirRaw = path50.resolve(directory);
25408
25717
  const scanDir = (() => {
25409
25718
  try {
25410
- return fs20.realpathSync(_scanDirRaw);
25719
+ return fs21.realpathSync(_scanDirRaw);
25411
25720
  } catch {
25412
25721
  return _scanDirRaw;
25413
25722
  }
25414
25723
  })();
25415
- if (!fs20.existsSync(scanDir)) {
25724
+ if (!fs21.existsSync(scanDir)) {
25416
25725
  const errorResult = {
25417
25726
  error: "directory not found",
25418
25727
  scan_dir: directory,
@@ -25423,7 +25732,7 @@ var secretscan = createSwarmTool({
25423
25732
  };
25424
25733
  return JSON.stringify(errorResult, null, 2);
25425
25734
  }
25426
- const dirStat = fs20.statSync(scanDir);
25735
+ const dirStat = fs21.statSync(scanDir);
25427
25736
  if (!dirStat.isDirectory()) {
25428
25737
  const errorResult = {
25429
25738
  error: "target must be a directory, not a file",
@@ -25474,7 +25783,7 @@ var secretscan = createSwarmTool({
25474
25783
  break;
25475
25784
  const fileFindings = scanFileForSecrets(filePath);
25476
25785
  try {
25477
- const stat6 = fs20.statSync(filePath);
25786
+ const stat6 = fs21.statSync(filePath);
25478
25787
  if (stat6.size > MAX_FILE_SIZE_BYTES) {
25479
25788
  skippedFiles++;
25480
25789
  continue;
@@ -25566,12 +25875,12 @@ var _internals38 = {
25566
25875
  };
25567
25876
 
25568
25877
  // src/tools/test-runner.ts
25569
- import * as fs24 from "fs";
25570
- import * as path53 from "path";
25878
+ import * as fs25 from "fs";
25879
+ import * as path54 from "path";
25571
25880
 
25572
25881
  // src/test-impact/analyzer.ts
25573
- import fs21 from "fs";
25574
- import path50 from "path";
25882
+ import fs22 from "fs";
25883
+ import path51 from "path";
25575
25884
  var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
25576
25885
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
25577
25886
  var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
@@ -25598,7 +25907,7 @@ function sharedTrailingSegments(a, b) {
25598
25907
  function isCacheStale(impactMap, generatedAtMs) {
25599
25908
  for (const sourcePath of Object.keys(impactMap)) {
25600
25909
  try {
25601
- const stat6 = fs21.statSync(sourcePath);
25910
+ const stat6 = fs22.statSync(sourcePath);
25602
25911
  if (stat6.mtimeMs > generatedAtMs) {
25603
25912
  return true;
25604
25913
  }
@@ -25612,15 +25921,15 @@ function resolveRelativeImport(fromDir, importPath) {
25612
25921
  if (!importPath.startsWith(".")) {
25613
25922
  return null;
25614
25923
  }
25615
- const resolved = path50.resolve(fromDir, importPath);
25616
- if (path50.extname(resolved)) {
25617
- if (fs21.existsSync(resolved) && fs21.statSync(resolved).isFile()) {
25924
+ const resolved = path51.resolve(fromDir, importPath);
25925
+ if (path51.extname(resolved)) {
25926
+ if (fs22.existsSync(resolved) && fs22.statSync(resolved).isFile()) {
25618
25927
  return normalizePath2(resolved);
25619
25928
  }
25620
25929
  } else {
25621
25930
  for (const ext of EXTENSIONS_TO_TRY) {
25622
25931
  const withExt = resolved + ext;
25623
- if (fs21.existsSync(withExt) && fs21.statSync(withExt).isFile()) {
25932
+ if (fs22.existsSync(withExt) && fs22.statSync(withExt).isFile()) {
25624
25933
  return normalizePath2(withExt);
25625
25934
  }
25626
25935
  }
@@ -25633,30 +25942,30 @@ function resolvePythonImport(fromDir, module) {
25633
25942
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
25634
25943
  let baseDir = fromDir;
25635
25944
  for (let i = 1;i < leadingDots; i++) {
25636
- baseDir = path50.dirname(baseDir);
25945
+ baseDir = path51.dirname(baseDir);
25637
25946
  }
25638
25947
  const rest = module.slice(leadingDots);
25639
25948
  if (rest.length === 0) {
25640
- const initPath = path50.join(baseDir, "__init__.py");
25641
- if (fs21.existsSync(initPath) && fs21.statSync(initPath).isFile()) {
25949
+ const initPath = path51.join(baseDir, "__init__.py");
25950
+ if (fs22.existsSync(initPath) && fs22.statSync(initPath).isFile()) {
25642
25951
  return normalizePath2(initPath);
25643
25952
  }
25644
25953
  return null;
25645
25954
  }
25646
- const subpath = rest.replace(/\./g, path50.sep);
25955
+ const subpath = rest.replace(/\./g, path51.sep);
25647
25956
  const candidates = [
25648
- `${path50.join(baseDir, subpath)}.py`,
25649
- path50.join(baseDir, subpath, "__init__.py")
25957
+ `${path51.join(baseDir, subpath)}.py`,
25958
+ path51.join(baseDir, subpath, "__init__.py")
25650
25959
  ];
25651
25960
  for (const c of candidates) {
25652
- if (fs21.existsSync(c) && fs21.statSync(c).isFile())
25961
+ if (fs22.existsSync(c) && fs22.statSync(c).isFile())
25653
25962
  return normalizePath2(c);
25654
25963
  }
25655
25964
  return null;
25656
25965
  }
25657
25966
  var goModuleCache = new Map;
25658
25967
  function findGoModule(fromDir) {
25659
- const resolved = path50.resolve(fromDir);
25968
+ const resolved = path51.resolve(fromDir);
25660
25969
  let cur = resolved;
25661
25970
  const walked = [];
25662
25971
  for (let i = 0;i < 16; i++) {
@@ -25668,8 +25977,8 @@ function findGoModule(fromDir) {
25668
25977
  }
25669
25978
  walked.push(cur);
25670
25979
  try {
25671
- const goMod = path50.join(cur, "go.mod");
25672
- const content = fs21.readFileSync(goMod, "utf-8");
25980
+ const goMod = path51.join(cur, "go.mod");
25981
+ const content = fs22.readFileSync(goMod, "utf-8");
25673
25982
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
25674
25983
  if (moduleMatch) {
25675
25984
  const result = { moduleRoot: cur, modulePath: moduleMatch[1] };
@@ -25679,10 +25988,10 @@ function findGoModule(fromDir) {
25679
25988
  }
25680
25989
  } catch {}
25681
25990
  try {
25682
- fs21.accessSync(path50.join(cur, ".git"));
25991
+ fs22.accessSync(path51.join(cur, ".git"));
25683
25992
  break;
25684
25993
  } catch {}
25685
- const parent = path50.dirname(cur);
25994
+ const parent = path51.dirname(cur);
25686
25995
  if (parent === cur)
25687
25996
  break;
25688
25997
  cur = parent;
@@ -25694,20 +26003,20 @@ function findGoModule(fromDir) {
25694
26003
  function resolveGoImport(fromDir, importPath) {
25695
26004
  let dir = null;
25696
26005
  if (importPath.startsWith(".")) {
25697
- dir = path50.resolve(fromDir, importPath);
26006
+ dir = path51.resolve(fromDir, importPath);
25698
26007
  } else {
25699
26008
  const mod = findGoModule(fromDir);
25700
26009
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
25701
26010
  const subpath = importPath.slice(mod.modulePath.length);
25702
- dir = path50.join(mod.moduleRoot, subpath);
26011
+ dir = path51.join(mod.moduleRoot, subpath);
25703
26012
  }
25704
26013
  }
25705
26014
  if (dir === null)
25706
26015
  return [];
25707
- if (!fs21.existsSync(dir) || !fs21.statSync(dir).isDirectory())
26016
+ if (!fs22.existsSync(dir) || !fs22.statSync(dir).isDirectory())
25708
26017
  return [];
25709
26018
  try {
25710
- return fs21.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path50.join(dir, f)));
26019
+ return fs22.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path51.join(dir, f)));
25711
26020
  } catch {
25712
26021
  return [];
25713
26022
  }
@@ -25727,13 +26036,13 @@ function findTestFilesSync(cwd) {
25727
26036
  function walk(dir, visitedInodes) {
25728
26037
  let entries;
25729
26038
  try {
25730
- entries = fs21.readdirSync(dir, { withFileTypes: true });
26039
+ entries = fs22.readdirSync(dir, { withFileTypes: true });
25731
26040
  } catch {
25732
26041
  return;
25733
26042
  }
25734
26043
  let dirInode;
25735
26044
  try {
25736
- dirInode = fs21.statSync(dir).ino;
26045
+ dirInode = fs22.statSync(dir).ino;
25737
26046
  } catch {
25738
26047
  return;
25739
26048
  }
@@ -25746,15 +26055,15 @@ function findTestFilesSync(cwd) {
25746
26055
  for (const entry of entries) {
25747
26056
  if (entry.isDirectory()) {
25748
26057
  if (!skipDirs.has(entry.name)) {
25749
- walk(path50.join(dir, entry.name), visitedInodes);
26058
+ walk(path51.join(dir, entry.name), visitedInodes);
25750
26059
  }
25751
26060
  } else if (entry.isFile()) {
25752
26061
  const name = entry.name;
25753
26062
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
25754
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path50.sep}tests${path50.sep}`) && name.endsWith(".py");
26063
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path51.sep}tests${path51.sep}`) && name.endsWith(".py");
25755
26064
  const isGoTest = /.+_test\.go$/.test(name);
25756
26065
  if (isTsTest || isPyTest || isGoTest) {
25757
- testFiles.push(normalizePath2(path50.join(dir, entry.name)));
26066
+ testFiles.push(normalizePath2(path51.join(dir, entry.name)));
25758
26067
  }
25759
26068
  }
25760
26069
  }
@@ -25779,8 +26088,8 @@ function extractImports(content) {
25779
26088
  ];
25780
26089
  }
25781
26090
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
25782
- const ext = path50.extname(testFile).toLowerCase();
25783
- const testDir = path50.dirname(testFile);
26091
+ const ext = path51.extname(testFile).toLowerCase();
26092
+ const testDir = path51.dirname(testFile);
25784
26093
  function addEdge(source) {
25785
26094
  if (!impactMap[source])
25786
26095
  impactMap[source] = [];
@@ -25822,7 +26131,7 @@ async function buildImpactMapInternal(cwd) {
25822
26131
  for (const testFile of testFiles) {
25823
26132
  let content;
25824
26133
  try {
25825
- content = fs21.readFileSync(testFile, "utf-8");
26134
+ content = fs22.readFileSync(testFile, "utf-8");
25826
26135
  } catch {
25827
26136
  continue;
25828
26137
  }
@@ -25853,10 +26162,10 @@ async function buildImpactMap(cwd) {
25853
26162
  return impactMap;
25854
26163
  }
25855
26164
  async function loadImpactMap(cwd, options) {
25856
- const cachePath = path50.join(cwd, ".swarm", "cache", "impact-map.json");
25857
- if (fs21.existsSync(cachePath)) {
26165
+ const cachePath = path51.join(cwd, ".swarm", "cache", "impact-map.json");
26166
+ if (fs22.existsSync(cachePath)) {
25858
26167
  try {
25859
- const content = fs21.readFileSync(cachePath, "utf-8");
26168
+ const content = fs22.readFileSync(cachePath, "utf-8");
25860
26169
  const data = JSON.parse(content);
25861
26170
  if (data.map !== null && typeof data.map === "object" && !Array.isArray(data.map)) {
25862
26171
  const map = data.map;
@@ -25886,21 +26195,21 @@ async function loadImpactMap(cwd, options) {
25886
26195
  return _internals39.buildImpactMap(cwd);
25887
26196
  }
25888
26197
  async function saveImpactMap(cwd, impactMap) {
25889
- if (!path50.isAbsolute(cwd)) {
26198
+ if (!path51.isAbsolute(cwd)) {
25890
26199
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
25891
26200
  }
25892
26201
  _internals39.validateProjectRoot(cwd);
25893
- const cacheDir2 = path50.join(cwd, ".swarm", "cache");
25894
- const cachePath = path50.join(cacheDir2, "impact-map.json");
25895
- if (!fs21.existsSync(cacheDir2)) {
25896
- fs21.mkdirSync(cacheDir2, { recursive: true });
26202
+ const cacheDir2 = path51.join(cwd, ".swarm", "cache");
26203
+ const cachePath = path51.join(cacheDir2, "impact-map.json");
26204
+ if (!fs22.existsSync(cacheDir2)) {
26205
+ fs22.mkdirSync(cacheDir2, { recursive: true });
25897
26206
  }
25898
26207
  const data = {
25899
26208
  generatedAt: new Date().toISOString(),
25900
26209
  fileCount: Object.keys(impactMap).length,
25901
26210
  map: impactMap
25902
26211
  };
25903
- fs21.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
26212
+ fs22.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
25904
26213
  }
25905
26214
  async function analyzeImpact(changedFiles, cwd, budget) {
25906
26215
  if (!Array.isArray(changedFiles)) {
@@ -25923,7 +26232,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
25923
26232
  budgetExceeded = true;
25924
26233
  break;
25925
26234
  }
25926
- const normalizedChanged = normalizePath2(path50.resolve(changedFile));
26235
+ const normalizedChanged = normalizePath2(path51.resolve(changedFile));
25927
26236
  const tests = impactMap[normalizedChanged];
25928
26237
  if (tests && tests.length > 0) {
25929
26238
  for (const test of tests) {
@@ -25937,13 +26246,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
25937
26246
  if (budgetExceeded)
25938
26247
  break;
25939
26248
  } else {
25940
- const changedDir = normalizePath2(path50.dirname(normalizedChanged));
25941
- const changedInputDir = normalizePath2(path50.dirname(changedFile));
26249
+ const changedDir = normalizePath2(path51.dirname(normalizedChanged));
26250
+ const changedInputDir = normalizePath2(path51.dirname(changedFile));
25942
26251
  const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
25943
26252
  return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
25944
26253
  }).sort(([sourceA], [sourceB]) => {
25945
- const sourceDirA = normalizePath2(path50.dirname(sourceA));
25946
- const sourceDirB = normalizePath2(path50.dirname(sourceB));
26254
+ const sourceDirA = normalizePath2(path51.dirname(sourceA));
26255
+ const sourceDirB = normalizePath2(path51.dirname(sourceB));
25947
26256
  const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
25948
26257
  const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
25949
26258
  if (exactA !== exactB)
@@ -26269,8 +26578,8 @@ function detectFlakyTests(allHistory) {
26269
26578
  }
26270
26579
 
26271
26580
  // src/test-impact/history-store.ts
26272
- import fs22 from "fs";
26273
- import path51 from "path";
26581
+ import fs23 from "fs";
26582
+ import path52 from "path";
26274
26583
  var MAX_HISTORY_PER_TEST = 20;
26275
26584
  var MAX_ERROR_LENGTH = 500;
26276
26585
  var MAX_STACK_LENGTH = 200;
@@ -26282,10 +26591,10 @@ function getHistoryPath(workingDir) {
26282
26591
  if (!workingDir) {
26283
26592
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
26284
26593
  }
26285
- if (!path51.isAbsolute(workingDir)) {
26594
+ if (!path52.isAbsolute(workingDir)) {
26286
26595
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
26287
26596
  }
26288
- return path51.join(workingDir, ".swarm", "cache", "test-history.jsonl");
26597
+ return path52.join(workingDir, ".swarm", "cache", "test-history.jsonl");
26289
26598
  }
26290
26599
  function sanitizeErrorMessage(errorMessage) {
26291
26600
  if (errorMessage === undefined) {
@@ -26377,10 +26686,10 @@ function batchAppendTestRuns(records, workingDir) {
26377
26686
  }
26378
26687
  }
26379
26688
  const historyPath = getHistoryPath(workingDir);
26380
- const historyDir = path51.dirname(historyPath);
26689
+ const historyDir = path52.dirname(historyPath);
26381
26690
  _internals40.validateProjectRoot(workingDir);
26382
- if (!fs22.existsSync(historyDir)) {
26383
- fs22.mkdirSync(historyDir, { recursive: true });
26691
+ if (!fs23.existsSync(historyDir)) {
26692
+ fs23.mkdirSync(historyDir, { recursive: true });
26384
26693
  }
26385
26694
  withHistoryWriteLock(historyPath, () => {
26386
26695
  const existingRecords = readAllRecords(historyPath);
@@ -26414,13 +26723,13 @@ function batchAppendTestRuns(records, workingDir) {
26414
26723
  `)}
26415
26724
  `;
26416
26725
  const tempPath = `${historyPath}.tmp`;
26417
- fs22.writeFileSync(tempPath, content, "utf-8");
26418
- fs22.renameSync(tempPath, historyPath);
26726
+ fs23.writeFileSync(tempPath, content, "utf-8");
26727
+ fs23.renameSync(tempPath, historyPath);
26419
26728
  } catch (err) {
26420
26729
  try {
26421
26730
  const tempPath = `${historyPath}.tmp`;
26422
- if (fs22.existsSync(tempPath)) {
26423
- fs22.unlinkSync(tempPath);
26731
+ if (fs23.existsSync(tempPath)) {
26732
+ fs23.unlinkSync(tempPath);
26424
26733
  }
26425
26734
  } catch {}
26426
26735
  throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
@@ -26432,7 +26741,7 @@ function withHistoryWriteLock(historyPath, fn) {
26432
26741
  const deadline = Date.now() + HISTORY_WRITE_LOCK_TIMEOUT_MS;
26433
26742
  while (true) {
26434
26743
  try {
26435
- fs22.mkdirSync(lockPath);
26744
+ fs23.mkdirSync(lockPath);
26436
26745
  break;
26437
26746
  } catch (error2) {
26438
26747
  const code = error2 instanceof Error && "code" in error2 ? error2.code : undefined;
@@ -26443,9 +26752,9 @@ function withHistoryWriteLock(historyPath, fn) {
26443
26752
  throw new Error(`Timed out waiting for test history lock: ${historyPath}`);
26444
26753
  }
26445
26754
  try {
26446
- const lockStat = fs22.statSync(lockPath);
26755
+ const lockStat = fs23.statSync(lockPath);
26447
26756
  if (Date.now() - lockStat.mtimeMs >= HISTORY_WRITE_LOCK_STALE_MS) {
26448
- fs22.rmSync(lockPath, { recursive: true, force: true });
26757
+ fs23.rmSync(lockPath, { recursive: true, force: true });
26449
26758
  continue;
26450
26759
  }
26451
26760
  } catch {}
@@ -26460,7 +26769,7 @@ function withHistoryWriteLock(historyPath, fn) {
26460
26769
  return fn();
26461
26770
  } finally {
26462
26771
  try {
26463
- fs22.rmSync(lockPath, { recursive: true, force: true });
26772
+ fs23.rmSync(lockPath, { recursive: true, force: true });
26464
26773
  } catch {}
26465
26774
  }
26466
26775
  function sleepSync(ms) {
@@ -26469,11 +26778,11 @@ function withHistoryWriteLock(historyPath, fn) {
26469
26778
  }
26470
26779
  }
26471
26780
  function readAllRecords(historyPath) {
26472
- if (!fs22.existsSync(historyPath)) {
26781
+ if (!fs23.existsSync(historyPath)) {
26473
26782
  return [];
26474
26783
  }
26475
26784
  try {
26476
- const content = fs22.readFileSync(historyPath, "utf-8");
26785
+ const content = fs23.readFileSync(historyPath, "utf-8");
26477
26786
  const lines = content.split(`
26478
26787
  `);
26479
26788
  const records = [];
@@ -26506,8 +26815,8 @@ var _internals40 = {
26506
26815
  };
26507
26816
 
26508
26817
  // src/tools/resolve-working-directory.ts
26509
- import * as fs23 from "fs";
26510
- import * as path52 from "path";
26818
+ import * as fs24 from "fs";
26819
+ import * as path53 from "path";
26511
26820
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26512
26821
  if (workingDirectory == null || workingDirectory === "") {
26513
26822
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
@@ -26539,18 +26848,18 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26539
26848
  };
26540
26849
  }
26541
26850
  }
26542
- const rawPathParts = workingDirectory.split(path52.sep);
26851
+ const rawPathParts = workingDirectory.split(path53.sep);
26543
26852
  if (rawPathParts.includes("..")) {
26544
26853
  return {
26545
26854
  success: false,
26546
26855
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
26547
26856
  };
26548
26857
  }
26549
- const normalizedDir = path52.normalize(workingDirectory);
26550
- const resolvedDir = path52.resolve(normalizedDir);
26858
+ const normalizedDir = path53.normalize(workingDirectory);
26859
+ const resolvedDir = path53.resolve(normalizedDir);
26551
26860
  let statResult;
26552
26861
  try {
26553
- statResult = fs23.statSync(resolvedDir);
26862
+ statResult = fs24.statSync(resolvedDir);
26554
26863
  } catch {
26555
26864
  return {
26556
26865
  success: false,
@@ -26566,16 +26875,16 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26566
26875
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
26567
26876
  return { success: true, directory: resolvedDir };
26568
26877
  }
26569
- const resolvedFallback = path52.resolve(fallbackDirectory);
26878
+ const resolvedFallback = path53.resolve(fallbackDirectory);
26570
26879
  let fallbackExists = false;
26571
26880
  try {
26572
- fs23.statSync(resolvedFallback);
26881
+ fs24.statSync(resolvedFallback);
26573
26882
  fallbackExists = true;
26574
26883
  } catch {
26575
26884
  fallbackExists = false;
26576
26885
  }
26577
26886
  if (fallbackExists) {
26578
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path52.sep);
26887
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path53.sep);
26579
26888
  if (isSubdirectory) {
26580
26889
  return {
26581
26890
  success: false,
@@ -26598,7 +26907,7 @@ async function estimateFanOut(sourceFiles, cwd) {
26598
26907
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
26599
26908
  const uniqueTestFiles = new Set;
26600
26909
  for (const sourceFile of sourceFiles) {
26601
- const resolvedPath = path53.resolve(cwd, sourceFile);
26910
+ const resolvedPath = path54.resolve(cwd, sourceFile);
26602
26911
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
26603
26912
  const testFiles = impactMap[normalizedPath];
26604
26913
  if (testFiles) {
@@ -26683,19 +26992,19 @@ function hasDevDependency(devDeps, ...patterns) {
26683
26992
  return hasPackageJsonDependency(devDeps, ...patterns);
26684
26993
  }
26685
26994
  function detectGoTest(cwd) {
26686
- return fs24.existsSync(path53.join(cwd, "go.mod")) && isCommandAvailable("go");
26995
+ return fs25.existsSync(path54.join(cwd, "go.mod")) && isCommandAvailable("go");
26687
26996
  }
26688
26997
  function detectJavaMaven(cwd) {
26689
- return fs24.existsSync(path53.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
26998
+ return fs25.existsSync(path54.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
26690
26999
  }
26691
27000
  function detectGradle(cwd) {
26692
- const hasBuildFile = fs24.existsSync(path53.join(cwd, "build.gradle")) || fs24.existsSync(path53.join(cwd, "build.gradle.kts"));
26693
- const hasGradlew = fs24.existsSync(path53.join(cwd, "gradlew")) || fs24.existsSync(path53.join(cwd, "gradlew.bat"));
27001
+ const hasBuildFile = fs25.existsSync(path54.join(cwd, "build.gradle")) || fs25.existsSync(path54.join(cwd, "build.gradle.kts"));
27002
+ const hasGradlew = fs25.existsSync(path54.join(cwd, "gradlew")) || fs25.existsSync(path54.join(cwd, "gradlew.bat"));
26694
27003
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
26695
27004
  }
26696
27005
  function detectDotnetTest(cwd) {
26697
27006
  try {
26698
- const files = fs24.readdirSync(cwd);
27007
+ const files = fs25.readdirSync(cwd);
26699
27008
  const hasCsproj = files.some((f) => f.endsWith(".csproj"));
26700
27009
  return hasCsproj && isCommandAvailable("dotnet");
26701
27010
  } catch {
@@ -26703,25 +27012,25 @@ function detectDotnetTest(cwd) {
26703
27012
  }
26704
27013
  }
26705
27014
  function detectCTest(cwd) {
26706
- const hasSource = fs24.existsSync(path53.join(cwd, "CMakeLists.txt"));
26707
- const hasBuildCache = fs24.existsSync(path53.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path53.join(cwd, "build", "CMakeCache.txt"));
27015
+ const hasSource = fs25.existsSync(path54.join(cwd, "CMakeLists.txt"));
27016
+ const hasBuildCache = fs25.existsSync(path54.join(cwd, "CMakeCache.txt")) || fs25.existsSync(path54.join(cwd, "build", "CMakeCache.txt"));
26708
27017
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
26709
27018
  }
26710
27019
  function detectSwiftTest(cwd) {
26711
- return fs24.existsSync(path53.join(cwd, "Package.swift")) && isCommandAvailable("swift");
27020
+ return fs25.existsSync(path54.join(cwd, "Package.swift")) && isCommandAvailable("swift");
26712
27021
  }
26713
27022
  function detectDartTest(cwd) {
26714
- return fs24.existsSync(path53.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
27023
+ return fs25.existsSync(path54.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
26715
27024
  }
26716
27025
  function detectRSpec(cwd) {
26717
- const hasRSpecFile = fs24.existsSync(path53.join(cwd, ".rspec"));
26718
- const hasGemfile = fs24.existsSync(path53.join(cwd, "Gemfile"));
26719
- const hasSpecDir = fs24.existsSync(path53.join(cwd, "spec"));
27026
+ const hasRSpecFile = fs25.existsSync(path54.join(cwd, ".rspec"));
27027
+ const hasGemfile = fs25.existsSync(path54.join(cwd, "Gemfile"));
27028
+ const hasSpecDir = fs25.existsSync(path54.join(cwd, "spec"));
26720
27029
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
26721
27030
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
26722
27031
  }
26723
27032
  function detectMinitest(cwd) {
26724
- return fs24.existsSync(path53.join(cwd, "test")) && (fs24.existsSync(path53.join(cwd, "Gemfile")) || fs24.existsSync(path53.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
27033
+ return fs25.existsSync(path54.join(cwd, "test")) && (fs25.existsSync(path54.join(cwd, "Gemfile")) || fs25.existsSync(path54.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
26725
27034
  }
26726
27035
  var DISPATCH_FRAMEWORK_MAP = {
26727
27036
  bun: "bun",
@@ -26806,9 +27115,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
26806
27115
  async function detectTestFramework(cwd) {
26807
27116
  const baseDir = cwd;
26808
27117
  try {
26809
- const packageJsonPath = path53.join(baseDir, "package.json");
26810
- if (fs24.existsSync(packageJsonPath)) {
26811
- const content = fs24.readFileSync(packageJsonPath, "utf-8");
27118
+ const packageJsonPath = path54.join(baseDir, "package.json");
27119
+ if (fs25.existsSync(packageJsonPath)) {
27120
+ const content = fs25.readFileSync(packageJsonPath, "utf-8");
26812
27121
  const pkg = JSON.parse(content);
26813
27122
  const _deps = pkg.dependencies || {};
26814
27123
  const devDeps = pkg.devDependencies || {};
@@ -26827,38 +27136,38 @@ async function detectTestFramework(cwd) {
26827
27136
  return "jest";
26828
27137
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
26829
27138
  return "mocha";
26830
- if (fs24.existsSync(path53.join(baseDir, "bun.lockb")) || fs24.existsSync(path53.join(baseDir, "bun.lock"))) {
27139
+ if (fs25.existsSync(path54.join(baseDir, "bun.lockb")) || fs25.existsSync(path54.join(baseDir, "bun.lock"))) {
26831
27140
  if (scripts.test?.includes("bun"))
26832
27141
  return "bun";
26833
27142
  }
26834
27143
  }
26835
27144
  } catch {}
26836
27145
  try {
26837
- const pyprojectTomlPath = path53.join(baseDir, "pyproject.toml");
26838
- const setupCfgPath = path53.join(baseDir, "setup.cfg");
26839
- const requirementsTxtPath = path53.join(baseDir, "requirements.txt");
26840
- if (fs24.existsSync(pyprojectTomlPath)) {
26841
- const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
27146
+ const pyprojectTomlPath = path54.join(baseDir, "pyproject.toml");
27147
+ const setupCfgPath = path54.join(baseDir, "setup.cfg");
27148
+ const requirementsTxtPath = path54.join(baseDir, "requirements.txt");
27149
+ if (fs25.existsSync(pyprojectTomlPath)) {
27150
+ const content = fs25.readFileSync(pyprojectTomlPath, "utf-8");
26842
27151
  if (content.includes("[tool.pytest"))
26843
27152
  return "pytest";
26844
27153
  if (content.includes("pytest"))
26845
27154
  return "pytest";
26846
27155
  }
26847
- if (fs24.existsSync(setupCfgPath)) {
26848
- const content = fs24.readFileSync(setupCfgPath, "utf-8");
27156
+ if (fs25.existsSync(setupCfgPath)) {
27157
+ const content = fs25.readFileSync(setupCfgPath, "utf-8");
26849
27158
  if (content.includes("[pytest]"))
26850
27159
  return "pytest";
26851
27160
  }
26852
- if (fs24.existsSync(requirementsTxtPath)) {
26853
- const content = fs24.readFileSync(requirementsTxtPath, "utf-8");
27161
+ if (fs25.existsSync(requirementsTxtPath)) {
27162
+ const content = fs25.readFileSync(requirementsTxtPath, "utf-8");
26854
27163
  if (content.includes("pytest"))
26855
27164
  return "pytest";
26856
27165
  }
26857
27166
  } catch {}
26858
27167
  try {
26859
- const cargoTomlPath = path53.join(baseDir, "Cargo.toml");
26860
- if (fs24.existsSync(cargoTomlPath)) {
26861
- const content = fs24.readFileSync(cargoTomlPath, "utf-8");
27168
+ const cargoTomlPath = path54.join(baseDir, "Cargo.toml");
27169
+ if (fs25.existsSync(cargoTomlPath)) {
27170
+ const content = fs25.readFileSync(cargoTomlPath, "utf-8");
26862
27171
  if (content.includes("[dev-dependencies]")) {
26863
27172
  if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
26864
27173
  return "cargo";
@@ -26867,10 +27176,10 @@ async function detectTestFramework(cwd) {
26867
27176
  }
26868
27177
  } catch {}
26869
27178
  try {
26870
- const pesterConfigPath = path53.join(baseDir, "pester.config.ps1");
26871
- const pesterConfigJsonPath = path53.join(baseDir, "pester.config.ps1.json");
26872
- const pesterPs1Path = path53.join(baseDir, "tests.ps1");
26873
- if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
27179
+ const pesterConfigPath = path54.join(baseDir, "pester.config.ps1");
27180
+ const pesterConfigJsonPath = path54.join(baseDir, "pester.config.ps1.json");
27181
+ const pesterPs1Path = path54.join(baseDir, "tests.ps1");
27182
+ if (fs25.existsSync(pesterConfigPath) || fs25.existsSync(pesterConfigJsonPath) || fs25.existsSync(pesterPs1Path)) {
26874
27183
  return "pester";
26875
27184
  }
26876
27185
  } catch {}
@@ -26912,12 +27221,12 @@ function isTestDirectoryPath(normalizedPath) {
26912
27221
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
26913
27222
  }
26914
27223
  function resolveWorkspacePath(file, workingDir) {
26915
- return path53.isAbsolute(file) ? path53.resolve(file) : path53.resolve(workingDir, file);
27224
+ return path54.isAbsolute(file) ? path54.resolve(file) : path54.resolve(workingDir, file);
26916
27225
  }
26917
27226
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
26918
27227
  if (!preferRelative)
26919
27228
  return absolutePath;
26920
- return path53.relative(workingDir, absolutePath);
27229
+ return path54.relative(workingDir, absolutePath);
26921
27230
  }
26922
27231
  function dedupePush(target, value) {
26923
27232
  if (!target.includes(value)) {
@@ -26954,18 +27263,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
26954
27263
  }
26955
27264
  }
26956
27265
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
26957
- const relativeDir = path53.dirname(relativePath);
27266
+ const relativeDir = path54.dirname(relativePath);
26958
27267
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
26959
27268
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
26960
- const rootDir = path53.join(workingDir, dirName);
26961
- return nestedRelativeDir ? [rootDir, path53.join(rootDir, nestedRelativeDir)] : [rootDir];
27269
+ const rootDir = path54.join(workingDir, dirName);
27270
+ return nestedRelativeDir ? [rootDir, path54.join(rootDir, nestedRelativeDir)] : [rootDir];
26962
27271
  });
26963
27272
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
26964
27273
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
26965
- directories.push(path53.join(workingDir, "src/test/java", path53.dirname(normalizedRelativePath.slice("src/main/java/".length))));
27274
+ directories.push(path54.join(workingDir, "src/test/java", path54.dirname(normalizedRelativePath.slice("src/main/java/".length))));
26966
27275
  }
26967
27276
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
26968
- directories.push(path53.join(workingDir, "src/test/kotlin", path53.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
27277
+ directories.push(path54.join(workingDir, "src/test/kotlin", path54.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
26969
27278
  }
26970
27279
  return [...new Set(directories)];
26971
27280
  }
@@ -26973,19 +27282,19 @@ function hasCompoundTestExtension(filename) {
26973
27282
  const lower = filename.toLowerCase();
26974
27283
  return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
26975
27284
  }
26976
- function isLanguageSpecificTestFile(basename9) {
26977
- const lower = basename9.toLowerCase();
27285
+ function isLanguageSpecificTestFile(basename10) {
27286
+ const lower = basename10.toLowerCase();
26978
27287
  if (lower.endsWith("_test.go"))
26979
27288
  return true;
26980
27289
  if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
26981
27290
  return true;
26982
27291
  if (lower.endsWith("_spec.rb"))
26983
27292
  return true;
26984
- if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename9) || basename9.endsWith("Test.java") || basename9.endsWith("Tests.java") || lower.endsWith("it.java")))
27293
+ if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename10) || basename10.endsWith("Test.java") || basename10.endsWith("Tests.java") || lower.endsWith("it.java")))
26985
27294
  return true;
26986
27295
  if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
26987
27296
  return true;
26988
- if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename9) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
27297
+ if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename10) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
26989
27298
  return true;
26990
27299
  if (lower.endsWith(".tests.ps1"))
26991
27300
  return true;
@@ -26993,23 +27302,23 @@ function isLanguageSpecificTestFile(basename9) {
26993
27302
  }
26994
27303
  function isConventionTestFilePath(filePath) {
26995
27304
  const normalizedPath = filePath.replace(/\\/g, "/");
26996
- const basename9 = path53.basename(filePath);
26997
- return hasCompoundTestExtension(basename9) || basename9.includes(".spec.") || basename9.includes(".test.") || isLanguageSpecificTestFile(basename9) || isTestDirectoryPath(normalizedPath);
27305
+ const basename10 = path54.basename(filePath);
27306
+ return hasCompoundTestExtension(basename10) || basename10.includes(".spec.") || basename10.includes(".test.") || isLanguageSpecificTestFile(basename10) || isTestDirectoryPath(normalizedPath);
26998
27307
  }
26999
27308
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
27000
27309
  const testFiles = [];
27001
27310
  for (const file of sourceFiles) {
27002
27311
  const absoluteFile = resolveWorkspacePath(file, workingDir);
27003
- const relativeFile = path53.relative(workingDir, absoluteFile);
27004
- const basename9 = path53.basename(absoluteFile);
27005
- const dirname25 = path53.dirname(absoluteFile);
27006
- const preferRelativeOutput = !path53.isAbsolute(file);
27312
+ const relativeFile = path54.relative(workingDir, absoluteFile);
27313
+ const basename10 = path54.basename(absoluteFile);
27314
+ const dirname25 = path54.dirname(absoluteFile);
27315
+ const preferRelativeOutput = !path54.isAbsolute(file);
27007
27316
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
27008
27317
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
27009
27318
  continue;
27010
27319
  }
27011
- const nameWithoutExt = basename9.replace(/\.[^.]+$/, "");
27012
- const ext = path53.extname(basename9);
27320
+ const nameWithoutExt = basename10.replace(/\.[^.]+$/, "");
27321
+ const ext = path54.extname(basename10);
27013
27322
  const genericTestNames = [
27014
27323
  `${nameWithoutExt}.spec${ext}`,
27015
27324
  `${nameWithoutExt}.test${ext}`
@@ -27018,20 +27327,20 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
27018
27327
  const colocatedCandidates = [
27019
27328
  ...genericTestNames,
27020
27329
  ...languageSpecificTestNames
27021
- ].map((candidateName) => path53.join(dirname25, candidateName));
27330
+ ].map((candidateName) => path54.join(dirname25, candidateName));
27022
27331
  const testDirectoryNames = [
27023
- basename9,
27332
+ basename10,
27024
27333
  ...genericTestNames,
27025
27334
  ...languageSpecificTestNames
27026
27335
  ];
27027
27336
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
27028
27337
  const possibleTestFiles = [
27029
27338
  ...colocatedCandidates,
27030
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path53.join(dirname25, dirName, candidateName))),
27031
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path53.join(candidateDir, candidateName)))
27339
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path54.join(dirname25, dirName, candidateName))),
27340
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path54.join(candidateDir, candidateName)))
27032
27341
  ];
27033
27342
  for (const testFile of possibleTestFiles) {
27034
- if (fs24.existsSync(testFile)) {
27343
+ if (fs25.existsSync(testFile)) {
27035
27344
  dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
27036
27345
  }
27037
27346
  }
@@ -27048,8 +27357,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27048
27357
  for (const testFile of candidateTestFiles) {
27049
27358
  try {
27050
27359
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
27051
- const content = fs24.readFileSync(absoluteTestFile, "utf-8");
27052
- const testDir = path53.dirname(absoluteTestFile);
27360
+ const content = fs25.readFileSync(absoluteTestFile, "utf-8");
27361
+ const testDir = path54.dirname(absoluteTestFile);
27053
27362
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
27054
27363
  let match;
27055
27364
  match = importRegex.exec(content);
@@ -27057,8 +27366,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27057
27366
  const importPath = match[1];
27058
27367
  let resolvedImport;
27059
27368
  if (importPath.startsWith(".")) {
27060
- resolvedImport = path53.resolve(testDir, importPath);
27061
- const existingExt = path53.extname(resolvedImport);
27369
+ resolvedImport = path54.resolve(testDir, importPath);
27370
+ const existingExt = path54.extname(resolvedImport);
27062
27371
  if (!existingExt) {
27063
27372
  for (const extToTry of [
27064
27373
  ".ts",
@@ -27069,7 +27378,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27069
27378
  ".cjs"
27070
27379
  ]) {
27071
27380
  const withExt = resolvedImport + extToTry;
27072
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
27381
+ if (absoluteSourceFiles.includes(withExt) || fs25.existsSync(withExt)) {
27073
27382
  resolvedImport = withExt;
27074
27383
  break;
27075
27384
  }
@@ -27078,12 +27387,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27078
27387
  } else {
27079
27388
  continue;
27080
27389
  }
27081
- const importBasename = path53.basename(resolvedImport, path53.extname(resolvedImport));
27082
- const importDir = path53.dirname(resolvedImport);
27390
+ const importBasename = path54.basename(resolvedImport, path54.extname(resolvedImport));
27391
+ const importDir = path54.dirname(resolvedImport);
27083
27392
  for (const sourceFile of absoluteSourceFiles) {
27084
- const sourceDir = path53.dirname(sourceFile);
27085
- const sourceBasename = path53.basename(sourceFile, path53.extname(sourceFile));
27086
- const isRelatedDir = importDir === sourceDir || importDir === path53.join(sourceDir, "__tests__") || importDir === path53.join(sourceDir, "tests") || importDir === path53.join(sourceDir, "test") || importDir === path53.join(sourceDir, "spec");
27393
+ const sourceDir = path54.dirname(sourceFile);
27394
+ const sourceBasename = path54.basename(sourceFile, path54.extname(sourceFile));
27395
+ const isRelatedDir = importDir === sourceDir || importDir === path54.join(sourceDir, "__tests__") || importDir === path54.join(sourceDir, "tests") || importDir === path54.join(sourceDir, "test") || importDir === path54.join(sourceDir, "spec");
27087
27396
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
27088
27397
  dedupePush(testFiles, testFile);
27089
27398
  break;
@@ -27096,8 +27405,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27096
27405
  while (match !== null) {
27097
27406
  const importPath = match[1];
27098
27407
  if (importPath.startsWith(".")) {
27099
- let resolvedImport = path53.resolve(testDir, importPath);
27100
- const existingExt = path53.extname(resolvedImport);
27408
+ let resolvedImport = path54.resolve(testDir, importPath);
27409
+ const existingExt = path54.extname(resolvedImport);
27101
27410
  if (!existingExt) {
27102
27411
  for (const extToTry of [
27103
27412
  ".ts",
@@ -27108,18 +27417,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27108
27417
  ".cjs"
27109
27418
  ]) {
27110
27419
  const withExt = resolvedImport + extToTry;
27111
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
27420
+ if (absoluteSourceFiles.includes(withExt) || fs25.existsSync(withExt)) {
27112
27421
  resolvedImport = withExt;
27113
27422
  break;
27114
27423
  }
27115
27424
  }
27116
27425
  }
27117
- const importDir = path53.dirname(resolvedImport);
27118
- const importBasename = path53.basename(resolvedImport, path53.extname(resolvedImport));
27426
+ const importDir = path54.dirname(resolvedImport);
27427
+ const importBasename = path54.basename(resolvedImport, path54.extname(resolvedImport));
27119
27428
  for (const sourceFile of absoluteSourceFiles) {
27120
- const sourceDir = path53.dirname(sourceFile);
27121
- const sourceBasename = path53.basename(sourceFile, path53.extname(sourceFile));
27122
- const isRelatedDir = importDir === sourceDir || importDir === path53.join(sourceDir, "__tests__") || importDir === path53.join(sourceDir, "tests") || importDir === path53.join(sourceDir, "test") || importDir === path53.join(sourceDir, "spec");
27429
+ const sourceDir = path54.dirname(sourceFile);
27430
+ const sourceBasename = path54.basename(sourceFile, path54.extname(sourceFile));
27431
+ const isRelatedDir = importDir === sourceDir || importDir === path54.join(sourceDir, "__tests__") || importDir === path54.join(sourceDir, "tests") || importDir === path54.join(sourceDir, "test") || importDir === path54.join(sourceDir, "spec");
27123
27432
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
27124
27433
  dedupePush(testFiles, testFile);
27125
27434
  break;
@@ -27239,8 +27548,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
27239
27548
  return ["mvn", "test"];
27240
27549
  case "gradle": {
27241
27550
  const isWindows = process.platform === "win32";
27242
- const hasGradlewBat = fs24.existsSync(path53.join(baseDir, "gradlew.bat"));
27243
- const hasGradlew = fs24.existsSync(path53.join(baseDir, "gradlew"));
27551
+ const hasGradlewBat = fs25.existsSync(path54.join(baseDir, "gradlew.bat"));
27552
+ const hasGradlew = fs25.existsSync(path54.join(baseDir, "gradlew"));
27244
27553
  if (hasGradlewBat && isWindows)
27245
27554
  return ["gradlew.bat", "test"];
27246
27555
  if (hasGradlew)
@@ -27257,7 +27566,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
27257
27566
  "cmake-build-release",
27258
27567
  "out"
27259
27568
  ];
27260
- const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path53.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
27569
+ const actualBuildDir = buildDirCandidates.find((d) => fs25.existsSync(path54.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
27261
27570
  return ["ctest", "--test-dir", actualBuildDir];
27262
27571
  }
27263
27572
  case "swift-test":
@@ -27691,13 +28000,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27691
28000
  };
27692
28001
  }
27693
28002
  const startTime = Date.now();
27694
- const vitestJsonOutputPath = framework === "vitest" ? path53.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
28003
+ const vitestJsonOutputPath = framework === "vitest" ? path54.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
27695
28004
  try {
27696
28005
  if (vitestJsonOutputPath) {
27697
28006
  try {
27698
- fs24.mkdirSync(path53.dirname(vitestJsonOutputPath), { recursive: true });
27699
- if (fs24.existsSync(vitestJsonOutputPath)) {
27700
- fs24.unlinkSync(vitestJsonOutputPath);
28007
+ fs25.mkdirSync(path54.dirname(vitestJsonOutputPath), { recursive: true });
28008
+ if (fs25.existsSync(vitestJsonOutputPath)) {
28009
+ fs25.unlinkSync(vitestJsonOutputPath);
27701
28010
  }
27702
28011
  } catch {}
27703
28012
  }
@@ -27723,8 +28032,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27723
28032
  }
27724
28033
  if (vitestJsonOutputPath) {
27725
28034
  try {
27726
- if (fs24.existsSync(vitestJsonOutputPath)) {
27727
- const vitestJsonOutput = fs24.readFileSync(vitestJsonOutputPath, "utf-8");
28035
+ if (fs25.existsSync(vitestJsonOutputPath)) {
28036
+ const vitestJsonOutput = fs25.readFileSync(vitestJsonOutputPath, "utf-8");
27728
28037
  if (vitestJsonOutput.trim().length > 0) {
27729
28038
  output += (output ? `
27730
28039
  ` : "") + vitestJsonOutput;
@@ -27863,10 +28172,10 @@ var SKIP_DIRECTORIES = new Set([
27863
28172
  ]);
27864
28173
  function normalizeHistoryTestFile(testFile, workingDir) {
27865
28174
  const normalized = testFile.replace(/\\/g, "/");
27866
- if (!path53.isAbsolute(testFile))
28175
+ if (!path54.isAbsolute(testFile))
27867
28176
  return normalized;
27868
- const relative8 = path53.relative(workingDir, testFile);
27869
- if (relative8.startsWith("..") || path53.isAbsolute(relative8)) {
28177
+ const relative8 = path54.relative(workingDir, testFile);
28178
+ if (relative8.startsWith("..") || path54.isAbsolute(relative8)) {
27870
28179
  return normalized;
27871
28180
  }
27872
28181
  return relative8.replace(/\\/g, "/");
@@ -28105,7 +28414,7 @@ var test_runner = createSwarmTool({
28105
28414
  const sourceFiles = args.files.filter((file) => {
28106
28415
  if (directTestFiles.includes(file))
28107
28416
  return false;
28108
- const ext = path53.extname(file).toLowerCase();
28417
+ const ext = path54.extname(file).toLowerCase();
28109
28418
  return SOURCE_EXTENSIONS.has(ext);
28110
28419
  });
28111
28420
  const invalidFiles = args.files.filter((file) => !directTestFiles.includes(file) && !sourceFiles.includes(file));
@@ -28151,7 +28460,7 @@ var test_runner = createSwarmTool({
28151
28460
  if (isConventionTestFilePath(f)) {
28152
28461
  return false;
28153
28462
  }
28154
- const ext = path53.extname(f).toLowerCase();
28463
+ const ext = path54.extname(f).toLowerCase();
28155
28464
  return SOURCE_EXTENSIONS.has(ext);
28156
28465
  });
28157
28466
  if (sourceFiles.length === 0) {
@@ -28201,7 +28510,7 @@ var test_runner = createSwarmTool({
28201
28510
  if (isConventionTestFilePath(f)) {
28202
28511
  return false;
28203
28512
  }
28204
- const ext = path53.extname(f).toLowerCase();
28513
+ const ext = path54.extname(f).toLowerCase();
28205
28514
  return SOURCE_EXTENSIONS.has(ext);
28206
28515
  });
28207
28516
  if (sourceFiles.length === 0) {
@@ -28253,8 +28562,8 @@ var test_runner = createSwarmTool({
28253
28562
  }
28254
28563
  if (impactResult.impactedTests.length > 0) {
28255
28564
  testFiles = impactResult.impactedTests.map((absPath) => {
28256
- const relativePath = path53.relative(workingDir, absPath);
28257
- return path53.isAbsolute(relativePath) ? absPath : relativePath;
28565
+ const relativePath = path54.relative(workingDir, absPath);
28566
+ return path54.isAbsolute(relativePath) ? absPath : relativePath;
28258
28567
  });
28259
28568
  } else {
28260
28569
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -28349,8 +28658,8 @@ function validateDirectoryPath(dir) {
28349
28658
  if (dir.includes("..")) {
28350
28659
  throw new Error("Directory path must not contain path traversal sequences");
28351
28660
  }
28352
- const normalized = path54.normalize(dir);
28353
- const absolutePath = path54.isAbsolute(normalized) ? normalized : path54.resolve(normalized);
28661
+ const normalized = path55.normalize(dir);
28662
+ const absolutePath = path55.isAbsolute(normalized) ? normalized : path55.resolve(normalized);
28354
28663
  return absolutePath;
28355
28664
  }
28356
28665
  function validateTimeout(timeoutMs, defaultValue) {
@@ -28373,9 +28682,9 @@ function validateTimeout(timeoutMs, defaultValue) {
28373
28682
  }
28374
28683
  function getPackageVersion(dir) {
28375
28684
  try {
28376
- const packagePath = path54.join(dir, "package.json");
28377
- if (fs25.existsSync(packagePath)) {
28378
- const content = fs25.readFileSync(packagePath, "utf-8");
28685
+ const packagePath = path55.join(dir, "package.json");
28686
+ if (fs26.existsSync(packagePath)) {
28687
+ const content = fs26.readFileSync(packagePath, "utf-8");
28379
28688
  const pkg = JSON.parse(content);
28380
28689
  return pkg.version ?? null;
28381
28690
  }
@@ -28384,9 +28693,9 @@ function getPackageVersion(dir) {
28384
28693
  }
28385
28694
  function getChangelogVersion(dir) {
28386
28695
  try {
28387
- const changelogPath = path54.join(dir, "CHANGELOG.md");
28388
- if (fs25.existsSync(changelogPath)) {
28389
- const content = fs25.readFileSync(changelogPath, "utf-8");
28696
+ const changelogPath = path55.join(dir, "CHANGELOG.md");
28697
+ if (fs26.existsSync(changelogPath)) {
28698
+ const content = fs26.readFileSync(changelogPath, "utf-8");
28390
28699
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
28391
28700
  if (match) {
28392
28701
  return match[1];
@@ -28398,10 +28707,10 @@ function getChangelogVersion(dir) {
28398
28707
  function getVersionFileVersion(dir) {
28399
28708
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
28400
28709
  for (const file of possibleFiles) {
28401
- const filePath = path54.join(dir, file);
28402
- if (fs25.existsSync(filePath)) {
28710
+ const filePath = path55.join(dir, file);
28711
+ if (fs26.existsSync(filePath)) {
28403
28712
  try {
28404
- const content = fs25.readFileSync(filePath, "utf-8").trim();
28713
+ const content = fs26.readFileSync(filePath, "utf-8").trim();
28405
28714
  const match = content.match(/(\d+\.\d+\.\d+)/);
28406
28715
  if (match) {
28407
28716
  return match[1];
@@ -29135,8 +29444,8 @@ async function handleQaGatesCommand(directory, args, sessionID) {
29135
29444
  }
29136
29445
 
29137
29446
  // src/commands/reset.ts
29138
- import * as fs26 from "fs";
29139
- import * as path55 from "path";
29447
+ import * as fs27 from "fs";
29448
+ import * as path56 from "path";
29140
29449
 
29141
29450
  // src/background/circuit-breaker.ts
29142
29451
  class CircuitBreaker {
@@ -29843,8 +30152,8 @@ async function handleResetCommand(directory, args) {
29843
30152
  for (const filename of filesToReset) {
29844
30153
  try {
29845
30154
  const resolvedPath = validateSwarmPath(directory, filename);
29846
- if (fs26.existsSync(resolvedPath)) {
29847
- fs26.unlinkSync(resolvedPath);
30155
+ if (fs27.existsSync(resolvedPath)) {
30156
+ fs27.unlinkSync(resolvedPath);
29848
30157
  results.push(`- \u2705 Deleted ${filename}`);
29849
30158
  } else {
29850
30159
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -29855,9 +30164,9 @@ async function handleResetCommand(directory, args) {
29855
30164
  }
29856
30165
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
29857
30166
  try {
29858
- const rootPath = path55.join(directory, filename);
29859
- if (fs26.existsSync(rootPath)) {
29860
- fs26.unlinkSync(rootPath);
30167
+ const rootPath = path56.join(directory, filename);
30168
+ if (fs27.existsSync(rootPath)) {
30169
+ fs27.unlinkSync(rootPath);
29861
30170
  results.push(`- \u2705 Deleted ${filename} (root)`);
29862
30171
  }
29863
30172
  } catch (err) {
@@ -29872,8 +30181,8 @@ async function handleResetCommand(directory, args) {
29872
30181
  }
29873
30182
  try {
29874
30183
  const summariesPath = validateSwarmPath(directory, "summaries");
29875
- if (fs26.existsSync(summariesPath)) {
29876
- fs26.rmSync(summariesPath, { recursive: true, force: true });
30184
+ if (fs27.existsSync(summariesPath)) {
30185
+ fs27.rmSync(summariesPath, { recursive: true, force: true });
29877
30186
  results.push("- \u2705 Deleted summaries/ directory");
29878
30187
  } else {
29879
30188
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -29892,8 +30201,8 @@ async function handleResetCommand(directory, args) {
29892
30201
  }
29893
30202
 
29894
30203
  // src/commands/reset-session.ts
29895
- import * as fs28 from "fs";
29896
- import * as path57 from "path";
30204
+ import * as fs29 from "fs";
30205
+ import * as path58 from "path";
29897
30206
 
29898
30207
  // src/hooks/trajectory-logger.ts
29899
30208
  var callStartTimes = new Map;
@@ -30299,17 +30608,17 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
30299
30608
  };
30300
30609
  }
30301
30610
  // src/prm/replay.ts
30302
- import { promises as fs27 } from "fs";
30303
- import path56 from "path";
30611
+ import { promises as fs28 } from "fs";
30612
+ import path57 from "path";
30304
30613
  function isPathSafe(targetPath, basePath) {
30305
- const resolvedTarget = path56.resolve(targetPath);
30306
- const resolvedBase = path56.resolve(basePath);
30307
- const rel = path56.relative(resolvedBase, resolvedTarget);
30308
- return !rel.startsWith("..") && !path56.isAbsolute(rel);
30614
+ const resolvedTarget = path57.resolve(targetPath);
30615
+ const resolvedBase = path57.resolve(basePath);
30616
+ const rel = path57.relative(resolvedBase, resolvedTarget);
30617
+ return !rel.startsWith("..") && !path57.isAbsolute(rel);
30309
30618
  }
30310
30619
  function isWithinReplaysDir(targetPath) {
30311
- const resolved = path56.resolve(targetPath);
30312
- const parts = resolved.split(path56.sep);
30620
+ const resolved = path57.resolve(targetPath);
30621
+ const parts = resolved.split(path57.sep);
30313
30622
  for (let i = 0;i < parts.length - 1; i++) {
30314
30623
  if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
30315
30624
  return true;
@@ -30322,15 +30631,15 @@ function sanitizeFilename(input) {
30322
30631
  }
30323
30632
  async function startReplayRecording(sessionID, directory) {
30324
30633
  try {
30325
- const replayDir = path56.join(directory, ".swarm", "replays");
30634
+ const replayDir = path57.join(directory, ".swarm", "replays");
30326
30635
  const safeSessionID = sanitizeFilename(sessionID);
30327
30636
  const filename = `${safeSessionID}-${Date.now()}.jsonl`;
30328
- const filepath = path56.join(replayDir, filename);
30637
+ const filepath = path57.join(replayDir, filename);
30329
30638
  if (!isPathSafe(filepath, replayDir)) {
30330
30639
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
30331
30640
  return null;
30332
30641
  }
30333
- await fs27.mkdir(replayDir, { recursive: true });
30642
+ await fs28.mkdir(replayDir, { recursive: true });
30334
30643
  return filepath;
30335
30644
  } catch (err) {
30336
30645
  console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err}`);
@@ -30350,7 +30659,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
30350
30659
  };
30351
30660
  const line = `${JSON.stringify(fullEntry)}
30352
30661
  `;
30353
- await fs27.appendFile(artifactPath, line, "utf-8");
30662
+ await fs28.appendFile(artifactPath, line, "utf-8");
30354
30663
  } catch (err) {
30355
30664
  console.warn(`[replay] Failed to record entry: ${err}`);
30356
30665
  }
@@ -30394,8 +30703,8 @@ async function handleResetSessionCommand(directory, _args) {
30394
30703
  const results = [];
30395
30704
  try {
30396
30705
  const statePath = validateSwarmPath(directory, "session/state.json");
30397
- if (fs28.existsSync(statePath)) {
30398
- fs28.unlinkSync(statePath);
30706
+ if (fs29.existsSync(statePath)) {
30707
+ fs29.unlinkSync(statePath);
30399
30708
  results.push("\u2705 Deleted .swarm/session/state.json");
30400
30709
  } else {
30401
30710
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -30403,11 +30712,11 @@ async function handleResetSessionCommand(directory, _args) {
30403
30712
  } catch {
30404
30713
  results.push("\u274C Failed to delete state.json");
30405
30714
  }
30406
- const sessionDir = path57.dirname(validateSwarmPath(directory, "session/state.json"));
30715
+ const sessionDir = path58.dirname(validateSwarmPath(directory, "session/state.json"));
30407
30716
  let sessionFiles = [];
30408
- if (fs28.existsSync(sessionDir)) {
30717
+ if (fs29.existsSync(sessionDir)) {
30409
30718
  try {
30410
- sessionFiles = fs28.readdirSync(sessionDir);
30719
+ sessionFiles = fs29.readdirSync(sessionDir);
30411
30720
  } catch (err) {
30412
30721
  results.push(`\u274C Failed to read session directory: ${errorMessage(err)}`);
30413
30722
  }
@@ -30415,13 +30724,13 @@ async function handleResetSessionCommand(directory, _args) {
30415
30724
  for (const file of sessionFiles) {
30416
30725
  if (file === "state.json")
30417
30726
  continue;
30418
- const filePath = path57.join(sessionDir, file);
30727
+ const filePath = path58.join(sessionDir, file);
30419
30728
  try {
30420
- if (!fs28.existsSync(filePath))
30729
+ if (!fs29.existsSync(filePath))
30421
30730
  continue;
30422
- if (!fs28.lstatSync(filePath).isFile())
30731
+ if (!fs29.lstatSync(filePath).isFile())
30423
30732
  continue;
30424
- fs28.unlinkSync(filePath);
30733
+ fs29.unlinkSync(filePath);
30425
30734
  results.push(`\u2713 Deleted ${file}`);
30426
30735
  } catch (err) {
30427
30736
  results.push(`\u274C Failed to delete ${file}: ${errorMessage(err)}`);
@@ -30450,7 +30759,7 @@ async function handleResetSessionCommand(directory, _args) {
30450
30759
  }
30451
30760
 
30452
30761
  // src/summaries/manager.ts
30453
- import * as path58 from "path";
30762
+ import * as path59 from "path";
30454
30763
  var SUMMARY_ID_REGEX = /^S\d+$/;
30455
30764
  function sanitizeSummaryId(id) {
30456
30765
  if (!id || id.length === 0) {
@@ -30474,7 +30783,7 @@ function sanitizeSummaryId(id) {
30474
30783
  }
30475
30784
  async function loadFullOutput(directory, id) {
30476
30785
  const sanitizedId = sanitizeSummaryId(id);
30477
- const relativePath = path58.join("summaries", `${sanitizedId}.json`);
30786
+ const relativePath = path59.join("summaries", `${sanitizedId}.json`);
30478
30787
  validateSwarmPath(directory, relativePath);
30479
30788
  const content = await readSwarmFileAsync(directory, relativePath);
30480
30789
  if (content === null) {
@@ -30526,18 +30835,18 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
30526
30835
  }
30527
30836
 
30528
30837
  // src/commands/rollback.ts
30529
- import * as fs29 from "fs";
30530
- import * as path59 from "path";
30838
+ import * as fs30 from "fs";
30839
+ import * as path60 from "path";
30531
30840
  async function handleRollbackCommand(directory, args) {
30532
30841
  const phaseArg = args[0];
30533
30842
  if (!phaseArg) {
30534
30843
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
30535
- if (!fs29.existsSync(manifestPath2)) {
30844
+ if (!fs30.existsSync(manifestPath2)) {
30536
30845
  return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
30537
30846
  }
30538
30847
  let manifest2;
30539
30848
  try {
30540
- manifest2 = JSON.parse(fs29.readFileSync(manifestPath2, "utf-8"));
30849
+ manifest2 = JSON.parse(fs30.readFileSync(manifestPath2, "utf-8"));
30541
30850
  } catch {
30542
30851
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
30543
30852
  }
@@ -30559,12 +30868,12 @@ async function handleRollbackCommand(directory, args) {
30559
30868
  return "Error: Phase number must be a positive integer.";
30560
30869
  }
30561
30870
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
30562
- if (!fs29.existsSync(manifestPath)) {
30871
+ if (!fs30.existsSync(manifestPath)) {
30563
30872
  return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
30564
30873
  }
30565
30874
  let manifest;
30566
30875
  try {
30567
- manifest = JSON.parse(fs29.readFileSync(manifestPath, "utf-8"));
30876
+ manifest = JSON.parse(fs30.readFileSync(manifestPath, "utf-8"));
30568
30877
  } catch {
30569
30878
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
30570
30879
  }
@@ -30574,10 +30883,10 @@ async function handleRollbackCommand(directory, args) {
30574
30883
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
30575
30884
  }
30576
30885
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
30577
- if (!fs29.existsSync(checkpointDir)) {
30886
+ if (!fs30.existsSync(checkpointDir)) {
30578
30887
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
30579
30888
  }
30580
- const checkpointFiles = fs29.readdirSync(checkpointDir);
30889
+ const checkpointFiles = fs30.readdirSync(checkpointDir);
30581
30890
  if (checkpointFiles.length === 0) {
30582
30891
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
30583
30892
  }
@@ -30593,10 +30902,10 @@ async function handleRollbackCommand(directory, args) {
30593
30902
  if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
30594
30903
  continue;
30595
30904
  }
30596
- const src = path59.join(checkpointDir, file);
30597
- const dest = path59.join(swarmDir, file);
30905
+ const src = path60.join(checkpointDir, file);
30906
+ const dest = path60.join(swarmDir, file);
30598
30907
  try {
30599
- fs29.cpSync(src, dest, { recursive: true, force: true });
30908
+ fs30.cpSync(src, dest, { recursive: true, force: true });
30600
30909
  successes.push(file);
30601
30910
  } catch (error2) {
30602
30911
  failures.push({ file, error: error2.message });
@@ -30613,11 +30922,11 @@ async function handleRollbackCommand(directory, args) {
30613
30922
  ].join(`
30614
30923
  `);
30615
30924
  }
30616
- const existingLedgerPath = path59.join(swarmDir, "plan-ledger.jsonl");
30925
+ const existingLedgerPath = path60.join(swarmDir, "plan-ledger.jsonl");
30617
30926
  let ledgerDeletionFailed = false;
30618
- if (fs29.existsSync(existingLedgerPath)) {
30927
+ if (fs30.existsSync(existingLedgerPath)) {
30619
30928
  try {
30620
- fs29.unlinkSync(existingLedgerPath);
30929
+ fs30.unlinkSync(existingLedgerPath);
30621
30930
  } catch (err) {
30622
30931
  ledgerDeletionFailed = true;
30623
30932
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -30626,9 +30935,9 @@ async function handleRollbackCommand(directory, args) {
30626
30935
  }
30627
30936
  if (!ledgerDeletionFailed) {
30628
30937
  try {
30629
- const planJsonPath = path59.join(swarmDir, "plan.json");
30630
- if (fs29.existsSync(planJsonPath)) {
30631
- const planRaw = fs29.readFileSync(planJsonPath, "utf-8");
30938
+ const planJsonPath = path60.join(swarmDir, "plan.json");
30939
+ if (fs30.existsSync(planJsonPath)) {
30940
+ const planRaw = fs30.readFileSync(planJsonPath, "utf-8");
30632
30941
  const plan = PlanSchema.parse(JSON.parse(planRaw));
30633
30942
  const planId = derivePlanId(plan);
30634
30943
  const planHash = computePlanHash(plan);
@@ -30656,7 +30965,7 @@ async function handleRollbackCommand(directory, args) {
30656
30965
  timestamp: new Date().toISOString()
30657
30966
  };
30658
30967
  try {
30659
- fs29.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30968
+ fs30.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30660
30969
  `);
30661
30970
  } catch (error2) {
30662
30971
  console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
@@ -30838,7 +31147,7 @@ async function handleSddCommand(_directory, _args) {
30838
31147
  }
30839
31148
 
30840
31149
  // src/commands/simulate.ts
30841
- import { renameSync as renameSync11, unlinkSync as unlinkSync11 } from "fs";
31150
+ import { renameSync as renameSync11, unlinkSync as unlinkSync12 } from "fs";
30842
31151
  async function handleSimulateCommand(directory, args) {
30843
31152
  const thresholdIndex = args.indexOf("--threshold");
30844
31153
  const minCommitsIndex = args.indexOf("--min-commits");
@@ -30886,17 +31195,17 @@ Ensure this is a git repository with commit history.`;
30886
31195
  const report = reportLines.filter(Boolean).join(`
30887
31196
  `);
30888
31197
  try {
30889
- const fs30 = await import("fs/promises");
30890
- const path60 = await import("path");
30891
- const reportPath = path60.join(directory, ".swarm", "simulate-report.md");
30892
- await fs30.mkdir(path60.dirname(reportPath), { recursive: true });
30893
- const reportTempPath = path60.join(path60.dirname(reportPath), `${path60.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
31198
+ const fs31 = await import("fs/promises");
31199
+ const path61 = await import("path");
31200
+ const reportPath = path61.join(directory, ".swarm", "simulate-report.md");
31201
+ await fs31.mkdir(path61.dirname(reportPath), { recursive: true });
31202
+ const reportTempPath = path61.join(path61.dirname(reportPath), `${path61.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
30894
31203
  try {
30895
- await fs30.writeFile(reportTempPath, report, "utf-8");
31204
+ await fs31.writeFile(reportTempPath, report, "utf-8");
30896
31205
  renameSync11(reportTempPath, reportPath);
30897
31206
  } catch (err) {
30898
31207
  try {
30899
- unlinkSync11(reportTempPath);
31208
+ unlinkSync12(reportTempPath);
30900
31209
  } catch {}
30901
31210
  throw err;
30902
31211
  }
@@ -30919,20 +31228,20 @@ async function handleSpecifyCommand(_directory, args) {
30919
31228
  // src/services/status-service.ts
30920
31229
  import * as fsSync3 from "fs";
30921
31230
  import { readFile as readFile16 } from "fs/promises";
30922
- import * as path61 from "path";
31231
+ import * as path62 from "path";
30923
31232
 
30924
31233
  // src/turbo/lean/state.ts
30925
31234
  init_logger();
30926
- import * as fs30 from "fs";
30927
- import * as path60 from "path";
31235
+ import * as fs31 from "fs";
31236
+ import * as path61 from "path";
30928
31237
  var STATE_FILE3 = "turbo-state.json";
30929
31238
  function nowISO3() {
30930
31239
  return new Date().toISOString();
30931
31240
  }
30932
31241
  function ensureSwarmDir2(directory) {
30933
- const swarmDir = path60.resolve(directory, ".swarm");
30934
- if (!fs30.existsSync(swarmDir)) {
30935
- fs30.mkdirSync(swarmDir, { recursive: true });
31242
+ const swarmDir = path61.resolve(directory, ".swarm");
31243
+ if (!fs31.existsSync(swarmDir)) {
31244
+ fs31.mkdirSync(swarmDir, { recursive: true });
30936
31245
  }
30937
31246
  return swarmDir;
30938
31247
  }
@@ -30975,17 +31284,17 @@ function markStateUnreadable2(directory, reason) {
30975
31284
  }
30976
31285
  function readPersisted2(directory) {
30977
31286
  try {
30978
- const filePath = path60.join(directory, ".swarm", STATE_FILE3);
30979
- if (!fs30.existsSync(filePath)) {
31287
+ const filePath = path61.join(directory, ".swarm", STATE_FILE3);
31288
+ if (!fs31.existsSync(filePath)) {
30980
31289
  const seed = emptyPersisted2();
30981
31290
  try {
30982
31291
  ensureSwarmDir2(directory);
30983
- fs30.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
31292
+ fs31.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
30984
31293
  `, "utf-8");
30985
31294
  } catch {}
30986
31295
  return seed;
30987
31296
  }
30988
- const raw = fs30.readFileSync(filePath, "utf-8");
31297
+ const raw = fs31.readFileSync(filePath, "utf-8");
30989
31298
  const parsed = JSON.parse(raw);
30990
31299
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
30991
31300
  markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -31011,7 +31320,7 @@ function writePersisted2(directory, persisted) {
31011
31320
  let payload;
31012
31321
  try {
31013
31322
  ensureSwarmDir2(directory);
31014
- filePath = path60.join(directory, ".swarm", STATE_FILE3);
31323
+ filePath = path61.join(directory, ".swarm", STATE_FILE3);
31015
31324
  tmpPath = `${filePath}.tmp.${Date.now()}`;
31016
31325
  persisted.updatedAt = nowISO3();
31017
31326
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -31022,14 +31331,14 @@ function writePersisted2(directory, persisted) {
31022
31331
  throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
31023
31332
  }
31024
31333
  try {
31025
- fs30.writeFileSync(tmpPath, payload, "utf-8");
31026
- fs30.renameSync(tmpPath, filePath);
31334
+ fs31.writeFileSync(tmpPath, payload, "utf-8");
31335
+ fs31.renameSync(tmpPath, filePath);
31027
31336
  } catch (error2) {
31028
31337
  const msg = error2 instanceof Error ? error2.message : String(error2);
31029
31338
  error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
31030
31339
  try {
31031
- if (fs30.existsSync(tmpPath)) {
31032
- fs30.unlinkSync(tmpPath);
31340
+ if (fs31.existsSync(tmpPath)) {
31341
+ fs31.unlinkSync(tmpPath);
31033
31342
  }
31034
31343
  } catch {}
31035
31344
  throw new Error(`Lean Turbo state persistence failed: ${msg}`);
@@ -31129,7 +31438,7 @@ var _internals43 = {
31129
31438
  };
31130
31439
  function readSpecStalenessSnapshot(directory) {
31131
31440
  try {
31132
- const p = path61.join(directory, ".swarm", "spec-staleness.json");
31441
+ const p = path62.join(directory, ".swarm", "spec-staleness.json");
31133
31442
  if (!fsSync3.existsSync(p))
31134
31443
  return { stale: false };
31135
31444
  const raw = fsSync3.readFileSync(p, "utf-8");
@@ -31661,13 +31970,13 @@ function buildStatusMessage2(session, directory, sessionID) {
31661
31970
  }
31662
31971
 
31663
31972
  // src/commands/unlink.ts
31664
- import { existsSync as existsSync36 } from "fs";
31665
- import * as path62 from "path";
31973
+ import { existsSync as existsSync37 } from "fs";
31974
+ import * as path63 from "path";
31666
31975
  var DEDUP_THRESHOLD2 = 0.6;
31667
31976
  async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
31668
- const sharedPath = path62.join(linkDir, "knowledge.jsonl");
31669
- const localPath = path62.join(localSwarmDir, "knowledge.jsonl");
31670
- if (!existsSync36(sharedPath))
31977
+ const sharedPath = path63.join(linkDir, "knowledge.jsonl");
31978
+ const localPath = path63.join(localSwarmDir, "knowledge.jsonl");
31979
+ if (!existsSync37(sharedPath))
31671
31980
  return 0;
31672
31981
  const sharedEntries = await readKnowledge(sharedPath);
31673
31982
  if (sharedEntries.length === 0)
@@ -31701,7 +32010,7 @@ async function handleUnlinkCommand(directory, args) {
31701
32010
  let copied = 0;
31702
32011
  if (copyBack) {
31703
32012
  try {
31704
- copied = await copySharedKnowledgeToLocal(linkDir, path62.join(directory, ".swarm"));
32013
+ copied = await copySharedKnowledgeToLocal(linkDir, path63.join(directory, ".swarm"));
31705
32014
  } catch (error2) {
31706
32015
  return `\u274C Failed to copy shared knowledge back to local: ${error2 instanceof Error ? error2.message : String(error2)}`;
31707
32016
  }
@@ -31856,7 +32165,7 @@ function buildDetailedHelp(commandName, entry) {
31856
32165
  async function handleHelpCommand(ctx) {
31857
32166
  const targetCommand = ctx.args.join(" ");
31858
32167
  if (!targetCommand) {
31859
- const { buildHelpText } = await import("./index-attgb1ma.js");
32168
+ const { buildHelpText } = await import("./index-4pt2py5p.js");
31860
32169
  return buildHelpText();
31861
32170
  }
31862
32171
  const tokens = targetCommand.split(/\s+/);
@@ -31865,7 +32174,7 @@ async function handleHelpCommand(ctx) {
31865
32174
  return _internals45.buildDetailedHelp(resolved.key, resolved.entry);
31866
32175
  }
31867
32176
  const similar = _internals45.findSimilarCommands(targetCommand);
31868
- const { buildHelpText: fullHelp } = await import("./index-attgb1ma.js");
32177
+ const { buildHelpText: fullHelp } = await import("./index-4pt2py5p.js");
31869
32178
  if (similar.length > 0) {
31870
32179
  return `Command '/swarm ${targetCommand}' not found.
31871
32180
 
@@ -31998,7 +32307,7 @@ var COMMAND_REGISTRY = {
31998
32307
  },
31999
32308
  "guardrail explain": {
32000
32309
  handler: async (ctx) => {
32001
- const { handleGuardrailExplain } = await import("./guardrail-explain-cm08h4mt.js");
32310
+ const { handleGuardrailExplain } = await import("./guardrail-explain-ktm6szbm.js");
32002
32311
  return handleGuardrailExplain(ctx.directory, ctx.args);
32003
32312
  },
32004
32313
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -32008,7 +32317,7 @@ var COMMAND_REGISTRY = {
32008
32317
  },
32009
32318
  "guardrail-log": {
32010
32319
  handler: async (ctx) => {
32011
- const { handleGuardrailLog } = await import("./guardrail-log-53z1cf46.js");
32320
+ const { handleGuardrailLog } = await import("./guardrail-log-ya49kpwn.js");
32012
32321
  return handleGuardrailLog(ctx.directory, ctx.args);
32013
32322
  },
32014
32323
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -32033,8 +32342,15 @@ var COMMAND_REGISTRY = {
32033
32342
  },
32034
32343
  benchmark: {
32035
32344
  handler: (ctx) => handleBenchmarkCommand(ctx.directory, ctx.args),
32036
- description: "Show performance metrics [--cumulative] [--ci-gate]",
32037
- args: "--cumulative, --ci-gate",
32345
+ description: "Show performance metrics [--cumulative] [--ci-gate] [--max-cost-usd <n>]",
32346
+ args: "--cumulative, --ci-gate, --max-cost-usd <n>",
32347
+ category: "diagnostics",
32348
+ toolPolicy: "agent"
32349
+ },
32350
+ costs: {
32351
+ handler: (ctx) => handleCostsCommand(ctx.directory, ctx.args),
32352
+ description: "Show per-agent and per-task token/cost telemetry [--json]",
32353
+ args: "--json",
32038
32354
  category: "diagnostics",
32039
32355
  toolPolicy: "agent"
32040
32356
  },
@@ -32769,24 +33085,24 @@ function validateAliases() {
32769
33085
  }
32770
33086
  aliasTargets.get(target).push(name);
32771
33087
  const visited = new Set;
32772
- const path63 = [];
33088
+ const path64 = [];
32773
33089
  let current = target;
32774
33090
  while (current) {
32775
33091
  const currentEntry = COMMAND_REGISTRY[current];
32776
33092
  if (!currentEntry)
32777
33093
  break;
32778
33094
  if (visited.has(current)) {
32779
- const cycleStart = path63.indexOf(current);
33095
+ const cycleStart = path64.indexOf(current);
32780
33096
  const fullChain = [
32781
33097
  name,
32782
- ...path63.slice(0, cycleStart > 0 ? cycleStart : path63.length),
33098
+ ...path64.slice(0, cycleStart > 0 ? cycleStart : path64.length),
32783
33099
  current
32784
33100
  ].join(" \u2192 ");
32785
33101
  errors.push(`Circular alias detected: ${fullChain}`);
32786
33102
  break;
32787
33103
  }
32788
33104
  visited.add(current);
32789
- path63.push(current);
33105
+ path64.push(current);
32790
33106
  current = currentEntry.aliasOf || "";
32791
33107
  }
32792
33108
  }
@@ -32952,4 +33268,4 @@ ${text}`;
32952
33268
  };
32953
33269
  }
32954
33270
 
32955
- export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleClarifyCommand, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals45 as _internals, resolveCommand };
33271
+ export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleClarifyCommand, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals45 as _internals, resolveCommand };