opencode-swarm 7.98.2 → 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 (38) 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-559nas1m.js → evidence-summary-service-4hs44n2c.js} +5 -5
  4. package/dist/cli/{gate-evidence-nphg8hay.js → gate-evidence-ywys9vfs.js} +4 -4
  5. package/dist/cli/{guardrail-explain-xktjjh53.js → guardrail-explain-ktm6szbm.js} +13 -13
  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-chan9mkv.js → index-4pt2py5p.js} +16 -14
  9. package/dist/cli/{index-a0dv2c7k.js → index-5fxjagjt.js} +1 -1
  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-rvweaxsd.js → index-ft4gehk1.js} +2 -2
  14. package/dist/cli/{index-gnd1280x.js → index-h9ptj4b1.js} +1 -1
  15. package/dist/cli/{index-72k57f21.js → index-hw8r3e5p.js} +1098 -790
  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-yrzfbqqh.js → index-wwnjw0fb.js} +3 -3
  21. package/dist/cli/{index-5z2e78tv.js → index-xsswhy6k.js} +1 -1
  22. package/dist/cli/index.js +12 -12
  23. package/dist/cli/{knowledge-store-pa58msy5.js → knowledge-store-tsa8ezka.js} +4 -4
  24. package/dist/cli/{pending-delegations-8b2js1vq.js → pending-delegations-c785p5n2.js} +2 -2
  25. package/dist/cli/{pr-subscriptions-ttvr1ta9.js → pr-subscriptions-fqrzm0tv.js} +3 -3
  26. package/dist/cli/{schema-mygkbbe9.js → schema-nz638xc3.js} +5 -1
  27. package/dist/cli/{skill-generator-3tkwcg4x.js → skill-generator-99rrfwae.js} +5 -5
  28. package/dist/cli/{telemetry-aa1ma1dr.js → telemetry-jm7t8031.js} +1 -1
  29. package/dist/commands/costs.d.ts +4 -0
  30. package/dist/commands/index.d.ts +1 -0
  31. package/dist/commands/registry.d.ts +9 -2
  32. package/dist/config/evidence-schema.d.ts +44 -44
  33. package/dist/config/index.d.ts +2 -2
  34. package/dist/config/schema.d.ts +24 -0
  35. package/dist/index.js +2933 -2314
  36. package/dist/services/cost-accounting.d.ts +65 -0
  37. package/dist/telemetry.d.ts +2 -1
  38. package/package.json +1 -1
@@ -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-yrzfbqqh.js";
117
+ } from "./index-wwnjw0fb.js";
118
118
  import {
119
119
  _internals as _internals2,
120
120
  _internals1 as _internals3,
@@ -132,13 +132,13 @@ 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-a0dv2c7k.js";
141
+ } from "./index-5fxjagjt.js";
142
142
  import {
143
143
  readSwarmFileAsync,
144
144
  safeHook,
@@ -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.2",
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 {
@@ -5981,7 +5996,7 @@ function hasActiveEpicMode(sessionID) {
5981
5996
  async function rehydratePrSubscriptions(sessionID, directory) {
5982
5997
  const map = new Map;
5983
5998
  try {
5984
- const { listActive: listActive2 } = await import("./pr-subscriptions-ttvr1ta9.js");
5999
+ const { listActive: listActive2 } = await import("./pr-subscriptions-fqrzm0tv.js");
5985
6000
  const records = await listActive2(directory);
5986
6001
  for (const record of records) {
5987
6002
  if (record.sessionID !== sessionID)
@@ -6058,6 +6073,199 @@ async function handleAutoProceedCommand(_directory, args, sessionID) {
6058
6073
  }
6059
6074
  }
6060
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
+
6061
6269
  // src/commands/benchmark.ts
6062
6270
  var CI = {
6063
6271
  review_pass_rate: 70,
@@ -6073,7 +6281,9 @@ async function handleBenchmarkCommand(directory, args) {
6073
6281
  let cumulative = args.includes("--cumulative");
6074
6282
  if (args.includes("--ci-gate"))
6075
6283
  cumulative = true;
6284
+ const maxCostUsd = parseMaxCostUsd(args);
6076
6285
  const mode = cumulative ? "cumulative" : "in-memory";
6286
+ const costSummary = cumulative ? summarizeTelemetryCosts(directory) : undefined;
6077
6287
  const agentMap = new Map;
6078
6288
  for (const [, s] of swarmState.agentSessions) {
6079
6289
  const e = agentMap.get(s.agentName) || {
@@ -6265,6 +6475,15 @@ async function handleBenchmarkCommand(directory, args) {
6265
6475
  passed: !hasQualityEvidence || testToCodeRatio >= CI.min_test_to_code_ratio
6266
6476
  }
6267
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
+ }
6268
6487
  ciGate = { passed: checks.every((c) => c.passed), checks };
6269
6488
  }
6270
6489
  const lines = [
@@ -6316,16 +6535,23 @@ async function handleBenchmarkCommand(directory, args) {
6316
6535
  lines.push(`- Test-to-Code Ratio: ${qualityMetrics.testToCodeRatio}% (min: ${qualityMetrics.thresholds.minTestToCodeRatio}%) ${qualityMetrics.testToCodeRatio >= qualityMetrics.thresholds.minTestToCodeRatio ? "\u2705" : "\u274C"}`);
6317
6536
  lines.push("");
6318
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
+ }
6319
6543
  if (ciGate) {
6320
6544
  lines.push("### CI Gate", ciGate.passed ? "\u2705 PASSED" : "\u274C FAILED");
6321
6545
  for (const c of ciGate.checks) {
6322
6546
  let valueStr;
6323
6547
  if (c.name === "Complexity Delta" || c.name === "Public API Delta") {
6324
6548
  valueStr = `${c.value}`;
6549
+ } else if (c.name === "Total cost") {
6550
+ valueStr = `$${c.value.toFixed(6)}`;
6325
6551
  } else {
6326
6552
  valueStr = `${c.value}%`;
6327
6553
  }
6328
- 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}%`;
6329
6555
  lines.push(`- ${c.name}: ${valueStr} ${c.operator} ${thresholdStr} ${c.passed ? "\u2705" : "\u274C"}`);
6330
6556
  }
6331
6557
  lines.push("");
@@ -6366,6 +6592,18 @@ async function handleBenchmarkCommand(directory, args) {
6366
6592
  thresholds: qualityMetrics.thresholds,
6367
6593
  has_evidence: qualityMetrics.hasEvidence
6368
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
+ };
6369
6607
  if (ciGate)
6370
6608
  json.ci_gate = {
6371
6609
  passed: ciGate.passed,
@@ -6381,6 +6619,20 @@ async function handleBenchmarkCommand(directory, args) {
6381
6619
  return lines.join(`
6382
6620
  `);
6383
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
+ }
6384
6636
 
6385
6637
  // src/commands/brainstorm.ts
6386
6638
  function sanitizeTopic(raw) {
@@ -6402,8 +6654,8 @@ async function handleBrainstormCommand(_directory, args) {
6402
6654
 
6403
6655
  // src/tools/checkpoint.ts
6404
6656
  import * as child_process from "child_process";
6405
- import * as fs7 from "fs";
6406
- import * as path12 from "path";
6657
+ import * as fs8 from "fs";
6658
+ import * as path13 from "path";
6407
6659
 
6408
6660
  // src/tools/create-tool.ts
6409
6661
  function classifyToolError(error2) {
@@ -6490,13 +6742,13 @@ function validateLabel(label) {
6490
6742
  return null;
6491
6743
  }
6492
6744
  function getCheckpointLogPath(directory) {
6493
- return path12.join(directory, CHECKPOINT_LOG_PATH);
6745
+ return path13.join(directory, CHECKPOINT_LOG_PATH);
6494
6746
  }
6495
6747
  function readCheckpointLog(directory) {
6496
6748
  const logPath = getCheckpointLogPath(directory);
6497
6749
  try {
6498
- if (fs7.existsSync(logPath)) {
6499
- const content = fs7.readFileSync(logPath, "utf-8");
6750
+ if (fs8.existsSync(logPath)) {
6751
+ const content = fs8.readFileSync(logPath, "utf-8");
6500
6752
  const parsed = JSON.parse(content);
6501
6753
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
6502
6754
  return { version: 1, checkpoints: [] };
@@ -6508,13 +6760,13 @@ function readCheckpointLog(directory) {
6508
6760
  }
6509
6761
  function writeCheckpointLog(log2, directory) {
6510
6762
  const logPath = getCheckpointLogPath(directory);
6511
- const dir = path12.dirname(logPath);
6512
- if (!fs7.existsSync(dir)) {
6513
- fs7.mkdirSync(dir, { recursive: true });
6763
+ const dir = path13.dirname(logPath);
6764
+ if (!fs8.existsSync(dir)) {
6765
+ fs8.mkdirSync(dir, { recursive: true });
6514
6766
  }
6515
6767
  const tempPath = `${logPath}.tmp`;
6516
- fs7.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
6517
- fs7.renameSync(tempPath, logPath);
6768
+ fs8.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
6769
+ fs8.renameSync(tempPath, logPath);
6518
6770
  }
6519
6771
  function gitExec(args, cwd) {
6520
6772
  for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
@@ -6545,10 +6797,10 @@ function gitExec(args, cwd) {
6545
6797
  }
6546
6798
  function appendRetentionEvent(directory, event) {
6547
6799
  try {
6548
- const eventsPath = path12.join(directory, ".swarm", "events.jsonl");
6800
+ const eventsPath = path13.join(directory, ".swarm", "events.jsonl");
6549
6801
  const line = `${JSON.stringify({ ...event, timestamp: new Date().toISOString() })}
6550
6802
  `;
6551
- fs7.appendFileSync(eventsPath, line);
6803
+ fs8.appendFileSync(eventsPath, line);
6552
6804
  } catch {}
6553
6805
  }
6554
6806
  function getCurrentSha(directory) {
@@ -6910,8 +7162,8 @@ async function handleClarifyCommand(_directory, args) {
6910
7162
  // src/commands/close.ts
6911
7163
  import { spawnSync as spawnSync5 } from "child_process";
6912
7164
  import * as fsSync2 from "fs";
6913
- import { promises as fs12 } from "fs";
6914
- import path25 from "path";
7165
+ import { promises as fs13 } from "fs";
7166
+ import path26 from "path";
6915
7167
 
6916
7168
  // src/hooks/abort-utils.ts
6917
7169
  function isAbortError(err) {
@@ -7040,8 +7292,8 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
7040
7292
  }
7041
7293
 
7042
7294
  // src/hooks/curator-postmortem.ts
7043
- import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync5 } from "fs";
7044
- import * as path13 from "path";
7295
+ import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync6 } from "fs";
7296
+ import * as path14 from "path";
7045
7297
  var MAX_INPUT_TEXT_CHARS = 500;
7046
7298
  var MAX_KNOWLEDGE_ENTRIES = 500;
7047
7299
  var MAX_PROPOSALS = 50;
@@ -7086,9 +7338,9 @@ async function collectKnowledgeSummary(directory) {
7086
7338
  }
7087
7339
  function readJsonlFile(filePath, maxLines) {
7088
7340
  try {
7089
- if (!existsSync5(filePath))
7341
+ if (!existsSync6(filePath))
7090
7342
  return [];
7091
- const content = readFileSync5(filePath, "utf-8");
7343
+ const content = readFileSync6(filePath, "utf-8");
7092
7344
  const results = [];
7093
7345
  const max = maxLines !== undefined && maxLines > 0 ? maxLines : Infinity;
7094
7346
  for (const line of content.split(`
@@ -7108,16 +7360,16 @@ function readJsonlFile(filePath, maxLines) {
7108
7360
  }
7109
7361
  function collectRetrospectives(directory) {
7110
7362
  const results = [];
7111
- const evidenceDir = path13.join(directory, ".swarm", "evidence");
7363
+ const evidenceDir = path14.join(directory, ".swarm", "evidence");
7112
7364
  try {
7113
- if (!existsSync5(evidenceDir))
7365
+ if (!existsSync6(evidenceDir))
7114
7366
  return results;
7115
7367
  const retroDirs = readdirSync(evidenceDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("retro-")).slice(0, MAX_RETROSPECTIVES);
7116
7368
  for (const entry of retroDirs) {
7117
- const retroPath = path13.join(evidenceDir, entry.name, "evidence.json");
7118
- if (existsSync5(retroPath)) {
7369
+ const retroPath = path14.join(evidenceDir, entry.name, "evidence.json");
7370
+ if (existsSync6(retroPath)) {
7119
7371
  try {
7120
- results.push(readFileSync5(retroPath, "utf-8"));
7372
+ results.push(readFileSync6(retroPath, "utf-8"));
7121
7373
  } catch {}
7122
7374
  }
7123
7375
  }
@@ -7126,14 +7378,14 @@ function collectRetrospectives(directory) {
7126
7378
  }
7127
7379
  function collectDriftReports(directory) {
7128
7380
  const results = [];
7129
- const swarmDir = path13.join(directory, ".swarm");
7381
+ const swarmDir = path14.join(directory, ".swarm");
7130
7382
  try {
7131
- if (!existsSync5(swarmDir))
7383
+ if (!existsSync6(swarmDir))
7132
7384
  return results;
7133
7385
  const driftFiles = readdirSync(swarmDir).filter((e) => e.startsWith("drift-report-phase-") && e.endsWith(".json")).slice(0, MAX_DRIFT_REPORTS);
7134
7386
  for (const entry of driftFiles) {
7135
7387
  try {
7136
- results.push(readFileSync5(path13.join(swarmDir, entry), "utf-8"));
7388
+ results.push(readFileSync6(path14.join(swarmDir, entry), "utf-8"));
7137
7389
  } catch {}
7138
7390
  }
7139
7391
  } catch {}
@@ -7141,24 +7393,24 @@ function collectDriftReports(directory) {
7141
7393
  }
7142
7394
  function collectPendingProposals(directory) {
7143
7395
  const results = [];
7144
- const insightPath = path13.join(directory, ".swarm", "insight-candidates.jsonl");
7145
- if (existsSync5(insightPath)) {
7396
+ const insightPath = path14.join(directory, ".swarm", "insight-candidates.jsonl");
7397
+ if (existsSync6(insightPath)) {
7146
7398
  try {
7147
7399
  results.push({
7148
7400
  source: "insight-candidates",
7149
- content: readFileSync5(insightPath, "utf-8")
7401
+ content: readFileSync6(insightPath, "utf-8")
7150
7402
  });
7151
7403
  } catch {}
7152
7404
  }
7153
- const proposalsDir = path13.join(directory, ".swarm", "skills", "proposals");
7405
+ const proposalsDir = path14.join(directory, ".swarm", "skills", "proposals");
7154
7406
  try {
7155
- if (existsSync5(proposalsDir)) {
7407
+ if (existsSync6(proposalsDir)) {
7156
7408
  const proposalFiles = readdirSync(proposalsDir).filter((e) => e.endsWith(".md") || e.endsWith(".json")).slice(0, MAX_PROPOSALS);
7157
7409
  for (const entry of proposalFiles) {
7158
7410
  try {
7159
7411
  results.push({
7160
7412
  source: `proposals/${entry}`,
7161
- content: readFileSync5(path13.join(proposalsDir, entry), "utf-8")
7413
+ content: readFileSync6(path14.join(proposalsDir, entry), "utf-8")
7162
7414
  });
7163
7415
  } catch {}
7164
7416
  }
@@ -7168,9 +7420,9 @@ function collectPendingProposals(directory) {
7168
7420
  }
7169
7421
  function isReportValid(reportPath) {
7170
7422
  try {
7171
- if (!existsSync5(reportPath))
7423
+ if (!existsSync6(reportPath))
7172
7424
  return false;
7173
- const content = readFileSync5(reportPath, "utf-8").trim();
7425
+ const content = readFileSync6(reportPath, "utf-8").trim();
7174
7426
  if (content.length === 0)
7175
7427
  return false;
7176
7428
  if (!content.startsWith("# Post-Mortem Report:"))
@@ -7379,7 +7631,7 @@ async function runCuratorPostMortem(directory, options = {}) {
7379
7631
  warnings.push(`Pending proposals capped at ${MAX_PROPOSALS} (had ${proposals.length}); older entries truncated.`);
7380
7632
  proposals = proposals.slice(0, MAX_PROPOSALS);
7381
7633
  }
7382
- const unactionablePath = path13.join(resolveKnowledgeStoreDir(directory), "knowledge-unactionable.jsonl");
7634
+ const unactionablePath = path14.join(resolveKnowledgeStoreDir(directory), "knowledge-unactionable.jsonl");
7383
7635
  let unactionable = readJsonlFile(unactionablePath, MAX_UNACTIONABLE);
7384
7636
  if (unactionable.length > MAX_UNACTIONABLE) {
7385
7637
  warnings.push(`Unactionable entries capped at ${MAX_UNACTIONABLE} (had ${unactionable.length}); older entries truncated.`);
@@ -7429,7 +7681,7 @@ ${llmOutput}`;
7429
7681
  }
7430
7682
  try {
7431
7683
  const { mkdirSync: mkdirSync6 } = await import("fs");
7432
- mkdirSync6(path13.dirname(reportPath), { recursive: true });
7684
+ mkdirSync6(path14.dirname(reportPath), { recursive: true });
7433
7685
  await atomicWriteFile(reportPath, reportContent);
7434
7686
  } catch (err) {
7435
7687
  const msg = err instanceof Error ? err.message : String(err);
@@ -7477,7 +7729,7 @@ var _internals13 = {
7477
7729
  };
7478
7730
 
7479
7731
  // src/hooks/hive-promoter.ts
7480
- import path16 from "path";
7732
+ import path17 from "path";
7481
7733
 
7482
7734
  // src/background/event-bus.ts
7483
7735
  class AutomationEventBus {
@@ -7981,9 +8233,9 @@ init_logger();
7981
8233
 
7982
8234
  // src/services/skill-improver-quota.ts
7983
8235
  var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
7984
- import { existsSync as existsSync6 } from "fs";
8236
+ import { existsSync as existsSync7 } from "fs";
7985
8237
  import { mkdir as mkdir3, readFile as readFile3, rename, writeFile as writeFile2 } from "fs/promises";
7986
- import * as path14 from "path";
8238
+ import * as path15 from "path";
7987
8239
  var LOCK_ACQUIRE_TIMEOUT_MS = 1e4;
7988
8240
  var LOCK_RETRY_OPTS = {
7989
8241
  retries: {
@@ -8012,7 +8264,7 @@ async function acquireLock(dir) {
8012
8264
  }
8013
8265
  function resolveQuotaPath(directory, scope = "skill-improver") {
8014
8266
  const fileName = scope === "knowledge-enrichment" ? "knowledge-enrichment-quota.json" : "skill-improver-quota.json";
8015
- return path14.join(directory, ".swarm", fileName);
8267
+ return path15.join(directory, ".swarm", fileName);
8016
8268
  }
8017
8269
  function todayKey(window, now = new Date) {
8018
8270
  if (window === "utc") {
@@ -8024,7 +8276,7 @@ function todayKey(window, now = new Date) {
8024
8276
  return `${yr}-${m}-${d}`;
8025
8277
  }
8026
8278
  async function readState(filePath) {
8027
- if (!existsSync6(filePath))
8279
+ if (!existsSync7(filePath))
8028
8280
  return null;
8029
8281
  try {
8030
8282
  const raw = await readFile3(filePath, "utf-8");
@@ -8038,7 +8290,7 @@ async function readState(filePath) {
8038
8290
  }
8039
8291
  }
8040
8292
  async function writeState(filePath, state) {
8041
- await mkdir3(path14.dirname(filePath), { recursive: true });
8293
+ await mkdir3(path15.dirname(filePath), { recursive: true });
8042
8294
  const tmp = `${filePath}.tmp-${process.pid}`;
8043
8295
  await writeFile2(tmp, JSON.stringify(state, null, 2), "utf-8");
8044
8296
  await rename(tmp, filePath);
@@ -8061,10 +8313,10 @@ async function getQuotaState(directory, opts) {
8061
8313
  }
8062
8314
  async function reserveQuota(directory, opts) {
8063
8315
  const filePath = resolveQuotaPath(directory, opts.scope);
8064
- await mkdir3(path14.dirname(filePath), { recursive: true });
8316
+ await mkdir3(path15.dirname(filePath), { recursive: true });
8065
8317
  let release = null;
8066
8318
  try {
8067
- release = await acquireLock(path14.dirname(filePath));
8319
+ release = await acquireLock(path15.dirname(filePath));
8068
8320
  const state = await getQuotaState(directory, opts);
8069
8321
  if (state.calls_used + opts.nCalls > opts.maxCalls) {
8070
8322
  return {
@@ -8091,10 +8343,10 @@ async function reserveQuota(directory, opts) {
8091
8343
  }
8092
8344
  async function releaseQuota(directory, opts) {
8093
8345
  const filePath = resolveQuotaPath(directory, opts.scope);
8094
- await mkdir3(path14.dirname(filePath), { recursive: true });
8346
+ await mkdir3(path15.dirname(filePath), { recursive: true });
8095
8347
  let release = null;
8096
8348
  try {
8097
- release = await acquireLock(path14.dirname(filePath));
8349
+ release = await acquireLock(path15.dirname(filePath));
8098
8350
  const state = await getQuotaState(directory, opts);
8099
8351
  const next = {
8100
8352
  ...state,
@@ -8117,8 +8369,8 @@ init_logger();
8117
8369
 
8118
8370
  // src/hooks/skill-usage-log.ts
8119
8371
  import * as crypto3 from "crypto";
8120
- import * as fs8 from "fs";
8121
- import * as path15 from "path";
8372
+ import * as fs9 from "fs";
8373
+ import * as path16 from "path";
8122
8374
  function resolveLogPath(directory) {
8123
8375
  return validateSwarmPath(directory, "skill-usage.jsonl");
8124
8376
  }
@@ -8127,16 +8379,16 @@ function normalizeComplianceVerdict(verdict) {
8127
8379
  }
8128
8380
  var _internals14 = {
8129
8381
  generateId: () => crypto3.randomUUID(),
8130
- appendFileSync: fs8.appendFileSync.bind(fs8),
8131
- readFileSync: fs8.readFileSync.bind(fs8),
8132
- writeFileSync: fs8.writeFileSync.bind(fs8),
8133
- renameSync: fs8.renameSync.bind(fs8),
8134
- mkdirSync: fs8.mkdirSync.bind(fs8),
8135
- existsSync: fs8.existsSync.bind(fs8),
8136
- statSync: fs8.statSync.bind(fs8),
8137
- openSync: fs8.openSync.bind(fs8),
8138
- readSync: fs8.readSync.bind(fs8),
8139
- 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),
8140
8392
  pruneSkillUsageLog,
8141
8393
  resolveSourceKnowledgeIds,
8142
8394
  applySkillUsageFeedback,
@@ -8217,7 +8469,7 @@ function appendFeedbackAppliedMarker(directory, processedEntryIds) {
8217
8469
  if (processedEntryIds.length === 0)
8218
8470
  return;
8219
8471
  const resolved = resolveLogPath(directory);
8220
- const dir = path15.dirname(resolved);
8472
+ const dir = path16.dirname(resolved);
8221
8473
  if (!_internals14.existsSync(dir)) {
8222
8474
  _internals14.mkdirSync(dir, { recursive: true });
8223
8475
  }
@@ -8262,7 +8514,7 @@ function appendSkillUsageEntry(directory, entry) {
8262
8514
  throw new Error("sessionID is required and must be a non-empty string");
8263
8515
  }
8264
8516
  const resolved = validateSwarmPath(directory, "skill-usage.jsonl");
8265
- const dir = path15.dirname(resolved);
8517
+ const dir = path16.dirname(resolved);
8266
8518
  if (!_internals14.existsSync(dir)) {
8267
8519
  _internals14.mkdirSync(dir, { recursive: true });
8268
8520
  }
@@ -8438,8 +8690,8 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8438
8690
  }
8439
8691
  if (entries.length === 0) {
8440
8692
  if (preservedMarkers.length > 0) {
8441
- const dir2 = path15.dirname(resolved);
8442
- 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`);
8443
8695
  const content2 = preservedMarkers.join(`
8444
8696
  `).concat(preservedMarkers.length > 0 ? `
8445
8697
  ` : "");
@@ -8481,8 +8733,8 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8481
8733
  if (pruned === 0) {
8482
8734
  return { pruned: 0, remaining: entries.length };
8483
8735
  }
8484
- const dir = path15.dirname(resolved);
8485
- 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`);
8486
8738
  const entryLines = surviving.map((e) => JSON.stringify(e));
8487
8739
  const allLines = [...entryLines, ...preservedMarkers];
8488
8740
  const content = allLines.join(`
@@ -8511,9 +8763,9 @@ async function resolveSourceKnowledgeIds(directory, skillPath) {
8511
8763
  if (/\.\.[/\\]/.test(cleanPath)) {
8512
8764
  return [];
8513
8765
  }
8514
- const absolute = path15.normalize(path15.isAbsolute(cleanPath) ? cleanPath : path15.resolve(directory, cleanPath));
8515
- const baseDir = path15.normalize(path15.resolve(directory));
8516
- 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);
8517
8769
  if (!isContained) {
8518
8770
  return [];
8519
8771
  }
@@ -8825,7 +9077,7 @@ async function promoteToHive(directory, lesson, category) {
8825
9077
  schema_version: 1,
8826
9078
  created_at: new Date().toISOString(),
8827
9079
  updated_at: new Date().toISOString(),
8828
- source_project: path16.basename(directory) || "unknown",
9080
+ source_project: path17.basename(directory) || "unknown",
8829
9081
  encounter_score: 1
8830
9082
  };
8831
9083
  await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
@@ -8877,9 +9129,9 @@ async function promoteFromSwarm(directory, lessonId) {
8877
9129
 
8878
9130
  // src/hooks/knowledge-curator.ts
8879
9131
  import { createHash as createHash3 } from "crypto";
8880
- import { existsSync as existsSync10 } from "fs";
9132
+ import { existsSync as existsSync11 } from "fs";
8881
9133
  import { appendFile as appendFile2, mkdir as mkdir5, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
8882
- import * as path21 from "path";
9134
+ import * as path22 from "path";
8883
9135
 
8884
9136
  // src/services/synonym-map.ts
8885
9137
  var import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
@@ -8891,7 +9143,7 @@ import {
8891
9143
  unlink as unlink2,
8892
9144
  writeFile as writeFile3
8893
9145
  } from "fs/promises";
8894
- import * as path17 from "path";
9146
+ import * as path18 from "path";
8895
9147
  var SYNONYM_MAP_FILENAME = "synonym-map.json";
8896
9148
  var MAX_TOKEN_LENGTH = 64;
8897
9149
  var DEFAULT_MAX_PAIRS = 500;
@@ -9046,7 +9298,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
9046
9298
  }
9047
9299
  }
9048
9300
  async function writeSynonymMapAtomic(filePath, map) {
9049
- await mkdir4(path17.dirname(filePath), { recursive: true });
9301
+ await mkdir4(path18.dirname(filePath), { recursive: true });
9050
9302
  const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
9051
9303
  try {
9052
9304
  await writeFile3(tmp, JSON.stringify(map, null, 2), "utf-8");
@@ -9059,7 +9311,7 @@ async function writeSynonymMapAtomic(filePath, map) {
9059
9311
  }
9060
9312
  async function rebuildSynonymMap(directory, entries, maxPairs = DEFAULT_MAX_PAIRS) {
9061
9313
  const filePath = resolveSynonymMapPath(directory);
9062
- const dir = path17.dirname(filePath);
9314
+ const dir = path18.dirname(filePath);
9063
9315
  await mkdir4(dir, { recursive: true });
9064
9316
  let release = null;
9065
9317
  try {
@@ -9122,19 +9374,19 @@ function reinforceSwarmKnowledgeEntry(entry, confirmation) {
9122
9374
  }
9123
9375
 
9124
9376
  // src/hooks/micro-reflector.ts
9125
- import { existsSync as existsSync9 } from "fs";
9377
+ import { existsSync as existsSync10 } from "fs";
9126
9378
  import { readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
9127
- import * as path20 from "path";
9379
+ import * as path21 from "path";
9128
9380
  init_logger();
9129
9381
 
9130
9382
  // src/hooks/skill-propagation-gate.ts
9131
- import * as fs10 from "fs";
9132
- import * as path19 from "path";
9383
+ import * as fs11 from "fs";
9384
+ import * as path20 from "path";
9133
9385
  init_logger();
9134
9386
 
9135
9387
  // src/hooks/skill-scoring.ts
9136
- import * as fs9 from "fs";
9137
- import * as path18 from "path";
9388
+ import * as fs10 from "fs";
9389
+ import * as path19 from "path";
9138
9390
  var FREQUENCY_CAP = 10;
9139
9391
  var FREQUENCY_WEIGHT = 0.3;
9140
9392
  var COMPLIANCE_WEIGHT = 0.3;
@@ -9162,10 +9414,10 @@ var _internals15 = {
9162
9414
  computeTriggerMatchBoost: null
9163
9415
  };
9164
9416
  function extractSkillName(skillPath) {
9165
- const base = path18.basename(skillPath, path18.extname(skillPath));
9417
+ const base = path19.basename(skillPath, path19.extname(skillPath));
9166
9418
  if (base !== "SKILL")
9167
9419
  return base;
9168
- const parent = path18.basename(path18.dirname(skillPath));
9420
+ const parent = path19.basename(path19.dirname(skillPath));
9169
9421
  return parent;
9170
9422
  }
9171
9423
  function stripQuotes(value) {
@@ -9307,25 +9559,25 @@ function parseSkillFrontmatter(content, skillPath) {
9307
9559
  return meta;
9308
9560
  }
9309
9561
  function readFilePrefix(filePath) {
9310
- const fd = fs9.openSync(filePath, "r");
9562
+ const fd = fs10.openSync(filePath, "r");
9311
9563
  try {
9312
9564
  const buffer = Buffer.alloc(SKILL_FRONTMATTER_READ_BYTES);
9313
- 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);
9314
9566
  return buffer.toString("utf-8", 0, bytesRead);
9315
9567
  } finally {
9316
- fs9.closeSync(fd);
9568
+ fs10.closeSync(fd);
9317
9569
  }
9318
9570
  }
9319
9571
  function readSkillMetadata(skillPath, directory) {
9320
9572
  const normalizedPath = skillPath.replace(/^file:/, "").replace(/\\/g, "/");
9321
9573
  const fallback = parseSkillFrontmatter("", normalizedPath);
9322
9574
  try {
9323
- if (path18.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
9575
+ if (path19.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
9324
9576
  return fallback;
9325
9577
  }
9326
- const root = path18.resolve(directory);
9327
- const absolutePath = path18.resolve(directory, normalizedPath);
9328
- 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)) {
9329
9581
  return fallback;
9330
9582
  }
9331
9583
  const content = readFilePrefix(absolutePath);
@@ -9459,10 +9711,10 @@ function getSkillStats(skillPath, directory) {
9459
9711
  };
9460
9712
  }
9461
9713
  function formatSkillIndexWithContext(skills, directory) {
9462
- const usageLogPath = path18.join(directory, ".swarm", "skill-usage.jsonl");
9714
+ const usageLogPath = path19.join(directory, ".swarm", "skill-usage.jsonl");
9463
9715
  let hasHistory = false;
9464
9716
  try {
9465
- const stat4 = fs9.statSync(usageLogPath);
9717
+ const stat4 = fs10.statSync(usageLogPath);
9466
9718
  hasHistory = stat4.size > 0;
9467
9719
  } catch {}
9468
9720
  if (!hasHistory) {
@@ -9593,7 +9845,7 @@ function parseYamlValue(value) {
9593
9845
  return trimmed;
9594
9846
  }
9595
9847
  function loadRoutingSkills(directory, targetAgent) {
9596
- const routingPath = path19.join(directory, ".opencode", "skill-routing.yaml");
9848
+ const routingPath = path20.join(directory, ".opencode", "skill-routing.yaml");
9597
9849
  if (!_internals16.existsSync(routingPath))
9598
9850
  return [];
9599
9851
  try {
@@ -9625,13 +9877,13 @@ var SKILL_SEARCH_ROOTS = [
9625
9877
  ];
9626
9878
  var MAX_SCORING_SESSION_ENTRIES = 500;
9627
9879
  var _internals16 = {
9628
- readdirSync: fs10.readdirSync.bind(fs10),
9629
- existsSync: fs10.existsSync.bind(fs10),
9630
- statSync: fs10.statSync.bind(fs10),
9631
- mkdirSync: fs10.mkdirSync.bind(fs10),
9632
- appendFileSync: fs10.appendFileSync.bind(fs10),
9633
- readFileSync: fs10.readFileSync.bind(fs10),
9634
- 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),
9635
9887
  skillPropagationGateBefore: null,
9636
9888
  skillPropagationTransformScan: null,
9637
9889
  SKILL_CAPABLE_AGENTS,
@@ -9653,7 +9905,7 @@ var _internals16 = {
9653
9905
  function discoverAvailableSkills(directory) {
9654
9906
  const results = [];
9655
9907
  for (const root of SKILL_SEARCH_ROOTS) {
9656
- const rootPath = path19.join(directory, root);
9908
+ const rootPath = path20.join(directory, root);
9657
9909
  if (!_internals16.existsSync(rootPath))
9658
9910
  continue;
9659
9911
  let entries;
@@ -9665,13 +9917,13 @@ function discoverAvailableSkills(directory) {
9665
9917
  for (const entry of entries) {
9666
9918
  if (entry.startsWith("."))
9667
9919
  continue;
9668
- const skillDir = path19.join(rootPath, entry);
9669
- 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")))
9670
9922
  continue;
9671
- const skillFile = path19.join(skillDir, "SKILL.md");
9923
+ const skillFile = path20.join(skillDir, "SKILL.md");
9672
9924
  try {
9673
9925
  if (_internals16.statSync(skillDir).isDirectory() && _internals16.existsSync(skillFile)) {
9674
- results.push(path19.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
9926
+ results.push(path20.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
9675
9927
  }
9676
9928
  } catch (err) {
9677
9929
  warn(`[skill-propagation-gate] failed to stat skill directory ${entry}: ${err instanceof Error ? err.message : String(err)}`);
@@ -9740,9 +9992,9 @@ function extractSkillsFieldFromPrompt(prompt) {
9740
9992
  return "";
9741
9993
  }
9742
9994
  function writeWarnEvent(directory, record) {
9743
- const filePath = path19.join(directory, ".swarm", "events.jsonl");
9995
+ const filePath = path20.join(directory, ".swarm", "events.jsonl");
9744
9996
  try {
9745
- const dir = path19.dirname(filePath);
9997
+ const dir = path20.dirname(filePath);
9746
9998
  if (!_internals16.existsSync(dir)) {
9747
9999
  _internals16.mkdirSync(dir, { recursive: true });
9748
10000
  }
@@ -9871,8 +10123,8 @@ async function skillPropagationGateBefore(directory, input, config) {
9871
10123
  if (routingPaths.length > 0) {
9872
10124
  const existingPaths = new Set(scored.map((s) => s.skillPath));
9873
10125
  for (const routingPath of routingPaths) {
9874
- const routedSkillDir = path19.dirname(path19.join(directory, routingPath));
9875
- 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")))
9876
10128
  continue;
9877
10129
  if (!existingPaths.has(routingPath)) {
9878
10130
  scored.push({
@@ -9891,8 +10143,8 @@ async function skillPropagationGateBefore(directory, input, config) {
9891
10143
  let skillsForIndex = availableSkills;
9892
10144
  if (scoringSkipped) {
9893
10145
  skillsForIndex = [...availableSkills].sort((a, b) => {
9894
- const nameA = path19.basename(path19.dirname(a));
9895
- const nameB = path19.basename(path19.dirname(b));
10146
+ const nameA = path20.basename(path20.dirname(a));
10147
+ const nameB = path20.basename(path20.dirname(b));
9896
10148
  return nameA.localeCompare(nameB);
9897
10149
  });
9898
10150
  } else if (typeof scored !== "undefined" && scored.length > 0) {
@@ -9900,7 +10152,7 @@ async function skillPropagationGateBefore(directory, input, config) {
9900
10152
  }
9901
10153
  const formattedIndex = _internals16.formatSkillIndexWithContext(skillsForIndex, directory);
9902
10154
  if (formattedIndex.length > 0) {
9903
- const contextPath = path19.join(directory, ".swarm", "context.md");
10155
+ const contextPath = path20.join(directory, ".swarm", "context.md");
9904
10156
  let existingContent = "";
9905
10157
  if (_internals16.existsSync(contextPath)) {
9906
10158
  existingContent = _internals16.readFileSync(contextPath, "utf-8");
@@ -9922,7 +10174,7 @@ ${newSection}`;
9922
10174
  updatedContent = existingContent + newSection;
9923
10175
  }
9924
10176
  }
9925
- const swarmDir = path19.dirname(contextPath);
10177
+ const swarmDir = path20.dirname(contextPath);
9926
10178
  if (!_internals16.existsSync(swarmDir)) {
9927
10179
  _internals16.mkdirSync(swarmDir, { recursive: true });
9928
10180
  }
@@ -10148,9 +10400,9 @@ function resolveInsightCandidatesPath(directory) {
10148
10400
  }
10149
10401
  async function readTaskTrajectory(directory, taskId) {
10150
10402
  try {
10151
- const rel = path20.join("evidence", sanitizeTaskId(taskId), "trajectory.jsonl");
10403
+ const rel = path21.join("evidence", sanitizeTaskId(taskId), "trajectory.jsonl");
10152
10404
  const filePath = validateSwarmPath(directory, rel);
10153
- if (!existsSync9(filePath))
10405
+ if (!existsSync10(filePath))
10154
10406
  return [];
10155
10407
  const content = await readFile5(filePath, "utf-8");
10156
10408
  const out = [];
@@ -10206,7 +10458,7 @@ var WRITE_TOOLS = new Set([
10206
10458
  "apply_patch",
10207
10459
  "swarm_apply_patch"
10208
10460
  ]);
10209
- function isRecord(value) {
10461
+ function isRecord2(value) {
10210
10462
  return typeof value === "object" && value !== null;
10211
10463
  }
10212
10464
  function normalizePathField(value) {
@@ -10216,13 +10468,13 @@ function firstPathFromRecord(record) {
10216
10468
  return normalizePathField(record.path) ?? normalizePathField(record.filePath) ?? normalizePathField(record.file);
10217
10469
  }
10218
10470
  function normalizeWriteTrigger(input, output) {
10219
- if (!isRecord(input))
10471
+ if (!isRecord2(input))
10220
10472
  return null;
10221
10473
  const toolName = typeof input.toolName === "string" ? input.toolName : typeof input.tool === "string" ? input.tool : null;
10222
10474
  if (!toolName || !WRITE_TOOLS.has(toolName))
10223
10475
  return null;
10224
- const inputArgs = isRecord(input.args) ? input.args : null;
10225
- 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;
10226
10478
  const filePath = firstPathFromRecord(input) ?? (inputArgs ? firstPathFromRecord(inputArgs) : null) ?? (outputArgs ? firstPathFromRecord(outputArgs) : null);
10227
10479
  if (!filePath)
10228
10480
  return null;
@@ -10578,8 +10830,8 @@ RETRY: your last output was missing ${result.missing.join("; ")}; produce valid
10578
10830
  }
10579
10831
  async function appendCuratorSkippedEvent(directory, record) {
10580
10832
  try {
10581
- const filePath = path21.join(directory, ".swarm", "events.jsonl");
10582
- await mkdir5(path21.dirname(filePath), { recursive: true });
10833
+ const filePath = path22.join(directory, ".swarm", "events.jsonl");
10834
+ await mkdir5(path22.dirname(filePath), { recursive: true });
10583
10835
  await appendFile2(filePath, `${JSON.stringify({
10584
10836
  timestamp: new Date().toISOString(),
10585
10837
  event: "curator_skipped",
@@ -10619,7 +10871,7 @@ function readInsightJsonl(content) {
10619
10871
  async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BATCH_LIMIT) {
10620
10872
  try {
10621
10873
  const filePath = resolveInsightCandidatesPath(directory);
10622
- if (!existsSync10(filePath))
10874
+ if (!existsSync11(filePath))
10623
10875
  return [];
10624
10876
  const consumed = [];
10625
10877
  await transactFile(filePath, async (p) => readInsightJsonl(await readFile6(p, "utf-8").catch(() => "")), async (p, data) => {
@@ -11032,8 +11284,8 @@ var _internals17 = {
11032
11284
  };
11033
11285
 
11034
11286
  // src/services/session-reflection.ts
11035
- import { promises as fs11 } from "fs";
11036
- import * as path22 from "path";
11287
+ import { promises as fs12 } from "fs";
11288
+ import * as path23 from "path";
11037
11289
 
11038
11290
  // src/hooks/skill-improver-llm-factory.ts
11039
11291
  function resolveSkillImproverAgentName(sessionId) {
@@ -11186,13 +11438,13 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
11186
11438
  const lessons = [];
11187
11439
  const taxonomy = {};
11188
11440
  try {
11189
- const evidenceDir = path22.join(directory, ".swarm", "evidence");
11190
- const entries = await fs11.readdir(evidenceDir);
11441
+ const evidenceDir = path23.join(directory, ".swarm", "evidence");
11442
+ const entries = await fs12.readdir(evidenceDir);
11191
11443
  const retroDirs = entries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
11192
11444
  for (const retroDir of retroDirs) {
11193
- const evidencePath = path22.join(evidenceDir, retroDir, "evidence.json");
11445
+ const evidencePath = path23.join(evidenceDir, retroDir, "evidence.json");
11194
11446
  try {
11195
- const content = await fs11.readFile(evidencePath, "utf-8");
11447
+ const content = await fs12.readFile(evidencePath, "utf-8");
11196
11448
  const parsed = JSON.parse(content);
11197
11449
  const bundleEntries = parsed.entries ?? [parsed];
11198
11450
  for (const entry of bundleEntries) {
@@ -11219,14 +11471,14 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
11219
11471
  async function gatherGateFailures(directory) {
11220
11472
  const failures = new Map;
11221
11473
  try {
11222
- const evidenceDir = path22.join(directory, ".swarm", "evidence");
11223
- const entries = await fs11.readdir(evidenceDir);
11474
+ const evidenceDir = path23.join(directory, ".swarm", "evidence");
11475
+ const entries = await fs12.readdir(evidenceDir);
11224
11476
  for (const entry of entries) {
11225
11477
  if (entry.startsWith("retro-"))
11226
11478
  continue;
11227
- const evidencePath = path22.join(evidenceDir, entry, "evidence.json");
11479
+ const evidencePath = path23.join(evidenceDir, entry, "evidence.json");
11228
11480
  try {
11229
- const content = await fs11.readFile(evidencePath, "utf-8");
11481
+ const content = await fs12.readFile(evidencePath, "utf-8");
11230
11482
  const parsed = JSON.parse(content);
11231
11483
  const bundleEntries = parsed.entries ?? [parsed];
11232
11484
  for (const e of bundleEntries) {
@@ -11418,19 +11670,19 @@ async function writeSessionReflection(directory, result) {
11418
11670
  lines.push(result.architectReport);
11419
11671
  const content = lines.join(`
11420
11672
  `);
11421
- await fs11.writeFile(reflectionPath, content, "utf-8");
11673
+ await fs12.writeFile(reflectionPath, content, "utf-8");
11422
11674
  return reflectionPath;
11423
11675
  }
11424
11676
 
11425
11677
  // src/services/skill-improver.ts
11426
- import { existsSync as existsSync12 } from "fs";
11678
+ import { existsSync as existsSync13 } from "fs";
11427
11679
  import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as writeFile7 } from "fs/promises";
11428
- import * as path24 from "path";
11680
+ import * as path25 from "path";
11429
11681
  init_logger();
11430
11682
 
11431
11683
  // src/services/trajectory-cluster.ts
11432
11684
  import { mkdir as mkdir6, writeFile as writeFile6 } from "fs/promises";
11433
- import * as path23 from "path";
11685
+ import * as path24 from "path";
11434
11686
  init_logger();
11435
11687
  var MACRO_TRAJECTORY_WINDOW = 200;
11436
11688
  var MOTIF_MIN_TASKS = 2;
@@ -11562,11 +11814,11 @@ async function writeMotifProposals(directory, opts = {}) {
11562
11814
  if (motifs.length === 0)
11563
11815
  return result;
11564
11816
  const max = opts.maxProposals ?? 10;
11565
- const proposalsDir = validateSwarmPath(directory, path23.join("skills", "proposals"));
11817
+ const proposalsDir = validateSwarmPath(directory, path24.join("skills", "proposals"));
11566
11818
  await mkdir6(proposalsDir, { recursive: true });
11567
11819
  for (const motif of motifs.slice(0, max)) {
11568
11820
  const slug = `motif-${slugify(motif.signature)}`;
11569
- const filePath = path23.join(proposalsDir, `${slug}.md`);
11821
+ const filePath = path24.join(proposalsDir, `${slug}.md`);
11570
11822
  await writeFile6(filePath, buildMotifProposal(motif), "utf-8");
11571
11823
  result.proposalsWritten.push(filePath);
11572
11824
  }
@@ -11707,11 +11959,11 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
11707
11959
  if (motifs.length === 0)
11708
11960
  return result;
11709
11961
  const max = opts.maxProposals ?? 10;
11710
- const proposalsDir = validateSwarmPath(directory, path23.join("skills", "proposals"));
11962
+ const proposalsDir = validateSwarmPath(directory, path24.join("skills", "proposals"));
11711
11963
  await mkdir6(proposalsDir, { recursive: true });
11712
11964
  for (const motif of motifs.slice(0, max)) {
11713
11965
  const slug = workflowSlug(motif.signature);
11714
- const filePath = path23.join(proposalsDir, `${slug}.md`);
11966
+ const filePath = path24.join(proposalsDir, `${slug}.md`);
11715
11967
  await writeFile6(filePath, buildWorkflowProposal(motif), "utf-8");
11716
11968
  result.proposalsWritten.push(filePath);
11717
11969
  }
@@ -11723,14 +11975,14 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
11723
11975
  }
11724
11976
 
11725
11977
  // src/services/unactionable-hardening.ts
11726
- import { existsSync as existsSync11 } from "fs";
11978
+ import { existsSync as existsSync12 } from "fs";
11727
11979
  init_logger();
11728
11980
  var HARDENING_BATCH_LIMIT = 5;
11729
11981
  async function hardenUnactionableEntries(params) {
11730
11982
  const result = { hardened: 0, retired: 0, remaining: 0 };
11731
11983
  try {
11732
11984
  const queuePath = resolveUnactionablePath(params.directory);
11733
- if (!existsSync11(queuePath))
11985
+ if (!existsSync12(queuePath))
11734
11986
  return result;
11735
11987
  const limit = params.batchLimit ?? HARDENING_BATCH_LIMIT;
11736
11988
  const dedupThreshold = params.dedupThreshold ?? 0.6;
@@ -11834,7 +12086,7 @@ function timestampSlug(d) {
11834
12086
  return d.toISOString().replace(/[:.]/g, "-");
11835
12087
  }
11836
12088
  async function atomicWrite(p, content) {
11837
- await mkdir7(path24.dirname(p), { recursive: true });
12089
+ await mkdir7(path25.dirname(p), { recursive: true });
11838
12090
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
11839
12091
  await writeFile7(tmp, content, "utf-8");
11840
12092
  await rename3(tmp, p);
@@ -11842,7 +12094,7 @@ async function atomicWrite(p, content) {
11842
12094
  async function gatherInventory(directory) {
11843
12095
  const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
11844
12096
  const hivePath = resolveHiveKnowledgePath();
11845
- const hive = existsSync12(hivePath) ? await readKnowledge(hivePath) : [];
12097
+ const hive = existsSync13(hivePath) ? await readKnowledge(hivePath) : [];
11846
12098
  const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
11847
12099
  const skills = await listSkills(directory);
11848
12100
  const knowledgeById = new Map([...swarm, ...hive].map((entry) => [entry.id, entry]));
@@ -12237,8 +12489,8 @@ async function runSkillImprover(req) {
12237
12489
  }
12238
12490
  throw err;
12239
12491
  }
12240
- const proposalDir = path24.join(req.directory, ".swarm", "skill-improver", "proposals");
12241
- 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`);
12242
12494
  const finalBody = source === "llm" ? buildLLMProposalFrame({
12243
12495
  body,
12244
12496
  targets,
@@ -12721,20 +12973,20 @@ function countSessionKnowledgeEntries(entries, sessionStart, fallbackCount) {
12721
12973
  async function copyDirRecursiveWithFailures(src, dest) {
12722
12974
  let count = 0;
12723
12975
  const failures = [];
12724
- const entries = await fs12.readdir(src);
12725
- await fs12.mkdir(dest, { recursive: true });
12976
+ const entries = await fs13.readdir(src);
12977
+ await fs13.mkdir(dest, { recursive: true });
12726
12978
  for (const entry of entries) {
12727
- const srcEntry = path25.join(src, entry);
12728
- const destEntry = path25.join(dest, entry);
12979
+ const srcEntry = path26.join(src, entry);
12980
+ const destEntry = path26.join(dest, entry);
12729
12981
  try {
12730
- const stat4 = await fs12.stat(srcEntry);
12982
+ const stat4 = await fs13.stat(srcEntry);
12731
12983
  if (stat4.isDirectory()) {
12732
12984
  const subResult = await copyDirRecursiveWithFailures(srcEntry, destEntry);
12733
12985
  count += subResult.copied;
12734
12986
  failures.push(...subResult.failures);
12735
12987
  } else {
12736
12988
  try {
12737
- await fs12.copyFile(srcEntry, destEntry);
12989
+ await fs13.copyFile(srcEntry, destEntry);
12738
12990
  count++;
12739
12991
  } catch (err) {
12740
12992
  const errno = err?.code;
@@ -12909,20 +13161,20 @@ async function runFinalizeStage(ctx) {
12909
13161
  ctx.warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
12910
13162
  }
12911
13163
  }
12912
- const lessonsFilePath = path25.join(ctx.swarmDir, "close-lessons.md");
13164
+ const lessonsFilePath = path26.join(ctx.swarmDir, "close-lessons.md");
12913
13165
  try {
12914
- const lessonsText = await fs12.readFile(lessonsFilePath, "utf-8");
13166
+ const lessonsText = await fs13.readFile(lessonsFilePath, "utf-8");
12915
13167
  ctx.explicitLessons = lessonsText.split(`
12916
13168
  `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
12917
13169
  } catch {}
12918
13170
  try {
12919
- const evidenceDir = path25.join(ctx.swarmDir, "evidence");
12920
- const evidenceEntries = await fs12.readdir(evidenceDir);
13171
+ const evidenceDir = path26.join(ctx.swarmDir, "evidence");
13172
+ const evidenceEntries = await fs13.readdir(evidenceDir);
12921
13173
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
12922
13174
  for (const retroDir of retroDirs) {
12923
- const evidencePath = path25.join(evidenceDir, retroDir, "evidence.json");
13175
+ const evidencePath = path26.join(evidenceDir, retroDir, "evidence.json");
12924
13176
  try {
12925
- const content = await fs12.readFile(evidencePath, "utf-8");
13177
+ const content = await fs13.readFile(evidencePath, "utf-8");
12926
13178
  const parsed = JSON.parse(content);
12927
13179
  const entries = parsed.entries ?? [parsed];
12928
13180
  for (const entry of entries) {
@@ -12966,7 +13218,7 @@ async function runFinalizeStage(ctx) {
12966
13218
  console.warn("[close-command] curateAndStoreSwarm error:", error2);
12967
13219
  }
12968
13220
  if (ctx.curationSucceeded && ctx.allLessons.length > 0) {
12969
- await fs12.unlink(lessonsFilePath).catch(() => {});
13221
+ await fs13.unlink(lessonsFilePath).catch(() => {});
12970
13222
  }
12971
13223
  if (ctx.curationSucceeded) {
12972
13224
  if (ctx.config.hive_enabled === false) {} else {
@@ -13072,7 +13324,7 @@ async function runFinalizeStage(ctx) {
13072
13324
  }
13073
13325
  }
13074
13326
  try {
13075
- const { CuratorConfigSchema: CCS } = await import("./schema-mygkbbe9.js");
13327
+ const { CuratorConfigSchema: CCS } = await import("./schema-nz638xc3.js");
13076
13328
  const { config: pmLoadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
13077
13329
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
13078
13330
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -13102,7 +13354,7 @@ async function copySqliteSafe(srcPath, destPath) {
13102
13354
  let checkpointVerified = false;
13103
13355
  try {
13104
13356
  const result = spawnSync5("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
13105
- cwd: path25.dirname(srcPath),
13357
+ cwd: path26.dirname(srcPath),
13106
13358
  encoding: "utf-8",
13107
13359
  stdio: ["ignore", "pipe", "pipe"],
13108
13360
  timeout: 1e4,
@@ -13113,7 +13365,7 @@ async function copySqliteSafe(srcPath, destPath) {
13113
13365
  const code = result.error.code;
13114
13366
  if (code === "ENOENT") {
13115
13367
  try {
13116
- await fs12.copyFile(srcPath, destPath);
13368
+ await fs13.copyFile(srcPath, destPath);
13117
13369
  return {
13118
13370
  success: true,
13119
13371
  reason: "copied without WAL checkpoint (sqlite3 CLI unavailable)"
@@ -13152,7 +13404,7 @@ async function copySqliteSafe(srcPath, destPath) {
13152
13404
  };
13153
13405
  }
13154
13406
  try {
13155
- await fs12.copyFile(srcPath, destPath);
13407
+ await fs13.copyFile(srcPath, destPath);
13156
13408
  if (checkpointVerified) {
13157
13409
  return { success: true };
13158
13410
  }
@@ -13170,9 +13422,9 @@ async function copySqliteSafe(srcPath, destPath) {
13170
13422
  async function runArchiveStage(ctx) {
13171
13423
  ctx.timestamp = new Date().toISOString().replace(/[:.]/g, "-");
13172
13424
  ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
13173
- 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}`);
13174
13426
  try {
13175
- await fs12.mkdir(ctx.archiveDir, { recursive: true });
13427
+ await fs13.mkdir(ctx.archiveDir, { recursive: true });
13176
13428
  const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
13177
13429
  const linkedKnowledgeShared = isLinked(ctx.directory);
13178
13430
  if (linkedKnowledgeShared) {
@@ -13185,8 +13437,8 @@ async function runArchiveStage(ctx) {
13185
13437
  if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
13186
13438
  continue;
13187
13439
  }
13188
- const srcPath = path25.join(ctx.swarmDir, artifact);
13189
- const destPath = path25.join(ctx.archiveDir, artifact);
13440
+ const srcPath = path26.join(ctx.swarmDir, artifact);
13441
+ const destPath = path26.join(ctx.archiveDir, artifact);
13190
13442
  if (artifact === "swarm.db") {
13191
13443
  const result = await copySqliteSafe(srcPath, destPath);
13192
13444
  if (result.skipped) {} else if (result.success) {
@@ -13202,7 +13454,7 @@ async function runArchiveStage(ctx) {
13202
13454
  }
13203
13455
  } else {
13204
13456
  try {
13205
- await fs12.copyFile(srcPath, destPath);
13457
+ await fs13.copyFile(srcPath, destPath);
13206
13458
  ctx.archivedFileCount++;
13207
13459
  if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
13208
13460
  ctx.archivedActiveStateFiles.add(artifact);
@@ -13218,8 +13470,8 @@ async function runArchiveStage(ctx) {
13218
13470
  }
13219
13471
  }
13220
13472
  for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
13221
- const srcDir = path25.join(ctx.swarmDir, dirName);
13222
- const destDir = path25.join(ctx.archiveDir, dirName);
13473
+ const srcDir = path26.join(ctx.swarmDir, dirName);
13474
+ const destDir = path26.join(ctx.archiveDir, dirName);
13223
13475
  try {
13224
13476
  const result = await copyDirRecursiveWithFailures(srcDir, destDir);
13225
13477
  ctx.archivedFileCount += result.copied;
@@ -13292,9 +13544,9 @@ async function runCleanStage(ctx) {
13292
13544
  ctx.warnings.push(reason ? `Preserved ${artifact} because it was not successfully archived: ${reason}.` : `Preserved ${artifact} because it was not successfully archived.`);
13293
13545
  continue;
13294
13546
  }
13295
- const filePath = path25.join(ctx.swarmDir, artifact);
13547
+ const filePath = path26.join(ctx.swarmDir, artifact);
13296
13548
  try {
13297
- await fs12.unlink(filePath);
13549
+ await fs13.unlink(filePath);
13298
13550
  cleanedFiles.push(artifact);
13299
13551
  } catch (err) {
13300
13552
  const errno = err?.code;
@@ -13311,18 +13563,18 @@ async function runCleanStage(ctx) {
13311
13563
  if (!ctx.archivedActiveStateDirs.has(dirName)) {
13312
13564
  continue;
13313
13565
  }
13314
- const dirPath = path25.join(ctx.swarmDir, dirName);
13566
+ const dirPath = path26.join(ctx.swarmDir, dirName);
13315
13567
  try {
13316
- await fs12.rm(dirPath, { recursive: true, force: true });
13568
+ await fs13.rm(dirPath, { recursive: true, force: true });
13317
13569
  cleanedFiles.push(`${dirName}/`);
13318
13570
  } catch {}
13319
13571
  }
13320
13572
  try {
13321
- const swarmFiles = await fs12.readdir(ctx.swarmDir);
13573
+ const swarmFiles = await fs13.readdir(ctx.swarmDir);
13322
13574
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
13323
13575
  for (const backup of configBackups) {
13324
13576
  try {
13325
- await fs12.unlink(path25.join(ctx.swarmDir, backup));
13577
+ await fs13.unlink(path26.join(ctx.swarmDir, backup));
13326
13578
  configBackupsRemoved++;
13327
13579
  } catch (err) {
13328
13580
  const errno = err?.code;
@@ -13335,7 +13587,7 @@ async function runCleanStage(ctx) {
13335
13587
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
13336
13588
  for (const sibling of ledgerSiblings) {
13337
13589
  try {
13338
- await fs12.unlink(path25.join(ctx.swarmDir, sibling));
13590
+ await fs13.unlink(path26.join(ctx.swarmDir, sibling));
13339
13591
  } catch (err) {
13340
13592
  const errno = err?.code;
13341
13593
  if (errno === "ENOENT") {} else {
@@ -13353,16 +13605,16 @@ async function runCleanStage(ctx) {
13353
13605
  }
13354
13606
  let swarmPlanFilesRemoved = 0;
13355
13607
  const candidates = [
13356
- path25.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
13357
- path25.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
13358
- path25.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
13359
- path25.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
13360
- path25.join(ctx.directory, "SWARM_PLAN.json"),
13361
- 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")
13362
13614
  ];
13363
13615
  for (const candidate of candidates) {
13364
13616
  try {
13365
- await fs12.unlink(candidate);
13617
+ await fs13.unlink(candidate);
13366
13618
  swarmPlanFilesRemoved++;
13367
13619
  } catch (err) {
13368
13620
  if (err?.code !== "ENOENT") {
@@ -13372,11 +13624,11 @@ async function runCleanStage(ctx) {
13372
13624
  }
13373
13625
  let tmpFilesRemoved = 0;
13374
13626
  try {
13375
- const swarmFiles = await fs12.readdir(ctx.swarmDir);
13627
+ const swarmFiles = await fs13.readdir(ctx.swarmDir);
13376
13628
  const tmpFiles = swarmFiles.filter((f) => f.startsWith(".tmp."));
13377
13629
  for (const tmp of tmpFiles) {
13378
13630
  try {
13379
- await fs12.unlink(path25.join(ctx.swarmDir, tmp));
13631
+ await fs13.unlink(path26.join(ctx.swarmDir, tmp));
13380
13632
  tmpFilesRemoved++;
13381
13633
  } catch (err) {
13382
13634
  const errno = err?.code;
@@ -13397,7 +13649,7 @@ async function runCleanStage(ctx) {
13397
13649
  cleanedFiles.push(`${tmpFilesRemoved} .tmp.* file(s)`);
13398
13650
  }
13399
13651
  clearAllScopes(ctx.directory);
13400
- const contextPath = path25.join(ctx.swarmDir, "context.md");
13652
+ const contextPath = path26.join(ctx.swarmDir, "context.md");
13401
13653
  const contextContent = [
13402
13654
  "# Context",
13403
13655
  "",
@@ -13409,9 +13661,9 @@ async function runCleanStage(ctx) {
13409
13661
  ""
13410
13662
  ].join(`
13411
13663
  `);
13412
- 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)}`);
13413
13665
  try {
13414
- await fs12.writeFile(contextTempPath, contextContent, "utf-8");
13666
+ await fs13.writeFile(contextTempPath, contextContent, "utf-8");
13415
13667
  fsSync2.renameSync(contextTempPath, contextPath);
13416
13668
  } catch (error2) {
13417
13669
  try {
@@ -13473,7 +13725,7 @@ async function runAlignStage(ctx) {
13473
13725
  return { gitAlignResult, prunedBranches };
13474
13726
  }
13475
13727
  async function handleCloseCommand(directory, args, options = {}) {
13476
- const swarmDir = path25.join(directory, ".swarm");
13728
+ const swarmDir = path26.join(directory, ".swarm");
13477
13729
  try {
13478
13730
  const stat4 = fsSync2.lstatSync(swarmDir);
13479
13731
  if (stat4.isSymbolicLink()) {
@@ -13487,18 +13739,18 @@ async function handleCloseCommand(directory, args, options = {}) {
13487
13739
  const planPath = validateSwarmPath(directory, "plan.json");
13488
13740
  let planExists = false;
13489
13741
  let planData = {
13490
- title: path25.basename(directory) || "Ad-hoc session",
13742
+ title: path26.basename(directory) || "Ad-hoc session",
13491
13743
  phases: []
13492
13744
  };
13493
13745
  try {
13494
- const content = await fs12.readFile(planPath, "utf-8");
13746
+ const content = await fs13.readFile(planPath, "utf-8");
13495
13747
  planData = JSON.parse(content);
13496
13748
  planExists = true;
13497
13749
  } catch (error2) {
13498
13750
  if (error2?.code !== "ENOENT") {
13499
13751
  return `\u274C Failed to read plan.json: ${error2 instanceof Error ? error2.message : String(error2)}`;
13500
13752
  }
13501
- const swarmDirExists = await fs12.access(swarmDir).then(() => true).catch(() => false);
13753
+ const swarmDirExists = await fs13.access(swarmDir).then(() => true).catch(() => false);
13502
13754
  if (!swarmDirExists) {
13503
13755
  return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
13504
13756
  }
@@ -13512,15 +13764,15 @@ async function handleCloseCommand(directory, args, options = {}) {
13512
13764
  }
13513
13765
  try {
13514
13766
  if (!planExists) {
13515
- const archiveDir = path25.join(swarmDir, "archive");
13767
+ const archiveDir = path26.join(swarmDir, "archive");
13516
13768
  try {
13517
- const archiveEntries = await fs12.readdir(archiveDir);
13769
+ const archiveEntries = await fs13.readdir(archiveDir);
13518
13770
  const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
13519
13771
  if (hasArchiveBundle) {
13520
13772
  const hasActiveState = [
13521
13773
  ...ACTIVE_STATE_TO_CLEAN,
13522
13774
  ...ACTIVE_STATE_DIRS_TO_CLEAN
13523
- ].some((entry) => fsSync2.existsSync(path25.join(swarmDir, entry)));
13775
+ ].some((entry) => fsSync2.existsSync(path26.join(swarmDir, entry)));
13524
13776
  if (!hasActiveState) {
13525
13777
  return `\u2705 Already finalized \u2014 nothing to do.
13526
13778
 
@@ -13643,9 +13895,9 @@ This project was already finalized in a previous /swarm close run. The plan has
13643
13895
  ...ctx.warnings.length > 0 ? ["## Warnings", ...ctx.warnings.map((w) => `- ${w}`), ""] : []
13644
13896
  ].join(`
13645
13897
  `);
13646
- 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)}`);
13647
13899
  try {
13648
- await fs12.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
13900
+ await fs13.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
13649
13901
  fsSync2.renameSync(closeSummaryTempPath, closeSummaryPath);
13650
13902
  } catch (error2) {
13651
13903
  try {
@@ -13985,15 +14237,15 @@ function buildStatusMessage(session, plan) {
13985
14237
  }
13986
14238
 
13987
14239
  // src/commands/config.ts
13988
- import * as os6 from "os";
13989
- import * as path26 from "path";
14240
+ import * as os7 from "os";
14241
+ import * as path27 from "path";
13990
14242
  function getUserConfigDir2() {
13991
- return process.env.XDG_CONFIG_HOME || path26.join(os6.homedir(), ".config");
14243
+ return process.env.XDG_CONFIG_HOME || path27.join(os7.homedir(), ".config");
13992
14244
  }
13993
14245
  async function handleConfigCommand(directory, _args) {
13994
14246
  const config = loadPluginConfig(directory);
13995
- const userConfigPath = path26.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
13996
- 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");
13997
14249
  const lines = [
13998
14250
  "## Swarm Configuration",
13999
14251
  "",
@@ -14011,9 +14263,9 @@ async function handleConfigCommand(directory, _args) {
14011
14263
  }
14012
14264
 
14013
14265
  // src/services/skill-consolidation.ts
14014
- import { existsSync as existsSync14 } from "fs";
14266
+ import { existsSync as existsSync15 } from "fs";
14015
14267
  import { mkdir as mkdir8, readFile as readFile8, rename as rename4, writeFile as writeFile8 } from "fs/promises";
14016
- import * as path27 from "path";
14268
+ import * as path28 from "path";
14017
14269
 
14018
14270
  // src/utils/timeout.ts
14019
14271
  async function withTimeout(promise, ms, timeoutError) {
@@ -14038,11 +14290,11 @@ var DEFAULT_CONSOLIDATION_MAX_CALLS_PER_RUN = 1;
14038
14290
  var CONSOLIDATION_RUN_TIMEOUT_MS = 5 * 60 * 1000;
14039
14291
  var runningByDirectory = new Map;
14040
14292
  function consolidationStatePath(directory) {
14041
- return path27.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
14293
+ return path28.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
14042
14294
  }
14043
14295
  async function readState2(directory) {
14044
14296
  const filePath = consolidationStatePath(directory);
14045
- if (!existsSync14(filePath))
14297
+ if (!existsSync15(filePath))
14046
14298
  return {};
14047
14299
  try {
14048
14300
  const parsed = JSON.parse(await readFile8(filePath, "utf-8"));
@@ -14054,7 +14306,7 @@ async function readState2(directory) {
14054
14306
  }
14055
14307
  }
14056
14308
  async function atomicWrite2(filePath, content) {
14057
- await mkdir8(path27.dirname(filePath), { recursive: true });
14309
+ await mkdir8(path28.dirname(filePath), { recursive: true });
14058
14310
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
14059
14311
  await writeFile8(tmp, content, "utf-8");
14060
14312
  await rename4(tmp, filePath);
@@ -14134,7 +14386,7 @@ async function runSkillConsolidationInner(req) {
14134
14386
  };
14135
14387
  }
14136
14388
  async function runSkillConsolidation(req) {
14137
- const key = path27.resolve(req.directory);
14389
+ const key = path28.resolve(req.directory);
14138
14390
  const existing = runningByDirectory.get(key);
14139
14391
  if (existing) {
14140
14392
  return {
@@ -14216,6 +14468,55 @@ async function handleConsolidateCommand(directory, args, options = {}) {
14216
14468
  }
14217
14469
  }
14218
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
+
14219
14520
  // src/commands/council.ts
14220
14521
  var MAX_QUESTION_LEN = 2000;
14221
14522
  function sanitizeQuestion(raw) {
@@ -14286,8 +14587,8 @@ async function handleCouncilCommand(_directory, args) {
14286
14587
 
14287
14588
  // src/commands/coupling.ts
14288
14589
  import { randomBytes } from "crypto";
14289
- import * as fs13 from "fs";
14290
- import * as path29 from "path";
14590
+ import * as fs14 from "fs";
14591
+ import * as path30 from "path";
14291
14592
 
14292
14593
  // src/turbo/epic/cochange-source.ts
14293
14594
  import * as child_process3 from "child_process";
@@ -14297,7 +14598,7 @@ import { promisify as promisify2 } from "util";
14297
14598
  import * as child_process2 from "child_process";
14298
14599
  import { randomUUID as randomUUID3 } from "crypto";
14299
14600
  import { readdir as readdir4, readFile as readFile9, stat as stat4 } from "fs/promises";
14300
- import * as path28 from "path";
14601
+ import * as path29 from "path";
14301
14602
  import { promisify } from "util";
14302
14603
  function getExecFileAsync() {
14303
14604
  return promisify(child_process2.execFile);
@@ -14401,7 +14702,7 @@ async function scanSourceFiles(dir) {
14401
14702
  try {
14402
14703
  const entries = await readdir4(dir, { withFileTypes: true });
14403
14704
  for (const entry of entries) {
14404
- const fullPath = path28.join(dir, entry.name);
14705
+ const fullPath = path29.join(dir, entry.name);
14405
14706
  if (entry.isDirectory()) {
14406
14707
  if (skipDirs.has(entry.name)) {
14407
14708
  continue;
@@ -14409,7 +14710,7 @@ async function scanSourceFiles(dir) {
14409
14710
  const subFiles = await scanSourceFiles(fullPath);
14410
14711
  results.push(...subFiles);
14411
14712
  } else if (entry.isFile()) {
14412
- const ext = path28.extname(entry.name);
14713
+ const ext = path29.extname(entry.name);
14413
14714
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
14414
14715
  results.push(fullPath);
14415
14716
  }
@@ -14431,8 +14732,8 @@ async function getStaticEdges(directory) {
14431
14732
  continue;
14432
14733
  }
14433
14734
  try {
14434
- const sourceDir = path28.dirname(sourceFile);
14435
- const resolvedPath = path28.resolve(sourceDir, importPath);
14735
+ const sourceDir = path29.dirname(sourceFile);
14736
+ const resolvedPath = path29.resolve(sourceDir, importPath);
14436
14737
  const extensions = [
14437
14738
  "",
14438
14739
  ".ts",
@@ -14457,8 +14758,8 @@ async function getStaticEdges(directory) {
14457
14758
  if (!targetFile) {
14458
14759
  continue;
14459
14760
  }
14460
- const relSource = path28.relative(directory, sourceFile).replace(/\\/g, "/");
14461
- 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, "/");
14462
14763
  const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
14463
14764
  edges.add(key);
14464
14765
  } catch {}
@@ -14470,7 +14771,7 @@ async function getStaticEdges(directory) {
14470
14771
  function isTestImplementationPair(fileA, fileB) {
14471
14772
  const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
14472
14773
  const getBaseName = (filePath) => {
14473
- const base = path28.basename(filePath);
14774
+ const base = path29.basename(filePath);
14474
14775
  for (const pattern of testPatterns) {
14475
14776
  if (base.endsWith(pattern)) {
14476
14777
  return base.slice(0, -pattern.length);
@@ -14480,16 +14781,16 @@ function isTestImplementationPair(fileA, fileB) {
14480
14781
  };
14481
14782
  const baseA = getBaseName(fileA);
14482
14783
  const baseB = getBaseName(fileB);
14483
- return baseA === baseB && baseA !== path28.basename(fileA) && baseA !== path28.basename(fileB);
14784
+ return baseA === baseB && baseA !== path29.basename(fileA) && baseA !== path29.basename(fileB);
14484
14785
  }
14485
14786
  function hasSharedPrefix(fileA, fileB) {
14486
- const dirA = path28.dirname(fileA);
14487
- const dirB = path28.dirname(fileB);
14787
+ const dirA = path29.dirname(fileA);
14788
+ const dirB = path29.dirname(fileB);
14488
14789
  if (dirA !== dirB) {
14489
14790
  return false;
14490
14791
  }
14491
- const baseA = path28.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
14492
- 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)$/, "");
14493
14794
  if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
14494
14795
  return true;
14495
14796
  }
@@ -14544,8 +14845,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
14544
14845
  const entries = [];
14545
14846
  const now = new Date().toISOString();
14546
14847
  for (const pair of pairs.slice(0, 10)) {
14547
- const baseA = path28.basename(pair.fileA);
14548
- const baseB = path28.basename(pair.fileB);
14848
+ const baseA = path29.basename(pair.fileA);
14849
+ const baseB = path29.basename(pair.fileB);
14549
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.`;
14550
14851
  if (lesson.length > 280) {
14551
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.`;
@@ -14971,17 +15272,17 @@ function parseArgs3(args) {
14971
15272
  return parsed;
14972
15273
  }
14973
15274
  function persistReportJson(directory, report) {
14974
- const epicDir = path29.join(directory, ".swarm", "epic");
14975
- fs13.mkdirSync(epicDir, { recursive: true });
14976
- 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");
14977
15278
  const tmpPath = `${filePath}.tmp.${randomBytes(8).toString("hex")}`;
14978
- fs13.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
15279
+ fs14.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
14979
15280
  `, "utf-8");
14980
15281
  try {
14981
- fs13.renameSync(tmpPath, filePath);
15282
+ fs14.renameSync(tmpPath, filePath);
14982
15283
  } catch (err) {
14983
15284
  try {
14984
- fs13.unlinkSync(tmpPath);
15285
+ fs14.unlinkSync(tmpPath);
14985
15286
  } catch {}
14986
15287
  throw err;
14987
15288
  }
@@ -15032,7 +15333,7 @@ Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>
15032
15333
  persistStatus = {
15033
15334
  requested: true,
15034
15335
  written: true,
15035
- path: path29.relative(directory, writtenAt)
15336
+ path: path30.relative(directory, writtenAt)
15036
15337
  };
15037
15338
  } catch (err) {
15038
15339
  persistStatus = {
@@ -15091,7 +15392,7 @@ function formatCurationSummary(summary) {
15091
15392
  }
15092
15393
 
15093
15394
  // src/commands/dark-matter.ts
15094
- import path30 from "path";
15395
+ import path31 from "path";
15095
15396
  async function handleDarkMatterCommand(directory, args) {
15096
15397
  const options = {};
15097
15398
  for (let i = 0;i < args.length; i++) {
@@ -15123,7 +15424,7 @@ Ensure this is a git repository with commit history.`;
15123
15424
  const output = formatDarkMatterOutput(pairs);
15124
15425
  if (pairs.length > 0) {
15125
15426
  try {
15126
- const projectName = path30.basename(path30.resolve(directory));
15427
+ const projectName = path31.basename(path31.resolve(directory));
15127
15428
  const entries = darkMatterToKnowledgeEntries(pairs, projectName);
15128
15429
  if (entries.length > 0) {
15129
15430
  const knowledgePath = resolveSwarmKnowledgePath(directory);
@@ -15489,50 +15790,50 @@ ${USAGE5}`;
15489
15790
 
15490
15791
  // src/services/diagnose-service.ts
15491
15792
  import * as child_process4 from "child_process";
15492
- import { existsSync as existsSync17, readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync6 } from "fs";
15493
- 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";
15494
15795
  import { fileURLToPath } from "url";
15495
15796
 
15496
15797
  // src/config/cache-paths.ts
15497
- import * as os7 from "os";
15498
- import * as path31 from "path";
15798
+ import * as os8 from "os";
15799
+ import * as path32 from "path";
15499
15800
  function getPluginConfigDir() {
15500
- 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");
15501
15802
  }
15502
15803
  function getPluginCachePaths() {
15503
- 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");
15504
15805
  const configDir = getPluginConfigDir();
15505
15806
  const paths = [
15506
- path31.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
15507
- path31.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
15508
- 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")
15509
15810
  ];
15510
15811
  if (process.platform === "darwin") {
15511
- const libCaches = path31.join(os7.homedir(), "Library", "Caches");
15512
- 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"));
15513
15814
  }
15514
15815
  if (process.platform === "win32") {
15515
- const localAppData = process.env.LOCALAPPDATA || path31.join(os7.homedir(), "AppData", "Local");
15516
- const appData = process.env.APPDATA || path31.join(os7.homedir(), "AppData", "Roaming");
15517
- 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"));
15518
15819
  }
15519
15820
  return paths;
15520
15821
  }
15521
15822
  function getPluginLockFilePaths() {
15522
- 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");
15523
15824
  const configDir = getPluginConfigDir();
15524
15825
  const paths = [
15525
- path31.join(cacheBase, "opencode", "bun.lock"),
15526
- path31.join(cacheBase, "opencode", "bun.lockb"),
15527
- 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")
15528
15829
  ];
15529
15830
  if (process.platform === "darwin") {
15530
- const libCaches = path31.join(os7.homedir(), "Library", "Caches");
15531
- 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"));
15532
15833
  }
15533
15834
  if (process.platform === "win32") {
15534
- const localAppData = process.env.LOCALAPPDATA || path31.join(os7.homedir(), "AppData", "Local");
15535
- 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"));
15536
15837
  }
15537
15838
  return paths;
15538
15839
  }
@@ -15542,28 +15843,28 @@ init_capability_probe();
15542
15843
  init_executor();
15543
15844
 
15544
15845
  // src/services/knowledge-diagnostics.ts
15545
- import { existsSync as existsSync16 } from "fs";
15846
+ import { existsSync as existsSync17 } from "fs";
15546
15847
  import { readFile as readFile10 } from "fs/promises";
15547
15848
 
15548
15849
  // src/services/version-check.ts
15549
- 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";
15550
15851
  import { homedir as homedir4 } from "os";
15551
- import { join as join26 } from "path";
15852
+ import { join as join27 } from "path";
15552
15853
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
15553
15854
  function cacheDir() {
15554
15855
  const xdg = process.env.XDG_CACHE_HOME;
15555
- const base = xdg && xdg.length > 0 ? xdg : join26(homedir4(), ".cache");
15556
- return join26(base, "opencode-swarm");
15856
+ const base = xdg && xdg.length > 0 ? xdg : join27(homedir4(), ".cache");
15857
+ return join27(base, "opencode-swarm");
15557
15858
  }
15558
15859
  function cacheFile() {
15559
- return join26(cacheDir(), "version-check.json");
15860
+ return join27(cacheDir(), "version-check.json");
15560
15861
  }
15561
15862
  function readVersionCache() {
15562
15863
  try {
15563
- const path32 = cacheFile();
15564
- if (!existsSync15(path32))
15864
+ const path33 = cacheFile();
15865
+ if (!existsSync16(path33))
15565
15866
  return null;
15566
- const raw = readFileSync8(path32, "utf-8");
15867
+ const raw = readFileSync9(path33, "utf-8");
15567
15868
  const parsed = JSON.parse(raw);
15568
15869
  if (typeof parsed?.checkedAt !== "number")
15569
15870
  return null;
@@ -15602,7 +15903,7 @@ var SEVEN_DAYS_MS2 = 7 * 24 * 60 * 60 * 1000;
15602
15903
  var UNACTIONABLE_BACKLOG_WARN = 100;
15603
15904
  var INSIGHT_BACKLOG_WARN = 50;
15604
15905
  async function readRawLines(filePath) {
15605
- if (!existsSync16(filePath))
15906
+ if (!existsSync17(filePath))
15606
15907
  return { entries: [], corrupt: 0 };
15607
15908
  const content = await readFile10(filePath, "utf-8");
15608
15909
  const entries = [];
@@ -15727,7 +16028,7 @@ async function computeKnowledgeDebug(directory) {
15727
16028
  };
15728
16029
  }
15729
16030
  async function safeJsonlCount(filePath) {
15730
- if (!filePath || !existsSync16(filePath))
16031
+ if (!filePath || !existsSync17(filePath))
15731
16032
  return 0;
15732
16033
  try {
15733
16034
  const content = await readFile10(filePath, "utf-8");
@@ -16048,7 +16349,7 @@ async function checkConfigBackups(directory) {
16048
16349
  }
16049
16350
  async function checkGitRepository(directory) {
16050
16351
  try {
16051
- if (!existsSync17(directory) || !statSync6(directory).isDirectory()) {
16352
+ if (!existsSync18(directory) || !statSync6(directory).isDirectory()) {
16052
16353
  return {
16053
16354
  name: "Git Repository",
16054
16355
  status: "\u274C",
@@ -16112,8 +16413,8 @@ async function checkSpecStaleness(directory, plan) {
16112
16413
  };
16113
16414
  }
16114
16415
  async function checkConfigParseability(directory) {
16115
- const configPath = path32.join(directory, ".opencode/opencode-swarm.json");
16116
- if (!existsSync17(configPath)) {
16416
+ const configPath = path33.join(directory, ".opencode/opencode-swarm.json");
16417
+ if (!existsSync18(configPath)) {
16117
16418
  return {
16118
16419
  name: "Config Parseability",
16119
16420
  status: "\u2705",
@@ -16121,7 +16422,7 @@ async function checkConfigParseability(directory) {
16121
16422
  };
16122
16423
  }
16123
16424
  try {
16124
- const content = readFileSync9(configPath, "utf-8");
16425
+ const content = readFileSync10(configPath, "utf-8");
16125
16426
  JSON.parse(content);
16126
16427
  return {
16127
16428
  name: "Config Parseability",
@@ -16141,7 +16442,7 @@ function resolveGrammarDir(thisDir) {
16141
16442
  const normalized = thisDir.replace(/\\/g, "/");
16142
16443
  const isSource = normalized.endsWith("/src/services");
16143
16444
  const isCliBundle = normalized.endsWith("/cli");
16144
- 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");
16145
16446
  }
16146
16447
  async function checkGrammarWasmFiles() {
16147
16448
  const grammarFiles = [
@@ -16165,14 +16466,14 @@ async function checkGrammarWasmFiles() {
16165
16466
  "tree-sitter-ini.wasm",
16166
16467
  "tree-sitter-regex.wasm"
16167
16468
  ];
16168
- const thisDir = path32.dirname(fileURLToPath(import.meta.url));
16469
+ const thisDir = path33.dirname(fileURLToPath(import.meta.url));
16169
16470
  const grammarDir = resolveGrammarDir(thisDir);
16170
16471
  const missing = [];
16171
- if (!existsSync17(path32.join(grammarDir, "tree-sitter.wasm"))) {
16472
+ if (!existsSync18(path33.join(grammarDir, "tree-sitter.wasm"))) {
16172
16473
  missing.push("tree-sitter.wasm (core runtime)");
16173
16474
  }
16174
16475
  for (const file of grammarFiles) {
16175
- if (!existsSync17(path32.join(grammarDir, file))) {
16476
+ if (!existsSync18(path33.join(grammarDir, file))) {
16176
16477
  missing.push(file);
16177
16478
  }
16178
16479
  }
@@ -16190,8 +16491,8 @@ async function checkGrammarWasmFiles() {
16190
16491
  };
16191
16492
  }
16192
16493
  async function checkCheckpointManifest(directory) {
16193
- const manifestPath = path32.join(directory, ".swarm/checkpoints.json");
16194
- if (!existsSync17(manifestPath)) {
16494
+ const manifestPath = path33.join(directory, ".swarm/checkpoints.json");
16495
+ if (!existsSync18(manifestPath)) {
16195
16496
  return {
16196
16497
  name: "Checkpoint Manifest",
16197
16498
  status: "\u2705",
@@ -16199,7 +16500,7 @@ async function checkCheckpointManifest(directory) {
16199
16500
  };
16200
16501
  }
16201
16502
  try {
16202
- const content = readFileSync9(manifestPath, "utf-8");
16503
+ const content = readFileSync10(manifestPath, "utf-8");
16203
16504
  const parsed = JSON.parse(content);
16204
16505
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
16205
16506
  return {
@@ -16242,8 +16543,8 @@ async function checkCheckpointManifest(directory) {
16242
16543
  }
16243
16544
  }
16244
16545
  async function checkEventStreamIntegrity(directory) {
16245
- const eventsPath = path32.join(directory, ".swarm/events.jsonl");
16246
- if (!existsSync17(eventsPath)) {
16546
+ const eventsPath = path33.join(directory, ".swarm/events.jsonl");
16547
+ if (!existsSync18(eventsPath)) {
16247
16548
  return {
16248
16549
  name: "Event Stream",
16249
16550
  status: "\u2705",
@@ -16251,7 +16552,7 @@ async function checkEventStreamIntegrity(directory) {
16251
16552
  };
16252
16553
  }
16253
16554
  try {
16254
- const content = readFileSync9(eventsPath, "utf-8");
16555
+ const content = readFileSync10(eventsPath, "utf-8");
16255
16556
  const lines = content.split(`
16256
16557
  `).filter((line) => line.trim() !== "");
16257
16558
  let malformedCount = 0;
@@ -16283,8 +16584,8 @@ async function checkEventStreamIntegrity(directory) {
16283
16584
  }
16284
16585
  }
16285
16586
  async function checkSteeringDirectives(directory) {
16286
- const eventsPath = path32.join(directory, ".swarm/events.jsonl");
16287
- if (!existsSync17(eventsPath)) {
16587
+ const eventsPath = path33.join(directory, ".swarm/events.jsonl");
16588
+ if (!existsSync18(eventsPath)) {
16288
16589
  return {
16289
16590
  name: "Steering Directives",
16290
16591
  status: "\u2705",
@@ -16292,7 +16593,7 @@ async function checkSteeringDirectives(directory) {
16292
16593
  };
16293
16594
  }
16294
16595
  try {
16295
- const content = readFileSync9(eventsPath, "utf-8");
16596
+ const content = readFileSync10(eventsPath, "utf-8");
16296
16597
  const lines = content.split(`
16297
16598
  `).filter((line) => line.trim() !== "");
16298
16599
  const directivesIssued = [];
@@ -16339,8 +16640,8 @@ async function checkCurator(directory) {
16339
16640
  detail: "Disabled (enable via curator.enabled)"
16340
16641
  };
16341
16642
  }
16342
- const summaryPath = path32.join(directory, ".swarm/curator-summary.json");
16343
- if (!existsSync17(summaryPath)) {
16643
+ const summaryPath = path33.join(directory, ".swarm/curator-summary.json");
16644
+ if (!existsSync18(summaryPath)) {
16344
16645
  return {
16345
16646
  name: "Curator",
16346
16647
  status: "\u2705",
@@ -16348,7 +16649,7 @@ async function checkCurator(directory) {
16348
16649
  };
16349
16650
  }
16350
16651
  try {
16351
- const content = readFileSync9(summaryPath, "utf-8");
16652
+ const content = readFileSync10(summaryPath, "utf-8");
16352
16653
  const parsed = JSON.parse(content);
16353
16654
  if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
16354
16655
  return {
@@ -16541,8 +16842,8 @@ async function getDiagnoseData(directory) {
16541
16842
  checks.push(await checkCurator(directory));
16542
16843
  checks.push(await checkKnowledgeHealth(directory));
16543
16844
  try {
16544
- const evidenceDir = path32.join(directory, ".swarm", "evidence");
16545
- 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")) : [];
16546
16847
  if (snapshotFiles.length > 0) {
16547
16848
  const latest = snapshotFiles.sort().pop();
16548
16849
  checks.push({
@@ -16575,13 +16876,13 @@ async function getDiagnoseData(directory) {
16575
16876
  const cacheRows = [];
16576
16877
  for (const cachePath of cachePaths) {
16577
16878
  try {
16578
- if (!existsSync17(cachePath)) {
16879
+ if (!existsSync18(cachePath)) {
16579
16880
  cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
16580
16881
  continue;
16581
16882
  }
16582
- const pkgJsonPath = path32.join(cachePath, "package.json");
16883
+ const pkgJsonPath = path33.join(cachePath, "package.json");
16583
16884
  try {
16584
- const raw = readFileSync9(pkgJsonPath, "utf-8");
16885
+ const raw = readFileSync10(pkgJsonPath, "utf-8");
16585
16886
  const parsed = JSON.parse(raw);
16586
16887
  const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
16587
16888
  cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
@@ -16800,7 +17101,7 @@ async function handleDoctorCommand(directory, args) {
16800
17101
  const result = runConfigDoctor(config, directory);
16801
17102
  let output;
16802
17103
  if (enableAutoFix && result.hasAutoFixableIssues) {
16803
- const { runConfigDoctorWithFixes } = await import("./config-doctor-7yrxfa6b.js");
17104
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-9fhfy6p7.js");
16804
17105
  const fixResult = await runConfigDoctorWithFixes(directory, config, true);
16805
17106
  output = formatDoctorMarkdown(fixResult.result);
16806
17107
  } else {
@@ -16950,10 +17251,10 @@ function decideEpicActivation(tasks, cochangePairs, commitsObserved, options) {
16950
17251
 
16951
17252
  // src/turbo/epic/calibration.ts
16952
17253
  init_logger();
16953
- import * as fs14 from "fs";
16954
- import * as path33 from "path";
17254
+ import * as fs15 from "fs";
17255
+ import * as path34 from "path";
16955
17256
  var STATE_FILE = "calibration.json";
16956
- var STATE_REL_DIR = path33.join(".swarm", "epic");
17257
+ var STATE_REL_DIR = path34.join(".swarm", "epic");
16957
17258
  function nowISO() {
16958
17259
  return new Date().toISOString();
16959
17260
  }
@@ -16975,13 +17276,13 @@ function markUnreadable(directory, reason) {
16975
17276
  error(`[epic/calibration] state file unreadable for ${directory}: ${reason} \u2014 failing closed`);
16976
17277
  }
16977
17278
  function repairCalibrationUnreadable(directory) {
16978
- const filePath = path33.join(directory, STATE_REL_DIR, STATE_FILE);
16979
- if (!fs14.existsSync(filePath)) {
17279
+ const filePath = path34.join(directory, STATE_REL_DIR, STATE_FILE);
17280
+ if (!fs15.existsSync(filePath)) {
16980
17281
  stateUnreadableMap.delete(directory);
16981
17282
  return;
16982
17283
  }
16983
17284
  try {
16984
- const raw = fs14.readFileSync(filePath, "utf-8");
17285
+ const raw = fs15.readFileSync(filePath, "utf-8");
16985
17286
  const parsed = JSON.parse(raw);
16986
17287
  if (!isValidCalibrationShape(parsed)) {
16987
17288
  stateUnreadableMap.set(directory, true);
@@ -17007,9 +17308,9 @@ function isValidCalibrationShape(candidate) {
17007
17308
  return true;
17008
17309
  }
17009
17310
  function ensureSwarmEpicDir(directory) {
17010
- const dir = path33.resolve(directory, STATE_REL_DIR);
17011
- if (!fs14.existsSync(dir)) {
17012
- 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 });
17013
17314
  }
17014
17315
  return dir;
17015
17316
  }
@@ -17019,18 +17320,18 @@ function loadCalibrationState(directory) {
17019
17320
  if (stateUnreadableMap.get(directory))
17020
17321
  return null;
17021
17322
  }
17022
- const filePath = path33.join(directory, STATE_REL_DIR, STATE_FILE);
17323
+ const filePath = path34.join(directory, STATE_REL_DIR, STATE_FILE);
17023
17324
  try {
17024
- if (!fs14.existsSync(filePath)) {
17325
+ if (!fs15.existsSync(filePath)) {
17025
17326
  const seed = emptyCalibrationState();
17026
17327
  try {
17027
17328
  ensureSwarmEpicDir(directory);
17028
- fs14.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
17329
+ fs15.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
17029
17330
  `, "utf-8");
17030
17331
  } catch {}
17031
17332
  return seed;
17032
17333
  }
17033
- const raw = fs14.readFileSync(filePath, "utf-8");
17334
+ const raw = fs15.readFileSync(filePath, "utf-8");
17034
17335
  const parsed = JSON.parse(raw);
17035
17336
  if (!isValidCalibrationShape(parsed)) {
17036
17337
  markUnreadable(directory, `malformed shape (version=${parsed?.version}, hotModuleAdditions type=${Array.isArray(parsed?.hotModuleAdditions) ? "array" : typeof parsed?.hotModuleAdditions})`);
@@ -17045,36 +17346,36 @@ function loadCalibrationState(directory) {
17045
17346
 
17046
17347
  // src/turbo/epic/divergence-recorder.ts
17047
17348
  init_logger();
17048
- import * as fs15 from "fs";
17049
- import * as path34 from "path";
17050
- 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");
17051
17352
  var EVIDENCE_FILE = "divergence.jsonl";
17052
17353
  var MAX_TAIL_BYTES2 = 16 * 1024 * 1024;
17053
17354
  function readDivergenceHistory(directory, options) {
17054
- const filePath = path34.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
17055
- if (!fs15.existsSync(filePath)) {
17355
+ const filePath = path35.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
17356
+ if (!fs16.existsSync(filePath)) {
17056
17357
  return [];
17057
17358
  }
17058
17359
  const maxBytes = options?.maxBytes ?? MAX_TAIL_BYTES2;
17059
17360
  let raw;
17060
17361
  let tailTruncated = false;
17061
17362
  try {
17062
- const stat5 = fs15.statSync(filePath);
17363
+ const stat5 = fs16.statSync(filePath);
17063
17364
  if (Number.isFinite(maxBytes) && stat5.size > maxBytes) {
17064
- const fd = fs15.openSync(filePath, "r");
17365
+ const fd = fs16.openSync(filePath, "r");
17065
17366
  try {
17066
17367
  const buf = Buffer.alloc(maxBytes);
17067
17368
  const offset = stat5.size - maxBytes;
17068
- fs15.readSync(fd, buf, 0, maxBytes, offset);
17369
+ fs16.readSync(fd, buf, 0, maxBytes, offset);
17069
17370
  raw = buf.toString("utf-8");
17070
17371
  tailTruncated = true;
17071
17372
  } finally {
17072
17373
  try {
17073
- fs15.closeSync(fd);
17374
+ fs16.closeSync(fd);
17074
17375
  } catch {}
17075
17376
  }
17076
17377
  } else {
17077
- raw = fs15.readFileSync(filePath, "utf-8");
17378
+ raw = fs16.readFileSync(filePath, "utf-8");
17078
17379
  }
17079
17380
  } catch {
17080
17381
  return [];
@@ -17099,16 +17400,16 @@ function readDivergenceHistory(directory, options) {
17099
17400
  }
17100
17401
 
17101
17402
  // src/turbo/epic/promotion-evidence.ts
17102
- import * as fs16 from "fs";
17103
- import * as path35 from "path";
17104
- 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");
17105
17406
  var EVIDENCE_FILE2 = "epic-promotions.jsonl";
17106
17407
  function readPromotionEvidence(directory) {
17107
- const filePath = path35.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
17108
- if (!fs16.existsSync(filePath)) {
17408
+ const filePath = path36.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
17409
+ if (!fs17.existsSync(filePath)) {
17109
17410
  return [];
17110
17411
  }
17111
- const raw = fs16.readFileSync(filePath, "utf-8");
17412
+ const raw = fs17.readFileSync(filePath, "utf-8");
17112
17413
  const lines = raw.split(`
17113
17414
  `).filter((l) => l.trim().length > 0);
17114
17415
  const records = [];
@@ -17613,7 +17914,7 @@ async function handleEvidenceCommand(directory, args) {
17613
17914
  return formatTaskEvidenceMarkdown(evidenceData);
17614
17915
  }
17615
17916
  async function handleEvidenceSummaryCommand(directory) {
17616
- const { buildEvidenceSummary } = await import("./evidence-summary-service-559nas1m.js");
17917
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-4hs44n2c.js");
17617
17918
  const artifact = await buildEvidenceSummary(directory);
17618
17919
  if (!artifact) {
17619
17920
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -17677,8 +17978,8 @@ async function handleExportCommand(directory, _args) {
17677
17978
  }
17678
17979
  // src/full-auto/state.ts
17679
17980
  var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
17680
- import * as fs17 from "fs";
17681
- import * as path36 from "path";
17981
+ import * as fs18 from "fs";
17982
+ import * as path37 from "path";
17682
17983
  init_logger();
17683
17984
  var lockfile4 = import_proper_lockfile4.default;
17684
17985
  var STATE_FILE2 = "full-auto-state.json";
@@ -17686,9 +17987,9 @@ function nowISO2() {
17686
17987
  return new Date().toISOString();
17687
17988
  }
17688
17989
  function ensureSwarmDir(directory) {
17689
- const swarmDir = path36.resolve(directory, ".swarm");
17690
- if (!fs17.existsSync(swarmDir)) {
17691
- fs17.mkdirSync(swarmDir, { recursive: true });
17990
+ const swarmDir = path37.resolve(directory, ".swarm");
17991
+ if (!fs18.existsSync(swarmDir)) {
17992
+ fs18.mkdirSync(swarmDir, { recursive: true });
17692
17993
  }
17693
17994
  return swarmDir;
17694
17995
  }
@@ -17746,7 +18047,7 @@ function withStateLock(directory, fn) {
17746
18047
  let release;
17747
18048
  try {
17748
18049
  const lockTarget = validateSwarmPath(directory, STATE_FILE2);
17749
- if (!fs17.existsSync(lockTarget)) {
18050
+ if (!fs18.existsSync(lockTarget)) {
17750
18051
  ensureSwarmDir(directory);
17751
18052
  const seed = {
17752
18053
  version: 2,
@@ -17754,7 +18055,7 @@ function withStateLock(directory, fn) {
17754
18055
  oversightSequence: 0,
17755
18056
  sessions: {}
17756
18057
  };
17757
- fs17.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
18058
+ fs18.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
17758
18059
  `, "utf-8");
17759
18060
  }
17760
18061
  release = lockfile4.lockSync(lockTarget, {
@@ -17804,7 +18105,7 @@ function readPersisted(directory) {
17804
18105
  const filePath = validateSwarmPath(directory, STATE_FILE2);
17805
18106
  let stats;
17806
18107
  try {
17807
- stats = fs17.statSync(filePath);
18108
+ stats = fs18.statSync(filePath);
17808
18109
  } catch {
17809
18110
  clearStateUnreadable();
17810
18111
  readCache.delete(filePath);
@@ -17815,7 +18116,7 @@ function readPersisted(directory) {
17815
18116
  clearStateUnreadable();
17816
18117
  return structuredClone(cached.state);
17817
18118
  }
17818
- const raw = fs17.readFileSync(filePath, "utf-8");
18119
+ const raw = fs18.readFileSync(filePath, "utf-8");
17819
18120
  const parsed = JSON.parse(raw);
17820
18121
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 2 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
17821
18122
  markStateUnreadable(`malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -17840,8 +18141,8 @@ function readPersisted(directory) {
17840
18141
  error(`[full-auto/state] Failed to read ${STATE_FILE2}: ${reason} \u2014 attempting .bak recovery`);
17841
18142
  try {
17842
18143
  const bakPath = validateSwarmPath(directory, `${STATE_FILE2}.bak`);
17843
- if (fs17.existsSync(bakPath)) {
17844
- const raw = fs17.readFileSync(bakPath, "utf-8");
18144
+ if (fs18.existsSync(bakPath)) {
18145
+ const raw = fs18.readFileSync(bakPath, "utf-8");
17845
18146
  const parsed = JSON.parse(raw);
17846
18147
  if (parsed?.version === 2 && parsed.sessions && !Array.isArray(parsed.sessions)) {
17847
18148
  warn(`[full-auto/state] Recovered from ${STATE_FILE2}.bak`);
@@ -17881,23 +18182,23 @@ function writePersisted(directory, persisted) {
17881
18182
  throw new Error(`Full-Auto state persistence prepare failed: ${msg}`);
17882
18183
  }
17883
18184
  try {
17884
- if (fs17.existsSync(filePath)) {
17885
- fs17.copyFileSync(filePath, bakPath);
18185
+ if (fs18.existsSync(filePath)) {
18186
+ fs18.copyFileSync(filePath, bakPath);
17886
18187
  }
17887
18188
  } catch {}
17888
18189
  try {
17889
- fs17.writeFileSync(tmpPath, payload, "utf-8");
18190
+ fs18.writeFileSync(tmpPath, payload, "utf-8");
17890
18191
  try {
17891
- const fd = fs17.openSync(tmpPath, "r+");
18192
+ const fd = fs18.openSync(tmpPath, "r+");
17892
18193
  try {
17893
- fs17.fsyncSync(fd);
18194
+ fs18.fsyncSync(fd);
17894
18195
  } finally {
17895
- fs17.closeSync(fd);
18196
+ fs18.closeSync(fd);
17896
18197
  }
17897
18198
  } catch {}
17898
- fs17.renameSync(tmpPath, filePath);
18199
+ fs18.renameSync(tmpPath, filePath);
17899
18200
  readCache.delete(filePath);
17900
- const readback = fs17.readFileSync(filePath, "utf-8");
18201
+ const readback = fs18.readFileSync(filePath, "utf-8");
17901
18202
  const parsed = JSON.parse(readback);
17902
18203
  if (parsed?.version !== 2) {
17903
18204
  throw new Error("Round-trip readback returned wrong version");
@@ -18117,7 +18418,7 @@ function buildStatusReport(directory, sessionID, sessionFlag) {
18117
18418
 
18118
18419
  // src/commands/handoff.ts
18119
18420
  import crypto4 from "crypto";
18120
- import { renameSync as renameSync9, unlinkSync as unlinkSync5 } from "fs";
18421
+ import { renameSync as renameSync9, unlinkSync as unlinkSync6 } from "fs";
18121
18422
 
18122
18423
  // src/services/handoff-service.ts
18123
18424
  var RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
@@ -18498,7 +18799,7 @@ var _internals27 = {
18498
18799
 
18499
18800
  // src/session/snapshot-writer.ts
18500
18801
  import { closeSync as closeSync6, fsyncSync as fsyncSync2, mkdirSync as mkdirSync14, openSync as openSync6, renameSync as renameSync8 } from "fs";
18501
- import * as path37 from "path";
18802
+ import * as path38 from "path";
18502
18803
  var _writeInFlight = Promise.resolve();
18503
18804
  function serializeAgentSession(s) {
18504
18805
  const gateLog = {};
@@ -18605,7 +18906,7 @@ async function writeSnapshot(directory, state) {
18605
18906
  }
18606
18907
  const content = JSON.stringify(snapshot, null, 2);
18607
18908
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
18608
- const dir = path37.dirname(resolvedPath);
18909
+ const dir = path38.dirname(resolvedPath);
18609
18910
  mkdirSync14(dir, { recursive: true });
18610
18911
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
18611
18912
  await bunWrite(tempPath, content);
@@ -18652,7 +18953,7 @@ async function handleHandoffCommand(directory, _args) {
18652
18953
  renameSync9(tempPath, resolvedPath);
18653
18954
  } catch (renameErr) {
18654
18955
  try {
18655
- unlinkSync5(tempPath);
18956
+ unlinkSync6(tempPath);
18656
18957
  } catch {}
18657
18958
  throw renameErr;
18658
18959
  }
@@ -18664,7 +18965,7 @@ async function handleHandoffCommand(directory, _args) {
18664
18965
  renameSync9(promptTempPath, promptPath);
18665
18966
  } catch (renameErr) {
18666
18967
  try {
18667
- unlinkSync5(promptTempPath);
18968
+ unlinkSync6(promptTempPath);
18668
18969
  } catch {}
18669
18970
  throw renameErr;
18670
18971
  }
@@ -19108,15 +19409,15 @@ ${USAGE6}`;
19108
19409
  }
19109
19410
 
19110
19411
  // src/commands/knowledge.ts
19111
- import { join as join31 } from "path";
19412
+ import { join as join32 } from "path";
19112
19413
 
19113
19414
  // src/hooks/knowledge-migrator.ts
19114
19415
  init_logger();
19115
19416
  import { randomUUID as randomUUID4 } from "crypto";
19116
- import { existsSync as existsSync22, readFileSync as readFileSync14 } from "fs";
19417
+ import { existsSync as existsSync23, readFileSync as readFileSync15 } from "fs";
19117
19418
  import { mkdir as mkdir9, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
19118
- import * as os8 from "os";
19119
- import * as path38 from "path";
19419
+ import * as os9 from "os";
19420
+ import * as path39 from "path";
19120
19421
 
19121
19422
  // src/hooks/knowledge-types.ts
19122
19423
  var KNOWLEDGE_SCHEMA_VERSION = 2;
@@ -19146,10 +19447,10 @@ var _internals30 = {
19146
19447
  resolveLegacyHiveKnowledgePath
19147
19448
  };
19148
19449
  async function migrateContextToKnowledge(directory, config) {
19149
- const sentinelPath = path38.join(directory, ".swarm", ".knowledge-migrated");
19150
- 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");
19151
19452
  const knowledgePath = resolveSwarmKnowledgePath(directory);
19152
- if (existsSync22(sentinelPath)) {
19453
+ if (existsSync23(sentinelPath)) {
19153
19454
  return {
19154
19455
  migrated: false,
19155
19456
  entriesMigrated: 0,
@@ -19158,7 +19459,7 @@ async function migrateContextToKnowledge(directory, config) {
19158
19459
  skippedReason: "sentinel-exists"
19159
19460
  };
19160
19461
  }
19161
- if (!existsSync22(contextPath)) {
19462
+ if (!existsSync23(contextPath)) {
19162
19463
  return {
19163
19464
  migrated: false,
19164
19465
  entriesMigrated: 0,
@@ -19249,8 +19550,8 @@ async function migrateContextToKnowledge(directory, config) {
19249
19550
  async function migrateHiveKnowledgeLegacy(config) {
19250
19551
  const legacyHivePath = _internals30.resolveLegacyHiveKnowledgePath();
19251
19552
  const canonicalHivePath = resolveHiveKnowledgePath();
19252
- const sentinelPath = path38.join(path38.dirname(canonicalHivePath), ".hive-knowledge-migrated");
19253
- if (existsSync22(sentinelPath)) {
19553
+ const sentinelPath = path39.join(path39.dirname(canonicalHivePath), ".hive-knowledge-migrated");
19554
+ if (existsSync23(sentinelPath)) {
19254
19555
  return {
19255
19556
  migrated: false,
19256
19557
  entriesMigrated: 0,
@@ -19259,7 +19560,7 @@ async function migrateHiveKnowledgeLegacy(config) {
19259
19560
  skippedReason: "sentinel-exists"
19260
19561
  };
19261
19562
  }
19262
- if (!existsSync22(legacyHivePath)) {
19563
+ if (!existsSync23(legacyHivePath)) {
19263
19564
  return {
19264
19565
  migrated: false,
19265
19566
  entriesMigrated: 0,
@@ -19460,16 +19761,16 @@ function truncateLesson2(text) {
19460
19761
  return `${text.slice(0, 277)}...`;
19461
19762
  }
19462
19763
  function inferProjectName(directory) {
19463
- const packageJsonPath = path38.join(directory, "package.json");
19464
- if (existsSync22(packageJsonPath)) {
19764
+ const packageJsonPath = path39.join(directory, "package.json");
19765
+ if (existsSync23(packageJsonPath)) {
19465
19766
  try {
19466
- const pkg = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
19767
+ const pkg = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
19467
19768
  if (pkg.name && typeof pkg.name === "string") {
19468
19769
  return pkg.name;
19469
19770
  }
19470
19771
  } catch {}
19471
19772
  }
19472
- return path38.basename(directory);
19773
+ return path39.basename(directory);
19473
19774
  }
19474
19775
  async function writeSentinel(sentinelPath, migrated, dropped) {
19475
19776
  const sentinel = {
@@ -19481,21 +19782,21 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
19481
19782
  schema_version: 1,
19482
19783
  migration_tool: "knowledge-migrator.ts"
19483
19784
  };
19484
- await mkdir9(path38.dirname(sentinelPath), { recursive: true });
19785
+ await mkdir9(path39.dirname(sentinelPath), { recursive: true });
19485
19786
  await writeFile9(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
19486
19787
  }
19487
19788
  function resolveLegacyHiveKnowledgePath() {
19488
19789
  const platform = process.platform;
19489
- const home = process.env.HOME || os8.homedir();
19790
+ const home = process.env.HOME || os9.homedir();
19490
19791
  let dataDir;
19491
19792
  if (platform === "win32") {
19492
- 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");
19493
19794
  } else if (platform === "darwin") {
19494
- dataDir = path38.join(home, "Library", "Application Support", "opencode-swarm");
19795
+ dataDir = path39.join(home, "Library", "Application Support", "opencode-swarm");
19495
19796
  } else {
19496
- 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");
19497
19798
  }
19498
- return path38.join(dataDir, "hive-knowledge.jsonl");
19799
+ return path39.join(dataDir, "hive-knowledge.jsonl");
19499
19800
  }
19500
19801
 
19501
19802
  // src/commands/knowledge.ts
@@ -19549,7 +19850,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
19549
19850
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
19550
19851
  }
19551
19852
  try {
19552
- const quarantinePath = join31(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
19853
+ const quarantinePath = join32(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
19553
19854
  const entries = await readKnowledge(quarantinePath);
19554
19855
  const resolved = resolveEntryByPrefix(entries, inputId);
19555
19856
  if ("error" in resolved) {
@@ -19800,15 +20101,15 @@ var _internals31 = {
19800
20101
  };
19801
20102
 
19802
20103
  // src/commands/link.ts
19803
- import { existsSync as existsSync23 } from "fs";
19804
- import * as path40 from "path";
20104
+ import { existsSync as existsSync24 } from "fs";
20105
+ import * as path41 from "path";
19805
20106
 
19806
20107
  // src/knowledge/identity.ts
19807
20108
  import * as child_process5 from "child_process";
19808
20109
  import { createHash as createHash4 } from "crypto";
19809
- import * as path39 from "path";
20110
+ import * as path40 from "path";
19810
20111
  function deriveProjectHash(directory) {
19811
- const absolutePath = path39.resolve(directory);
20112
+ const absolutePath = path40.resolve(directory);
19812
20113
  let hashInput;
19813
20114
  try {
19814
20115
  const remoteUrl = child_process5.execSync("git remote get-url origin", {
@@ -19828,18 +20129,18 @@ function deriveProjectHash(directory) {
19828
20129
  // src/commands/link.ts
19829
20130
  var DEDUP_THRESHOLD = 0.6;
19830
20131
  async function mergeLocalKnowledgeIntoLink(localSwarmDir, linkDir) {
19831
- const localPath = path40.join(localSwarmDir, "knowledge.jsonl");
19832
- const sharedPath = path40.join(linkDir, "knowledge.jsonl");
19833
- if (!existsSync23(localPath))
20132
+ const localPath = path41.join(localSwarmDir, "knowledge.jsonl");
20133
+ const sharedPath = path41.join(linkDir, "knowledge.jsonl");
20134
+ if (!existsSync24(localPath))
19834
20135
  return { merged: 0, skipped: 0 };
19835
20136
  let merged = 0;
19836
20137
  let skipped = 0;
19837
- const { readFileSync: readFileSync15 } = await import("fs");
20138
+ const { readFileSync: readFileSync16 } = await import("fs");
19838
20139
  let changed = false;
19839
20140
  await transactKnowledge(sharedPath, (sharedEntries) => {
19840
20141
  const localEntries = [];
19841
20142
  try {
19842
- const content = readFileSync15(localPath, "utf-8");
20143
+ const content = readFileSync16(localPath, "utf-8");
19843
20144
  for (const line of content.split(`
19844
20145
  `)) {
19845
20146
  if (line.trim()) {
@@ -19927,7 +20228,7 @@ ${formatStatus(directory)}`;
19927
20228
  const linkDir = resolveLinkDir(linkId);
19928
20229
  let merge;
19929
20230
  try {
19930
- merge = await mergeLocalKnowledgeIntoLink(path40.join(directory, ".swarm"), linkDir);
20231
+ merge = await mergeLocalKnowledgeIntoLink(path41.join(directory, ".swarm"), linkDir);
19931
20232
  } catch (error2) {
19932
20233
  return `\u274C Failed to merge local knowledge into the link store: ${error2 instanceof Error ? error2.message : String(error2)}`;
19933
20234
  }
@@ -20071,8 +20372,8 @@ ${USAGE7}`;
20071
20372
  }
20072
20373
 
20073
20374
  // src/commands/memory.ts
20074
- import { existsSync as existsSync26 } from "fs";
20075
- import * as path47 from "path";
20375
+ import { existsSync as existsSync27 } from "fs";
20376
+ import * as path48 from "path";
20076
20377
  import { fileURLToPath as fileURLToPath2 } from "url";
20077
20378
 
20078
20379
  // src/memory/config.ts
@@ -20212,13 +20513,13 @@ class MemoryValidationError extends Error {
20212
20513
  }
20213
20514
  }
20214
20515
  // src/memory/evaluation.ts
20215
- import * as fs18 from "fs/promises";
20216
- import * as os9 from "os";
20217
- import * as path45 from "path";
20516
+ import * as fs19 from "fs/promises";
20517
+ import * as os10 from "os";
20518
+ import * as path46 from "path";
20218
20519
 
20219
20520
  // src/memory/local-jsonl-provider.ts
20220
20521
  import { randomUUID as randomUUID5 } from "crypto";
20221
- import { existsSync as existsSync24 } from "fs";
20522
+ import { existsSync as existsSync25 } from "fs";
20222
20523
  import {
20223
20524
  appendFile as appendFile3,
20224
20525
  mkdir as mkdir10,
@@ -20226,7 +20527,7 @@ import {
20226
20527
  rename as rename5,
20227
20528
  writeFile as writeFile10
20228
20529
  } from "fs/promises";
20229
- import * as path41 from "path";
20530
+ import * as path42 from "path";
20230
20531
 
20231
20532
  // src/memory/schema.ts
20232
20533
  import { createHash as createHash5 } from "crypto";
@@ -21087,7 +21388,7 @@ class LocalJsonlMemoryProvider {
21087
21388
  pathFor(file) {
21088
21389
  const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
21089
21390
  const filename = file === "memories" ? "memories.jsonl" : file === "proposals" ? "proposals.jsonl" : "audit.jsonl";
21090
- return validateSwarmPath(this.rootDirectory, path41.join(storageDir, filename));
21391
+ return validateSwarmPath(this.rootDirectory, path42.join(storageDir, filename));
21091
21392
  }
21092
21393
  async initialize() {
21093
21394
  if (this.initialized)
@@ -21414,7 +21715,7 @@ function validateLoadedProposals(values, config) {
21414
21715
  return { records, invalidCount };
21415
21716
  }
21416
21717
  async function readJsonl(filePath) {
21417
- if (!existsSync24(filePath))
21718
+ if (!existsSync25(filePath))
21418
21719
  return [];
21419
21720
  const content = await readFile12(filePath, "utf-8");
21420
21721
  const records = [];
@@ -21470,12 +21771,12 @@ function parseRecallUsageEvent(event) {
21470
21771
  }
21471
21772
  }
21472
21773
  async function appendJsonl(filePath, value) {
21473
- await mkdir10(path41.dirname(filePath), { recursive: true });
21774
+ await mkdir10(path42.dirname(filePath), { recursive: true });
21474
21775
  await appendFile3(filePath, `${JSON.stringify(value)}
21475
21776
  `, "utf-8");
21476
21777
  }
21477
21778
  async function writeJsonlAtomic(filePath, values) {
21478
- await mkdir10(path41.dirname(filePath), { recursive: true });
21779
+ await mkdir10(path42.dirname(filePath), { recursive: true });
21479
21780
  const tmp = `${filePath}.tmp.${randomUUID5()}`;
21480
21781
  const content = values.map((value) => JSON.stringify(value)).join(`
21481
21782
  `) + (values.length > 0 ? `
@@ -21486,18 +21787,18 @@ async function writeJsonlAtomic(filePath, values) {
21486
21787
 
21487
21788
  // src/memory/provider-pool.ts
21488
21789
  import { realpathSync as realpathSync2 } from "fs";
21489
- import * as path44 from "path";
21790
+ import * as path45 from "path";
21490
21791
 
21491
21792
  // src/memory/sqlite-provider.ts
21492
21793
  import { randomUUID as randomUUID6 } from "crypto";
21493
21794
  import { mkdirSync as mkdirSync15 } from "fs";
21494
21795
  import { createRequire as createRequire2 } from "module";
21495
- import * as path43 from "path";
21796
+ import * as path44 from "path";
21496
21797
 
21497
21798
  // src/memory/jsonl-migration.ts
21498
- 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";
21499
21800
  import { copyFile as copyFile2, mkdir as mkdir11, readFile as readFile13, stat as stat5, writeFile as writeFile11 } from "fs/promises";
21500
- import * as path42 from "path";
21801
+ import * as path43 from "path";
21501
21802
  var LEGACY_JSONL_MIGRATION_VERSION = 2;
21502
21803
  var LEGACY_JSONL_MIGRATION_NAME = "legacy_jsonl_import_complete";
21503
21804
  function resolveMemoryStorageDir(rootDirectory, config = {}) {
@@ -21513,8 +21814,8 @@ function resolveSqliteDatabasePath(rootDirectory, config = {}) {
21513
21814
  async function readLegacyJsonl(rootDirectory, config = {}) {
21514
21815
  const resolved = resolveConfig(config);
21515
21816
  const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
21516
- const memoryLoad = await readMemoryJsonl(path42.join(storageDir, "memories.jsonl"), resolved);
21517
- 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);
21518
21819
  return {
21519
21820
  memories: memoryLoad.records,
21520
21821
  proposals: proposalLoad.records,
@@ -21524,15 +21825,15 @@ async function readLegacyJsonl(rootDirectory, config = {}) {
21524
21825
  }
21525
21826
  async function backupLegacyJsonl(rootDirectory, config = {}) {
21526
21827
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
21527
- const backupDir = path42.join(storageDir, "backups");
21828
+ const backupDir = path43.join(storageDir, "backups");
21528
21829
  await mkdir11(backupDir, { recursive: true });
21529
21830
  const results = [];
21530
21831
  for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
21531
- const source = path42.join(storageDir, filename);
21532
- if (!existsSync25(source))
21832
+ const source = path43.join(storageDir, filename);
21833
+ if (!existsSync26(source))
21533
21834
  continue;
21534
- const backup = path42.join(backupDir, `${filename}.pre-sqlite-migration`);
21535
- if (existsSync25(backup)) {
21835
+ const backup = path43.join(backupDir, `${filename}.pre-sqlite-migration`);
21836
+ if (existsSync26(backup)) {
21536
21837
  results.push({ source, backup, created: false });
21537
21838
  continue;
21538
21839
  }
@@ -21542,51 +21843,51 @@ async function backupLegacyJsonl(rootDirectory, config = {}) {
21542
21843
  return results;
21543
21844
  }
21544
21845
  async function writeJsonlExport(rootDirectory, config, memories, proposals) {
21545
- const exportDir = path42.join(resolveMemoryStorageDir(rootDirectory, config), "export");
21846
+ const exportDir = path43.join(resolveMemoryStorageDir(rootDirectory, config), "export");
21546
21847
  await mkdir11(exportDir, { recursive: true });
21547
- const memoriesPath = path42.join(exportDir, "memories.jsonl");
21548
- const proposalsPath = path42.join(exportDir, "proposals.jsonl");
21549
- 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)}`);
21550
21851
  try {
21551
21852
  await writeFile11(memoriesTempPath, toJsonl(memories), "utf-8");
21552
21853
  renameSync10(memoriesTempPath, memoriesPath);
21553
21854
  } catch (err) {
21554
21855
  try {
21555
- unlinkSync6(memoriesTempPath);
21856
+ unlinkSync7(memoriesTempPath);
21556
21857
  } catch {}
21557
21858
  throw err;
21558
21859
  }
21559
- 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)}`);
21560
21861
  try {
21561
21862
  await writeFile11(proposalsTempPath, toJsonl(proposals), "utf-8");
21562
21863
  renameSync10(proposalsTempPath, proposalsPath);
21563
21864
  } catch (err) {
21564
21865
  try {
21565
- unlinkSync6(proposalsTempPath);
21866
+ unlinkSync7(proposalsTempPath);
21566
21867
  } catch {}
21567
21868
  throw err;
21568
21869
  }
21569
21870
  return { directory: exportDir, memoriesPath, proposalsPath };
21570
21871
  }
21571
21872
  async function writeMigrationReport(rootDirectory, report, config = {}) {
21572
- const reportPath = path42.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
21573
- await mkdir11(path42.dirname(reportPath), { recursive: true });
21574
- 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)}`);
21575
21876
  try {
21576
21877
  await writeFile11(reportTempPath, `${JSON.stringify(report, null, 2)}
21577
21878
  `, "utf-8");
21578
21879
  renameSync10(reportTempPath, reportPath);
21579
21880
  } catch (err) {
21580
21881
  try {
21581
- unlinkSync6(reportTempPath);
21882
+ unlinkSync7(reportTempPath);
21582
21883
  } catch {}
21583
21884
  throw err;
21584
21885
  }
21585
21886
  return reportPath;
21586
21887
  }
21587
21888
  async function readMigrationReport(rootDirectory, config = {}) {
21588
- const reportPath = path42.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
21589
- if (!existsSync25(reportPath))
21889
+ const reportPath = path43.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
21890
+ if (!existsSync26(reportPath))
21590
21891
  return null;
21591
21892
  try {
21592
21893
  return JSON.parse(await readFile13(reportPath, "utf-8"));
@@ -21598,15 +21899,15 @@ async function getLegacyJsonlFileStatus(rootDirectory, config = {}) {
21598
21899
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
21599
21900
  const statuses = [];
21600
21901
  for (const file of ["memories.jsonl", "proposals.jsonl"]) {
21601
- const filePath = path42.join(storageDir, file);
21902
+ const filePath = path43.join(storageDir, file);
21602
21903
  let sizeBytes = 0;
21603
- if (existsSync25(filePath)) {
21904
+ if (existsSync26(filePath)) {
21604
21905
  sizeBytes = (await stat5(filePath)).size;
21605
21906
  }
21606
21907
  statuses.push({
21607
21908
  file,
21608
21909
  path: filePath,
21609
- exists: existsSync25(filePath),
21910
+ exists: existsSync26(filePath),
21610
21911
  sizeBytes
21611
21912
  });
21612
21913
  }
@@ -21687,7 +21988,7 @@ async function readProposalJsonl(filePath, config) {
21687
21988
  return { records, invalidRows, totalRows: rows.totalRows };
21688
21989
  }
21689
21990
  async function readJsonlRows(filePath) {
21690
- if (!existsSync25(filePath)) {
21991
+ if (!existsSync26(filePath)) {
21691
21992
  return { rows: [], invalidRows: [], totalRows: 0 };
21692
21993
  }
21693
21994
  const content = await readFile13(filePath, "utf-8");
@@ -21906,7 +22207,7 @@ class SQLiteMemoryProvider {
21906
22207
  }
21907
22208
  async doInitialize() {
21908
22209
  const dbPath = this.databasePath();
21909
- mkdirSync15(path43.dirname(dbPath), { recursive: true });
22210
+ mkdirSync15(path44.dirname(dbPath), { recursive: true });
21910
22211
  const Db = loadDatabaseCtor2();
21911
22212
  this.db = new Db(dbPath);
21912
22213
  this.db.run("PRAGMA journal_mode = WAL;");
@@ -22935,7 +23236,7 @@ function resolvePoolKey(directory) {
22935
23236
  try {
22936
23237
  return realpathSync2(directory);
22937
23238
  } catch {
22938
- return path44.resolve(directory);
23239
+ return path45.resolve(directory);
22939
23240
  }
22940
23241
  }
22941
23242
 
@@ -23007,7 +23308,7 @@ var DEFAULT_MODES = [
23007
23308
  ];
23008
23309
  var DEFAULT_TIMESTAMP = "2026-05-26T12:00:00.000Z";
23009
23310
  async function evaluateMemoryRecallFixtures(options) {
23010
- const fixtureDirectory = path45.resolve(options.fixtureDirectory);
23311
+ const fixtureDirectory = path46.resolve(options.fixtureDirectory);
23011
23312
  const providers = options.providers ?? DEFAULT_PROVIDERS;
23012
23313
  const modes = options.modes ?? DEFAULT_MODES;
23013
23314
  const generatedAt = new Date().toISOString();
@@ -23016,7 +23317,7 @@ async function evaluateMemoryRecallFixtures(options) {
23016
23317
  for (const fixture of fixtures) {
23017
23318
  const materialized = materializeFixture(fixture);
23018
23319
  for (const providerName of providers) {
23019
- 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-")));
23020
23321
  const provider = createEvaluationProvider(providerName, tempRoot);
23021
23322
  try {
23022
23323
  await provider.initialize?.();
@@ -23040,7 +23341,7 @@ async function evaluateMemoryRecallFixtures(options) {
23040
23341
  } finally {
23041
23342
  await provider.close?.();
23042
23343
  if (!options.keepTempRoots) {
23043
- await fs18.rm(tempRoot, { recursive: true, force: true });
23344
+ await fs19.rm(tempRoot, { recursive: true, force: true });
23044
23345
  }
23045
23346
  }
23046
23347
  }
@@ -23056,11 +23357,11 @@ async function evaluateMemoryRecallFixtures(options) {
23056
23357
  };
23057
23358
  }
23058
23359
  async function loadRecallEvaluationFixtures(fixtureDirectory) {
23059
- const entries = await fs18.readdir(fixtureDirectory, { withFileTypes: true });
23360
+ const entries = await fs19.readdir(fixtureDirectory, { withFileTypes: true });
23060
23361
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
23061
23362
  const fixtures = [];
23062
23363
  for (const file of files) {
23063
- const raw = await fs18.readFile(path45.join(fixtureDirectory, file), "utf-8");
23364
+ const raw = await fs19.readFile(path46.join(fixtureDirectory, file), "utf-8");
23064
23365
  fixtures.push(validateFixture(JSON.parse(raw), file));
23065
23366
  }
23066
23367
  return fixtures;
@@ -23337,8 +23638,8 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
23337
23638
  }).passthrough();
23338
23639
  // src/memory/consolidation-log.ts
23339
23640
  import { appendFile as appendFile4, mkdir as mkdir12, readFile as readFile15 } from "fs/promises";
23340
- import * as path46 from "path";
23341
- 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");
23342
23643
  async function readConsolidationLog(directory) {
23343
23644
  const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
23344
23645
  let raw;
@@ -23361,7 +23662,7 @@ async function readConsolidationLog(directory) {
23361
23662
  }
23362
23663
 
23363
23664
  // src/commands/memory.ts
23364
- var PACKAGE_ROOT = path47.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
23665
+ var PACKAGE_ROOT = path48.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
23365
23666
  async function handleMemoryCommand(_directory, _args) {
23366
23667
  return [
23367
23668
  "## Swarm Memory",
@@ -23419,7 +23720,7 @@ async function handleMemoryStatusCommand(directory, _args) {
23419
23720
  `- Provider: \`${config.provider}\``,
23420
23721
  `- Storage: \`${storageDir}\``,
23421
23722
  `- SQLite path: \`${sqlitePath}\``,
23422
- `- SQLite database exists: \`${existsSync26(sqlitePath)}\``,
23723
+ `- SQLite database exists: \`${existsSync27(sqlitePath)}\``,
23423
23724
  `- Automatic destructive cleanup: \`disabled\``,
23424
23725
  "",
23425
23726
  "### Legacy JSONL"
@@ -23659,7 +23960,7 @@ function resolveCommandMemoryConfig(directory) {
23659
23960
  }
23660
23961
  function parseEvaluateArgs(directory, args) {
23661
23962
  let json = false;
23662
- let fixtureDirectory = path47.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
23963
+ let fixtureDirectory = path48.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
23663
23964
  for (let i = 0;i < args.length; i++) {
23664
23965
  const arg = args[i];
23665
23966
  if (arg === "--json") {
@@ -23673,10 +23974,10 @@ function parseEvaluateArgs(directory, args) {
23673
23974
  error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
23674
23975
  };
23675
23976
  }
23676
- const resolvedFixtures = path47.resolve(directory, next);
23677
- const canonical = path47.normalize(resolvedFixtures) + path47.sep;
23678
- const allowedRootA = path47.normalize(directory) + path47.sep;
23679
- 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;
23680
23981
  if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
23681
23982
  return {
23682
23983
  error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
@@ -23715,15 +24016,15 @@ function parseMaintenanceArgs(args, options) {
23715
24016
  return { limit, confirm };
23716
24017
  }
23717
24018
  function resolvePackageRootFromModule(modulePath) {
23718
- const moduleDir = path47.dirname(modulePath);
23719
- const leaf = path47.basename(moduleDir);
24019
+ const moduleDir = path48.dirname(modulePath);
24020
+ const leaf = path48.basename(moduleDir);
23720
24021
  if (leaf === "commands" || leaf === "cli") {
23721
- return path47.resolve(moduleDir, "..", "..");
24022
+ return path48.resolve(moduleDir, "..", "..");
23722
24023
  }
23723
24024
  if (leaf === "dist") {
23724
- return path47.resolve(moduleDir, "..");
24025
+ return path48.resolve(moduleDir, "..");
23725
24026
  }
23726
- return path47.resolve(moduleDir, "..");
24027
+ return path48.resolve(moduleDir, "..");
23727
24028
  }
23728
24029
  function formatMigrationResult(label, report) {
23729
24030
  if (!report) {
@@ -24417,12 +24718,12 @@ var _internals36 = {
24417
24718
  };
24418
24719
 
24419
24720
  // src/services/preflight-service.ts
24420
- import * as fs25 from "fs";
24421
- import * as path54 from "path";
24721
+ import * as fs26 from "fs";
24722
+ import * as path55 from "path";
24422
24723
 
24423
24724
  // src/tools/lint.ts
24424
- import * as fs19 from "fs";
24425
- import * as path48 from "path";
24725
+ import * as fs20 from "fs";
24726
+ import * as path49 from "path";
24426
24727
 
24427
24728
  // src/utils/path-security.ts
24428
24729
  function containsPathTraversal(str) {
@@ -24478,9 +24779,9 @@ function validateArgs(args) {
24478
24779
  }
24479
24780
  function getLinterCommand(linter, mode, projectDir) {
24480
24781
  const isWindows = process.platform === "win32";
24481
- const binDir = path48.join(projectDir, "node_modules", ".bin");
24482
- const biomeBin = isWindows ? path48.join(binDir, "biome.EXE") : path48.join(binDir, "biome");
24483
- 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");
24484
24785
  switch (linter) {
24485
24786
  case "biome":
24486
24787
  if (mode === "fix") {
@@ -24496,7 +24797,7 @@ function getLinterCommand(linter, mode, projectDir) {
24496
24797
  }
24497
24798
  function getAdditionalLinterCommand(linter, mode, cwd) {
24498
24799
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
24499
- 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;
24500
24801
  switch (linter) {
24501
24802
  case "ruff":
24502
24803
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -24530,12 +24831,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
24530
24831
  }
24531
24832
  }
24532
24833
  function detectRuff(cwd) {
24533
- if (fs19.existsSync(path48.join(cwd, "ruff.toml")))
24834
+ if (fs20.existsSync(path49.join(cwd, "ruff.toml")))
24534
24835
  return isCommandAvailable("ruff");
24535
24836
  try {
24536
- const pyproject = path48.join(cwd, "pyproject.toml");
24537
- if (fs19.existsSync(pyproject)) {
24538
- 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");
24539
24840
  if (content.includes("[tool.ruff]"))
24540
24841
  return isCommandAvailable("ruff");
24541
24842
  }
@@ -24543,21 +24844,21 @@ function detectRuff(cwd) {
24543
24844
  return false;
24544
24845
  }
24545
24846
  function detectClippy(cwd) {
24546
- return fs19.existsSync(path48.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
24847
+ return fs20.existsSync(path49.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
24547
24848
  }
24548
24849
  function detectGolangciLint(cwd) {
24549
- return fs19.existsSync(path48.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24850
+ return fs20.existsSync(path49.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24550
24851
  }
24551
24852
  function detectCheckstyle(cwd) {
24552
- const hasMaven = fs19.existsSync(path48.join(cwd, "pom.xml"));
24553
- const hasGradle = fs19.existsSync(path48.join(cwd, "build.gradle")) || fs19.existsSync(path48.join(cwd, "build.gradle.kts"));
24554
- 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"));
24555
24856
  return (hasMaven || hasGradle) && hasBinary;
24556
24857
  }
24557
24858
  function detectKtlint(cwd) {
24558
- 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")) || (() => {
24559
24860
  try {
24560
- 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"));
24561
24862
  } catch {
24562
24863
  return false;
24563
24864
  }
@@ -24566,7 +24867,7 @@ function detectKtlint(cwd) {
24566
24867
  }
24567
24868
  function detectDotnetFormat(cwd) {
24568
24869
  try {
24569
- const files = fs19.readdirSync(cwd);
24870
+ const files = fs20.readdirSync(cwd);
24570
24871
  const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
24571
24872
  return hasCsproj && isCommandAvailable("dotnet");
24572
24873
  } catch {
@@ -24574,14 +24875,14 @@ function detectDotnetFormat(cwd) {
24574
24875
  }
24575
24876
  }
24576
24877
  function detectCppcheck(cwd) {
24577
- if (fs19.existsSync(path48.join(cwd, "CMakeLists.txt"))) {
24878
+ if (fs20.existsSync(path49.join(cwd, "CMakeLists.txt"))) {
24578
24879
  return isCommandAvailable("cppcheck");
24579
24880
  }
24580
24881
  try {
24581
- const dirsToCheck = [cwd, path48.join(cwd, "src")];
24882
+ const dirsToCheck = [cwd, path49.join(cwd, "src")];
24582
24883
  const hasCpp = dirsToCheck.some((dir) => {
24583
24884
  try {
24584
- 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));
24585
24886
  } catch {
24586
24887
  return false;
24587
24888
  }
@@ -24592,13 +24893,13 @@ function detectCppcheck(cwd) {
24592
24893
  }
24593
24894
  }
24594
24895
  function detectSwiftlint(cwd) {
24595
- return fs19.existsSync(path48.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
24896
+ return fs20.existsSync(path49.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
24596
24897
  }
24597
24898
  function detectDartAnalyze(cwd) {
24598
- 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"));
24599
24900
  }
24600
24901
  function detectRubocop(cwd) {
24601
- 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"));
24602
24903
  }
24603
24904
  function detectAdditionalLinter(cwd) {
24604
24905
  if (detectRuff(cwd))
@@ -24626,10 +24927,10 @@ function detectAdditionalLinter(cwd) {
24626
24927
  function findBinInAncestors(startDir, binName) {
24627
24928
  let dir = startDir;
24628
24929
  while (true) {
24629
- const candidate = path48.join(dir, "node_modules", ".bin", binName);
24630
- if (fs19.existsSync(candidate))
24930
+ const candidate = path49.join(dir, "node_modules", ".bin", binName);
24931
+ if (fs20.existsSync(candidate))
24631
24932
  return candidate;
24632
- const parent = path48.dirname(dir);
24933
+ const parent = path49.dirname(dir);
24633
24934
  if (parent === dir)
24634
24935
  break;
24635
24936
  dir = parent;
@@ -24638,11 +24939,11 @@ function findBinInAncestors(startDir, binName) {
24638
24939
  }
24639
24940
  function findBinInEnvPath(binName) {
24640
24941
  const searchPath = process.env.PATH ?? "";
24641
- for (const dir of searchPath.split(path48.delimiter)) {
24942
+ for (const dir of searchPath.split(path49.delimiter)) {
24642
24943
  if (!dir)
24643
24944
  continue;
24644
- const candidate = path48.join(dir, binName);
24645
- if (fs19.existsSync(candidate))
24945
+ const candidate = path49.join(dir, binName);
24946
+ if (fs20.existsSync(candidate))
24646
24947
  return candidate;
24647
24948
  }
24648
24949
  return null;
@@ -24650,17 +24951,17 @@ function findBinInEnvPath(binName) {
24650
24951
  async function detectAvailableLinter(directory) {
24651
24952
  if (!directory)
24652
24953
  return null;
24653
- if (!fs19.existsSync(directory))
24954
+ if (!fs20.existsSync(directory))
24654
24955
  return null;
24655
24956
  const projectDir = directory;
24656
24957
  const isWindows = process.platform === "win32";
24657
- const biomeBin = isWindows ? path48.join(projectDir, "node_modules", ".bin", "biome.EXE") : path48.join(projectDir, "node_modules", ".bin", "biome");
24658
- 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");
24659
24960
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
24660
24961
  if (localResult)
24661
24962
  return localResult;
24662
- const biomeAncestor = findBinInAncestors(path48.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
24663
- 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");
24664
24965
  if (biomeAncestor || eslintAncestor) {
24665
24966
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
24666
24967
  }
@@ -24683,7 +24984,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24683
24984
  const result = await Promise.race([biomeExit, timeout]);
24684
24985
  if (result === "timeout") {
24685
24986
  biomeProc.kill();
24686
- } else if (biomeProc.exitCode === 0 && fs19.existsSync(biomeBin)) {
24987
+ } else if (biomeProc.exitCode === 0 && fs20.existsSync(biomeBin)) {
24687
24988
  return "biome";
24688
24989
  }
24689
24990
  } catch {}
@@ -24697,7 +24998,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24697
24998
  const result = await Promise.race([eslintExit, timeout]);
24698
24999
  if (result === "timeout") {
24699
25000
  eslintProc.kill();
24700
- } else if (eslintProc.exitCode === 0 && fs19.existsSync(eslintBin)) {
25001
+ } else if (eslintProc.exitCode === 0 && fs20.existsSync(eslintBin)) {
24701
25002
  return "eslint";
24702
25003
  }
24703
25004
  } catch {}
@@ -24873,8 +25174,8 @@ var _internals37 = {
24873
25174
  };
24874
25175
 
24875
25176
  // src/tools/secretscan.ts
24876
- import * as fs20 from "fs";
24877
- import * as path49 from "path";
25177
+ import * as fs21 from "fs";
25178
+ import * as path50 from "path";
24878
25179
  var MAX_FILE_PATH_LENGTH = 500;
24879
25180
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
24880
25181
  var MAX_FILES_SCANNED = 1000;
@@ -25101,11 +25402,11 @@ function isGlobOrPathPattern(pattern) {
25101
25402
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
25102
25403
  }
25103
25404
  function loadSecretScanIgnore(scanDir) {
25104
- const ignorePath = path49.join(scanDir, ".secretscanignore");
25405
+ const ignorePath = path50.join(scanDir, ".secretscanignore");
25105
25406
  try {
25106
- if (!fs20.existsSync(ignorePath))
25407
+ if (!fs21.existsSync(ignorePath))
25107
25408
  return [];
25108
- const content = fs20.readFileSync(ignorePath, "utf8");
25409
+ const content = fs21.readFileSync(ignorePath, "utf8");
25109
25410
  const patterns = [];
25110
25411
  for (const rawLine of content.split(/\r?\n/)) {
25111
25412
  const line = rawLine.trim();
@@ -25124,7 +25425,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
25124
25425
  if (exactNames.has(entry))
25125
25426
  return true;
25126
25427
  for (const pattern of globPatterns) {
25127
- if (path49.matchesGlob(relPath, pattern))
25428
+ if (path50.matchesGlob(relPath, pattern))
25128
25429
  return true;
25129
25430
  }
25130
25431
  return false;
@@ -25145,7 +25446,7 @@ function validateDirectoryInput(dir) {
25145
25446
  return null;
25146
25447
  }
25147
25448
  function isBinaryFile(filePath, buffer) {
25148
- const ext = path49.extname(filePath).toLowerCase();
25449
+ const ext = path50.extname(filePath).toLowerCase();
25149
25450
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
25150
25451
  return true;
25151
25452
  }
@@ -25220,11 +25521,11 @@ function createRedactedContext(line, findings) {
25220
25521
  result += line.slice(lastEnd);
25221
25522
  return result;
25222
25523
  }
25223
- var O_NOFOLLOW = process.platform !== "win32" ? fs20.constants.O_NOFOLLOW : undefined;
25524
+ var O_NOFOLLOW = process.platform !== "win32" ? fs21.constants.O_NOFOLLOW : undefined;
25224
25525
  function scanFileForSecrets(filePath) {
25225
25526
  const findings = [];
25226
25527
  try {
25227
- const lstat2 = fs20.lstatSync(filePath);
25528
+ const lstat2 = fs21.lstatSync(filePath);
25228
25529
  if (lstat2.isSymbolicLink()) {
25229
25530
  return findings;
25230
25531
  }
@@ -25233,14 +25534,14 @@ function scanFileForSecrets(filePath) {
25233
25534
  }
25234
25535
  let buffer;
25235
25536
  if (O_NOFOLLOW !== undefined) {
25236
- const fd = fs20.openSync(filePath, "r", O_NOFOLLOW);
25537
+ const fd = fs21.openSync(filePath, "r", O_NOFOLLOW);
25237
25538
  try {
25238
- buffer = fs20.readFileSync(fd);
25539
+ buffer = fs21.readFileSync(fd);
25239
25540
  } finally {
25240
- fs20.closeSync(fd);
25541
+ fs21.closeSync(fd);
25241
25542
  }
25242
25543
  } else {
25243
- buffer = fs20.readFileSync(filePath);
25544
+ buffer = fs21.readFileSync(filePath);
25244
25545
  }
25245
25546
  if (isBinaryFile(filePath, buffer)) {
25246
25547
  return findings;
@@ -25282,9 +25583,9 @@ function isSymlinkLoop(realPath, visited) {
25282
25583
  return false;
25283
25584
  }
25284
25585
  function isPathWithinScope(realPath, scanDir) {
25285
- const resolvedScanDir = path49.resolve(scanDir);
25286
- const resolvedRealPath = path49.resolve(realPath);
25287
- 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}\\`);
25288
25589
  }
25289
25590
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
25290
25591
  skippedDirs: 0,
@@ -25295,7 +25596,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
25295
25596
  const files = [];
25296
25597
  let entries;
25297
25598
  try {
25298
- entries = fs20.readdirSync(dir);
25599
+ entries = fs21.readdirSync(dir);
25299
25600
  } catch {
25300
25601
  stats.fileErrors++;
25301
25602
  return files;
@@ -25310,15 +25611,15 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
25310
25611
  return a.localeCompare(b);
25311
25612
  });
25312
25613
  for (const entry of entries) {
25313
- const fullPath = path49.join(dir, entry);
25314
- const relPath = path49.relative(scanDir, fullPath).replace(/\\/g, "/");
25614
+ const fullPath = path50.join(dir, entry);
25615
+ const relPath = path50.relative(scanDir, fullPath).replace(/\\/g, "/");
25315
25616
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
25316
25617
  stats.skippedDirs++;
25317
25618
  continue;
25318
25619
  }
25319
25620
  let lstat2;
25320
25621
  try {
25321
- lstat2 = fs20.lstatSync(fullPath);
25622
+ lstat2 = fs21.lstatSync(fullPath);
25322
25623
  } catch {
25323
25624
  stats.fileErrors++;
25324
25625
  continue;
@@ -25330,7 +25631,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
25330
25631
  if (lstat2.isDirectory()) {
25331
25632
  let realPath;
25332
25633
  try {
25333
- realPath = fs20.realpathSync(fullPath);
25634
+ realPath = fs21.realpathSync(fullPath);
25334
25635
  } catch {
25335
25636
  stats.fileErrors++;
25336
25637
  continue;
@@ -25346,7 +25647,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
25346
25647
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
25347
25648
  files.push(...subFiles);
25348
25649
  } else if (lstat2.isFile()) {
25349
- const ext = path49.extname(fullPath).toLowerCase();
25650
+ const ext = path50.extname(fullPath).toLowerCase();
25350
25651
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
25351
25652
  files.push(fullPath);
25352
25653
  } else {
@@ -25412,15 +25713,15 @@ var secretscan = createSwarmTool({
25412
25713
  }
25413
25714
  }
25414
25715
  try {
25415
- const _scanDirRaw = path49.resolve(directory);
25716
+ const _scanDirRaw = path50.resolve(directory);
25416
25717
  const scanDir = (() => {
25417
25718
  try {
25418
- return fs20.realpathSync(_scanDirRaw);
25719
+ return fs21.realpathSync(_scanDirRaw);
25419
25720
  } catch {
25420
25721
  return _scanDirRaw;
25421
25722
  }
25422
25723
  })();
25423
- if (!fs20.existsSync(scanDir)) {
25724
+ if (!fs21.existsSync(scanDir)) {
25424
25725
  const errorResult = {
25425
25726
  error: "directory not found",
25426
25727
  scan_dir: directory,
@@ -25431,7 +25732,7 @@ var secretscan = createSwarmTool({
25431
25732
  };
25432
25733
  return JSON.stringify(errorResult, null, 2);
25433
25734
  }
25434
- const dirStat = fs20.statSync(scanDir);
25735
+ const dirStat = fs21.statSync(scanDir);
25435
25736
  if (!dirStat.isDirectory()) {
25436
25737
  const errorResult = {
25437
25738
  error: "target must be a directory, not a file",
@@ -25482,7 +25783,7 @@ var secretscan = createSwarmTool({
25482
25783
  break;
25483
25784
  const fileFindings = scanFileForSecrets(filePath);
25484
25785
  try {
25485
- const stat6 = fs20.statSync(filePath);
25786
+ const stat6 = fs21.statSync(filePath);
25486
25787
  if (stat6.size > MAX_FILE_SIZE_BYTES) {
25487
25788
  skippedFiles++;
25488
25789
  continue;
@@ -25574,12 +25875,12 @@ var _internals38 = {
25574
25875
  };
25575
25876
 
25576
25877
  // src/tools/test-runner.ts
25577
- import * as fs24 from "fs";
25578
- import * as path53 from "path";
25878
+ import * as fs25 from "fs";
25879
+ import * as path54 from "path";
25579
25880
 
25580
25881
  // src/test-impact/analyzer.ts
25581
- import fs21 from "fs";
25582
- import path50 from "path";
25882
+ import fs22 from "fs";
25883
+ import path51 from "path";
25583
25884
  var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
25584
25885
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
25585
25886
  var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
@@ -25606,7 +25907,7 @@ function sharedTrailingSegments(a, b) {
25606
25907
  function isCacheStale(impactMap, generatedAtMs) {
25607
25908
  for (const sourcePath of Object.keys(impactMap)) {
25608
25909
  try {
25609
- const stat6 = fs21.statSync(sourcePath);
25910
+ const stat6 = fs22.statSync(sourcePath);
25610
25911
  if (stat6.mtimeMs > generatedAtMs) {
25611
25912
  return true;
25612
25913
  }
@@ -25620,15 +25921,15 @@ function resolveRelativeImport(fromDir, importPath) {
25620
25921
  if (!importPath.startsWith(".")) {
25621
25922
  return null;
25622
25923
  }
25623
- const resolved = path50.resolve(fromDir, importPath);
25624
- if (path50.extname(resolved)) {
25625
- 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()) {
25626
25927
  return normalizePath2(resolved);
25627
25928
  }
25628
25929
  } else {
25629
25930
  for (const ext of EXTENSIONS_TO_TRY) {
25630
25931
  const withExt = resolved + ext;
25631
- if (fs21.existsSync(withExt) && fs21.statSync(withExt).isFile()) {
25932
+ if (fs22.existsSync(withExt) && fs22.statSync(withExt).isFile()) {
25632
25933
  return normalizePath2(withExt);
25633
25934
  }
25634
25935
  }
@@ -25641,30 +25942,30 @@ function resolvePythonImport(fromDir, module) {
25641
25942
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
25642
25943
  let baseDir = fromDir;
25643
25944
  for (let i = 1;i < leadingDots; i++) {
25644
- baseDir = path50.dirname(baseDir);
25945
+ baseDir = path51.dirname(baseDir);
25645
25946
  }
25646
25947
  const rest = module.slice(leadingDots);
25647
25948
  if (rest.length === 0) {
25648
- const initPath = path50.join(baseDir, "__init__.py");
25649
- 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()) {
25650
25951
  return normalizePath2(initPath);
25651
25952
  }
25652
25953
  return null;
25653
25954
  }
25654
- const subpath = rest.replace(/\./g, path50.sep);
25955
+ const subpath = rest.replace(/\./g, path51.sep);
25655
25956
  const candidates = [
25656
- `${path50.join(baseDir, subpath)}.py`,
25657
- path50.join(baseDir, subpath, "__init__.py")
25957
+ `${path51.join(baseDir, subpath)}.py`,
25958
+ path51.join(baseDir, subpath, "__init__.py")
25658
25959
  ];
25659
25960
  for (const c of candidates) {
25660
- if (fs21.existsSync(c) && fs21.statSync(c).isFile())
25961
+ if (fs22.existsSync(c) && fs22.statSync(c).isFile())
25661
25962
  return normalizePath2(c);
25662
25963
  }
25663
25964
  return null;
25664
25965
  }
25665
25966
  var goModuleCache = new Map;
25666
25967
  function findGoModule(fromDir) {
25667
- const resolved = path50.resolve(fromDir);
25968
+ const resolved = path51.resolve(fromDir);
25668
25969
  let cur = resolved;
25669
25970
  const walked = [];
25670
25971
  for (let i = 0;i < 16; i++) {
@@ -25676,8 +25977,8 @@ function findGoModule(fromDir) {
25676
25977
  }
25677
25978
  walked.push(cur);
25678
25979
  try {
25679
- const goMod = path50.join(cur, "go.mod");
25680
- const content = fs21.readFileSync(goMod, "utf-8");
25980
+ const goMod = path51.join(cur, "go.mod");
25981
+ const content = fs22.readFileSync(goMod, "utf-8");
25681
25982
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
25682
25983
  if (moduleMatch) {
25683
25984
  const result = { moduleRoot: cur, modulePath: moduleMatch[1] };
@@ -25687,10 +25988,10 @@ function findGoModule(fromDir) {
25687
25988
  }
25688
25989
  } catch {}
25689
25990
  try {
25690
- fs21.accessSync(path50.join(cur, ".git"));
25991
+ fs22.accessSync(path51.join(cur, ".git"));
25691
25992
  break;
25692
25993
  } catch {}
25693
- const parent = path50.dirname(cur);
25994
+ const parent = path51.dirname(cur);
25694
25995
  if (parent === cur)
25695
25996
  break;
25696
25997
  cur = parent;
@@ -25702,20 +26003,20 @@ function findGoModule(fromDir) {
25702
26003
  function resolveGoImport(fromDir, importPath) {
25703
26004
  let dir = null;
25704
26005
  if (importPath.startsWith(".")) {
25705
- dir = path50.resolve(fromDir, importPath);
26006
+ dir = path51.resolve(fromDir, importPath);
25706
26007
  } else {
25707
26008
  const mod = findGoModule(fromDir);
25708
26009
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
25709
26010
  const subpath = importPath.slice(mod.modulePath.length);
25710
- dir = path50.join(mod.moduleRoot, subpath);
26011
+ dir = path51.join(mod.moduleRoot, subpath);
25711
26012
  }
25712
26013
  }
25713
26014
  if (dir === null)
25714
26015
  return [];
25715
- if (!fs21.existsSync(dir) || !fs21.statSync(dir).isDirectory())
26016
+ if (!fs22.existsSync(dir) || !fs22.statSync(dir).isDirectory())
25716
26017
  return [];
25717
26018
  try {
25718
- 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)));
25719
26020
  } catch {
25720
26021
  return [];
25721
26022
  }
@@ -25735,13 +26036,13 @@ function findTestFilesSync(cwd) {
25735
26036
  function walk(dir, visitedInodes) {
25736
26037
  let entries;
25737
26038
  try {
25738
- entries = fs21.readdirSync(dir, { withFileTypes: true });
26039
+ entries = fs22.readdirSync(dir, { withFileTypes: true });
25739
26040
  } catch {
25740
26041
  return;
25741
26042
  }
25742
26043
  let dirInode;
25743
26044
  try {
25744
- dirInode = fs21.statSync(dir).ino;
26045
+ dirInode = fs22.statSync(dir).ino;
25745
26046
  } catch {
25746
26047
  return;
25747
26048
  }
@@ -25754,15 +26055,15 @@ function findTestFilesSync(cwd) {
25754
26055
  for (const entry of entries) {
25755
26056
  if (entry.isDirectory()) {
25756
26057
  if (!skipDirs.has(entry.name)) {
25757
- walk(path50.join(dir, entry.name), visitedInodes);
26058
+ walk(path51.join(dir, entry.name), visitedInodes);
25758
26059
  }
25759
26060
  } else if (entry.isFile()) {
25760
26061
  const name = entry.name;
25761
26062
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
25762
- 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");
25763
26064
  const isGoTest = /.+_test\.go$/.test(name);
25764
26065
  if (isTsTest || isPyTest || isGoTest) {
25765
- testFiles.push(normalizePath2(path50.join(dir, entry.name)));
26066
+ testFiles.push(normalizePath2(path51.join(dir, entry.name)));
25766
26067
  }
25767
26068
  }
25768
26069
  }
@@ -25787,8 +26088,8 @@ function extractImports(content) {
25787
26088
  ];
25788
26089
  }
25789
26090
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
25790
- const ext = path50.extname(testFile).toLowerCase();
25791
- const testDir = path50.dirname(testFile);
26091
+ const ext = path51.extname(testFile).toLowerCase();
26092
+ const testDir = path51.dirname(testFile);
25792
26093
  function addEdge(source) {
25793
26094
  if (!impactMap[source])
25794
26095
  impactMap[source] = [];
@@ -25830,7 +26131,7 @@ async function buildImpactMapInternal(cwd) {
25830
26131
  for (const testFile of testFiles) {
25831
26132
  let content;
25832
26133
  try {
25833
- content = fs21.readFileSync(testFile, "utf-8");
26134
+ content = fs22.readFileSync(testFile, "utf-8");
25834
26135
  } catch {
25835
26136
  continue;
25836
26137
  }
@@ -25861,10 +26162,10 @@ async function buildImpactMap(cwd) {
25861
26162
  return impactMap;
25862
26163
  }
25863
26164
  async function loadImpactMap(cwd, options) {
25864
- const cachePath = path50.join(cwd, ".swarm", "cache", "impact-map.json");
25865
- if (fs21.existsSync(cachePath)) {
26165
+ const cachePath = path51.join(cwd, ".swarm", "cache", "impact-map.json");
26166
+ if (fs22.existsSync(cachePath)) {
25866
26167
  try {
25867
- const content = fs21.readFileSync(cachePath, "utf-8");
26168
+ const content = fs22.readFileSync(cachePath, "utf-8");
25868
26169
  const data = JSON.parse(content);
25869
26170
  if (data.map !== null && typeof data.map === "object" && !Array.isArray(data.map)) {
25870
26171
  const map = data.map;
@@ -25894,21 +26195,21 @@ async function loadImpactMap(cwd, options) {
25894
26195
  return _internals39.buildImpactMap(cwd);
25895
26196
  }
25896
26197
  async function saveImpactMap(cwd, impactMap) {
25897
- if (!path50.isAbsolute(cwd)) {
26198
+ if (!path51.isAbsolute(cwd)) {
25898
26199
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
25899
26200
  }
25900
26201
  _internals39.validateProjectRoot(cwd);
25901
- const cacheDir2 = path50.join(cwd, ".swarm", "cache");
25902
- const cachePath = path50.join(cacheDir2, "impact-map.json");
25903
- if (!fs21.existsSync(cacheDir2)) {
25904
- 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 });
25905
26206
  }
25906
26207
  const data = {
25907
26208
  generatedAt: new Date().toISOString(),
25908
26209
  fileCount: Object.keys(impactMap).length,
25909
26210
  map: impactMap
25910
26211
  };
25911
- fs21.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
26212
+ fs22.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
25912
26213
  }
25913
26214
  async function analyzeImpact(changedFiles, cwd, budget) {
25914
26215
  if (!Array.isArray(changedFiles)) {
@@ -25931,7 +26232,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
25931
26232
  budgetExceeded = true;
25932
26233
  break;
25933
26234
  }
25934
- const normalizedChanged = normalizePath2(path50.resolve(changedFile));
26235
+ const normalizedChanged = normalizePath2(path51.resolve(changedFile));
25935
26236
  const tests = impactMap[normalizedChanged];
25936
26237
  if (tests && tests.length > 0) {
25937
26238
  for (const test of tests) {
@@ -25945,13 +26246,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
25945
26246
  if (budgetExceeded)
25946
26247
  break;
25947
26248
  } else {
25948
- const changedDir = normalizePath2(path50.dirname(normalizedChanged));
25949
- const changedInputDir = normalizePath2(path50.dirname(changedFile));
26249
+ const changedDir = normalizePath2(path51.dirname(normalizedChanged));
26250
+ const changedInputDir = normalizePath2(path51.dirname(changedFile));
25950
26251
  const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
25951
26252
  return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
25952
26253
  }).sort(([sourceA], [sourceB]) => {
25953
- const sourceDirA = normalizePath2(path50.dirname(sourceA));
25954
- const sourceDirB = normalizePath2(path50.dirname(sourceB));
26254
+ const sourceDirA = normalizePath2(path51.dirname(sourceA));
26255
+ const sourceDirB = normalizePath2(path51.dirname(sourceB));
25955
26256
  const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
25956
26257
  const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
25957
26258
  if (exactA !== exactB)
@@ -26277,8 +26578,8 @@ function detectFlakyTests(allHistory) {
26277
26578
  }
26278
26579
 
26279
26580
  // src/test-impact/history-store.ts
26280
- import fs22 from "fs";
26281
- import path51 from "path";
26581
+ import fs23 from "fs";
26582
+ import path52 from "path";
26282
26583
  var MAX_HISTORY_PER_TEST = 20;
26283
26584
  var MAX_ERROR_LENGTH = 500;
26284
26585
  var MAX_STACK_LENGTH = 200;
@@ -26290,10 +26591,10 @@ function getHistoryPath(workingDir) {
26290
26591
  if (!workingDir) {
26291
26592
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
26292
26593
  }
26293
- if (!path51.isAbsolute(workingDir)) {
26594
+ if (!path52.isAbsolute(workingDir)) {
26294
26595
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
26295
26596
  }
26296
- return path51.join(workingDir, ".swarm", "cache", "test-history.jsonl");
26597
+ return path52.join(workingDir, ".swarm", "cache", "test-history.jsonl");
26297
26598
  }
26298
26599
  function sanitizeErrorMessage(errorMessage) {
26299
26600
  if (errorMessage === undefined) {
@@ -26385,10 +26686,10 @@ function batchAppendTestRuns(records, workingDir) {
26385
26686
  }
26386
26687
  }
26387
26688
  const historyPath = getHistoryPath(workingDir);
26388
- const historyDir = path51.dirname(historyPath);
26689
+ const historyDir = path52.dirname(historyPath);
26389
26690
  _internals40.validateProjectRoot(workingDir);
26390
- if (!fs22.existsSync(historyDir)) {
26391
- fs22.mkdirSync(historyDir, { recursive: true });
26691
+ if (!fs23.existsSync(historyDir)) {
26692
+ fs23.mkdirSync(historyDir, { recursive: true });
26392
26693
  }
26393
26694
  withHistoryWriteLock(historyPath, () => {
26394
26695
  const existingRecords = readAllRecords(historyPath);
@@ -26422,13 +26723,13 @@ function batchAppendTestRuns(records, workingDir) {
26422
26723
  `)}
26423
26724
  `;
26424
26725
  const tempPath = `${historyPath}.tmp`;
26425
- fs22.writeFileSync(tempPath, content, "utf-8");
26426
- fs22.renameSync(tempPath, historyPath);
26726
+ fs23.writeFileSync(tempPath, content, "utf-8");
26727
+ fs23.renameSync(tempPath, historyPath);
26427
26728
  } catch (err) {
26428
26729
  try {
26429
26730
  const tempPath = `${historyPath}.tmp`;
26430
- if (fs22.existsSync(tempPath)) {
26431
- fs22.unlinkSync(tempPath);
26731
+ if (fs23.existsSync(tempPath)) {
26732
+ fs23.unlinkSync(tempPath);
26432
26733
  }
26433
26734
  } catch {}
26434
26735
  throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
@@ -26440,7 +26741,7 @@ function withHistoryWriteLock(historyPath, fn) {
26440
26741
  const deadline = Date.now() + HISTORY_WRITE_LOCK_TIMEOUT_MS;
26441
26742
  while (true) {
26442
26743
  try {
26443
- fs22.mkdirSync(lockPath);
26744
+ fs23.mkdirSync(lockPath);
26444
26745
  break;
26445
26746
  } catch (error2) {
26446
26747
  const code = error2 instanceof Error && "code" in error2 ? error2.code : undefined;
@@ -26451,9 +26752,9 @@ function withHistoryWriteLock(historyPath, fn) {
26451
26752
  throw new Error(`Timed out waiting for test history lock: ${historyPath}`);
26452
26753
  }
26453
26754
  try {
26454
- const lockStat = fs22.statSync(lockPath);
26755
+ const lockStat = fs23.statSync(lockPath);
26455
26756
  if (Date.now() - lockStat.mtimeMs >= HISTORY_WRITE_LOCK_STALE_MS) {
26456
- fs22.rmSync(lockPath, { recursive: true, force: true });
26757
+ fs23.rmSync(lockPath, { recursive: true, force: true });
26457
26758
  continue;
26458
26759
  }
26459
26760
  } catch {}
@@ -26468,7 +26769,7 @@ function withHistoryWriteLock(historyPath, fn) {
26468
26769
  return fn();
26469
26770
  } finally {
26470
26771
  try {
26471
- fs22.rmSync(lockPath, { recursive: true, force: true });
26772
+ fs23.rmSync(lockPath, { recursive: true, force: true });
26472
26773
  } catch {}
26473
26774
  }
26474
26775
  function sleepSync(ms) {
@@ -26477,11 +26778,11 @@ function withHistoryWriteLock(historyPath, fn) {
26477
26778
  }
26478
26779
  }
26479
26780
  function readAllRecords(historyPath) {
26480
- if (!fs22.existsSync(historyPath)) {
26781
+ if (!fs23.existsSync(historyPath)) {
26481
26782
  return [];
26482
26783
  }
26483
26784
  try {
26484
- const content = fs22.readFileSync(historyPath, "utf-8");
26785
+ const content = fs23.readFileSync(historyPath, "utf-8");
26485
26786
  const lines = content.split(`
26486
26787
  `);
26487
26788
  const records = [];
@@ -26514,8 +26815,8 @@ var _internals40 = {
26514
26815
  };
26515
26816
 
26516
26817
  // src/tools/resolve-working-directory.ts
26517
- import * as fs23 from "fs";
26518
- import * as path52 from "path";
26818
+ import * as fs24 from "fs";
26819
+ import * as path53 from "path";
26519
26820
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26520
26821
  if (workingDirectory == null || workingDirectory === "") {
26521
26822
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
@@ -26547,18 +26848,18 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26547
26848
  };
26548
26849
  }
26549
26850
  }
26550
- const rawPathParts = workingDirectory.split(path52.sep);
26851
+ const rawPathParts = workingDirectory.split(path53.sep);
26551
26852
  if (rawPathParts.includes("..")) {
26552
26853
  return {
26553
26854
  success: false,
26554
26855
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
26555
26856
  };
26556
26857
  }
26557
- const normalizedDir = path52.normalize(workingDirectory);
26558
- const resolvedDir = path52.resolve(normalizedDir);
26858
+ const normalizedDir = path53.normalize(workingDirectory);
26859
+ const resolvedDir = path53.resolve(normalizedDir);
26559
26860
  let statResult;
26560
26861
  try {
26561
- statResult = fs23.statSync(resolvedDir);
26862
+ statResult = fs24.statSync(resolvedDir);
26562
26863
  } catch {
26563
26864
  return {
26564
26865
  success: false,
@@ -26574,16 +26875,16 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
26574
26875
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
26575
26876
  return { success: true, directory: resolvedDir };
26576
26877
  }
26577
- const resolvedFallback = path52.resolve(fallbackDirectory);
26878
+ const resolvedFallback = path53.resolve(fallbackDirectory);
26578
26879
  let fallbackExists = false;
26579
26880
  try {
26580
- fs23.statSync(resolvedFallback);
26881
+ fs24.statSync(resolvedFallback);
26581
26882
  fallbackExists = true;
26582
26883
  } catch {
26583
26884
  fallbackExists = false;
26584
26885
  }
26585
26886
  if (fallbackExists) {
26586
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path52.sep);
26887
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path53.sep);
26587
26888
  if (isSubdirectory) {
26588
26889
  return {
26589
26890
  success: false,
@@ -26606,7 +26907,7 @@ async function estimateFanOut(sourceFiles, cwd) {
26606
26907
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
26607
26908
  const uniqueTestFiles = new Set;
26608
26909
  for (const sourceFile of sourceFiles) {
26609
- const resolvedPath = path53.resolve(cwd, sourceFile);
26910
+ const resolvedPath = path54.resolve(cwd, sourceFile);
26610
26911
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
26611
26912
  const testFiles = impactMap[normalizedPath];
26612
26913
  if (testFiles) {
@@ -26691,19 +26992,19 @@ function hasDevDependency(devDeps, ...patterns) {
26691
26992
  return hasPackageJsonDependency(devDeps, ...patterns);
26692
26993
  }
26693
26994
  function detectGoTest(cwd) {
26694
- return fs24.existsSync(path53.join(cwd, "go.mod")) && isCommandAvailable("go");
26995
+ return fs25.existsSync(path54.join(cwd, "go.mod")) && isCommandAvailable("go");
26695
26996
  }
26696
26997
  function detectJavaMaven(cwd) {
26697
- return fs24.existsSync(path53.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
26998
+ return fs25.existsSync(path54.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
26698
26999
  }
26699
27000
  function detectGradle(cwd) {
26700
- const hasBuildFile = fs24.existsSync(path53.join(cwd, "build.gradle")) || fs24.existsSync(path53.join(cwd, "build.gradle.kts"));
26701
- 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"));
26702
27003
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
26703
27004
  }
26704
27005
  function detectDotnetTest(cwd) {
26705
27006
  try {
26706
- const files = fs24.readdirSync(cwd);
27007
+ const files = fs25.readdirSync(cwd);
26707
27008
  const hasCsproj = files.some((f) => f.endsWith(".csproj"));
26708
27009
  return hasCsproj && isCommandAvailable("dotnet");
26709
27010
  } catch {
@@ -26711,25 +27012,25 @@ function detectDotnetTest(cwd) {
26711
27012
  }
26712
27013
  }
26713
27014
  function detectCTest(cwd) {
26714
- const hasSource = fs24.existsSync(path53.join(cwd, "CMakeLists.txt"));
26715
- 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"));
26716
27017
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
26717
27018
  }
26718
27019
  function detectSwiftTest(cwd) {
26719
- return fs24.existsSync(path53.join(cwd, "Package.swift")) && isCommandAvailable("swift");
27020
+ return fs25.existsSync(path54.join(cwd, "Package.swift")) && isCommandAvailable("swift");
26720
27021
  }
26721
27022
  function detectDartTest(cwd) {
26722
- 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"));
26723
27024
  }
26724
27025
  function detectRSpec(cwd) {
26725
- const hasRSpecFile = fs24.existsSync(path53.join(cwd, ".rspec"));
26726
- const hasGemfile = fs24.existsSync(path53.join(cwd, "Gemfile"));
26727
- 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"));
26728
27029
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
26729
27030
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
26730
27031
  }
26731
27032
  function detectMinitest(cwd) {
26732
- 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");
26733
27034
  }
26734
27035
  var DISPATCH_FRAMEWORK_MAP = {
26735
27036
  bun: "bun",
@@ -26814,9 +27115,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
26814
27115
  async function detectTestFramework(cwd) {
26815
27116
  const baseDir = cwd;
26816
27117
  try {
26817
- const packageJsonPath = path53.join(baseDir, "package.json");
26818
- if (fs24.existsSync(packageJsonPath)) {
26819
- 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");
26820
27121
  const pkg = JSON.parse(content);
26821
27122
  const _deps = pkg.dependencies || {};
26822
27123
  const devDeps = pkg.devDependencies || {};
@@ -26835,38 +27136,38 @@ async function detectTestFramework(cwd) {
26835
27136
  return "jest";
26836
27137
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
26837
27138
  return "mocha";
26838
- 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"))) {
26839
27140
  if (scripts.test?.includes("bun"))
26840
27141
  return "bun";
26841
27142
  }
26842
27143
  }
26843
27144
  } catch {}
26844
27145
  try {
26845
- const pyprojectTomlPath = path53.join(baseDir, "pyproject.toml");
26846
- const setupCfgPath = path53.join(baseDir, "setup.cfg");
26847
- const requirementsTxtPath = path53.join(baseDir, "requirements.txt");
26848
- if (fs24.existsSync(pyprojectTomlPath)) {
26849
- 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");
26850
27151
  if (content.includes("[tool.pytest"))
26851
27152
  return "pytest";
26852
27153
  if (content.includes("pytest"))
26853
27154
  return "pytest";
26854
27155
  }
26855
- if (fs24.existsSync(setupCfgPath)) {
26856
- const content = fs24.readFileSync(setupCfgPath, "utf-8");
27156
+ if (fs25.existsSync(setupCfgPath)) {
27157
+ const content = fs25.readFileSync(setupCfgPath, "utf-8");
26857
27158
  if (content.includes("[pytest]"))
26858
27159
  return "pytest";
26859
27160
  }
26860
- if (fs24.existsSync(requirementsTxtPath)) {
26861
- const content = fs24.readFileSync(requirementsTxtPath, "utf-8");
27161
+ if (fs25.existsSync(requirementsTxtPath)) {
27162
+ const content = fs25.readFileSync(requirementsTxtPath, "utf-8");
26862
27163
  if (content.includes("pytest"))
26863
27164
  return "pytest";
26864
27165
  }
26865
27166
  } catch {}
26866
27167
  try {
26867
- const cargoTomlPath = path53.join(baseDir, "Cargo.toml");
26868
- if (fs24.existsSync(cargoTomlPath)) {
26869
- 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");
26870
27171
  if (content.includes("[dev-dependencies]")) {
26871
27172
  if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
26872
27173
  return "cargo";
@@ -26875,10 +27176,10 @@ async function detectTestFramework(cwd) {
26875
27176
  }
26876
27177
  } catch {}
26877
27178
  try {
26878
- const pesterConfigPath = path53.join(baseDir, "pester.config.ps1");
26879
- const pesterConfigJsonPath = path53.join(baseDir, "pester.config.ps1.json");
26880
- const pesterPs1Path = path53.join(baseDir, "tests.ps1");
26881
- 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)) {
26882
27183
  return "pester";
26883
27184
  }
26884
27185
  } catch {}
@@ -26920,12 +27221,12 @@ function isTestDirectoryPath(normalizedPath) {
26920
27221
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
26921
27222
  }
26922
27223
  function resolveWorkspacePath(file, workingDir) {
26923
- return path53.isAbsolute(file) ? path53.resolve(file) : path53.resolve(workingDir, file);
27224
+ return path54.isAbsolute(file) ? path54.resolve(file) : path54.resolve(workingDir, file);
26924
27225
  }
26925
27226
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
26926
27227
  if (!preferRelative)
26927
27228
  return absolutePath;
26928
- return path53.relative(workingDir, absolutePath);
27229
+ return path54.relative(workingDir, absolutePath);
26929
27230
  }
26930
27231
  function dedupePush(target, value) {
26931
27232
  if (!target.includes(value)) {
@@ -26962,18 +27263,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
26962
27263
  }
26963
27264
  }
26964
27265
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
26965
- const relativeDir = path53.dirname(relativePath);
27266
+ const relativeDir = path54.dirname(relativePath);
26966
27267
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
26967
27268
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
26968
- const rootDir = path53.join(workingDir, dirName);
26969
- return nestedRelativeDir ? [rootDir, path53.join(rootDir, nestedRelativeDir)] : [rootDir];
27269
+ const rootDir = path54.join(workingDir, dirName);
27270
+ return nestedRelativeDir ? [rootDir, path54.join(rootDir, nestedRelativeDir)] : [rootDir];
26970
27271
  });
26971
27272
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
26972
27273
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
26973
- 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))));
26974
27275
  }
26975
27276
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
26976
- 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))));
26977
27278
  }
26978
27279
  return [...new Set(directories)];
26979
27280
  }
@@ -26981,19 +27282,19 @@ function hasCompoundTestExtension(filename) {
26981
27282
  const lower = filename.toLowerCase();
26982
27283
  return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
26983
27284
  }
26984
- function isLanguageSpecificTestFile(basename9) {
26985
- const lower = basename9.toLowerCase();
27285
+ function isLanguageSpecificTestFile(basename10) {
27286
+ const lower = basename10.toLowerCase();
26986
27287
  if (lower.endsWith("_test.go"))
26987
27288
  return true;
26988
27289
  if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
26989
27290
  return true;
26990
27291
  if (lower.endsWith("_spec.rb"))
26991
27292
  return true;
26992
- 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")))
26993
27294
  return true;
26994
27295
  if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
26995
27296
  return true;
26996
- 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")))
26997
27298
  return true;
26998
27299
  if (lower.endsWith(".tests.ps1"))
26999
27300
  return true;
@@ -27001,23 +27302,23 @@ function isLanguageSpecificTestFile(basename9) {
27001
27302
  }
27002
27303
  function isConventionTestFilePath(filePath) {
27003
27304
  const normalizedPath = filePath.replace(/\\/g, "/");
27004
- const basename9 = path53.basename(filePath);
27005
- 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);
27006
27307
  }
27007
27308
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
27008
27309
  const testFiles = [];
27009
27310
  for (const file of sourceFiles) {
27010
27311
  const absoluteFile = resolveWorkspacePath(file, workingDir);
27011
- const relativeFile = path53.relative(workingDir, absoluteFile);
27012
- const basename9 = path53.basename(absoluteFile);
27013
- const dirname25 = path53.dirname(absoluteFile);
27014
- 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);
27015
27316
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
27016
27317
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
27017
27318
  continue;
27018
27319
  }
27019
- const nameWithoutExt = basename9.replace(/\.[^.]+$/, "");
27020
- const ext = path53.extname(basename9);
27320
+ const nameWithoutExt = basename10.replace(/\.[^.]+$/, "");
27321
+ const ext = path54.extname(basename10);
27021
27322
  const genericTestNames = [
27022
27323
  `${nameWithoutExt}.spec${ext}`,
27023
27324
  `${nameWithoutExt}.test${ext}`
@@ -27026,20 +27327,20 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
27026
27327
  const colocatedCandidates = [
27027
27328
  ...genericTestNames,
27028
27329
  ...languageSpecificTestNames
27029
- ].map((candidateName) => path53.join(dirname25, candidateName));
27330
+ ].map((candidateName) => path54.join(dirname25, candidateName));
27030
27331
  const testDirectoryNames = [
27031
- basename9,
27332
+ basename10,
27032
27333
  ...genericTestNames,
27033
27334
  ...languageSpecificTestNames
27034
27335
  ];
27035
27336
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
27036
27337
  const possibleTestFiles = [
27037
27338
  ...colocatedCandidates,
27038
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path53.join(dirname25, dirName, candidateName))),
27039
- ...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)))
27040
27341
  ];
27041
27342
  for (const testFile of possibleTestFiles) {
27042
- if (fs24.existsSync(testFile)) {
27343
+ if (fs25.existsSync(testFile)) {
27043
27344
  dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
27044
27345
  }
27045
27346
  }
@@ -27056,8 +27357,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27056
27357
  for (const testFile of candidateTestFiles) {
27057
27358
  try {
27058
27359
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
27059
- const content = fs24.readFileSync(absoluteTestFile, "utf-8");
27060
- const testDir = path53.dirname(absoluteTestFile);
27360
+ const content = fs25.readFileSync(absoluteTestFile, "utf-8");
27361
+ const testDir = path54.dirname(absoluteTestFile);
27061
27362
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
27062
27363
  let match;
27063
27364
  match = importRegex.exec(content);
@@ -27065,8 +27366,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27065
27366
  const importPath = match[1];
27066
27367
  let resolvedImport;
27067
27368
  if (importPath.startsWith(".")) {
27068
- resolvedImport = path53.resolve(testDir, importPath);
27069
- const existingExt = path53.extname(resolvedImport);
27369
+ resolvedImport = path54.resolve(testDir, importPath);
27370
+ const existingExt = path54.extname(resolvedImport);
27070
27371
  if (!existingExt) {
27071
27372
  for (const extToTry of [
27072
27373
  ".ts",
@@ -27077,7 +27378,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27077
27378
  ".cjs"
27078
27379
  ]) {
27079
27380
  const withExt = resolvedImport + extToTry;
27080
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
27381
+ if (absoluteSourceFiles.includes(withExt) || fs25.existsSync(withExt)) {
27081
27382
  resolvedImport = withExt;
27082
27383
  break;
27083
27384
  }
@@ -27086,12 +27387,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27086
27387
  } else {
27087
27388
  continue;
27088
27389
  }
27089
- const importBasename = path53.basename(resolvedImport, path53.extname(resolvedImport));
27090
- const importDir = path53.dirname(resolvedImport);
27390
+ const importBasename = path54.basename(resolvedImport, path54.extname(resolvedImport));
27391
+ const importDir = path54.dirname(resolvedImport);
27091
27392
  for (const sourceFile of absoluteSourceFiles) {
27092
- const sourceDir = path53.dirname(sourceFile);
27093
- const sourceBasename = path53.basename(sourceFile, path53.extname(sourceFile));
27094
- 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");
27095
27396
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
27096
27397
  dedupePush(testFiles, testFile);
27097
27398
  break;
@@ -27104,8 +27405,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27104
27405
  while (match !== null) {
27105
27406
  const importPath = match[1];
27106
27407
  if (importPath.startsWith(".")) {
27107
- let resolvedImport = path53.resolve(testDir, importPath);
27108
- const existingExt = path53.extname(resolvedImport);
27408
+ let resolvedImport = path54.resolve(testDir, importPath);
27409
+ const existingExt = path54.extname(resolvedImport);
27109
27410
  if (!existingExt) {
27110
27411
  for (const extToTry of [
27111
27412
  ".ts",
@@ -27116,18 +27417,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
27116
27417
  ".cjs"
27117
27418
  ]) {
27118
27419
  const withExt = resolvedImport + extToTry;
27119
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
27420
+ if (absoluteSourceFiles.includes(withExt) || fs25.existsSync(withExt)) {
27120
27421
  resolvedImport = withExt;
27121
27422
  break;
27122
27423
  }
27123
27424
  }
27124
27425
  }
27125
- const importDir = path53.dirname(resolvedImport);
27126
- const importBasename = path53.basename(resolvedImport, path53.extname(resolvedImport));
27426
+ const importDir = path54.dirname(resolvedImport);
27427
+ const importBasename = path54.basename(resolvedImport, path54.extname(resolvedImport));
27127
27428
  for (const sourceFile of absoluteSourceFiles) {
27128
- const sourceDir = path53.dirname(sourceFile);
27129
- const sourceBasename = path53.basename(sourceFile, path53.extname(sourceFile));
27130
- 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");
27131
27432
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
27132
27433
  dedupePush(testFiles, testFile);
27133
27434
  break;
@@ -27247,8 +27548,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
27247
27548
  return ["mvn", "test"];
27248
27549
  case "gradle": {
27249
27550
  const isWindows = process.platform === "win32";
27250
- const hasGradlewBat = fs24.existsSync(path53.join(baseDir, "gradlew.bat"));
27251
- 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"));
27252
27553
  if (hasGradlewBat && isWindows)
27253
27554
  return ["gradlew.bat", "test"];
27254
27555
  if (hasGradlew)
@@ -27265,7 +27566,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
27265
27566
  "cmake-build-release",
27266
27567
  "out"
27267
27568
  ];
27268
- 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";
27269
27570
  return ["ctest", "--test-dir", actualBuildDir];
27270
27571
  }
27271
27572
  case "swift-test":
@@ -27699,13 +28000,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27699
28000
  };
27700
28001
  }
27701
28002
  const startTime = Date.now();
27702
- 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;
27703
28004
  try {
27704
28005
  if (vitestJsonOutputPath) {
27705
28006
  try {
27706
- fs24.mkdirSync(path53.dirname(vitestJsonOutputPath), { recursive: true });
27707
- if (fs24.existsSync(vitestJsonOutputPath)) {
27708
- fs24.unlinkSync(vitestJsonOutputPath);
28007
+ fs25.mkdirSync(path54.dirname(vitestJsonOutputPath), { recursive: true });
28008
+ if (fs25.existsSync(vitestJsonOutputPath)) {
28009
+ fs25.unlinkSync(vitestJsonOutputPath);
27709
28010
  }
27710
28011
  } catch {}
27711
28012
  }
@@ -27731,8 +28032,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27731
28032
  }
27732
28033
  if (vitestJsonOutputPath) {
27733
28034
  try {
27734
- if (fs24.existsSync(vitestJsonOutputPath)) {
27735
- const vitestJsonOutput = fs24.readFileSync(vitestJsonOutputPath, "utf-8");
28035
+ if (fs25.existsSync(vitestJsonOutputPath)) {
28036
+ const vitestJsonOutput = fs25.readFileSync(vitestJsonOutputPath, "utf-8");
27736
28037
  if (vitestJsonOutput.trim().length > 0) {
27737
28038
  output += (output ? `
27738
28039
  ` : "") + vitestJsonOutput;
@@ -27871,10 +28172,10 @@ var SKIP_DIRECTORIES = new Set([
27871
28172
  ]);
27872
28173
  function normalizeHistoryTestFile(testFile, workingDir) {
27873
28174
  const normalized = testFile.replace(/\\/g, "/");
27874
- if (!path53.isAbsolute(testFile))
28175
+ if (!path54.isAbsolute(testFile))
27875
28176
  return normalized;
27876
- const relative8 = path53.relative(workingDir, testFile);
27877
- if (relative8.startsWith("..") || path53.isAbsolute(relative8)) {
28177
+ const relative8 = path54.relative(workingDir, testFile);
28178
+ if (relative8.startsWith("..") || path54.isAbsolute(relative8)) {
27878
28179
  return normalized;
27879
28180
  }
27880
28181
  return relative8.replace(/\\/g, "/");
@@ -28113,7 +28414,7 @@ var test_runner = createSwarmTool({
28113
28414
  const sourceFiles = args.files.filter((file) => {
28114
28415
  if (directTestFiles.includes(file))
28115
28416
  return false;
28116
- const ext = path53.extname(file).toLowerCase();
28417
+ const ext = path54.extname(file).toLowerCase();
28117
28418
  return SOURCE_EXTENSIONS.has(ext);
28118
28419
  });
28119
28420
  const invalidFiles = args.files.filter((file) => !directTestFiles.includes(file) && !sourceFiles.includes(file));
@@ -28159,7 +28460,7 @@ var test_runner = createSwarmTool({
28159
28460
  if (isConventionTestFilePath(f)) {
28160
28461
  return false;
28161
28462
  }
28162
- const ext = path53.extname(f).toLowerCase();
28463
+ const ext = path54.extname(f).toLowerCase();
28163
28464
  return SOURCE_EXTENSIONS.has(ext);
28164
28465
  });
28165
28466
  if (sourceFiles.length === 0) {
@@ -28209,7 +28510,7 @@ var test_runner = createSwarmTool({
28209
28510
  if (isConventionTestFilePath(f)) {
28210
28511
  return false;
28211
28512
  }
28212
- const ext = path53.extname(f).toLowerCase();
28513
+ const ext = path54.extname(f).toLowerCase();
28213
28514
  return SOURCE_EXTENSIONS.has(ext);
28214
28515
  });
28215
28516
  if (sourceFiles.length === 0) {
@@ -28261,8 +28562,8 @@ var test_runner = createSwarmTool({
28261
28562
  }
28262
28563
  if (impactResult.impactedTests.length > 0) {
28263
28564
  testFiles = impactResult.impactedTests.map((absPath) => {
28264
- const relativePath = path53.relative(workingDir, absPath);
28265
- return path53.isAbsolute(relativePath) ? absPath : relativePath;
28565
+ const relativePath = path54.relative(workingDir, absPath);
28566
+ return path54.isAbsolute(relativePath) ? absPath : relativePath;
28266
28567
  });
28267
28568
  } else {
28268
28569
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -28357,8 +28658,8 @@ function validateDirectoryPath(dir) {
28357
28658
  if (dir.includes("..")) {
28358
28659
  throw new Error("Directory path must not contain path traversal sequences");
28359
28660
  }
28360
- const normalized = path54.normalize(dir);
28361
- 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);
28362
28663
  return absolutePath;
28363
28664
  }
28364
28665
  function validateTimeout(timeoutMs, defaultValue) {
@@ -28381,9 +28682,9 @@ function validateTimeout(timeoutMs, defaultValue) {
28381
28682
  }
28382
28683
  function getPackageVersion(dir) {
28383
28684
  try {
28384
- const packagePath = path54.join(dir, "package.json");
28385
- if (fs25.existsSync(packagePath)) {
28386
- 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");
28387
28688
  const pkg = JSON.parse(content);
28388
28689
  return pkg.version ?? null;
28389
28690
  }
@@ -28392,9 +28693,9 @@ function getPackageVersion(dir) {
28392
28693
  }
28393
28694
  function getChangelogVersion(dir) {
28394
28695
  try {
28395
- const changelogPath = path54.join(dir, "CHANGELOG.md");
28396
- if (fs25.existsSync(changelogPath)) {
28397
- 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");
28398
28699
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
28399
28700
  if (match) {
28400
28701
  return match[1];
@@ -28406,10 +28707,10 @@ function getChangelogVersion(dir) {
28406
28707
  function getVersionFileVersion(dir) {
28407
28708
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
28408
28709
  for (const file of possibleFiles) {
28409
- const filePath = path54.join(dir, file);
28410
- if (fs25.existsSync(filePath)) {
28710
+ const filePath = path55.join(dir, file);
28711
+ if (fs26.existsSync(filePath)) {
28411
28712
  try {
28412
- const content = fs25.readFileSync(filePath, "utf-8").trim();
28713
+ const content = fs26.readFileSync(filePath, "utf-8").trim();
28413
28714
  const match = content.match(/(\d+\.\d+\.\d+)/);
28414
28715
  if (match) {
28415
28716
  return match[1];
@@ -29143,8 +29444,8 @@ async function handleQaGatesCommand(directory, args, sessionID) {
29143
29444
  }
29144
29445
 
29145
29446
  // src/commands/reset.ts
29146
- import * as fs26 from "fs";
29147
- import * as path55 from "path";
29447
+ import * as fs27 from "fs";
29448
+ import * as path56 from "path";
29148
29449
 
29149
29450
  // src/background/circuit-breaker.ts
29150
29451
  class CircuitBreaker {
@@ -29851,8 +30152,8 @@ async function handleResetCommand(directory, args) {
29851
30152
  for (const filename of filesToReset) {
29852
30153
  try {
29853
30154
  const resolvedPath = validateSwarmPath(directory, filename);
29854
- if (fs26.existsSync(resolvedPath)) {
29855
- fs26.unlinkSync(resolvedPath);
30155
+ if (fs27.existsSync(resolvedPath)) {
30156
+ fs27.unlinkSync(resolvedPath);
29856
30157
  results.push(`- \u2705 Deleted ${filename}`);
29857
30158
  } else {
29858
30159
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -29863,9 +30164,9 @@ async function handleResetCommand(directory, args) {
29863
30164
  }
29864
30165
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
29865
30166
  try {
29866
- const rootPath = path55.join(directory, filename);
29867
- if (fs26.existsSync(rootPath)) {
29868
- fs26.unlinkSync(rootPath);
30167
+ const rootPath = path56.join(directory, filename);
30168
+ if (fs27.existsSync(rootPath)) {
30169
+ fs27.unlinkSync(rootPath);
29869
30170
  results.push(`- \u2705 Deleted ${filename} (root)`);
29870
30171
  }
29871
30172
  } catch (err) {
@@ -29880,8 +30181,8 @@ async function handleResetCommand(directory, args) {
29880
30181
  }
29881
30182
  try {
29882
30183
  const summariesPath = validateSwarmPath(directory, "summaries");
29883
- if (fs26.existsSync(summariesPath)) {
29884
- fs26.rmSync(summariesPath, { recursive: true, force: true });
30184
+ if (fs27.existsSync(summariesPath)) {
30185
+ fs27.rmSync(summariesPath, { recursive: true, force: true });
29885
30186
  results.push("- \u2705 Deleted summaries/ directory");
29886
30187
  } else {
29887
30188
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -29900,8 +30201,8 @@ async function handleResetCommand(directory, args) {
29900
30201
  }
29901
30202
 
29902
30203
  // src/commands/reset-session.ts
29903
- import * as fs28 from "fs";
29904
- import * as path57 from "path";
30204
+ import * as fs29 from "fs";
30205
+ import * as path58 from "path";
29905
30206
 
29906
30207
  // src/hooks/trajectory-logger.ts
29907
30208
  var callStartTimes = new Map;
@@ -30307,17 +30608,17 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
30307
30608
  };
30308
30609
  }
30309
30610
  // src/prm/replay.ts
30310
- import { promises as fs27 } from "fs";
30311
- import path56 from "path";
30611
+ import { promises as fs28 } from "fs";
30612
+ import path57 from "path";
30312
30613
  function isPathSafe(targetPath, basePath) {
30313
- const resolvedTarget = path56.resolve(targetPath);
30314
- const resolvedBase = path56.resolve(basePath);
30315
- const rel = path56.relative(resolvedBase, resolvedTarget);
30316
- 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);
30317
30618
  }
30318
30619
  function isWithinReplaysDir(targetPath) {
30319
- const resolved = path56.resolve(targetPath);
30320
- const parts = resolved.split(path56.sep);
30620
+ const resolved = path57.resolve(targetPath);
30621
+ const parts = resolved.split(path57.sep);
30321
30622
  for (let i = 0;i < parts.length - 1; i++) {
30322
30623
  if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
30323
30624
  return true;
@@ -30330,15 +30631,15 @@ function sanitizeFilename(input) {
30330
30631
  }
30331
30632
  async function startReplayRecording(sessionID, directory) {
30332
30633
  try {
30333
- const replayDir = path56.join(directory, ".swarm", "replays");
30634
+ const replayDir = path57.join(directory, ".swarm", "replays");
30334
30635
  const safeSessionID = sanitizeFilename(sessionID);
30335
30636
  const filename = `${safeSessionID}-${Date.now()}.jsonl`;
30336
- const filepath = path56.join(replayDir, filename);
30637
+ const filepath = path57.join(replayDir, filename);
30337
30638
  if (!isPathSafe(filepath, replayDir)) {
30338
30639
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
30339
30640
  return null;
30340
30641
  }
30341
- await fs27.mkdir(replayDir, { recursive: true });
30642
+ await fs28.mkdir(replayDir, { recursive: true });
30342
30643
  return filepath;
30343
30644
  } catch (err) {
30344
30645
  console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err}`);
@@ -30358,7 +30659,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
30358
30659
  };
30359
30660
  const line = `${JSON.stringify(fullEntry)}
30360
30661
  `;
30361
- await fs27.appendFile(artifactPath, line, "utf-8");
30662
+ await fs28.appendFile(artifactPath, line, "utf-8");
30362
30663
  } catch (err) {
30363
30664
  console.warn(`[replay] Failed to record entry: ${err}`);
30364
30665
  }
@@ -30402,8 +30703,8 @@ async function handleResetSessionCommand(directory, _args) {
30402
30703
  const results = [];
30403
30704
  try {
30404
30705
  const statePath = validateSwarmPath(directory, "session/state.json");
30405
- if (fs28.existsSync(statePath)) {
30406
- fs28.unlinkSync(statePath);
30706
+ if (fs29.existsSync(statePath)) {
30707
+ fs29.unlinkSync(statePath);
30407
30708
  results.push("\u2705 Deleted .swarm/session/state.json");
30408
30709
  } else {
30409
30710
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -30411,11 +30712,11 @@ async function handleResetSessionCommand(directory, _args) {
30411
30712
  } catch {
30412
30713
  results.push("\u274C Failed to delete state.json");
30413
30714
  }
30414
- const sessionDir = path57.dirname(validateSwarmPath(directory, "session/state.json"));
30715
+ const sessionDir = path58.dirname(validateSwarmPath(directory, "session/state.json"));
30415
30716
  let sessionFiles = [];
30416
- if (fs28.existsSync(sessionDir)) {
30717
+ if (fs29.existsSync(sessionDir)) {
30417
30718
  try {
30418
- sessionFiles = fs28.readdirSync(sessionDir);
30719
+ sessionFiles = fs29.readdirSync(sessionDir);
30419
30720
  } catch (err) {
30420
30721
  results.push(`\u274C Failed to read session directory: ${errorMessage(err)}`);
30421
30722
  }
@@ -30423,13 +30724,13 @@ async function handleResetSessionCommand(directory, _args) {
30423
30724
  for (const file of sessionFiles) {
30424
30725
  if (file === "state.json")
30425
30726
  continue;
30426
- const filePath = path57.join(sessionDir, file);
30727
+ const filePath = path58.join(sessionDir, file);
30427
30728
  try {
30428
- if (!fs28.existsSync(filePath))
30729
+ if (!fs29.existsSync(filePath))
30429
30730
  continue;
30430
- if (!fs28.lstatSync(filePath).isFile())
30731
+ if (!fs29.lstatSync(filePath).isFile())
30431
30732
  continue;
30432
- fs28.unlinkSync(filePath);
30733
+ fs29.unlinkSync(filePath);
30433
30734
  results.push(`\u2713 Deleted ${file}`);
30434
30735
  } catch (err) {
30435
30736
  results.push(`\u274C Failed to delete ${file}: ${errorMessage(err)}`);
@@ -30458,7 +30759,7 @@ async function handleResetSessionCommand(directory, _args) {
30458
30759
  }
30459
30760
 
30460
30761
  // src/summaries/manager.ts
30461
- import * as path58 from "path";
30762
+ import * as path59 from "path";
30462
30763
  var SUMMARY_ID_REGEX = /^S\d+$/;
30463
30764
  function sanitizeSummaryId(id) {
30464
30765
  if (!id || id.length === 0) {
@@ -30482,7 +30783,7 @@ function sanitizeSummaryId(id) {
30482
30783
  }
30483
30784
  async function loadFullOutput(directory, id) {
30484
30785
  const sanitizedId = sanitizeSummaryId(id);
30485
- const relativePath = path58.join("summaries", `${sanitizedId}.json`);
30786
+ const relativePath = path59.join("summaries", `${sanitizedId}.json`);
30486
30787
  validateSwarmPath(directory, relativePath);
30487
30788
  const content = await readSwarmFileAsync(directory, relativePath);
30488
30789
  if (content === null) {
@@ -30534,18 +30835,18 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
30534
30835
  }
30535
30836
 
30536
30837
  // src/commands/rollback.ts
30537
- import * as fs29 from "fs";
30538
- import * as path59 from "path";
30838
+ import * as fs30 from "fs";
30839
+ import * as path60 from "path";
30539
30840
  async function handleRollbackCommand(directory, args) {
30540
30841
  const phaseArg = args[0];
30541
30842
  if (!phaseArg) {
30542
30843
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
30543
- if (!fs29.existsSync(manifestPath2)) {
30844
+ if (!fs30.existsSync(manifestPath2)) {
30544
30845
  return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
30545
30846
  }
30546
30847
  let manifest2;
30547
30848
  try {
30548
- manifest2 = JSON.parse(fs29.readFileSync(manifestPath2, "utf-8"));
30849
+ manifest2 = JSON.parse(fs30.readFileSync(manifestPath2, "utf-8"));
30549
30850
  } catch {
30550
30851
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
30551
30852
  }
@@ -30567,12 +30868,12 @@ async function handleRollbackCommand(directory, args) {
30567
30868
  return "Error: Phase number must be a positive integer.";
30568
30869
  }
30569
30870
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
30570
- if (!fs29.existsSync(manifestPath)) {
30871
+ if (!fs30.existsSync(manifestPath)) {
30571
30872
  return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
30572
30873
  }
30573
30874
  let manifest;
30574
30875
  try {
30575
- manifest = JSON.parse(fs29.readFileSync(manifestPath, "utf-8"));
30876
+ manifest = JSON.parse(fs30.readFileSync(manifestPath, "utf-8"));
30576
30877
  } catch {
30577
30878
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
30578
30879
  }
@@ -30582,10 +30883,10 @@ async function handleRollbackCommand(directory, args) {
30582
30883
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
30583
30884
  }
30584
30885
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
30585
- if (!fs29.existsSync(checkpointDir)) {
30886
+ if (!fs30.existsSync(checkpointDir)) {
30586
30887
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
30587
30888
  }
30588
- const checkpointFiles = fs29.readdirSync(checkpointDir);
30889
+ const checkpointFiles = fs30.readdirSync(checkpointDir);
30589
30890
  if (checkpointFiles.length === 0) {
30590
30891
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
30591
30892
  }
@@ -30601,10 +30902,10 @@ async function handleRollbackCommand(directory, args) {
30601
30902
  if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
30602
30903
  continue;
30603
30904
  }
30604
- const src = path59.join(checkpointDir, file);
30605
- const dest = path59.join(swarmDir, file);
30905
+ const src = path60.join(checkpointDir, file);
30906
+ const dest = path60.join(swarmDir, file);
30606
30907
  try {
30607
- fs29.cpSync(src, dest, { recursive: true, force: true });
30908
+ fs30.cpSync(src, dest, { recursive: true, force: true });
30608
30909
  successes.push(file);
30609
30910
  } catch (error2) {
30610
30911
  failures.push({ file, error: error2.message });
@@ -30621,11 +30922,11 @@ async function handleRollbackCommand(directory, args) {
30621
30922
  ].join(`
30622
30923
  `);
30623
30924
  }
30624
- const existingLedgerPath = path59.join(swarmDir, "plan-ledger.jsonl");
30925
+ const existingLedgerPath = path60.join(swarmDir, "plan-ledger.jsonl");
30625
30926
  let ledgerDeletionFailed = false;
30626
- if (fs29.existsSync(existingLedgerPath)) {
30927
+ if (fs30.existsSync(existingLedgerPath)) {
30627
30928
  try {
30628
- fs29.unlinkSync(existingLedgerPath);
30929
+ fs30.unlinkSync(existingLedgerPath);
30629
30930
  } catch (err) {
30630
30931
  ledgerDeletionFailed = true;
30631
30932
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -30634,9 +30935,9 @@ async function handleRollbackCommand(directory, args) {
30634
30935
  }
30635
30936
  if (!ledgerDeletionFailed) {
30636
30937
  try {
30637
- const planJsonPath = path59.join(swarmDir, "plan.json");
30638
- if (fs29.existsSync(planJsonPath)) {
30639
- 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");
30640
30941
  const plan = PlanSchema.parse(JSON.parse(planRaw));
30641
30942
  const planId = derivePlanId(plan);
30642
30943
  const planHash = computePlanHash(plan);
@@ -30664,7 +30965,7 @@ async function handleRollbackCommand(directory, args) {
30664
30965
  timestamp: new Date().toISOString()
30665
30966
  };
30666
30967
  try {
30667
- fs29.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30968
+ fs30.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
30668
30969
  `);
30669
30970
  } catch (error2) {
30670
30971
  console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
@@ -30846,7 +31147,7 @@ async function handleSddCommand(_directory, _args) {
30846
31147
  }
30847
31148
 
30848
31149
  // src/commands/simulate.ts
30849
- import { renameSync as renameSync11, unlinkSync as unlinkSync11 } from "fs";
31150
+ import { renameSync as renameSync11, unlinkSync as unlinkSync12 } from "fs";
30850
31151
  async function handleSimulateCommand(directory, args) {
30851
31152
  const thresholdIndex = args.indexOf("--threshold");
30852
31153
  const minCommitsIndex = args.indexOf("--min-commits");
@@ -30894,17 +31195,17 @@ Ensure this is a git repository with commit history.`;
30894
31195
  const report = reportLines.filter(Boolean).join(`
30895
31196
  `);
30896
31197
  try {
30897
- const fs30 = await import("fs/promises");
30898
- const path60 = await import("path");
30899
- const reportPath = path60.join(directory, ".swarm", "simulate-report.md");
30900
- await fs30.mkdir(path60.dirname(reportPath), { recursive: true });
30901
- 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)}`);
30902
31203
  try {
30903
- await fs30.writeFile(reportTempPath, report, "utf-8");
31204
+ await fs31.writeFile(reportTempPath, report, "utf-8");
30904
31205
  renameSync11(reportTempPath, reportPath);
30905
31206
  } catch (err) {
30906
31207
  try {
30907
- unlinkSync11(reportTempPath);
31208
+ unlinkSync12(reportTempPath);
30908
31209
  } catch {}
30909
31210
  throw err;
30910
31211
  }
@@ -30927,20 +31228,20 @@ async function handleSpecifyCommand(_directory, args) {
30927
31228
  // src/services/status-service.ts
30928
31229
  import * as fsSync3 from "fs";
30929
31230
  import { readFile as readFile16 } from "fs/promises";
30930
- import * as path61 from "path";
31231
+ import * as path62 from "path";
30931
31232
 
30932
31233
  // src/turbo/lean/state.ts
30933
31234
  init_logger();
30934
- import * as fs30 from "fs";
30935
- import * as path60 from "path";
31235
+ import * as fs31 from "fs";
31236
+ import * as path61 from "path";
30936
31237
  var STATE_FILE3 = "turbo-state.json";
30937
31238
  function nowISO3() {
30938
31239
  return new Date().toISOString();
30939
31240
  }
30940
31241
  function ensureSwarmDir2(directory) {
30941
- const swarmDir = path60.resolve(directory, ".swarm");
30942
- if (!fs30.existsSync(swarmDir)) {
30943
- fs30.mkdirSync(swarmDir, { recursive: true });
31242
+ const swarmDir = path61.resolve(directory, ".swarm");
31243
+ if (!fs31.existsSync(swarmDir)) {
31244
+ fs31.mkdirSync(swarmDir, { recursive: true });
30944
31245
  }
30945
31246
  return swarmDir;
30946
31247
  }
@@ -30983,17 +31284,17 @@ function markStateUnreadable2(directory, reason) {
30983
31284
  }
30984
31285
  function readPersisted2(directory) {
30985
31286
  try {
30986
- const filePath = path60.join(directory, ".swarm", STATE_FILE3);
30987
- if (!fs30.existsSync(filePath)) {
31287
+ const filePath = path61.join(directory, ".swarm", STATE_FILE3);
31288
+ if (!fs31.existsSync(filePath)) {
30988
31289
  const seed = emptyPersisted2();
30989
31290
  try {
30990
31291
  ensureSwarmDir2(directory);
30991
- fs30.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
31292
+ fs31.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
30992
31293
  `, "utf-8");
30993
31294
  } catch {}
30994
31295
  return seed;
30995
31296
  }
30996
- const raw = fs30.readFileSync(filePath, "utf-8");
31297
+ const raw = fs31.readFileSync(filePath, "utf-8");
30997
31298
  const parsed = JSON.parse(raw);
30998
31299
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
30999
31300
  markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -31019,7 +31320,7 @@ function writePersisted2(directory, persisted) {
31019
31320
  let payload;
31020
31321
  try {
31021
31322
  ensureSwarmDir2(directory);
31022
- filePath = path60.join(directory, ".swarm", STATE_FILE3);
31323
+ filePath = path61.join(directory, ".swarm", STATE_FILE3);
31023
31324
  tmpPath = `${filePath}.tmp.${Date.now()}`;
31024
31325
  persisted.updatedAt = nowISO3();
31025
31326
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -31030,14 +31331,14 @@ function writePersisted2(directory, persisted) {
31030
31331
  throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
31031
31332
  }
31032
31333
  try {
31033
- fs30.writeFileSync(tmpPath, payload, "utf-8");
31034
- fs30.renameSync(tmpPath, filePath);
31334
+ fs31.writeFileSync(tmpPath, payload, "utf-8");
31335
+ fs31.renameSync(tmpPath, filePath);
31035
31336
  } catch (error2) {
31036
31337
  const msg = error2 instanceof Error ? error2.message : String(error2);
31037
31338
  error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
31038
31339
  try {
31039
- if (fs30.existsSync(tmpPath)) {
31040
- fs30.unlinkSync(tmpPath);
31340
+ if (fs31.existsSync(tmpPath)) {
31341
+ fs31.unlinkSync(tmpPath);
31041
31342
  }
31042
31343
  } catch {}
31043
31344
  throw new Error(`Lean Turbo state persistence failed: ${msg}`);
@@ -31137,7 +31438,7 @@ var _internals43 = {
31137
31438
  };
31138
31439
  function readSpecStalenessSnapshot(directory) {
31139
31440
  try {
31140
- const p = path61.join(directory, ".swarm", "spec-staleness.json");
31441
+ const p = path62.join(directory, ".swarm", "spec-staleness.json");
31141
31442
  if (!fsSync3.existsSync(p))
31142
31443
  return { stale: false };
31143
31444
  const raw = fsSync3.readFileSync(p, "utf-8");
@@ -31669,13 +31970,13 @@ function buildStatusMessage2(session, directory, sessionID) {
31669
31970
  }
31670
31971
 
31671
31972
  // src/commands/unlink.ts
31672
- import { existsSync as existsSync36 } from "fs";
31673
- import * as path62 from "path";
31973
+ import { existsSync as existsSync37 } from "fs";
31974
+ import * as path63 from "path";
31674
31975
  var DEDUP_THRESHOLD2 = 0.6;
31675
31976
  async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
31676
- const sharedPath = path62.join(linkDir, "knowledge.jsonl");
31677
- const localPath = path62.join(localSwarmDir, "knowledge.jsonl");
31678
- if (!existsSync36(sharedPath))
31977
+ const sharedPath = path63.join(linkDir, "knowledge.jsonl");
31978
+ const localPath = path63.join(localSwarmDir, "knowledge.jsonl");
31979
+ if (!existsSync37(sharedPath))
31679
31980
  return 0;
31680
31981
  const sharedEntries = await readKnowledge(sharedPath);
31681
31982
  if (sharedEntries.length === 0)
@@ -31709,7 +32010,7 @@ async function handleUnlinkCommand(directory, args) {
31709
32010
  let copied = 0;
31710
32011
  if (copyBack) {
31711
32012
  try {
31712
- copied = await copySharedKnowledgeToLocal(linkDir, path62.join(directory, ".swarm"));
32013
+ copied = await copySharedKnowledgeToLocal(linkDir, path63.join(directory, ".swarm"));
31713
32014
  } catch (error2) {
31714
32015
  return `\u274C Failed to copy shared knowledge back to local: ${error2 instanceof Error ? error2.message : String(error2)}`;
31715
32016
  }
@@ -31864,7 +32165,7 @@ function buildDetailedHelp(commandName, entry) {
31864
32165
  async function handleHelpCommand(ctx) {
31865
32166
  const targetCommand = ctx.args.join(" ");
31866
32167
  if (!targetCommand) {
31867
- const { buildHelpText } = await import("./index-chan9mkv.js");
32168
+ const { buildHelpText } = await import("./index-4pt2py5p.js");
31868
32169
  return buildHelpText();
31869
32170
  }
31870
32171
  const tokens = targetCommand.split(/\s+/);
@@ -31873,7 +32174,7 @@ async function handleHelpCommand(ctx) {
31873
32174
  return _internals45.buildDetailedHelp(resolved.key, resolved.entry);
31874
32175
  }
31875
32176
  const similar = _internals45.findSimilarCommands(targetCommand);
31876
- const { buildHelpText: fullHelp } = await import("./index-chan9mkv.js");
32177
+ const { buildHelpText: fullHelp } = await import("./index-4pt2py5p.js");
31877
32178
  if (similar.length > 0) {
31878
32179
  return `Command '/swarm ${targetCommand}' not found.
31879
32180
 
@@ -32006,7 +32307,7 @@ var COMMAND_REGISTRY = {
32006
32307
  },
32007
32308
  "guardrail explain": {
32008
32309
  handler: async (ctx) => {
32009
- const { handleGuardrailExplain } = await import("./guardrail-explain-xktjjh53.js");
32310
+ const { handleGuardrailExplain } = await import("./guardrail-explain-ktm6szbm.js");
32010
32311
  return handleGuardrailExplain(ctx.directory, ctx.args);
32011
32312
  },
32012
32313
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -32016,7 +32317,7 @@ var COMMAND_REGISTRY = {
32016
32317
  },
32017
32318
  "guardrail-log": {
32018
32319
  handler: async (ctx) => {
32019
- const { handleGuardrailLog } = await import("./guardrail-log-53z1cf46.js");
32320
+ const { handleGuardrailLog } = await import("./guardrail-log-ya49kpwn.js");
32020
32321
  return handleGuardrailLog(ctx.directory, ctx.args);
32021
32322
  },
32022
32323
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -32041,8 +32342,15 @@ var COMMAND_REGISTRY = {
32041
32342
  },
32042
32343
  benchmark: {
32043
32344
  handler: (ctx) => handleBenchmarkCommand(ctx.directory, ctx.args),
32044
- description: "Show performance metrics [--cumulative] [--ci-gate]",
32045
- 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",
32046
32354
  category: "diagnostics",
32047
32355
  toolPolicy: "agent"
32048
32356
  },
@@ -32777,24 +33085,24 @@ function validateAliases() {
32777
33085
  }
32778
33086
  aliasTargets.get(target).push(name);
32779
33087
  const visited = new Set;
32780
- const path63 = [];
33088
+ const path64 = [];
32781
33089
  let current = target;
32782
33090
  while (current) {
32783
33091
  const currentEntry = COMMAND_REGISTRY[current];
32784
33092
  if (!currentEntry)
32785
33093
  break;
32786
33094
  if (visited.has(current)) {
32787
- const cycleStart = path63.indexOf(current);
33095
+ const cycleStart = path64.indexOf(current);
32788
33096
  const fullChain = [
32789
33097
  name,
32790
- ...path63.slice(0, cycleStart > 0 ? cycleStart : path63.length),
33098
+ ...path64.slice(0, cycleStart > 0 ? cycleStart : path64.length),
32791
33099
  current
32792
33100
  ].join(" \u2192 ");
32793
33101
  errors.push(`Circular alias detected: ${fullChain}`);
32794
33102
  break;
32795
33103
  }
32796
33104
  visited.add(current);
32797
- path63.push(current);
33105
+ path64.push(current);
32798
33106
  current = currentEntry.aliasOf || "";
32799
33107
  }
32800
33108
  }
@@ -32960,4 +33268,4 @@ ${text}`;
32960
33268
  };
32961
33269
  }
32962
33270
 
32963
- 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 };