opencode-swarm 7.109.2 → 7.109.3

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 (31) hide show
  1. package/.opencode/skills/ci-failure-batching/SKILL.md +39 -0
  2. package/.opencode/skills/gate-attribution/SKILL.md +31 -0
  3. package/.opencode/skills/merge-queue-readiness/SKILL.md +37 -0
  4. package/.opencode/skills/skill-edit-validation/SKILL.md +29 -0
  5. package/.opencode/skills/worktree-retry-cleanup/SKILL.md +24 -0
  6. package/dist/cli/{curator-6p9tpprq.js → curator-9q3m25va.js} +6 -6
  7. package/dist/cli/{curator-llm-factory-wqbm9mwr.js → curator-llm-factory-78dyv010.js} +6 -6
  8. package/dist/cli/{guardrail-explain-ynge4ww3.js → guardrail-explain-csnawe0d.js} +7 -7
  9. package/dist/cli/{hive-promoter-qh2rh8x2.js → hive-promoter-xnx734y3.js} +6 -6
  10. package/dist/cli/{index-3qwaydq1.js → index-3nd7bz90.js} +7 -7
  11. package/dist/cli/{index-fz1jgbvw.js → index-41fgssqr.js} +22 -2
  12. package/dist/cli/{index-wg0665ft.js → index-8f10r7ay.js} +2 -2
  13. package/dist/cli/{index-9qxntjtx.js → index-b15qbvph.js} +190 -41
  14. package/dist/cli/{index-5gnp8fyw.js → index-mtzjbaaa.js} +3 -3
  15. package/dist/cli/{index-8a8b5wjf.js → index-r9dbs4zr.js} +1 -1
  16. package/dist/cli/{index-cqbqynzp.js → index-xyz8epk6.js} +643 -548
  17. package/dist/cli/{index-mmny81g1.js → index-y5z2qdvk.js} +1 -1
  18. package/dist/cli/index.js +6 -6
  19. package/dist/cli/{knowledge-escalator-6v7sjprx.js → knowledge-escalator-9ksrgq7h.js} +3 -3
  20. package/dist/cli/{knowledge-events-6n3x3he2.js → knowledge-events-ymysgtrr.js} +1 -1
  21. package/dist/cli/{knowledge-store-exkw6yb1.js → knowledge-store-562fefjy.js} +1 -1
  22. package/dist/cli/{knowledge-validator-exymfcb9.js → knowledge-validator-b9nvmzjc.js} +4 -2
  23. package/dist/cli/{skill-generator-mx9br4ty.js → skill-generator-mjfqvnn0.js} +15 -5
  24. package/dist/config/bundled-skills.d.ts +1 -1
  25. package/dist/hooks/knowledge-types.d.ts +6 -0
  26. package/dist/hooks/knowledge-validator.d.ts +5 -0
  27. package/dist/hooks/skill-invalidator.d.ts +48 -0
  28. package/dist/index.js +215 -214
  29. package/dist/services/skill-generator.d.ts +47 -2
  30. package/dist/tools/knowledge-remove.d.ts +3 -8
  31. package/package.json +6 -1
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  readRecentEscalations
4
- } from "./index-5gnp8fyw.js";
4
+ } from "./index-mtzjbaaa.js";
5
5
  import {
6
6
  getGlobalEventBus
7
7
  } from "./index-c8s9a3zh.js";
@@ -102,6 +102,8 @@ import {
102
102
  appendSkillChangelog,
103
103
  autoApplyProposals,
104
104
  evaluateSkillChange,
105
+ findSkillsBySourceKnowledgeId,
106
+ findStaleSkillsBySourceKnowledgeId,
105
107
  generateSkills,
106
108
  listSkills,
107
109
  parseDraftFrontmatter,
@@ -109,14 +111,15 @@ import {
109
111
  retireOrMarkStale,
110
112
  retireSkill,
111
113
  selectCandidateEntries
112
- } from "./index-9qxntjtx.js";
114
+ } from "./index-b15qbvph.js";
113
115
  import {
114
116
  effectiveRetrievalOutcomes,
115
117
  readKnowledgeCounterRollups,
116
118
  readKnowledgeEvents,
119
+ recordHiveKnowledgeEvent,
117
120
  recordKnowledgeEvent,
118
121
  resolveKnowledgeEventsPath
119
- } from "./index-mmny81g1.js";
122
+ } from "./index-y5z2qdvk.js";
120
123
  import {
121
124
  appendUnactionable,
122
125
  quarantineEntry,
@@ -126,7 +129,7 @@ import {
126
129
  validateActionability,
127
130
  validateActionableFields,
128
131
  validateLesson
129
- } from "./index-fz1jgbvw.js";
132
+ } from "./index-41fgssqr.js";
130
133
  import {
131
134
  appendKnowledge,
132
135
  appendRejectedLesson,
@@ -148,7 +151,7 @@ import {
148
151
  rewriteKnowledge,
149
152
  transactFile,
150
153
  transactKnowledge
151
- } from "./index-wg0665ft.js";
154
+ } from "./index-8f10r7ay.js";
152
155
  import {
153
156
  isLinked,
154
157
  readLinkPointer,
@@ -211,7 +214,7 @@ import {
211
214
 
212
215
  // src/state.ts
213
216
  import * as fs30 from "fs/promises";
214
- import * as path65 from "path";
217
+ import * as path66 from "path";
215
218
 
216
219
  // src/db/qa-gate-profile.ts
217
220
  import { createHash } from "crypto";
@@ -4958,7 +4961,12 @@ var BUNDLED_PROJECT_SKILLS = [
4958
4961
  "writing-tests",
4959
4962
  "running-tests",
4960
4963
  "engineering-conventions",
4961
- "commit-pr"
4964
+ "commit-pr",
4965
+ "worktree-retry-cleanup",
4966
+ "skill-edit-validation",
4967
+ "merge-queue-readiness",
4968
+ "gate-attribution",
4969
+ "ci-failure-batching"
4962
4970
  ];
4963
4971
  var MAX_SKILL_FILES = 64;
4964
4972
  var MAX_SKILL_BYTES = 512000;
@@ -6484,7 +6492,7 @@ async function handleClarifyCommand(_directory, args) {
6484
6492
  import * as child_process2 from "child_process";
6485
6493
  import * as fsSync from "fs";
6486
6494
  import { promises as fs9 } from "fs";
6487
- import path27 from "path";
6495
+ import path28 from "path";
6488
6496
 
6489
6497
  // src/hooks/curator-postmortem.ts
6490
6498
  import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync4 } from "fs";
@@ -7203,11 +7211,11 @@ var _internals7 = {
7203
7211
  return KnowledgeConfigSchema2.parse({});
7204
7212
  },
7205
7213
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig) => {
7206
- const { applyCuratorKnowledgeUpdates } = await import("./curator-6p9tpprq.js");
7214
+ const { applyCuratorKnowledgeUpdates } = await import("./curator-9q3m25va.js");
7207
7215
  return applyCuratorKnowledgeUpdates(directory, recommendations, knowledgeConfig);
7208
7216
  },
7209
7217
  checkHivePromotions: async (entries, knowledgeConfig) => {
7210
- const { checkHivePromotions } = await import("./hive-promoter-qh2rh8x2.js");
7218
+ const { checkHivePromotions } = await import("./hive-promoter-xnx734y3.js");
7211
7219
  return checkHivePromotions(entries, knowledgeConfig);
7212
7220
  },
7213
7221
  applyProposalTriage: async (directory, triage) => {
@@ -7216,7 +7224,7 @@ var _internals7 = {
7216
7224
  activateProposal,
7217
7225
  listSkills: listSkills2,
7218
7226
  sanitizeSlug
7219
- } = await import("./skill-generator-mx9br4ty.js");
7227
+ } = await import("./skill-generator-mjfqvnn0.js");
7220
7228
  const result = {
7221
7229
  approved: [],
7222
7230
  rejected: [],
@@ -7233,7 +7241,8 @@ var _internals7 = {
7233
7241
  if (item.action === "apply") {
7234
7242
  const activation = await activateProposal(directory, slug, false, {
7235
7243
  evaluate: true,
7236
- operation: "post_mortem_queue_triage"
7244
+ operation: "post_mortem_queue_triage",
7245
+ confirmUnevaluated: true
7237
7246
  });
7238
7247
  if (activation.activated) {
7239
7248
  result.approved.push(slug);
@@ -7264,12 +7273,12 @@ var _internals7 = {
7264
7273
  };
7265
7274
 
7266
7275
  // src/hooks/hive-promoter.ts
7267
- import path16 from "path";
7276
+ import path17 from "path";
7268
7277
 
7269
7278
  // src/hooks/curator.ts
7270
7279
  import { randomUUID as randomUUID5 } from "crypto";
7271
7280
  import * as fs5 from "fs";
7272
- import * as path15 from "path";
7281
+ import * as path16 from "path";
7273
7282
 
7274
7283
  // src/services/learning-metrics.ts
7275
7284
  var SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
@@ -8087,10 +8096,69 @@ var _internals8 = {
8087
8096
  // src/hooks/curator.ts
8088
8097
  init_logger();
8089
8098
 
8099
+ // src/hooks/skill-invalidator.ts
8100
+ import * as path14 from "path";
8101
+ init_logger();
8102
+ async function writeArchiveTombstoneAndInvalidateSkills(ctx) {
8103
+ const label = ctx.sourceLabel ?? "skill-invalidator";
8104
+ if (!ctx.skipTombstone) {
8105
+ const tombstone = {
8106
+ type: "archived",
8107
+ entry_id: ctx.entryId,
8108
+ tier: ctx.tier,
8109
+ actor: ctx.actor,
8110
+ reason: ctx.reason,
8111
+ mode: ctx.mode,
8112
+ evidence: ctx.evidence,
8113
+ previous_status: ctx.previousStatus
8114
+ };
8115
+ if (ctx.tier === "hive") {
8116
+ await recordHiveKnowledgeEvent(tombstone);
8117
+ } else {
8118
+ await recordKnowledgeEvent(ctx.directory, tombstone);
8119
+ }
8120
+ }
8121
+ const allArchivedIds = ctx.precomputedArchivedIds ? new Set(ctx.precomputedArchivedIds) : await getArchivedKnowledgeIds(ctx.directory);
8122
+ allArchivedIds.add(ctx.entryId);
8123
+ queueMicrotask(async () => {
8124
+ try {
8125
+ const affectedSkillDirs = await findSkillsBySourceKnowledgeId(ctx.directory, ctx.entryId);
8126
+ const staleSkillDirs = await findStaleSkillsBySourceKnowledgeId(ctx.directory, allArchivedIds);
8127
+ const allSkillDirs = new Set([...affectedSkillDirs, ...staleSkillDirs]);
8128
+ if (allSkillDirs.size === 0)
8129
+ return;
8130
+ const slugSet = new Set;
8131
+ let retiredCount = 0;
8132
+ let staleCount = 0;
8133
+ for (const skillDir of allSkillDirs) {
8134
+ const slug = path14.basename(skillDir);
8135
+ if (slugSet.has(slug))
8136
+ continue;
8137
+ slugSet.add(slug);
8138
+ const result = await retireOrMarkStale(ctx.directory, skillDir, allArchivedIds);
8139
+ if (result.action === "retire")
8140
+ retiredCount++;
8141
+ else
8142
+ staleCount++;
8143
+ }
8144
+ const batchEvent = {
8145
+ type: "skill-stale-batch",
8146
+ skillIds: Array.from(slugSet),
8147
+ archivedIds: Array.from(allArchivedIds),
8148
+ retiredCount,
8149
+ staleCount
8150
+ };
8151
+ await recordKnowledgeEvent(ctx.directory, batchEvent);
8152
+ } catch (err) {
8153
+ warn(`[${label}] post-archive skill invalidation failed for entry '${ctx.entryId}': ${err instanceof Error ? err.message : String(err)}`);
8154
+ }
8155
+ });
8156
+ }
8157
+
8090
8158
  // src/hooks/skill-usage-log.ts
8091
8159
  import * as crypto2 from "crypto";
8092
8160
  import * as fs4 from "fs";
8093
- import * as path14 from "path";
8161
+ import * as path15 from "path";
8094
8162
  function resolveLogPath(directory) {
8095
8163
  return validateSwarmPath(directory, "skill-usage.jsonl");
8096
8164
  }
@@ -8189,7 +8257,7 @@ function appendFeedbackAppliedMarker(directory, processedEntryIds) {
8189
8257
  if (processedEntryIds.length === 0)
8190
8258
  return;
8191
8259
  const resolved = resolveLogPath(directory);
8192
- const dir = path14.dirname(resolved);
8260
+ const dir = path15.dirname(resolved);
8193
8261
  if (!_internals9.existsSync(dir)) {
8194
8262
  _internals9.mkdirSync(dir, { recursive: true });
8195
8263
  }
@@ -8234,7 +8302,7 @@ function appendSkillUsageEntry(directory, entry) {
8234
8302
  throw new Error("sessionID is required and must be a non-empty string");
8235
8303
  }
8236
8304
  const resolved = validateSwarmPath(directory, "skill-usage.jsonl");
8237
- const dir = path14.dirname(resolved);
8305
+ const dir = path15.dirname(resolved);
8238
8306
  if (!_internals9.existsSync(dir)) {
8239
8307
  _internals9.mkdirSync(dir, { recursive: true });
8240
8308
  }
@@ -8410,8 +8478,8 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8410
8478
  }
8411
8479
  if (entries.length === 0) {
8412
8480
  if (preservedMarkers.length > 0) {
8413
- const dir2 = path14.dirname(resolved);
8414
- const tmpPath2 = path14.join(dir2, `skill-usage-${Date.now()}.tmp`);
8481
+ const dir2 = path15.dirname(resolved);
8482
+ const tmpPath2 = path15.join(dir2, `skill-usage-${Date.now()}.tmp`);
8415
8483
  const content2 = preservedMarkers.join(`
8416
8484
  `).concat(preservedMarkers.length > 0 ? `
8417
8485
  ` : "");
@@ -8453,8 +8521,8 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8453
8521
  if (pruned === 0) {
8454
8522
  return { pruned: 0, remaining: entries.length };
8455
8523
  }
8456
- const dir = path14.dirname(resolved);
8457
- const tmpPath = path14.join(dir, `skill-usage-${Date.now()}.tmp`);
8524
+ const dir = path15.dirname(resolved);
8525
+ const tmpPath = path15.join(dir, `skill-usage-${Date.now()}.tmp`);
8458
8526
  const entryLines = surviving.map((e) => JSON.stringify(e));
8459
8527
  const allLines = [...entryLines, ...preservedMarkers];
8460
8528
  const content = allLines.join(`
@@ -8483,9 +8551,9 @@ async function resolveSourceKnowledgeIds(directory, skillPath) {
8483
8551
  if (/\.\.[/\\]/.test(cleanPath)) {
8484
8552
  return [];
8485
8553
  }
8486
- const absolute = path14.normalize(path14.isAbsolute(cleanPath) ? cleanPath : path14.resolve(directory, cleanPath));
8487
- const baseDir = path14.normalize(path14.resolve(directory));
8488
- const isContained = process.platform === "win32" ? absolute.toLowerCase().startsWith((baseDir + path14.sep).toLowerCase()) : absolute.startsWith(baseDir + path14.sep);
8554
+ const absolute = path15.normalize(path15.isAbsolute(cleanPath) ? cleanPath : path15.resolve(directory, cleanPath));
8555
+ const baseDir = path15.normalize(path15.resolve(directory));
8556
+ const isContained = process.platform === "win32" ? absolute.toLowerCase().startsWith((baseDir + path15.sep).toLowerCase()) : absolute.startsWith(baseDir + path15.sep);
8489
8557
  if (!isContained) {
8490
8558
  return [];
8491
8559
  }
@@ -8679,7 +8747,7 @@ async function autoRetireSkills(directory, _curatorKnowledgePath, excludeSlugs)
8679
8747
  }
8680
8748
  }
8681
8749
  if (archivedSourceMatched) {
8682
- const result = await _internals10.retireOrMarkStale(directory, path15.dirname(active.path), allArchivedIds);
8750
+ const result = await _internals10.retireOrMarkStale(directory, path16.dirname(active.path), allArchivedIds);
8683
8751
  if (result.action === "retire") {
8684
8752
  observations.push(`Skill '${active.slug}' auto-retired: all source knowledge entries archived`);
8685
8753
  warn(`[curator] ${observations[observations.length - 1]}`);
@@ -8876,11 +8944,11 @@ function arrayOfStrings(v) {
8876
8944
  }
8877
8945
  function readLatestPostMortemDigest(directory) {
8878
8946
  try {
8879
- const swarmDir = path15.join(directory, ".swarm");
8947
+ const swarmDir = path16.join(directory, ".swarm");
8880
8948
  if (!fs5.existsSync(swarmDir))
8881
8949
  return null;
8882
8950
  const candidates = fs5.readdirSync(swarmDir).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name)).map((name) => {
8883
- const filePath = path15.join(swarmDir, name);
8951
+ const filePath = path16.join(swarmDir, name);
8884
8952
  return { name, filePath, mtimeMs: fs5.statSync(filePath).mtimeMs };
8885
8953
  }).sort((a, b) => b.mtimeMs - a.mtimeMs);
8886
8954
  const latest = candidates[0];
@@ -8923,7 +8991,7 @@ async function readCuratorSummary(directory) {
8923
8991
  }
8924
8992
  async function writeCuratorSummary(directory, summary) {
8925
8993
  const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
8926
- fs5.mkdirSync(path15.dirname(resolvedPath), { recursive: true });
8994
+ fs5.mkdirSync(path16.dirname(resolvedPath), { recursive: true });
8927
8995
  await bunWrite(resolvedPath, JSON.stringify(summary, null, 2));
8928
8996
  }
8929
8997
  function normalizeAgentName(name) {
@@ -9363,15 +9431,15 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9363
9431
  await _internals10.writeCuratorSummary(directory, updatedSummary);
9364
9432
  if (knowledgeApplicationFindings.length > 0) {
9365
9433
  try {
9366
- const evidenceDir = path15.join(directory, ".swarm", "evidence", String(phase));
9434
+ const evidenceDir = path16.join(directory, ".swarm", "evidence", String(phase));
9367
9435
  fs5.mkdirSync(evidenceDir, { recursive: true });
9368
- const findingsPath = path15.join(evidenceDir, "curator-findings.json");
9436
+ const findingsPath = path16.join(evidenceDir, "curator-findings.json");
9369
9437
  await bunWrite(findingsPath, JSON.stringify({ findings: knowledgeApplicationFindings }, null, 2));
9370
9438
  } catch (err) {
9371
9439
  warn(`[curator] failed to persist application findings: ${err instanceof Error ? err.message : String(err)}`);
9372
9440
  }
9373
9441
  }
9374
- const eventsPath = path15.join(directory, ".swarm", "events.jsonl");
9442
+ const eventsPath = path16.join(directory, ".swarm", "events.jsonl");
9375
9443
  for (const obs of complianceObservations) {
9376
9444
  await appendKnowledge(eventsPath, {
9377
9445
  type: "curator_compliance",
@@ -9384,7 +9452,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9384
9452
  }
9385
9453
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
9386
9454
  try {
9387
- const skillModule = await import("./skill-generator-mx9br4ty.js");
9455
+ const skillModule = await import("./skill-generator-mjfqvnn0.js");
9388
9456
  for (const cand of skillCandidates) {
9389
9457
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
9390
9458
  continue;
@@ -9552,10 +9620,12 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
9552
9620
  const knowledgePath = resolveSwarmKnowledgePath(directory);
9553
9621
  const appliedIds = new Set;
9554
9622
  const foundIds = new Set;
9623
+ const archivedPrevStatus = new Map;
9555
9624
  const contradictedEntries = [];
9556
9625
  await transactKnowledge(knowledgePath, (entries) => {
9557
9626
  appliedIds.clear();
9558
9627
  foundIds.clear();
9628
+ archivedPrevStatus.clear();
9559
9629
  contradictedEntries.length = 0;
9560
9630
  let txApplied = 0;
9561
9631
  let modified = false;
@@ -9581,6 +9651,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
9581
9651
  return entry;
9582
9652
  }
9583
9653
  appliedIds.add(entry.id);
9654
+ archivedPrevStatus.set(entry.id, entry.status);
9584
9655
  txApplied++;
9585
9656
  modified = true;
9586
9657
  return {
@@ -9654,7 +9725,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
9654
9725
  } catch {}
9655
9726
  }
9656
9727
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
9657
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-6v7sjprx.js");
9728
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-9ksrgq7h.js");
9658
9729
  for (const { id } of contradictedEntries) {
9659
9730
  try {
9660
9731
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -9669,6 +9740,25 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
9669
9740
  skipped++;
9670
9741
  }
9671
9742
  }
9743
+ const archivedRecs = validRecommendations.filter((r) => r.action === "archive" && r.entry_id && appliedIds.has(r.entry_id));
9744
+ const precomputedArchivedIds = archivedRecs.length > 0 ? await getArchivedKnowledgeIds(directory) : undefined;
9745
+ for (const rec of archivedRecs) {
9746
+ try {
9747
+ await writeArchiveTombstoneAndInvalidateSkills({
9748
+ directory,
9749
+ entryId: rec.entry_id,
9750
+ tier: "swarm",
9751
+ actor: "curator",
9752
+ reason: rec.reason ?? "curator archive recommendation",
9753
+ mode: "archive",
9754
+ previousStatus: archivedPrevStatus.get(rec.entry_id),
9755
+ sourceLabel: "curator",
9756
+ precomputedArchivedIds
9757
+ });
9758
+ } catch (err) {
9759
+ warn(`[curator] archive invalidation for entry '${rec.entry_id}' failed: ${err instanceof Error ? err.message : String(err)}`);
9760
+ }
9761
+ }
9672
9762
  const currentEntries = await readKnowledge(knowledgePath);
9673
9763
  const currentLessons = currentEntries.map((e) => e.lesson);
9674
9764
  for (const rec of validRecommendations) {
@@ -9718,7 +9808,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
9718
9808
  created_at: now,
9719
9809
  updated_at: now,
9720
9810
  auto_generated: true,
9721
- project_name: path15.basename(directory)
9811
+ project_name: path16.basename(directory)
9722
9812
  };
9723
9813
  if (!validateActionability(newEntry).actionable) {
9724
9814
  try {
@@ -9964,7 +10054,7 @@ async function promoteToHive(directory, lesson, category) {
9964
10054
  schema_version: 1,
9965
10055
  created_at: new Date().toISOString(),
9966
10056
  updated_at: new Date().toISOString(),
9967
- source_project: path16.basename(directory) || "unknown",
10057
+ source_project: path17.basename(directory) || "unknown",
9968
10058
  encounter_score: 1
9969
10059
  };
9970
10060
  await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
@@ -10018,7 +10108,7 @@ async function promoteFromSwarm(directory, lessonId) {
10018
10108
  import { createHash as createHash4 } from "crypto";
10019
10109
  import { existsSync as existsSync13 } from "fs";
10020
10110
  import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile8, writeFile as writeFile8 } from "fs/promises";
10021
- import * as path21 from "path";
10111
+ import * as path22 from "path";
10022
10112
 
10023
10113
  // src/services/synonym-map.ts
10024
10114
  var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
@@ -10030,7 +10120,7 @@ import {
10030
10120
  unlink,
10031
10121
  writeFile as writeFile6
10032
10122
  } from "fs/promises";
10033
- import * as path17 from "path";
10123
+ import * as path18 from "path";
10034
10124
  var SYNONYM_MAP_FILENAME = "synonym-map.json";
10035
10125
  var MAX_TOKEN_LENGTH = 64;
10036
10126
  var DEFAULT_MAX_PAIRS = 500;
@@ -10185,7 +10275,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
10185
10275
  }
10186
10276
  }
10187
10277
  async function writeSynonymMapAtomic(filePath, map) {
10188
- await mkdir5(path17.dirname(filePath), { recursive: true });
10278
+ await mkdir5(path18.dirname(filePath), { recursive: true });
10189
10279
  const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
10190
10280
  try {
10191
10281
  await writeFile6(tmp, JSON.stringify(map, null, 2), "utf-8");
@@ -10198,7 +10288,7 @@ async function writeSynonymMapAtomic(filePath, map) {
10198
10288
  }
10199
10289
  async function rebuildSynonymMap(directory, entries, maxPairs = DEFAULT_MAX_PAIRS) {
10200
10290
  const filePath = resolveSynonymMapPath(directory);
10201
- const dir = path17.dirname(filePath);
10291
+ const dir = path18.dirname(filePath);
10202
10292
  await mkdir5(dir, { recursive: true });
10203
10293
  let release = null;
10204
10294
  try {
@@ -10258,17 +10348,17 @@ function reinforceSwarmKnowledgeEntry(entry, confirmation) {
10258
10348
  // src/hooks/micro-reflector.ts
10259
10349
  import { existsSync as existsSync12 } from "fs";
10260
10350
  import { readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
10261
- import * as path20 from "path";
10351
+ import * as path21 from "path";
10262
10352
  init_logger();
10263
10353
 
10264
10354
  // src/hooks/skill-propagation-gate.ts
10265
10355
  import * as fs7 from "fs";
10266
- import * as path19 from "path";
10356
+ import * as path20 from "path";
10267
10357
  init_logger();
10268
10358
 
10269
10359
  // src/hooks/skill-scoring.ts
10270
10360
  import * as fs6 from "fs";
10271
- import * as path18 from "path";
10361
+ import * as path19 from "path";
10272
10362
  var FREQUENCY_CAP = 10;
10273
10363
  var FREQUENCY_WEIGHT = 0.3;
10274
10364
  var COMPLIANCE_WEIGHT = 0.3;
@@ -10296,10 +10386,10 @@ var _internals11 = {
10296
10386
  computeTriggerMatchBoost: null
10297
10387
  };
10298
10388
  function extractSkillName(skillPath) {
10299
- const base = path18.basename(skillPath, path18.extname(skillPath));
10389
+ const base = path19.basename(skillPath, path19.extname(skillPath));
10300
10390
  if (base !== "SKILL")
10301
10391
  return base;
10302
- const parent = path18.basename(path18.dirname(skillPath));
10392
+ const parent = path19.basename(path19.dirname(skillPath));
10303
10393
  return parent;
10304
10394
  }
10305
10395
  function stripQuotes(value) {
@@ -10457,12 +10547,12 @@ function readSkillMetadata(skillPath, directory) {
10457
10547
  const normalizedPath = skillPath.replace(/^file:/, "").replace(/\\/g, "/");
10458
10548
  const fallback = parseSkillFrontmatter("", normalizedPath);
10459
10549
  try {
10460
- if (path18.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
10550
+ if (path19.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
10461
10551
  return fallback;
10462
10552
  }
10463
- const root = path18.resolve(directory);
10464
- const absolutePath = path18.resolve(directory, normalizedPath);
10465
- if (absolutePath !== root && !absolutePath.startsWith(root + path18.sep)) {
10553
+ const root = path19.resolve(directory);
10554
+ const absolutePath = path19.resolve(directory, normalizedPath);
10555
+ if (absolutePath !== root && !absolutePath.startsWith(root + path19.sep)) {
10466
10556
  return fallback;
10467
10557
  }
10468
10558
  const content = readFilePrefix(absolutePath);
@@ -10600,7 +10690,7 @@ function getSkillStats(skillPath, directory) {
10600
10690
  };
10601
10691
  }
10602
10692
  function formatSkillIndexWithContext(skills, directory) {
10603
- const usageLogPath = path18.join(directory, ".swarm", "skill-usage.jsonl");
10693
+ const usageLogPath = path19.join(directory, ".swarm", "skill-usage.jsonl");
10604
10694
  let hasHistory = false;
10605
10695
  try {
10606
10696
  const stat4 = fs6.statSync(usageLogPath);
@@ -10734,7 +10824,7 @@ function parseYamlValue(value) {
10734
10824
  return trimmed;
10735
10825
  }
10736
10826
  function loadRoutingSkills(directory, targetAgent) {
10737
- const routingPath = path19.join(directory, ".opencode", "skill-routing.yaml");
10827
+ const routingPath = path20.join(directory, ".opencode", "skill-routing.yaml");
10738
10828
  if (!_internals12.existsSync(routingPath))
10739
10829
  return [];
10740
10830
  try {
@@ -10794,7 +10884,7 @@ var _internals12 = {
10794
10884
  function discoverAvailableSkills(directory) {
10795
10885
  const results = [];
10796
10886
  for (const root of SKILL_SEARCH_ROOTS) {
10797
- const rootPath = path19.join(directory, root);
10887
+ const rootPath = path20.join(directory, root);
10798
10888
  if (!_internals12.existsSync(rootPath))
10799
10889
  continue;
10800
10890
  let entries;
@@ -10806,13 +10896,13 @@ function discoverAvailableSkills(directory) {
10806
10896
  for (const entry of entries) {
10807
10897
  if (entry.startsWith("."))
10808
10898
  continue;
10809
- const skillDir = path19.join(rootPath, entry);
10810
- if (_internals12.existsSync(path19.join(skillDir, "retired.marker")) || _internals12.existsSync(path19.join(skillDir, "stale.marker")))
10899
+ const skillDir = path20.join(rootPath, entry);
10900
+ if (_internals12.existsSync(path20.join(skillDir, "retired.marker")) || _internals12.existsSync(path20.join(skillDir, "stale.marker")))
10811
10901
  continue;
10812
- const skillFile = path19.join(skillDir, "SKILL.md");
10902
+ const skillFile = path20.join(skillDir, "SKILL.md");
10813
10903
  try {
10814
10904
  if (_internals12.statSync(skillDir).isDirectory() && _internals12.existsSync(skillFile)) {
10815
- results.push(path19.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
10905
+ results.push(path20.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
10816
10906
  }
10817
10907
  } catch (err) {
10818
10908
  warn(`[skill-propagation-gate] failed to stat skill directory ${entry}: ${err instanceof Error ? err.message : String(err)}`);
@@ -10881,9 +10971,9 @@ function extractSkillsFieldFromPrompt(prompt) {
10881
10971
  return "";
10882
10972
  }
10883
10973
  function writeWarnEvent(directory, record) {
10884
- const filePath = path19.join(directory, ".swarm", "events.jsonl");
10974
+ const filePath = path20.join(directory, ".swarm", "events.jsonl");
10885
10975
  try {
10886
- const dir = path19.dirname(filePath);
10976
+ const dir = path20.dirname(filePath);
10887
10977
  if (!_internals12.existsSync(dir)) {
10888
10978
  _internals12.mkdirSync(dir, { recursive: true });
10889
10979
  }
@@ -11012,8 +11102,8 @@ async function skillPropagationGateBefore(directory, input, config) {
11012
11102
  if (routingPaths.length > 0) {
11013
11103
  const existingPaths = new Set(scored.map((s) => s.skillPath));
11014
11104
  for (const routingPath of routingPaths) {
11015
- const routedSkillDir = path19.dirname(path19.join(directory, routingPath));
11016
- if (_internals12.existsSync(path19.join(routedSkillDir, "retired.marker")) || _internals12.existsSync(path19.join(routedSkillDir, "stale.marker")))
11105
+ const routedSkillDir = path20.dirname(path20.join(directory, routingPath));
11106
+ if (_internals12.existsSync(path20.join(routedSkillDir, "retired.marker")) || _internals12.existsSync(path20.join(routedSkillDir, "stale.marker")))
11017
11107
  continue;
11018
11108
  if (!existingPaths.has(routingPath)) {
11019
11109
  scored.push({
@@ -11032,8 +11122,8 @@ async function skillPropagationGateBefore(directory, input, config) {
11032
11122
  let skillsForIndex = availableSkills;
11033
11123
  if (scoringSkipped) {
11034
11124
  skillsForIndex = [...availableSkills].sort((a, b) => {
11035
- const nameA = path19.basename(path19.dirname(a));
11036
- const nameB = path19.basename(path19.dirname(b));
11125
+ const nameA = path20.basename(path20.dirname(a));
11126
+ const nameB = path20.basename(path20.dirname(b));
11037
11127
  return nameA.localeCompare(nameB);
11038
11128
  });
11039
11129
  } else if (typeof scored !== "undefined" && scored.length > 0) {
@@ -11041,7 +11131,7 @@ async function skillPropagationGateBefore(directory, input, config) {
11041
11131
  }
11042
11132
  const formattedIndex = _internals12.formatSkillIndexWithContext(skillsForIndex, directory);
11043
11133
  if (formattedIndex.length > 0) {
11044
- const contextPath = path19.join(directory, ".swarm", "context.md");
11134
+ const contextPath = path20.join(directory, ".swarm", "context.md");
11045
11135
  let existingContent = "";
11046
11136
  if (_internals12.existsSync(contextPath)) {
11047
11137
  existingContent = _internals12.readFileSync(contextPath, "utf-8");
@@ -11063,7 +11153,7 @@ ${newSection}`;
11063
11153
  updatedContent = existingContent + newSection;
11064
11154
  }
11065
11155
  }
11066
- const swarmDir = path19.dirname(contextPath);
11156
+ const swarmDir = path20.dirname(contextPath);
11067
11157
  if (!_internals12.existsSync(swarmDir)) {
11068
11158
  _internals12.mkdirSync(swarmDir, { recursive: true });
11069
11159
  }
@@ -11289,7 +11379,7 @@ function resolveInsightCandidatesPath(directory) {
11289
11379
  }
11290
11380
  async function readTaskTrajectory(directory, taskId) {
11291
11381
  try {
11292
- const rel = path20.join("evidence", sanitizeTaskId(taskId), "trajectory.jsonl");
11382
+ const rel = path21.join("evidence", sanitizeTaskId(taskId), "trajectory.jsonl");
11293
11383
  const filePath = validateSwarmPath(directory, rel);
11294
11384
  if (!existsSync12(filePath))
11295
11385
  return [];
@@ -11719,8 +11809,8 @@ RETRY: your last output was missing ${result.missing.join("; ")}; produce valid
11719
11809
  }
11720
11810
  async function appendCuratorSkippedEvent(directory, record) {
11721
11811
  try {
11722
- const filePath = path21.join(directory, ".swarm", "events.jsonl");
11723
- await mkdir6(path21.dirname(filePath), { recursive: true });
11812
+ const filePath = path22.join(directory, ".swarm", "events.jsonl");
11813
+ await mkdir6(path22.dirname(filePath), { recursive: true });
11724
11814
  await appendFile2(filePath, `${JSON.stringify({
11725
11815
  timestamp: new Date().toISOString(),
11726
11816
  event: "curator_skipped",
@@ -12287,7 +12377,7 @@ var _internals14 = {
12287
12377
 
12288
12378
  // src/services/session-reflection.ts
12289
12379
  import { promises as fs8 } from "fs";
12290
- import * as path22 from "path";
12380
+ import * as path23 from "path";
12291
12381
 
12292
12382
  // src/hooks/abort-utils.ts
12293
12383
  function isAbortError(err) {
@@ -12448,11 +12538,11 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
12448
12538
  const lessons = [];
12449
12539
  const taxonomy = {};
12450
12540
  try {
12451
- const evidenceDir = path22.join(directory, ".swarm", "evidence");
12541
+ const evidenceDir = path23.join(directory, ".swarm", "evidence");
12452
12542
  const entries = await fs8.readdir(evidenceDir);
12453
12543
  const retroDirs = entries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
12454
12544
  for (const retroDir of retroDirs) {
12455
- const evidencePath = path22.join(evidenceDir, retroDir, "evidence.json");
12545
+ const evidencePath = path23.join(evidenceDir, retroDir, "evidence.json");
12456
12546
  try {
12457
12547
  const content = await fs8.readFile(evidencePath, "utf-8");
12458
12548
  const parsed = JSON.parse(content);
@@ -12481,12 +12571,12 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
12481
12571
  async function gatherGateFailures(directory) {
12482
12572
  const failures = new Map;
12483
12573
  try {
12484
- const evidenceDir = path22.join(directory, ".swarm", "evidence");
12574
+ const evidenceDir = path23.join(directory, ".swarm", "evidence");
12485
12575
  const entries = await fs8.readdir(evidenceDir);
12486
12576
  for (const entry of entries) {
12487
12577
  if (entry.startsWith("retro-"))
12488
12578
  continue;
12489
- const evidencePath = path22.join(evidenceDir, entry, "evidence.json");
12579
+ const evidencePath = path23.join(evidenceDir, entry, "evidence.json");
12490
12580
  try {
12491
12581
  const content = await fs8.readFile(evidencePath, "utf-8");
12492
12582
  const parsed = JSON.parse(content);
@@ -12687,12 +12777,12 @@ async function writeSessionReflection(directory, result) {
12687
12777
  // src/services/skill-improver.ts
12688
12778
  import { existsSync as existsSync15 } from "fs";
12689
12779
  import { mkdir as mkdir8, readFile as readFile9, rename as rename6, writeFile as writeFile10 } from "fs/promises";
12690
- import * as path24 from "path";
12780
+ import * as path25 from "path";
12691
12781
  init_logger();
12692
12782
 
12693
12783
  // src/services/trajectory-cluster.ts
12694
12784
  import { mkdir as mkdir7, writeFile as writeFile9 } from "fs/promises";
12695
- import * as path23 from "path";
12785
+ import * as path24 from "path";
12696
12786
  init_logger();
12697
12787
  var MACRO_TRAJECTORY_WINDOW = 200;
12698
12788
  var MOTIF_MIN_TASKS = 2;
@@ -12824,11 +12914,11 @@ async function writeMotifProposals(directory, opts = {}) {
12824
12914
  if (motifs.length === 0)
12825
12915
  return result;
12826
12916
  const max = opts.maxProposals ?? 10;
12827
- const proposalsDir = validateSwarmPath(directory, path23.join("skills", "proposals"));
12917
+ const proposalsDir = validateSwarmPath(directory, path24.join("skills", "proposals"));
12828
12918
  await mkdir7(proposalsDir, { recursive: true });
12829
12919
  for (const motif of motifs.slice(0, max)) {
12830
12920
  const slug = `motif-${slugify(motif.signature)}`;
12831
- const filePath = path23.join(proposalsDir, `${slug}.md`);
12921
+ const filePath = path24.join(proposalsDir, `${slug}.md`);
12832
12922
  await writeFile9(filePath, buildMotifProposal(motif), "utf-8");
12833
12923
  result.proposalsWritten.push(filePath);
12834
12924
  }
@@ -12969,11 +13059,11 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
12969
13059
  if (motifs.length === 0)
12970
13060
  return result;
12971
13061
  const max = opts.maxProposals ?? 10;
12972
- const proposalsDir = validateSwarmPath(directory, path23.join("skills", "proposals"));
13062
+ const proposalsDir = validateSwarmPath(directory, path24.join("skills", "proposals"));
12973
13063
  await mkdir7(proposalsDir, { recursive: true });
12974
13064
  for (const motif of motifs.slice(0, max)) {
12975
13065
  const slug = workflowSlug(motif.signature);
12976
- const filePath = path23.join(proposalsDir, `${slug}.md`);
13066
+ const filePath = path24.join(proposalsDir, `${slug}.md`);
12977
13067
  await writeFile9(filePath, buildWorkflowProposal(motif), "utf-8");
12978
13068
  result.proposalsWritten.push(filePath);
12979
13069
  }
@@ -13096,7 +13186,7 @@ function timestampSlug(d) {
13096
13186
  return d.toISOString().replace(/[:.]/g, "-");
13097
13187
  }
13098
13188
  async function atomicWrite(p, content) {
13099
- await mkdir8(path24.dirname(p), { recursive: true });
13189
+ await mkdir8(path25.dirname(p), { recursive: true });
13100
13190
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
13101
13191
  await writeFile10(tmp, content, "utf-8");
13102
13192
  await rename6(tmp, p);
@@ -13499,8 +13589,8 @@ async function runSkillImprover(req) {
13499
13589
  }
13500
13590
  throw err;
13501
13591
  }
13502
- const proposalDir = path24.join(req.directory, ".swarm", "skill-improver", "proposals");
13503
- const proposalFile = path24.join(proposalDir, `${timestampSlug(now)}.md`);
13592
+ const proposalDir = path25.join(req.directory, ".swarm", "skill-improver", "proposals");
13593
+ const proposalFile = path25.join(proposalDir, `${timestampSlug(now)}.md`);
13504
13594
  const finalBody = source === "llm" ? buildLLMProposalFrame({
13505
13595
  body,
13506
13596
  targets,
@@ -13570,13 +13660,13 @@ var _internals15 = {
13570
13660
 
13571
13661
  // src/session/session-start-store.ts
13572
13662
  import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
13573
- import * as path25 from "path";
13663
+ import * as path26 from "path";
13574
13664
  var SESSION_START_FILE = "session-start.jsonl";
13575
13665
  function recordSessionStart(directory, startMs) {
13576
13666
  try {
13577
- const swarmDir = path25.join(directory, ".swarm");
13578
- const sessionDir = path25.join(swarmDir, "session");
13579
- const filePath = path25.join(sessionDir, SESSION_START_FILE);
13667
+ const swarmDir = path26.join(directory, ".swarm");
13668
+ const sessionDir = path26.join(swarmDir, "session");
13669
+ const filePath = path26.join(sessionDir, SESSION_START_FILE);
13580
13670
  const line = JSON.stringify({ startMs, ts: Date.now() });
13581
13671
  mkdirSync9(sessionDir, { recursive: true });
13582
13672
  writeFileSync4(filePath, `${line}
@@ -13585,7 +13675,7 @@ function recordSessionStart(directory, startMs) {
13585
13675
  }
13586
13676
  function readEarliestSessionStart(directory) {
13587
13677
  try {
13588
- const filePath = path25.join(directory, ".swarm", "session", SESSION_START_FILE);
13678
+ const filePath = path26.join(directory, ".swarm", "session", SESSION_START_FILE);
13589
13679
  if (!existsSync16(filePath))
13590
13680
  return null;
13591
13681
  const content = readFileSync8(filePath, "utf-8");
@@ -13612,7 +13702,7 @@ function readEarliestSessionStart(directory) {
13612
13702
 
13613
13703
  // src/tools/write-retro.ts
13614
13704
  import { existsSync as existsSync17 } from "fs";
13615
- import path26 from "path";
13705
+ import path27 from "path";
13616
13706
  async function executeWriteRetro(args, directory) {
13617
13707
  if (/^(CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9])(:|$)/i.test(directory)) {
13618
13708
  return JSON.stringify({
@@ -13620,7 +13710,7 @@ async function executeWriteRetro(args, directory) {
13620
13710
  message: "Invalid directory: reserved device name"
13621
13711
  }, null, 2);
13622
13712
  }
13623
- if (!existsSync17(path26.join(directory, ".swarm"))) {
13713
+ if (!existsSync17(path27.join(directory, ".swarm"))) {
13624
13714
  return JSON.stringify({
13625
13715
  success: false,
13626
13716
  message: `Cannot write evidence in "${directory}" \u2014 no .swarm/ folder was found. Run write_retro from an initialized project root.`
@@ -14036,8 +14126,8 @@ async function copyDirRecursiveWithFailures(src, dest) {
14036
14126
  const entries = await fs9.readdir(src);
14037
14127
  await fs9.mkdir(dest, { recursive: true });
14038
14128
  for (const entry of entries) {
14039
- const srcEntry = path27.join(src, entry);
14040
- const destEntry = path27.join(dest, entry);
14129
+ const srcEntry = path28.join(src, entry);
14130
+ const destEntry = path28.join(dest, entry);
14041
14131
  try {
14042
14132
  const stat4 = await fs9.stat(srcEntry);
14043
14133
  if (stat4.isDirectory()) {
@@ -14222,18 +14312,18 @@ async function runFinalizeStage(ctx) {
14222
14312
  ctx.warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
14223
14313
  }
14224
14314
  }
14225
- const lessonsFilePath = path27.join(ctx.swarmDir, "close-lessons.md");
14315
+ const lessonsFilePath = path28.join(ctx.swarmDir, "close-lessons.md");
14226
14316
  try {
14227
14317
  const lessonsText = await fs9.readFile(lessonsFilePath, "utf-8");
14228
14318
  ctx.explicitLessons = lessonsText.split(`
14229
14319
  `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
14230
14320
  } catch {}
14231
14321
  try {
14232
- const evidenceDir = path27.join(ctx.swarmDir, "evidence");
14322
+ const evidenceDir = path28.join(ctx.swarmDir, "evidence");
14233
14323
  const evidenceEntries = await fs9.readdir(evidenceDir);
14234
14324
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
14235
14325
  for (const retroDir of retroDirs) {
14236
- const evidencePath = path27.join(evidenceDir, retroDir, "evidence.json");
14326
+ const evidencePath = path28.join(evidenceDir, retroDir, "evidence.json");
14237
14327
  try {
14238
14328
  const content = await fs9.readFile(evidencePath, "utf-8");
14239
14329
  const parsed = JSON.parse(content);
@@ -14417,7 +14507,7 @@ async function copySqliteSafe(srcPath, destPath, laneEnv) {
14417
14507
  let checkpointVerified = false;
14418
14508
  try {
14419
14509
  const result = _internals17.spawnSync("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
14420
- cwd: path27.dirname(srcPath),
14510
+ cwd: path28.dirname(srcPath),
14421
14511
  encoding: "utf-8",
14422
14512
  stdio: ["ignore", "pipe", "pipe"],
14423
14513
  timeout: 1e4,
@@ -14486,7 +14576,7 @@ async function copySqliteSafe(srcPath, destPath, laneEnv) {
14486
14576
  async function runArchiveStage(ctx) {
14487
14577
  ctx.timestamp = new Date().toISOString().replace(/[:.]/g, "-");
14488
14578
  ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
14489
- ctx.archiveDir = path27.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
14579
+ ctx.archiveDir = path28.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
14490
14580
  try {
14491
14581
  await fs9.mkdir(ctx.archiveDir, { recursive: true });
14492
14582
  const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
@@ -14501,8 +14591,8 @@ async function runArchiveStage(ctx) {
14501
14591
  if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
14502
14592
  continue;
14503
14593
  }
14504
- const srcPath = path27.join(ctx.swarmDir, artifact);
14505
- const destPath = path27.join(ctx.archiveDir, artifact);
14594
+ const srcPath = path28.join(ctx.swarmDir, artifact);
14595
+ const destPath = path28.join(ctx.archiveDir, artifact);
14506
14596
  if (artifact === "swarm.db") {
14507
14597
  const result = await copySqliteSafe(srcPath, destPath, undefined);
14508
14598
  if (result.skipped) {} else if (result.success) {
@@ -14535,8 +14625,8 @@ async function runArchiveStage(ctx) {
14535
14625
  }
14536
14626
  const dynamicArchiveArtifacts = (await fs9.readdir(ctx.swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
14537
14627
  for (const artifact of dynamicArchiveArtifacts) {
14538
- const srcPath = path27.join(ctx.swarmDir, artifact);
14539
- const destPath = path27.join(ctx.archiveDir, artifact);
14628
+ const srcPath = path28.join(ctx.swarmDir, artifact);
14629
+ const destPath = path28.join(ctx.archiveDir, artifact);
14540
14630
  try {
14541
14631
  await fs9.copyFile(srcPath, destPath);
14542
14632
  ctx.archivedFileCount++;
@@ -14551,8 +14641,8 @@ async function runArchiveStage(ctx) {
14551
14641
  }
14552
14642
  }
14553
14643
  for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
14554
- const srcDir = path27.join(ctx.swarmDir, dirName);
14555
- const destDir = path27.join(ctx.archiveDir, dirName);
14644
+ const srcDir = path28.join(ctx.swarmDir, dirName);
14645
+ const destDir = path28.join(ctx.archiveDir, dirName);
14556
14646
  try {
14557
14647
  const result = await copyDirRecursiveWithFailures(srcDir, destDir);
14558
14648
  ctx.archivedFileCount += result.copied;
@@ -14629,7 +14719,7 @@ async function runCleanStage(ctx) {
14629
14719
  ctx.warnings.push(reason ? `Preserved ${artifact} because it was not successfully archived: ${reason}.` : `Preserved ${artifact} because it was not successfully archived.`);
14630
14720
  continue;
14631
14721
  }
14632
- const filePath = path27.join(ctx.swarmDir, artifact);
14722
+ const filePath = path28.join(ctx.swarmDir, artifact);
14633
14723
  try {
14634
14724
  await fs9.unlink(filePath);
14635
14725
  cleanedFiles.push(artifact);
@@ -14649,7 +14739,7 @@ async function runCleanStage(ctx) {
14649
14739
  continue;
14650
14740
  }
14651
14741
  try {
14652
- await fs9.unlink(path27.join(ctx.swarmDir, artifact));
14742
+ await fs9.unlink(path28.join(ctx.swarmDir, artifact));
14653
14743
  cleanedFiles.push(artifact);
14654
14744
  } catch (err) {
14655
14745
  const errno = err?.code;
@@ -14663,7 +14753,7 @@ async function runCleanStage(ctx) {
14663
14753
  if (!ctx.archivedActiveStateDirs.has(dirName)) {
14664
14754
  continue;
14665
14755
  }
14666
- const dirPath = path27.join(ctx.swarmDir, dirName);
14756
+ const dirPath = path28.join(ctx.swarmDir, dirName);
14667
14757
  try {
14668
14758
  await fs9.rm(dirPath, { recursive: true, force: true });
14669
14759
  cleanedFiles.push(`${dirName}/`);
@@ -14674,7 +14764,7 @@ async function runCleanStage(ctx) {
14674
14764
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
14675
14765
  for (const backup of configBackups) {
14676
14766
  try {
14677
- await fs9.unlink(path27.join(ctx.swarmDir, backup));
14767
+ await fs9.unlink(path28.join(ctx.swarmDir, backup));
14678
14768
  configBackupsRemoved++;
14679
14769
  } catch (err) {
14680
14770
  const errno = err?.code;
@@ -14687,7 +14777,7 @@ async function runCleanStage(ctx) {
14687
14777
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
14688
14778
  for (const sibling of ledgerSiblings) {
14689
14779
  try {
14690
- await fs9.unlink(path27.join(ctx.swarmDir, sibling));
14780
+ await fs9.unlink(path28.join(ctx.swarmDir, sibling));
14691
14781
  } catch (err) {
14692
14782
  const errno = err?.code;
14693
14783
  if (errno === "ENOENT") {} else {
@@ -14705,12 +14795,12 @@ async function runCleanStage(ctx) {
14705
14795
  }
14706
14796
  let swarmPlanFilesRemoved = 0;
14707
14797
  const candidates = [
14708
- path27.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
14709
- path27.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
14710
- path27.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
14711
- path27.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
14712
- path27.join(ctx.directory, "SWARM_PLAN.json"),
14713
- path27.join(ctx.directory, "SWARM_PLAN.md")
14798
+ path28.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
14799
+ path28.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
14800
+ path28.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
14801
+ path28.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
14802
+ path28.join(ctx.directory, "SWARM_PLAN.json"),
14803
+ path28.join(ctx.directory, "SWARM_PLAN.md")
14714
14804
  ];
14715
14805
  for (const candidate of candidates) {
14716
14806
  try {
@@ -14728,7 +14818,7 @@ async function runCleanStage(ctx) {
14728
14818
  const tmpFiles = swarmFiles.filter((f) => f.startsWith(".tmp."));
14729
14819
  for (const tmp of tmpFiles) {
14730
14820
  try {
14731
- await fs9.unlink(path27.join(ctx.swarmDir, tmp));
14821
+ await fs9.unlink(path28.join(ctx.swarmDir, tmp));
14732
14822
  tmpFilesRemoved++;
14733
14823
  } catch (err) {
14734
14824
  const errno = err?.code;
@@ -14750,7 +14840,7 @@ async function runCleanStage(ctx) {
14750
14840
  }
14751
14841
  for (const terminalFile of TERMINAL_STATE_FILES) {
14752
14842
  try {
14753
- await fs9.unlink(path27.join(ctx.swarmDir, terminalFile));
14843
+ await fs9.unlink(path28.join(ctx.swarmDir, terminalFile));
14754
14844
  if (!cleanedFiles.includes(terminalFile)) {
14755
14845
  cleanedFiles.push(terminalFile);
14756
14846
  }
@@ -14763,7 +14853,7 @@ async function runCleanStage(ctx) {
14763
14853
  }
14764
14854
  }
14765
14855
  clearAllScopes(ctx.directory);
14766
- const contextPath = path27.join(ctx.swarmDir, "context.md");
14856
+ const contextPath = path28.join(ctx.swarmDir, "context.md");
14767
14857
  const contextContent = [
14768
14858
  "# Context",
14769
14859
  "",
@@ -14775,7 +14865,7 @@ async function runCleanStage(ctx) {
14775
14865
  ""
14776
14866
  ].join(`
14777
14867
  `);
14778
- const contextTempPath = path27.join(path27.dirname(contextPath), `${path27.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
14868
+ const contextTempPath = path28.join(path28.dirname(contextPath), `${path28.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
14779
14869
  try {
14780
14870
  await fs9.writeFile(contextTempPath, contextContent, "utf-8");
14781
14871
  fsSync.renameSync(contextTempPath, contextPath);
@@ -14839,7 +14929,7 @@ async function runAlignStage(ctx) {
14839
14929
  return { gitAlignResult, prunedBranches };
14840
14930
  }
14841
14931
  async function handleCloseCommand(directory, args, options = {}) {
14842
- const swarmDir = path27.join(directory, ".swarm");
14932
+ const swarmDir = path28.join(directory, ".swarm");
14843
14933
  try {
14844
14934
  const stat4 = fsSync.lstatSync(swarmDir);
14845
14935
  if (stat4.isSymbolicLink()) {
@@ -14853,7 +14943,7 @@ async function handleCloseCommand(directory, args, options = {}) {
14853
14943
  const planPath = validateSwarmPath(directory, "plan.json");
14854
14944
  let planExists = false;
14855
14945
  let planData = {
14856
- title: path27.basename(directory) || "Ad-hoc session",
14946
+ title: path28.basename(directory) || "Ad-hoc session",
14857
14947
  phases: []
14858
14948
  };
14859
14949
  try {
@@ -14878,7 +14968,7 @@ async function handleCloseCommand(directory, args, options = {}) {
14878
14968
  }
14879
14969
  try {
14880
14970
  if (!planExists) {
14881
- const archiveDir = path27.join(swarmDir, "archive");
14971
+ const archiveDir = path28.join(swarmDir, "archive");
14882
14972
  try {
14883
14973
  const archiveEntries = await fs9.readdir(archiveDir);
14884
14974
  const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
@@ -14886,7 +14976,7 @@ async function handleCloseCommand(directory, args, options = {}) {
14886
14976
  const hasActiveState = [
14887
14977
  ...ACTIVE_STATE_TO_CLEAN,
14888
14978
  ...ACTIVE_STATE_DIRS_TO_CLEAN
14889
- ].some((entry) => fsSync.existsSync(path27.join(swarmDir, entry)));
14979
+ ].some((entry) => fsSync.existsSync(path28.join(swarmDir, entry)));
14890
14980
  if (!hasActiveState) {
14891
14981
  return `\u2705 Already finalized \u2014 nothing to do.
14892
14982
 
@@ -15014,7 +15104,7 @@ This project was already finalized in a previous /swarm close run. The plan has
15014
15104
  ...ctx.warnings.length > 0 ? ["## Warnings", ...ctx.warnings.map((w) => `- ${w}`), ""] : []
15015
15105
  ].join(`
15016
15106
  `);
15017
- const closeSummaryTempPath = path27.join(path27.dirname(closeSummaryPath), `${path27.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15107
+ const closeSummaryTempPath = path28.join(path28.dirname(closeSummaryPath), `${path28.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15018
15108
  try {
15019
15109
  await fs9.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
15020
15110
  fsSync.renameSync(closeSummaryTempPath, closeSummaryPath);
@@ -15365,14 +15455,14 @@ function buildStatusMessage(session, plan) {
15365
15455
 
15366
15456
  // src/commands/config.ts
15367
15457
  import * as os5 from "os";
15368
- import * as path28 from "path";
15458
+ import * as path29 from "path";
15369
15459
  function getUserConfigDir2() {
15370
- return process.env.XDG_CONFIG_HOME || path28.join(os5.homedir(), ".config");
15460
+ return process.env.XDG_CONFIG_HOME || path29.join(os5.homedir(), ".config");
15371
15461
  }
15372
15462
  async function handleConfigCommand(directory, _args) {
15373
15463
  const config = loadPluginConfig(directory);
15374
- const userConfigPath = path28.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
15375
- const projectConfigPath = path28.join(directory, ".opencode", "opencode-swarm.json");
15464
+ const userConfigPath = path29.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
15465
+ const projectConfigPath = path29.join(directory, ".opencode", "opencode-swarm.json");
15376
15466
  const lines = [
15377
15467
  "## Swarm Configuration",
15378
15468
  "",
@@ -15392,7 +15482,7 @@ async function handleConfigCommand(directory, _args) {
15392
15482
  // src/services/skill-consolidation.ts
15393
15483
  import { existsSync as existsSync19 } from "fs";
15394
15484
  import { mkdir as mkdir9, readFile as readFile10, rename as rename7, writeFile as writeFile11 } from "fs/promises";
15395
- import * as path29 from "path";
15485
+ import * as path30 from "path";
15396
15486
 
15397
15487
  // src/utils/timeout.ts
15398
15488
  async function withTimeout(promise, ms, timeoutError) {
@@ -15417,7 +15507,7 @@ var DEFAULT_CONSOLIDATION_MAX_CALLS_PER_RUN = 1;
15417
15507
  var CONSOLIDATION_RUN_TIMEOUT_MS = 5 * 60 * 1000;
15418
15508
  var runningByDirectory = new Map;
15419
15509
  function consolidationStatePath(directory) {
15420
- return path29.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
15510
+ return path30.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
15421
15511
  }
15422
15512
  async function readState2(directory) {
15423
15513
  const filePath = consolidationStatePath(directory);
@@ -15433,7 +15523,7 @@ async function readState2(directory) {
15433
15523
  }
15434
15524
  }
15435
15525
  async function atomicWrite2(filePath, content) {
15436
- await mkdir9(path29.dirname(filePath), { recursive: true });
15526
+ await mkdir9(path30.dirname(filePath), { recursive: true });
15437
15527
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
15438
15528
  await writeFile11(tmp, content, "utf-8");
15439
15529
  await rename7(tmp, filePath);
@@ -15513,7 +15603,7 @@ async function runSkillConsolidationInner(req) {
15513
15603
  };
15514
15604
  }
15515
15605
  async function runSkillConsolidation(req) {
15516
- const key = path29.resolve(req.directory);
15606
+ const key = path30.resolve(req.directory);
15517
15607
  const existing = runningByDirectory.get(key);
15518
15608
  if (existing) {
15519
15609
  return {
@@ -15715,7 +15805,7 @@ async function handleCouncilCommand(_directory, args) {
15715
15805
  // src/commands/coupling.ts
15716
15806
  import { randomBytes } from "crypto";
15717
15807
  import * as fs10 from "fs";
15718
- import * as path31 from "path";
15808
+ import * as path32 from "path";
15719
15809
 
15720
15810
  // src/turbo/epic/cochange-source.ts
15721
15811
  import * as child_process4 from "child_process";
@@ -15725,7 +15815,7 @@ import { promisify as promisify2 } from "util";
15725
15815
  import * as child_process3 from "child_process";
15726
15816
  import { randomUUID as randomUUID6 } from "crypto";
15727
15817
  import { readdir as readdir2, readFile as readFile11, stat as stat4 } from "fs/promises";
15728
- import * as path30 from "path";
15818
+ import * as path31 from "path";
15729
15819
  import { promisify } from "util";
15730
15820
  function getExecFileAsync() {
15731
15821
  return promisify(child_process3.execFile);
@@ -15829,7 +15919,7 @@ async function scanSourceFiles(dir) {
15829
15919
  try {
15830
15920
  const entries = await readdir2(dir, { withFileTypes: true });
15831
15921
  for (const entry of entries) {
15832
- const fullPath = path30.join(dir, entry.name);
15922
+ const fullPath = path31.join(dir, entry.name);
15833
15923
  if (entry.isDirectory()) {
15834
15924
  if (skipDirs.has(entry.name)) {
15835
15925
  continue;
@@ -15837,7 +15927,7 @@ async function scanSourceFiles(dir) {
15837
15927
  const subFiles = await scanSourceFiles(fullPath);
15838
15928
  results.push(...subFiles);
15839
15929
  } else if (entry.isFile()) {
15840
- const ext = path30.extname(entry.name);
15930
+ const ext = path31.extname(entry.name);
15841
15931
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
15842
15932
  results.push(fullPath);
15843
15933
  }
@@ -15859,8 +15949,8 @@ async function getStaticEdges(directory) {
15859
15949
  continue;
15860
15950
  }
15861
15951
  try {
15862
- const sourceDir = path30.dirname(sourceFile);
15863
- const resolvedPath = path30.resolve(sourceDir, importPath);
15952
+ const sourceDir = path31.dirname(sourceFile);
15953
+ const resolvedPath = path31.resolve(sourceDir, importPath);
15864
15954
  const extensions = [
15865
15955
  "",
15866
15956
  ".ts",
@@ -15885,8 +15975,8 @@ async function getStaticEdges(directory) {
15885
15975
  if (!targetFile) {
15886
15976
  continue;
15887
15977
  }
15888
- const relSource = path30.relative(directory, sourceFile).replace(/\\/g, "/");
15889
- const relTarget = path30.relative(directory, targetFile).replace(/\\/g, "/");
15978
+ const relSource = path31.relative(directory, sourceFile).replace(/\\/g, "/");
15979
+ const relTarget = path31.relative(directory, targetFile).replace(/\\/g, "/");
15890
15980
  const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
15891
15981
  edges.add(key);
15892
15982
  } catch {}
@@ -15898,7 +15988,7 @@ async function getStaticEdges(directory) {
15898
15988
  function isTestImplementationPair(fileA, fileB) {
15899
15989
  const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
15900
15990
  const getBaseName = (filePath) => {
15901
- const base = path30.basename(filePath);
15991
+ const base = path31.basename(filePath);
15902
15992
  for (const pattern of testPatterns) {
15903
15993
  if (base.endsWith(pattern)) {
15904
15994
  return base.slice(0, -pattern.length);
@@ -15908,16 +15998,16 @@ function isTestImplementationPair(fileA, fileB) {
15908
15998
  };
15909
15999
  const baseA = getBaseName(fileA);
15910
16000
  const baseB = getBaseName(fileB);
15911
- return baseA === baseB && baseA !== path30.basename(fileA) && baseA !== path30.basename(fileB);
16001
+ return baseA === baseB && baseA !== path31.basename(fileA) && baseA !== path31.basename(fileB);
15912
16002
  }
15913
16003
  function hasSharedPrefix(fileA, fileB) {
15914
- const dirA = path30.dirname(fileA);
15915
- const dirB = path30.dirname(fileB);
16004
+ const dirA = path31.dirname(fileA);
16005
+ const dirB = path31.dirname(fileB);
15916
16006
  if (dirA !== dirB) {
15917
16007
  return false;
15918
16008
  }
15919
- const baseA = path30.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
15920
- const baseB = path30.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
16009
+ const baseA = path31.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
16010
+ const baseB = path31.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
15921
16011
  if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
15922
16012
  return true;
15923
16013
  }
@@ -15972,8 +16062,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
15972
16062
  const entries = [];
15973
16063
  const now = new Date().toISOString();
15974
16064
  for (const pair of pairs.slice(0, 10)) {
15975
- const baseA = path30.basename(pair.fileA);
15976
- const baseB = path30.basename(pair.fileB);
16065
+ const baseA = path31.basename(pair.fileA);
16066
+ const baseB = path31.basename(pair.fileB);
15977
16067
  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.`;
15978
16068
  if (lesson.length > 280) {
15979
16069
  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.`;
@@ -16399,9 +16489,9 @@ function parseArgs3(args) {
16399
16489
  return parsed;
16400
16490
  }
16401
16491
  function persistReportJson(directory, report) {
16402
- const epicDir = path31.join(directory, ".swarm", "epic");
16492
+ const epicDir = path32.join(directory, ".swarm", "epic");
16403
16493
  fs10.mkdirSync(epicDir, { recursive: true });
16404
- const filePath = path31.join(epicDir, "coupling-report.json");
16494
+ const filePath = path32.join(epicDir, "coupling-report.json");
16405
16495
  const tmpPath = `${filePath}.tmp.${randomBytes(8).toString("hex")}`;
16406
16496
  fs10.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
16407
16497
  `, "utf-8");
@@ -16460,7 +16550,7 @@ Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>
16460
16550
  persistStatus = {
16461
16551
  requested: true,
16462
16552
  written: true,
16463
- path: path31.relative(directory, writtenAt).replace(/\\/g, "/")
16553
+ path: path32.relative(directory, writtenAt).replace(/\\/g, "/")
16464
16554
  };
16465
16555
  } catch (err) {
16466
16556
  persistStatus = {
@@ -16499,8 +16589,8 @@ var _internals21 = {
16499
16589
  loadCuratorDeps: async () => {
16500
16590
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
16501
16591
  import("./schema-x17zmd03.js"),
16502
- import("./curator-6p9tpprq.js"),
16503
- import("./curator-llm-factory-wqbm9mwr.js")
16592
+ import("./curator-9q3m25va.js"),
16593
+ import("./curator-llm-factory-78dyv010.js")
16504
16594
  ]);
16505
16595
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
16506
16596
  }
@@ -16592,7 +16682,7 @@ function formatCurationSummary(summary) {
16592
16682
  }
16593
16683
 
16594
16684
  // src/commands/dark-matter.ts
16595
- import path32 from "path";
16685
+ import path33 from "path";
16596
16686
  async function handleDarkMatterCommand(directory, args) {
16597
16687
  const options = {};
16598
16688
  for (let i = 0;i < args.length; i++) {
@@ -16624,7 +16714,7 @@ Ensure this is a git repository with commit history.`;
16624
16714
  const output = formatDarkMatterOutput(pairs);
16625
16715
  if (pairs.length > 0) {
16626
16716
  try {
16627
- const projectName = path32.basename(path32.resolve(directory));
16717
+ const projectName = path33.basename(path33.resolve(directory));
16628
16718
  const entries = darkMatterToKnowledgeEntries(pairs, projectName);
16629
16719
  if (entries.length > 0) {
16630
16720
  const knowledgePath = resolveSwarmKnowledgePath(directory);
@@ -16991,12 +17081,12 @@ ${USAGE5}`;
16991
17081
  // src/services/diagnose-service.ts
16992
17082
  import * as child_process5 from "child_process";
16993
17083
  import { existsSync as existsSync22, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
16994
- import * as path34 from "path";
17084
+ import * as path35 from "path";
16995
17085
  import { fileURLToPath } from "url";
16996
17086
  // package.json
16997
17087
  var package_default = {
16998
17088
  name: "opencode-swarm",
16999
- version: "7.109.2",
17089
+ version: "7.109.3",
17000
17090
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
17001
17091
  main: "dist/index.js",
17002
17092
  types: "dist/index.d.ts",
@@ -17063,6 +17153,11 @@ var package_default = {
17063
17153
  ".opencode/skills/running-tests",
17064
17154
  ".opencode/skills/engineering-conventions",
17065
17155
  ".opencode/skills/commit-pr",
17156
+ ".opencode/skills/worktree-retry-cleanup",
17157
+ ".opencode/skills/skill-edit-validation",
17158
+ ".opencode/skills/merge-queue-readiness",
17159
+ ".opencode/skills/gate-attribution",
17160
+ ".opencode/skills/ci-failure-batching",
17066
17161
  "tests/fixtures/memory-recall",
17067
17162
  "README.md",
17068
17163
  "LICENSE"
@@ -17105,44 +17200,44 @@ var package_default = {
17105
17200
 
17106
17201
  // src/config/cache-paths.ts
17107
17202
  import * as os6 from "os";
17108
- import * as path33 from "path";
17203
+ import * as path34 from "path";
17109
17204
  function getPluginConfigDir() {
17110
- return path33.join(process.env.XDG_CONFIG_HOME || path33.join(os6.homedir(), ".config"), "opencode");
17205
+ return path34.join(process.env.XDG_CONFIG_HOME || path34.join(os6.homedir(), ".config"), "opencode");
17111
17206
  }
17112
17207
  function getPluginCachePaths() {
17113
- const cacheBase = process.env.XDG_CACHE_HOME || path33.join(os6.homedir(), ".cache");
17208
+ const cacheBase = process.env.XDG_CACHE_HOME || path34.join(os6.homedir(), ".cache");
17114
17209
  const configDir = getPluginConfigDir();
17115
17210
  const paths = [
17116
- path33.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
17117
- path33.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
17118
- path33.join(configDir, "node_modules", "opencode-swarm")
17211
+ path34.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
17212
+ path34.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
17213
+ path34.join(configDir, "node_modules", "opencode-swarm")
17119
17214
  ];
17120
17215
  if (process.platform === "darwin") {
17121
- const libCaches = path33.join(os6.homedir(), "Library", "Caches");
17122
- paths.push(path33.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path33.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
17216
+ const libCaches = path34.join(os6.homedir(), "Library", "Caches");
17217
+ paths.push(path34.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path34.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
17123
17218
  }
17124
17219
  if (process.platform === "win32") {
17125
- const localAppData = process.env.LOCALAPPDATA || path33.join(os6.homedir(), "AppData", "Local");
17126
- const appData = process.env.APPDATA || path33.join(os6.homedir(), "AppData", "Roaming");
17127
- paths.push(path33.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path33.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path33.join(appData, "opencode", "node_modules", "opencode-swarm"));
17220
+ const localAppData = process.env.LOCALAPPDATA || path34.join(os6.homedir(), "AppData", "Local");
17221
+ const appData = process.env.APPDATA || path34.join(os6.homedir(), "AppData", "Roaming");
17222
+ paths.push(path34.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path34.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path34.join(appData, "opencode", "node_modules", "opencode-swarm"));
17128
17223
  }
17129
17224
  return paths;
17130
17225
  }
17131
17226
  function getPluginLockFilePaths() {
17132
- const cacheBase = process.env.XDG_CACHE_HOME || path33.join(os6.homedir(), ".cache");
17227
+ const cacheBase = process.env.XDG_CACHE_HOME || path34.join(os6.homedir(), ".cache");
17133
17228
  const configDir = getPluginConfigDir();
17134
17229
  const paths = [
17135
- path33.join(cacheBase, "opencode", "bun.lock"),
17136
- path33.join(cacheBase, "opencode", "bun.lockb"),
17137
- path33.join(configDir, "package-lock.json")
17230
+ path34.join(cacheBase, "opencode", "bun.lock"),
17231
+ path34.join(cacheBase, "opencode", "bun.lockb"),
17232
+ path34.join(configDir, "package-lock.json")
17138
17233
  ];
17139
17234
  if (process.platform === "darwin") {
17140
- const libCaches = path33.join(os6.homedir(), "Library", "Caches");
17141
- paths.push(path33.join(libCaches, "opencode", "bun.lock"), path33.join(libCaches, "opencode", "bun.lockb"));
17235
+ const libCaches = path34.join(os6.homedir(), "Library", "Caches");
17236
+ paths.push(path34.join(libCaches, "opencode", "bun.lock"), path34.join(libCaches, "opencode", "bun.lockb"));
17142
17237
  }
17143
17238
  if (process.platform === "win32") {
17144
- const localAppData = process.env.LOCALAPPDATA || path33.join(os6.homedir(), "AppData", "Local");
17145
- paths.push(path33.join(localAppData, "opencode", "bun.lock"), path33.join(localAppData, "opencode", "bun.lockb"));
17239
+ const localAppData = process.env.LOCALAPPDATA || path34.join(os6.homedir(), "AppData", "Local");
17240
+ paths.push(path34.join(localAppData, "opencode", "bun.lock"), path34.join(localAppData, "opencode", "bun.lockb"));
17146
17241
  }
17147
17242
  return paths;
17148
17243
  }
@@ -17172,10 +17267,10 @@ function cacheFile() {
17172
17267
  }
17173
17268
  function readVersionCache() {
17174
17269
  try {
17175
- const path34 = cacheFile();
17176
- if (!existsSync20(path34))
17270
+ const path35 = cacheFile();
17271
+ if (!existsSync20(path35))
17177
17272
  return null;
17178
- const raw = readFileSync9(path34, "utf-8");
17273
+ const raw = readFileSync9(path35, "utf-8");
17179
17274
  const parsed = JSON.parse(raw);
17180
17275
  if (typeof parsed?.checkedAt !== "number")
17181
17276
  return null;
@@ -17430,7 +17525,7 @@ var REQUIRED_CACHE_GRAMMAR_ASSETS = [
17430
17525
  "tree-sitter-typescript.wasm"
17431
17526
  ];
17432
17527
  function resolveCachePackageRoot(cachePath) {
17433
- const nestedPackageRoot = path34.join(cachePath, "node_modules", "opencode-swarm");
17528
+ const nestedPackageRoot = path35.join(cachePath, "node_modules", "opencode-swarm");
17434
17529
  return existsSync22(nestedPackageRoot) ? nestedPackageRoot : cachePath;
17435
17530
  }
17436
17531
  var _internals22 = {
@@ -17746,7 +17841,7 @@ async function checkSpecStaleness(directory, plan) {
17746
17841
  };
17747
17842
  }
17748
17843
  async function checkConfigParseability(directory) {
17749
- const configPath = path34.join(directory, ".opencode/opencode-swarm.json");
17844
+ const configPath = path35.join(directory, ".opencode/opencode-swarm.json");
17750
17845
  if (!existsSync22(configPath)) {
17751
17846
  return {
17752
17847
  name: "Config Parseability",
@@ -17775,7 +17870,7 @@ function resolveGrammarDir(thisDir) {
17775
17870
  const normalized = thisDir.replace(/\\/g, "/");
17776
17871
  const isSource = normalized.endsWith("/src/services");
17777
17872
  const isCliBundle = normalized.endsWith("/cli");
17778
- return isSource || isCliBundle ? path34.join(thisDir, "..", "lang", "grammars") : path34.join(thisDir, "lang", "grammars");
17873
+ return isSource || isCliBundle ? path35.join(thisDir, "..", "lang", "grammars") : path35.join(thisDir, "lang", "grammars");
17779
17874
  }
17780
17875
  async function checkGrammarWasmFiles() {
17781
17876
  const grammarFiles = [
@@ -17799,14 +17894,14 @@ async function checkGrammarWasmFiles() {
17799
17894
  "tree-sitter-ini.wasm",
17800
17895
  "tree-sitter-regex.wasm"
17801
17896
  ];
17802
- const thisDir = path34.dirname(fileURLToPath(import.meta.url));
17897
+ const thisDir = path35.dirname(fileURLToPath(import.meta.url));
17803
17898
  const grammarDir = resolveGrammarDir(thisDir);
17804
17899
  const missing = [];
17805
- if (!existsSync22(path34.join(grammarDir, "tree-sitter.wasm"))) {
17900
+ if (!existsSync22(path35.join(grammarDir, "tree-sitter.wasm"))) {
17806
17901
  missing.push("tree-sitter.wasm (core runtime)");
17807
17902
  }
17808
17903
  for (const file of grammarFiles) {
17809
- if (!existsSync22(path34.join(grammarDir, file))) {
17904
+ if (!existsSync22(path35.join(grammarDir, file))) {
17810
17905
  missing.push(file);
17811
17906
  }
17812
17907
  }
@@ -17824,7 +17919,7 @@ async function checkGrammarWasmFiles() {
17824
17919
  };
17825
17920
  }
17826
17921
  async function checkCheckpointManifest(directory) {
17827
- const manifestPath = path34.join(directory, ".swarm/checkpoints.json");
17922
+ const manifestPath = path35.join(directory, ".swarm/checkpoints.json");
17828
17923
  if (!existsSync22(manifestPath)) {
17829
17924
  return {
17830
17925
  name: "Checkpoint Manifest",
@@ -17876,7 +17971,7 @@ async function checkCheckpointManifest(directory) {
17876
17971
  }
17877
17972
  }
17878
17973
  async function checkEventStreamIntegrity(directory) {
17879
- const eventsPath = path34.join(directory, ".swarm/events.jsonl");
17974
+ const eventsPath = path35.join(directory, ".swarm/events.jsonl");
17880
17975
  if (!existsSync22(eventsPath)) {
17881
17976
  return {
17882
17977
  name: "Event Stream",
@@ -17917,7 +18012,7 @@ async function checkEventStreamIntegrity(directory) {
17917
18012
  }
17918
18013
  }
17919
18014
  async function checkSteeringDirectives(directory) {
17920
- const eventsPath = path34.join(directory, ".swarm/events.jsonl");
18015
+ const eventsPath = path35.join(directory, ".swarm/events.jsonl");
17921
18016
  if (!existsSync22(eventsPath)) {
17922
18017
  return {
17923
18018
  name: "Steering Directives",
@@ -17973,7 +18068,7 @@ async function checkCurator(directory) {
17973
18068
  detail: "Disabled (enable via curator.enabled)"
17974
18069
  };
17975
18070
  }
17976
- const summaryPath = path34.join(directory, ".swarm/curator-summary.json");
18071
+ const summaryPath = path35.join(directory, ".swarm/curator-summary.json");
17977
18072
  if (!existsSync22(summaryPath)) {
17978
18073
  return {
17979
18074
  name: "Curator",
@@ -18175,7 +18270,7 @@ async function getDiagnoseData(directory) {
18175
18270
  checks.push(await checkCurator(directory));
18176
18271
  checks.push(await checkKnowledgeHealth(directory));
18177
18272
  try {
18178
- const evidenceDir = path34.join(directory, ".swarm", "evidence");
18273
+ const evidenceDir = path35.join(directory, ".swarm", "evidence");
18179
18274
  const snapshotFiles = existsSync22(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
18180
18275
  if (snapshotFiles.length > 0) {
18181
18276
  const latest = snapshotFiles.sort().pop();
@@ -18215,8 +18310,8 @@ async function getDiagnoseData(directory) {
18215
18310
  }
18216
18311
  const packageRoot = resolveCachePackageRoot(cachePath);
18217
18312
  const cacheLabel = packageRoot === cachePath ? cachePath : `${cachePath} -> ${packageRoot}`;
18218
- const missingGrammarAssets = REQUIRED_CACHE_GRAMMAR_ASSETS.filter((file) => !existsSync22(path34.join(packageRoot, "dist", "lang", "grammars", file)));
18219
- const pkgJsonPath = path34.join(packageRoot, "package.json");
18313
+ const missingGrammarAssets = REQUIRED_CACHE_GRAMMAR_ASSETS.filter((file) => !existsSync22(path35.join(packageRoot, "dist", "lang", "grammars", file)));
18314
+ const pkgJsonPath = path35.join(packageRoot, "package.json");
18220
18315
  try {
18221
18316
  const raw = readFileSync10(pkgJsonPath, "utf-8");
18222
18317
  const parsed = JSON.parse(raw);
@@ -18592,9 +18687,9 @@ function decideEpicActivation(tasks, cochangePairs, commitsObserved, options) {
18592
18687
  // src/turbo/epic/calibration.ts
18593
18688
  init_logger();
18594
18689
  import * as fs11 from "fs";
18595
- import * as path35 from "path";
18690
+ import * as path36 from "path";
18596
18691
  var STATE_FILE = "calibration.json";
18597
- var STATE_REL_DIR = path35.join(".swarm", "epic");
18692
+ var STATE_REL_DIR = path36.join(".swarm", "epic");
18598
18693
  function nowISO() {
18599
18694
  return new Date().toISOString();
18600
18695
  }
@@ -18616,7 +18711,7 @@ function markUnreadable(directory, reason) {
18616
18711
  error(`[epic/calibration] state file unreadable for ${directory}: ${reason} \u2014 failing closed`);
18617
18712
  }
18618
18713
  function repairCalibrationUnreadable(directory) {
18619
- const filePath = path35.join(directory, STATE_REL_DIR, STATE_FILE);
18714
+ const filePath = path36.join(directory, STATE_REL_DIR, STATE_FILE);
18620
18715
  if (!fs11.existsSync(filePath)) {
18621
18716
  stateUnreadableMap.delete(directory);
18622
18717
  return;
@@ -18648,7 +18743,7 @@ function isValidCalibrationShape(candidate) {
18648
18743
  return true;
18649
18744
  }
18650
18745
  function ensureSwarmEpicDir(directory) {
18651
- const dir = path35.resolve(directory, STATE_REL_DIR);
18746
+ const dir = path36.resolve(directory, STATE_REL_DIR);
18652
18747
  if (!fs11.existsSync(dir)) {
18653
18748
  fs11.mkdirSync(dir, { recursive: true });
18654
18749
  }
@@ -18660,7 +18755,7 @@ function loadCalibrationState(directory) {
18660
18755
  if (stateUnreadableMap.get(directory))
18661
18756
  return null;
18662
18757
  }
18663
- const filePath = path35.join(directory, STATE_REL_DIR, STATE_FILE);
18758
+ const filePath = path36.join(directory, STATE_REL_DIR, STATE_FILE);
18664
18759
  try {
18665
18760
  if (!fs11.existsSync(filePath)) {
18666
18761
  const seed = emptyCalibrationState();
@@ -18687,12 +18782,12 @@ function loadCalibrationState(directory) {
18687
18782
  // src/turbo/epic/divergence-recorder.ts
18688
18783
  init_logger();
18689
18784
  import * as fs12 from "fs";
18690
- import * as path36 from "path";
18691
- var EVIDENCE_REL_DIR = path36.join(".swarm", "epic");
18785
+ import * as path37 from "path";
18786
+ var EVIDENCE_REL_DIR = path37.join(".swarm", "epic");
18692
18787
  var EVIDENCE_FILE = "divergence.jsonl";
18693
18788
  var MAX_TAIL_BYTES2 = 16 * 1024 * 1024;
18694
18789
  function readDivergenceHistory(directory, options) {
18695
- const filePath = path36.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
18790
+ const filePath = path37.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
18696
18791
  if (!fs12.existsSync(filePath)) {
18697
18792
  return [];
18698
18793
  }
@@ -18741,11 +18836,11 @@ function readDivergenceHistory(directory, options) {
18741
18836
 
18742
18837
  // src/turbo/epic/promotion-evidence.ts
18743
18838
  import * as fs13 from "fs";
18744
- import * as path37 from "path";
18745
- var EVIDENCE_REL_DIR2 = path37.join(".swarm", "evidence");
18839
+ import * as path38 from "path";
18840
+ var EVIDENCE_REL_DIR2 = path38.join(".swarm", "evidence");
18746
18841
  var EVIDENCE_FILE2 = "epic-promotions.jsonl";
18747
18842
  function readPromotionEvidence(directory) {
18748
- const filePath = path37.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
18843
+ const filePath = path38.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
18749
18844
  if (!fs13.existsSync(filePath)) {
18750
18845
  return [];
18751
18846
  }
@@ -19319,7 +19414,7 @@ async function handleExportCommand(directory, _args) {
19319
19414
  // src/full-auto/state.ts
19320
19415
  var import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
19321
19416
  import * as fs14 from "fs";
19322
- import * as path38 from "path";
19417
+ import * as path39 from "path";
19323
19418
  init_logger();
19324
19419
  var lockfile3 = import_proper_lockfile3.default;
19325
19420
  var STATE_FILE2 = "full-auto-state.json";
@@ -19327,7 +19422,7 @@ function nowISO2() {
19327
19422
  return new Date().toISOString();
19328
19423
  }
19329
19424
  function ensureSwarmDir(directory) {
19330
- const swarmDir = path38.resolve(directory, ".swarm");
19425
+ const swarmDir = path39.resolve(directory, ".swarm");
19331
19426
  if (!fs14.existsSync(swarmDir)) {
19332
19427
  fs14.mkdirSync(swarmDir, { recursive: true });
19333
19428
  }
@@ -20139,7 +20234,7 @@ var _internals25 = {
20139
20234
 
20140
20235
  // src/session/snapshot-writer.ts
20141
20236
  import { closeSync as closeSync5, fsyncSync as fsyncSync2, mkdirSync as mkdirSync16, openSync as openSync5, renameSync as renameSync8 } from "fs";
20142
- import * as path39 from "path";
20237
+ import * as path40 from "path";
20143
20238
  var _writeInFlight = Promise.resolve();
20144
20239
  function serializeAgentSession(s) {
20145
20240
  const gateLog = {};
@@ -20252,7 +20347,7 @@ async function writeSnapshot(directory, state) {
20252
20347
  }
20253
20348
  const content = JSON.stringify(snapshot, null, 2);
20254
20349
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
20255
- const dir = path39.dirname(resolvedPath);
20350
+ const dir = path40.dirname(resolvedPath);
20256
20351
  mkdirSync16(dir, { recursive: true });
20257
20352
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
20258
20353
  await bunWrite(tempPath, content);
@@ -20780,10 +20875,10 @@ import { randomUUID as randomUUID7 } from "crypto";
20780
20875
  import { existsSync as existsSync27, readFileSync as readFileSync15 } from "fs";
20781
20876
  import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile12 } from "fs/promises";
20782
20877
  import * as os7 from "os";
20783
- import * as path40 from "path";
20878
+ import * as path41 from "path";
20784
20879
  async function migrateKnowledgeToExternal(_directory, _config) {
20785
- const externalSentinelPath = path40.join(_directory, ".swarm", ".knowledge-external-migrated");
20786
- const contextPath = path40.join(_directory, ".swarm", "context.md");
20880
+ const externalSentinelPath = path41.join(_directory, ".swarm", ".knowledge-external-migrated");
20881
+ const contextPath = path41.join(_directory, ".swarm", "context.md");
20787
20882
  if (_internals28.existsSync(externalSentinelPath)) {
20788
20883
  return {
20789
20884
  migrated: false,
@@ -20848,8 +20943,8 @@ var _internals28 = {
20848
20943
  writeFile: writeFile12
20849
20944
  };
20850
20945
  async function migrateContextToKnowledge(directory, config) {
20851
- const sentinelPath = path40.join(directory, ".swarm", ".knowledge-migrated");
20852
- const contextPath = path40.join(directory, ".swarm", "context.md");
20946
+ const sentinelPath = path41.join(directory, ".swarm", ".knowledge-migrated");
20947
+ const contextPath = path41.join(directory, ".swarm", "context.md");
20853
20948
  const knowledgePath = resolveSwarmKnowledgePath(directory);
20854
20949
  if (existsSync27(sentinelPath)) {
20855
20950
  return {
@@ -20951,7 +21046,7 @@ async function migrateContextToKnowledge(directory, config) {
20951
21046
  async function migrateHiveKnowledgeLegacy(config) {
20952
21047
  const legacyHivePath = _internals28.resolveLegacyHiveKnowledgePath();
20953
21048
  const canonicalHivePath = resolveHiveKnowledgePath();
20954
- const sentinelPath = path40.join(path40.dirname(canonicalHivePath), ".hive-knowledge-migrated");
21049
+ const sentinelPath = path41.join(path41.dirname(canonicalHivePath), ".hive-knowledge-migrated");
20955
21050
  if (existsSync27(sentinelPath)) {
20956
21051
  return {
20957
21052
  migrated: false,
@@ -21162,7 +21257,7 @@ function truncateLesson2(text) {
21162
21257
  return `${text.slice(0, 277)}...`;
21163
21258
  }
21164
21259
  function inferProjectName(directory) {
21165
- const packageJsonPath = path40.join(directory, "package.json");
21260
+ const packageJsonPath = path41.join(directory, "package.json");
21166
21261
  if (existsSync27(packageJsonPath)) {
21167
21262
  try {
21168
21263
  const pkg = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
@@ -21171,7 +21266,7 @@ function inferProjectName(directory) {
21171
21266
  }
21172
21267
  } catch {}
21173
21268
  }
21174
- return path40.basename(directory);
21269
+ return path41.basename(directory);
21175
21270
  }
21176
21271
  async function writeSentinel(sentinelPath, migrated, dropped) {
21177
21272
  const sentinel = {
@@ -21183,7 +21278,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
21183
21278
  schema_version: 1,
21184
21279
  migration_tool: "knowledge-migrator.ts"
21185
21280
  };
21186
- await _internals28.mkdir(path40.dirname(sentinelPath), { recursive: true });
21281
+ await _internals28.mkdir(path41.dirname(sentinelPath), { recursive: true });
21187
21282
  await _internals28.writeFile(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
21188
21283
  }
21189
21284
  function resolveLegacyHiveKnowledgePath() {
@@ -21191,13 +21286,13 @@ function resolveLegacyHiveKnowledgePath() {
21191
21286
  const home = process.env.HOME || os7.homedir();
21192
21287
  let dataDir;
21193
21288
  if (platform === "win32") {
21194
- dataDir = path40.join(process.env.LOCALAPPDATA || path40.join(home, "AppData", "Local"), "opencode-swarm", "Data");
21289
+ dataDir = path41.join(process.env.LOCALAPPDATA || path41.join(home, "AppData", "Local"), "opencode-swarm", "Data");
21195
21290
  } else if (platform === "darwin") {
21196
- dataDir = path40.join(home, "Library", "Application Support", "opencode-swarm");
21291
+ dataDir = path41.join(home, "Library", "Application Support", "opencode-swarm");
21197
21292
  } else {
21198
- dataDir = path40.join(process.env.XDG_DATA_HOME || path40.join(home, ".local", "share"), "opencode-swarm");
21293
+ dataDir = path41.join(process.env.XDG_DATA_HOME || path41.join(home, ".local", "share"), "opencode-swarm");
21199
21294
  }
21200
- return path40.join(dataDir, "hive-knowledge.jsonl");
21295
+ return path41.join(dataDir, "hive-knowledge.jsonl");
21201
21296
  }
21202
21297
 
21203
21298
  // src/commands/knowledge.ts
@@ -21628,14 +21723,14 @@ var _internals29 = {
21628
21723
 
21629
21724
  // src/commands/link.ts
21630
21725
  import { existsSync as existsSync28 } from "fs";
21631
- import * as path42 from "path";
21726
+ import * as path43 from "path";
21632
21727
 
21633
21728
  // src/knowledge/identity.ts
21634
21729
  import * as child_process7 from "child_process";
21635
21730
  import { createHash as createHash5 } from "crypto";
21636
- import * as path41 from "path";
21731
+ import * as path42 from "path";
21637
21732
  function deriveProjectHash(directory) {
21638
- const absolutePath = path41.resolve(directory);
21733
+ const absolutePath = path42.resolve(directory);
21639
21734
  let hashInput;
21640
21735
  try {
21641
21736
  const remoteUrl = child_process7.execSync("git remote get-url origin", {
@@ -21655,8 +21750,8 @@ function deriveProjectHash(directory) {
21655
21750
  // src/commands/link.ts
21656
21751
  var DEDUP_THRESHOLD = 0.6;
21657
21752
  async function mergeLocalKnowledgeIntoLink(localSwarmDir, linkDir) {
21658
- const localPath = path42.join(localSwarmDir, "knowledge.jsonl");
21659
- const sharedPath = path42.join(linkDir, "knowledge.jsonl");
21753
+ const localPath = path43.join(localSwarmDir, "knowledge.jsonl");
21754
+ const sharedPath = path43.join(linkDir, "knowledge.jsonl");
21660
21755
  if (!existsSync28(localPath))
21661
21756
  return { merged: 0, skipped: 0 };
21662
21757
  let merged = 0;
@@ -21754,7 +21849,7 @@ ${formatStatus(directory)}`;
21754
21849
  const linkDir = resolveLinkDir(linkId);
21755
21850
  let merge;
21756
21851
  try {
21757
- merge = await mergeLocalKnowledgeIntoLink(path42.join(directory, ".swarm"), linkDir);
21852
+ merge = await mergeLocalKnowledgeIntoLink(path43.join(directory, ".swarm"), linkDir);
21758
21853
  } catch (error2) {
21759
21854
  return `\u274C Failed to merge local knowledge into the link store: ${error2 instanceof Error ? error2.message : String(error2)}`;
21760
21855
  }
@@ -21951,12 +22046,12 @@ ${USAGE7}`;
21951
22046
 
21952
22047
  // src/commands/memory.ts
21953
22048
  import { existsSync as existsSync29 } from "fs";
21954
- import * as path45 from "path";
22049
+ import * as path46 from "path";
21955
22050
  import { fileURLToPath as fileURLToPath2 } from "url";
21956
22051
  // src/memory/evaluation.ts
21957
22052
  import * as fs15 from "fs/promises";
21958
22053
  import * as os8 from "os";
21959
- import * as path43 from "path";
22054
+ import * as path44 from "path";
21960
22055
  var DEFAULT_PROVIDERS = [
21961
22056
  "local-jsonl",
21962
22057
  "sqlite"
@@ -21968,7 +22063,7 @@ var DEFAULT_MODES = [
21968
22063
  ];
21969
22064
  var DEFAULT_TIMESTAMP = "2026-05-26T12:00:00.000Z";
21970
22065
  async function evaluateMemoryRecallFixtures(options) {
21971
- const fixtureDirectory = path43.resolve(options.fixtureDirectory);
22066
+ const fixtureDirectory = path44.resolve(options.fixtureDirectory);
21972
22067
  const providers = options.providers ?? DEFAULT_PROVIDERS;
21973
22068
  const modes = options.modes ?? DEFAULT_MODES;
21974
22069
  const generatedAt = new Date().toISOString();
@@ -21977,7 +22072,7 @@ async function evaluateMemoryRecallFixtures(options) {
21977
22072
  for (const fixture of fixtures) {
21978
22073
  const materialized = materializeFixture(fixture);
21979
22074
  for (const providerName of providers) {
21980
- const tempRoot = await fs15.realpath(await fs15.mkdtemp(path43.join(os8.tmpdir(), "swarm-memory-eval-")));
22075
+ const tempRoot = await fs15.realpath(await fs15.mkdtemp(path44.join(os8.tmpdir(), "swarm-memory-eval-")));
21981
22076
  const provider = createEvaluationProvider(providerName, tempRoot);
21982
22077
  try {
21983
22078
  await provider.initialize?.();
@@ -22034,7 +22129,7 @@ async function loadRecallEvaluationFixtures(fixtureDirectory) {
22034
22129
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
22035
22130
  const fixtures = [];
22036
22131
  for (const file of files) {
22037
- const raw = await fs15.readFile(path43.join(fixtureDirectory, file), "utf-8");
22132
+ const raw = await fs15.readFile(path44.join(fixtureDirectory, file), "utf-8");
22038
22133
  fixtures.push(validateFixture(JSON.parse(raw), file));
22039
22134
  }
22040
22135
  return fixtures;
@@ -22311,8 +22406,8 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
22311
22406
  }).passthrough();
22312
22407
  // src/memory/consolidation-log.ts
22313
22408
  import { appendFile as appendFile3, mkdir as mkdir11, readFile as readFile15 } from "fs/promises";
22314
- import * as path44 from "path";
22315
- var LOG_RELATIVE_PATH = path44.join("memory", "consolidation-log.jsonl");
22409
+ import * as path45 from "path";
22410
+ var LOG_RELATIVE_PATH = path45.join("memory", "consolidation-log.jsonl");
22316
22411
  async function readConsolidationLog(directory) {
22317
22412
  const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
22318
22413
  let raw;
@@ -22335,7 +22430,7 @@ async function readConsolidationLog(directory) {
22335
22430
  }
22336
22431
 
22337
22432
  // src/commands/memory.ts
22338
- var PACKAGE_ROOT = path45.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
22433
+ var PACKAGE_ROOT = path46.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
22339
22434
  async function handleMemoryCommand(_directory, _args) {
22340
22435
  return [
22341
22436
  "## Swarm Memory",
@@ -22692,7 +22787,7 @@ function resolveCommandMemoryConfig(directory) {
22692
22787
  }
22693
22788
  function parseEvaluateArgs(directory, args) {
22694
22789
  let json = false;
22695
- let fixtureDirectory = path45.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
22790
+ let fixtureDirectory = path46.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
22696
22791
  for (let i = 0;i < args.length; i++) {
22697
22792
  const arg = args[i];
22698
22793
  if (arg === "--json") {
@@ -22706,10 +22801,10 @@ function parseEvaluateArgs(directory, args) {
22706
22801
  error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
22707
22802
  };
22708
22803
  }
22709
- const resolvedFixtures = path45.resolve(directory, next);
22710
- const canonical = path45.normalize(resolvedFixtures) + path45.sep;
22711
- const allowedRootA = path45.normalize(directory) + path45.sep;
22712
- const allowedRootB = path45.normalize(path45.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path45.sep;
22804
+ const resolvedFixtures = path46.resolve(directory, next);
22805
+ const canonical = path46.normalize(resolvedFixtures) + path46.sep;
22806
+ const allowedRootA = path46.normalize(directory) + path46.sep;
22807
+ const allowedRootB = path46.normalize(path46.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path46.sep;
22713
22808
  if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
22714
22809
  return {
22715
22810
  error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
@@ -22748,15 +22843,15 @@ function parseMaintenanceArgs(args, options) {
22748
22843
  return { limit, confirm };
22749
22844
  }
22750
22845
  function resolvePackageRootFromModule(modulePath) {
22751
- const moduleDir = path45.dirname(modulePath);
22752
- const leaf = path45.basename(moduleDir);
22846
+ const moduleDir = path46.dirname(modulePath);
22847
+ const leaf = path46.basename(moduleDir);
22753
22848
  if (leaf === "commands" || leaf === "cli") {
22754
- return path45.resolve(moduleDir, "..", "..");
22849
+ return path46.resolve(moduleDir, "..", "..");
22755
22850
  }
22756
22851
  if (leaf === "dist") {
22757
- return path45.resolve(moduleDir, "..");
22852
+ return path46.resolve(moduleDir, "..");
22758
22853
  }
22759
- return path45.resolve(moduleDir, "..");
22854
+ return path46.resolve(moduleDir, "..");
22760
22855
  }
22761
22856
  function formatMigrationResult(label, report) {
22762
22857
  if (!report) {
@@ -23491,11 +23586,11 @@ var _internals35 = {
23491
23586
 
23492
23587
  // src/services/preflight-service.ts
23493
23588
  import * as fs22 from "fs";
23494
- import * as path52 from "path";
23589
+ import * as path53 from "path";
23495
23590
 
23496
23591
  // src/tools/lint.ts
23497
23592
  import * as fs16 from "fs";
23498
- import * as path46 from "path";
23593
+ import * as path47 from "path";
23499
23594
 
23500
23595
  // src/utils/path-security.ts
23501
23596
  function containsPathTraversal(str) {
@@ -23551,9 +23646,9 @@ function validateArgs(args) {
23551
23646
  }
23552
23647
  function getLinterCommand(linter, mode, projectDir) {
23553
23648
  const isWindows = process.platform === "win32";
23554
- const binDir = path46.join(projectDir, "node_modules", ".bin");
23555
- const biomeBin = isWindows ? path46.join(binDir, "biome.EXE") : path46.join(binDir, "biome");
23556
- const eslintBin = isWindows ? path46.join(binDir, "eslint.cmd") : path46.join(binDir, "eslint");
23649
+ const binDir = path47.join(projectDir, "node_modules", ".bin");
23650
+ const biomeBin = isWindows ? path47.join(binDir, "biome.EXE") : path47.join(binDir, "biome");
23651
+ const eslintBin = isWindows ? path47.join(binDir, "eslint.cmd") : path47.join(binDir, "eslint");
23557
23652
  switch (linter) {
23558
23653
  case "biome":
23559
23654
  if (mode === "fix") {
@@ -23569,7 +23664,7 @@ function getLinterCommand(linter, mode, projectDir) {
23569
23664
  }
23570
23665
  function getAdditionalLinterCommand(linter, mode, cwd) {
23571
23666
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
23572
- const gradlew = fs16.existsSync(path46.join(cwd, gradlewName)) ? path46.join(cwd, gradlewName) : null;
23667
+ const gradlew = fs16.existsSync(path47.join(cwd, gradlewName)) ? path47.join(cwd, gradlewName) : null;
23573
23668
  switch (linter) {
23574
23669
  case "ruff":
23575
23670
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -23611,10 +23706,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
23611
23706
  }
23612
23707
  }
23613
23708
  function detectRuff(cwd) {
23614
- if (fs16.existsSync(path46.join(cwd, "ruff.toml")))
23709
+ if (fs16.existsSync(path47.join(cwd, "ruff.toml")))
23615
23710
  return isCommandAvailable("ruff");
23616
23711
  try {
23617
- const pyproject = path46.join(cwd, "pyproject.toml");
23712
+ const pyproject = path47.join(cwd, "pyproject.toml");
23618
23713
  if (fs16.existsSync(pyproject)) {
23619
23714
  const content = fs16.readFileSync(pyproject, "utf-8");
23620
23715
  if (content.includes("[tool.ruff]"))
@@ -23624,10 +23719,10 @@ function detectRuff(cwd) {
23624
23719
  return false;
23625
23720
  }
23626
23721
  function detectClippy(cwd) {
23627
- return fs16.existsSync(path46.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
23722
+ return fs16.existsSync(path47.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
23628
23723
  }
23629
23724
  function detectGolangciLint(cwd) {
23630
- return fs16.existsSync(path46.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
23725
+ return fs16.existsSync(path47.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
23631
23726
  }
23632
23727
  function readTextFileSafe(filePath) {
23633
23728
  try {
@@ -23638,18 +23733,18 @@ function readTextFileSafe(filePath) {
23638
23733
  }
23639
23734
  function phpVendorBin(_cwd, name) {
23640
23735
  const fileName = process.platform === "win32" ? `${name}.bat` : name;
23641
- return path46.join("vendor", "bin", fileName);
23736
+ return path47.join("vendor", "bin", fileName);
23642
23737
  }
23643
23738
  function phpVendorBinExists(cwd, name) {
23644
- const local = path46.join(cwd, "vendor", "bin", name);
23645
- const localWin = path46.join(cwd, "vendor", "bin", `${name}.bat`);
23739
+ const local = path47.join(cwd, "vendor", "bin", name);
23740
+ const localWin = path47.join(cwd, "vendor", "bin", `${name}.bat`);
23646
23741
  return fs16.existsSync(local) || fs16.existsSync(localWin);
23647
23742
  }
23648
23743
  function detectCheckstyle(cwd) {
23649
- const hasMaven = fs16.existsSync(path46.join(cwd, "pom.xml"));
23650
- const gradleFiles = ["build.gradle", "build.gradle.kts"].map((file) => path46.join(cwd, file)).filter((file) => fs16.existsSync(file));
23651
- const hasGradleCheckstyleSignal = fs16.existsSync(path46.join(cwd, "checkstyle.xml")) || fs16.existsSync(path46.join(cwd, "config", "checkstyle", "checkstyle.xml")) || gradleFiles.some((file) => /\bcheckstyle\b/i.test(readTextFileSafe(file)));
23652
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradleCheckstyleSignal && (fs16.existsSync(path46.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
23744
+ const hasMaven = fs16.existsSync(path47.join(cwd, "pom.xml"));
23745
+ const gradleFiles = ["build.gradle", "build.gradle.kts"].map((file) => path47.join(cwd, file)).filter((file) => fs16.existsSync(file));
23746
+ const hasGradleCheckstyleSignal = fs16.existsSync(path47.join(cwd, "checkstyle.xml")) || fs16.existsSync(path47.join(cwd, "config", "checkstyle", "checkstyle.xml")) || gradleFiles.some((file) => /\bcheckstyle\b/i.test(readTextFileSafe(file)));
23747
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradleCheckstyleSignal && (fs16.existsSync(path47.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
23653
23748
  return (hasMaven || hasGradleCheckstyleSignal) && hasBinary;
23654
23749
  }
23655
23750
  function hasRootKotlinFile(cwd) {
@@ -23660,24 +23755,24 @@ function hasRootKotlinFile(cwd) {
23660
23755
  }
23661
23756
  }
23662
23757
  function buildGradleHasKotlinSignal(cwd) {
23663
- const content = readTextFileSafe(path46.join(cwd, "build.gradle"));
23758
+ const content = readTextFileSafe(path47.join(cwd, "build.gradle"));
23664
23759
  return /\b(kotlin|org\.jetbrains\.kotlin|ktlint)\b/i.test(content);
23665
23760
  }
23666
23761
  function detectKtlint(cwd) {
23667
- const hasKotlin = fs16.existsSync(path46.join(cwd, "build.gradle.kts")) || fs16.existsSync(path46.join(cwd, "build.gradle")) && buildGradleHasKotlinSignal(cwd) || hasRootKotlinFile(cwd);
23762
+ const hasKotlin = fs16.existsSync(path47.join(cwd, "build.gradle.kts")) || fs16.existsSync(path47.join(cwd, "build.gradle")) && buildGradleHasKotlinSignal(cwd) || hasRootKotlinFile(cwd);
23668
23763
  return hasKotlin && isCommandAvailable("ktlint");
23669
23764
  }
23670
23765
  function detectPhpLinter(cwd) {
23671
- if ((fs16.existsSync(path46.join(cwd, "phpstan.neon")) || fs16.existsSync(path46.join(cwd, "phpstan.neon.dist"))) && phpVendorBinExists(cwd, "phpstan")) {
23766
+ if ((fs16.existsSync(path47.join(cwd, "phpstan.neon")) || fs16.existsSync(path47.join(cwd, "phpstan.neon.dist"))) && phpVendorBinExists(cwd, "phpstan")) {
23672
23767
  return "phpstan";
23673
23768
  }
23674
- if (fs16.existsSync(path46.join(cwd, "pint.json")) && phpVendorBinExists(cwd, "pint")) {
23769
+ if (fs16.existsSync(path47.join(cwd, "pint.json")) && phpVendorBinExists(cwd, "pint")) {
23675
23770
  return "pint";
23676
23771
  }
23677
- if (fs16.existsSync(path46.join(cwd, ".php-cs-fixer.php")) && phpVendorBinExists(cwd, "php-cs-fixer")) {
23772
+ if (fs16.existsSync(path47.join(cwd, ".php-cs-fixer.php")) && phpVendorBinExists(cwd, "php-cs-fixer")) {
23678
23773
  return "php-cs-fixer";
23679
23774
  }
23680
- if (fs16.existsSync(path46.join(cwd, "phpcs.xml")) && phpVendorBinExists(cwd, "phpcs")) {
23775
+ if (fs16.existsSync(path47.join(cwd, "phpcs.xml")) && phpVendorBinExists(cwd, "phpcs")) {
23681
23776
  return "phpcs";
23682
23777
  }
23683
23778
  return null;
@@ -23692,11 +23787,11 @@ function detectDotnetFormat(cwd) {
23692
23787
  }
23693
23788
  }
23694
23789
  function detectCppcheck(cwd) {
23695
- if (fs16.existsSync(path46.join(cwd, "CMakeLists.txt"))) {
23790
+ if (fs16.existsSync(path47.join(cwd, "CMakeLists.txt"))) {
23696
23791
  return isCommandAvailable("cppcheck");
23697
23792
  }
23698
23793
  try {
23699
- const dirsToCheck = [cwd, path46.join(cwd, "src")];
23794
+ const dirsToCheck = [cwd, path47.join(cwd, "src")];
23700
23795
  const hasCpp = dirsToCheck.some((dir) => {
23701
23796
  try {
23702
23797
  return fs16.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
@@ -23710,13 +23805,13 @@ function detectCppcheck(cwd) {
23710
23805
  }
23711
23806
  }
23712
23807
  function detectSwiftlint(cwd) {
23713
- return fs16.existsSync(path46.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
23808
+ return fs16.existsSync(path47.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
23714
23809
  }
23715
23810
  function detectDartAnalyze(cwd) {
23716
- return fs16.existsSync(path46.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
23811
+ return fs16.existsSync(path47.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
23717
23812
  }
23718
23813
  function detectRubocop(cwd) {
23719
- return (fs16.existsSync(path46.join(cwd, "Gemfile")) || fs16.existsSync(path46.join(cwd, "gems.rb")) || fs16.existsSync(path46.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
23814
+ return (fs16.existsSync(path47.join(cwd, "Gemfile")) || fs16.existsSync(path47.join(cwd, "gems.rb")) || fs16.existsSync(path47.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
23720
23815
  }
23721
23816
  function detectAdditionalLinter(cwd) {
23722
23817
  if (detectRuff(cwd))
@@ -23747,10 +23842,10 @@ function detectAdditionalLinter(cwd) {
23747
23842
  function findBinInAncestors(startDir, binName) {
23748
23843
  let dir = startDir;
23749
23844
  while (true) {
23750
- const candidate = path46.join(dir, "node_modules", ".bin", binName);
23845
+ const candidate = path47.join(dir, "node_modules", ".bin", binName);
23751
23846
  if (fs16.existsSync(candidate))
23752
23847
  return candidate;
23753
- const parent = path46.dirname(dir);
23848
+ const parent = path47.dirname(dir);
23754
23849
  if (parent === dir)
23755
23850
  break;
23756
23851
  dir = parent;
@@ -23759,10 +23854,10 @@ function findBinInAncestors(startDir, binName) {
23759
23854
  }
23760
23855
  function findBinInEnvPath(binName) {
23761
23856
  const searchPath = process.env.PATH ?? "";
23762
- for (const dir of searchPath.split(path46.delimiter)) {
23857
+ for (const dir of searchPath.split(path47.delimiter)) {
23763
23858
  if (!dir)
23764
23859
  continue;
23765
- const candidate = path46.join(dir, binName);
23860
+ const candidate = path47.join(dir, binName);
23766
23861
  if (fs16.existsSync(candidate))
23767
23862
  return candidate;
23768
23863
  }
@@ -23775,13 +23870,13 @@ async function detectAvailableLinter(directory) {
23775
23870
  return null;
23776
23871
  const projectDir = directory;
23777
23872
  const isWindows = process.platform === "win32";
23778
- const biomeBin = isWindows ? path46.join(projectDir, "node_modules", ".bin", "biome.EXE") : path46.join(projectDir, "node_modules", ".bin", "biome");
23779
- const eslintBin = isWindows ? path46.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path46.join(projectDir, "node_modules", ".bin", "eslint");
23873
+ const biomeBin = isWindows ? path47.join(projectDir, "node_modules", ".bin", "biome.EXE") : path47.join(projectDir, "node_modules", ".bin", "biome");
23874
+ const eslintBin = isWindows ? path47.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path47.join(projectDir, "node_modules", ".bin", "eslint");
23780
23875
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
23781
23876
  if (localResult)
23782
23877
  return localResult;
23783
- const biomeAncestor = findBinInAncestors(path46.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
23784
- const eslintAncestor = findBinInAncestors(path46.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
23878
+ const biomeAncestor = findBinInAncestors(path47.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
23879
+ const eslintAncestor = findBinInAncestors(path47.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
23785
23880
  if (biomeAncestor || eslintAncestor) {
23786
23881
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
23787
23882
  }
@@ -23995,7 +24090,7 @@ var _internals36 = {
23995
24090
 
23996
24091
  // src/tools/secretscan.ts
23997
24092
  import * as fs17 from "fs";
23998
- import * as path47 from "path";
24093
+ import * as path48 from "path";
23999
24094
  var MAX_FILE_PATH_LENGTH = 500;
24000
24095
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
24001
24096
  var MAX_FILES_SCANNED = 1000;
@@ -24222,7 +24317,7 @@ function isGlobOrPathPattern(pattern) {
24222
24317
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
24223
24318
  }
24224
24319
  function loadSecretScanIgnore(scanDir) {
24225
- const ignorePath = path47.join(scanDir, ".secretscanignore");
24320
+ const ignorePath = path48.join(scanDir, ".secretscanignore");
24226
24321
  try {
24227
24322
  if (!fs17.existsSync(ignorePath))
24228
24323
  return [];
@@ -24245,7 +24340,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
24245
24340
  if (exactNames.has(entry))
24246
24341
  return true;
24247
24342
  for (const pattern of globPatterns) {
24248
- if (path47.matchesGlob(relPath, pattern))
24343
+ if (path48.matchesGlob(relPath, pattern))
24249
24344
  return true;
24250
24345
  }
24251
24346
  return false;
@@ -24266,7 +24361,7 @@ function validateDirectoryInput(dir) {
24266
24361
  return null;
24267
24362
  }
24268
24363
  function isBinaryFile(filePath, buffer) {
24269
- const ext = path47.extname(filePath).toLowerCase();
24364
+ const ext = path48.extname(filePath).toLowerCase();
24270
24365
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
24271
24366
  return true;
24272
24367
  }
@@ -24403,9 +24498,9 @@ function isSymlinkLoop(realPath, visited) {
24403
24498
  return false;
24404
24499
  }
24405
24500
  function isPathWithinScope(realPath, scanDir) {
24406
- const resolvedScanDir = path47.resolve(scanDir);
24407
- const resolvedRealPath = path47.resolve(realPath);
24408
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path47.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
24501
+ const resolvedScanDir = path48.resolve(scanDir);
24502
+ const resolvedRealPath = path48.resolve(realPath);
24503
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path48.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
24409
24504
  }
24410
24505
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
24411
24506
  skippedDirs: 0,
@@ -24431,8 +24526,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24431
24526
  return a.localeCompare(b);
24432
24527
  });
24433
24528
  for (const entry of entries) {
24434
- const fullPath = path47.join(dir, entry);
24435
- const relPath = path47.relative(scanDir, fullPath).replace(/\\/g, "/");
24529
+ const fullPath = path48.join(dir, entry);
24530
+ const relPath = path48.relative(scanDir, fullPath).replace(/\\/g, "/");
24436
24531
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
24437
24532
  stats.skippedDirs++;
24438
24533
  continue;
@@ -24467,7 +24562,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
24467
24562
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
24468
24563
  files.push(...subFiles);
24469
24564
  } else if (lstat2.isFile()) {
24470
- const ext = path47.extname(fullPath).toLowerCase();
24565
+ const ext = path48.extname(fullPath).toLowerCase();
24471
24566
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
24472
24567
  files.push(fullPath);
24473
24568
  } else {
@@ -24533,7 +24628,7 @@ var secretscan = createSwarmTool({
24533
24628
  }
24534
24629
  }
24535
24630
  try {
24536
- const _scanDirRaw = path47.resolve(directory);
24631
+ const _scanDirRaw = path48.resolve(directory);
24537
24632
  const scanDir = (() => {
24538
24633
  try {
24539
24634
  return fs17.realpathSync(_scanDirRaw);
@@ -24699,12 +24794,12 @@ async function runSecretscanOnFiles(files, directory) {
24699
24794
  skippedFiles++;
24700
24795
  continue;
24701
24796
  }
24702
- const resolvedPath = path47.isAbsolute(file) ? path47.resolve(file) : path47.resolve(directory, file);
24797
+ const resolvedPath = path48.isAbsolute(file) ? path48.resolve(file) : path48.resolve(directory, file);
24703
24798
  if (!isPathWithinScope(resolvedPath, directory)) {
24704
24799
  skippedFiles++;
24705
24800
  continue;
24706
24801
  }
24707
- const ext = path47.extname(resolvedPath).toLowerCase();
24802
+ const ext = path48.extname(resolvedPath).toLowerCase();
24708
24803
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
24709
24804
  skippedFiles++;
24710
24805
  continue;
@@ -24755,11 +24850,11 @@ var _internals37 = {
24755
24850
 
24756
24851
  // src/tools/test-runner.ts
24757
24852
  import * as fs21 from "fs";
24758
- import * as path51 from "path";
24853
+ import * as path52 from "path";
24759
24854
 
24760
24855
  // src/test-impact/analyzer.ts
24761
24856
  import fs18 from "fs";
24762
- import path48 from "path";
24857
+ import path49 from "path";
24763
24858
  var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
24764
24859
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
24765
24860
  var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
@@ -24800,8 +24895,8 @@ function resolveRelativeImport(fromDir, importPath) {
24800
24895
  if (!importPath.startsWith(".")) {
24801
24896
  return null;
24802
24897
  }
24803
- const resolved = path48.resolve(fromDir, importPath);
24804
- if (path48.extname(resolved)) {
24898
+ const resolved = path49.resolve(fromDir, importPath);
24899
+ if (path49.extname(resolved)) {
24805
24900
  if (fs18.existsSync(resolved) && fs18.statSync(resolved).isFile()) {
24806
24901
  return normalizePath2(resolved);
24807
24902
  }
@@ -24821,20 +24916,20 @@ function resolvePythonImport(fromDir, module) {
24821
24916
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
24822
24917
  let baseDir = fromDir;
24823
24918
  for (let i = 1;i < leadingDots; i++) {
24824
- baseDir = path48.dirname(baseDir);
24919
+ baseDir = path49.dirname(baseDir);
24825
24920
  }
24826
24921
  const rest = module.slice(leadingDots);
24827
24922
  if (rest.length === 0) {
24828
- const initPath = path48.join(baseDir, "__init__.py");
24923
+ const initPath = path49.join(baseDir, "__init__.py");
24829
24924
  if (fs18.existsSync(initPath) && fs18.statSync(initPath).isFile()) {
24830
24925
  return normalizePath2(initPath);
24831
24926
  }
24832
24927
  return null;
24833
24928
  }
24834
- const subpath = rest.replace(/\./g, path48.sep);
24929
+ const subpath = rest.replace(/\./g, path49.sep);
24835
24930
  const candidates = [
24836
- `${path48.join(baseDir, subpath)}.py`,
24837
- path48.join(baseDir, subpath, "__init__.py")
24931
+ `${path49.join(baseDir, subpath)}.py`,
24932
+ path49.join(baseDir, subpath, "__init__.py")
24838
24933
  ];
24839
24934
  for (const c of candidates) {
24840
24935
  if (fs18.existsSync(c) && fs18.statSync(c).isFile())
@@ -24844,7 +24939,7 @@ function resolvePythonImport(fromDir, module) {
24844
24939
  }
24845
24940
  var goModuleCache = new Map;
24846
24941
  function findGoModule(fromDir) {
24847
- const resolved = path48.resolve(fromDir);
24942
+ const resolved = path49.resolve(fromDir);
24848
24943
  let cur = resolved;
24849
24944
  const walked = [];
24850
24945
  for (let i = 0;i < 16; i++) {
@@ -24856,7 +24951,7 @@ function findGoModule(fromDir) {
24856
24951
  }
24857
24952
  walked.push(cur);
24858
24953
  try {
24859
- const goMod = path48.join(cur, "go.mod");
24954
+ const goMod = path49.join(cur, "go.mod");
24860
24955
  const content = fs18.readFileSync(goMod, "utf-8");
24861
24956
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
24862
24957
  if (moduleMatch) {
@@ -24867,10 +24962,10 @@ function findGoModule(fromDir) {
24867
24962
  }
24868
24963
  } catch {}
24869
24964
  try {
24870
- fs18.accessSync(path48.join(cur, ".git"));
24965
+ fs18.accessSync(path49.join(cur, ".git"));
24871
24966
  break;
24872
24967
  } catch {}
24873
- const parent = path48.dirname(cur);
24968
+ const parent = path49.dirname(cur);
24874
24969
  if (parent === cur)
24875
24970
  break;
24876
24971
  cur = parent;
@@ -24882,12 +24977,12 @@ function findGoModule(fromDir) {
24882
24977
  function resolveGoImport(fromDir, importPath) {
24883
24978
  let dir = null;
24884
24979
  if (importPath.startsWith(".")) {
24885
- dir = path48.resolve(fromDir, importPath);
24980
+ dir = path49.resolve(fromDir, importPath);
24886
24981
  } else {
24887
24982
  const mod = findGoModule(fromDir);
24888
24983
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
24889
24984
  const subpath = importPath.slice(mod.modulePath.length);
24890
- dir = path48.join(mod.moduleRoot, subpath);
24985
+ dir = path49.join(mod.moduleRoot, subpath);
24891
24986
  }
24892
24987
  }
24893
24988
  if (dir === null)
@@ -24895,7 +24990,7 @@ function resolveGoImport(fromDir, importPath) {
24895
24990
  if (!fs18.existsSync(dir) || !fs18.statSync(dir).isDirectory())
24896
24991
  return [];
24897
24992
  try {
24898
- return fs18.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path48.join(dir, f)));
24993
+ return fs18.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path49.join(dir, f)));
24899
24994
  } catch {
24900
24995
  return [];
24901
24996
  }
@@ -24934,15 +25029,15 @@ function findTestFilesSync(cwd) {
24934
25029
  for (const entry of entries) {
24935
25030
  if (entry.isDirectory()) {
24936
25031
  if (!skipDirs.has(entry.name)) {
24937
- walk(path48.join(dir, entry.name), visitedInodes);
25032
+ walk(path49.join(dir, entry.name), visitedInodes);
24938
25033
  }
24939
25034
  } else if (entry.isFile()) {
24940
25035
  const name = entry.name;
24941
25036
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
24942
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path48.sep}tests${path48.sep}`) && name.endsWith(".py");
25037
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path49.sep}tests${path49.sep}`) && name.endsWith(".py");
24943
25038
  const isGoTest = /.+_test\.go$/.test(name);
24944
25039
  if (isTsTest || isPyTest || isGoTest) {
24945
- testFiles.push(normalizePath2(path48.join(dir, entry.name)));
25040
+ testFiles.push(normalizePath2(path49.join(dir, entry.name)));
24946
25041
  }
24947
25042
  }
24948
25043
  }
@@ -24967,8 +25062,8 @@ function extractImports(content) {
24967
25062
  ];
24968
25063
  }
24969
25064
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
24970
- const ext = path48.extname(testFile).toLowerCase();
24971
- const testDir = path48.dirname(testFile);
25065
+ const ext = path49.extname(testFile).toLowerCase();
25066
+ const testDir = path49.dirname(testFile);
24972
25067
  function addEdge(source) {
24973
25068
  if (!impactMap[source])
24974
25069
  impactMap[source] = [];
@@ -25042,7 +25137,7 @@ async function buildImpactMap(cwd) {
25042
25137
  return impactMap;
25043
25138
  }
25044
25139
  async function loadImpactMap(cwd, options) {
25045
- const cachePath = path48.join(cwd, ".swarm", "cache", "impact-map.json");
25140
+ const cachePath = path49.join(cwd, ".swarm", "cache", "impact-map.json");
25046
25141
  if (fs18.existsSync(cachePath)) {
25047
25142
  try {
25048
25143
  const content = fs18.readFileSync(cachePath, "utf-8");
@@ -25075,12 +25170,12 @@ async function loadImpactMap(cwd, options) {
25075
25170
  return _internals38.buildImpactMap(cwd);
25076
25171
  }
25077
25172
  async function saveImpactMap(cwd, impactMap) {
25078
- if (!path48.isAbsolute(cwd)) {
25173
+ if (!path49.isAbsolute(cwd)) {
25079
25174
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
25080
25175
  }
25081
25176
  _internals38.validateProjectRoot(cwd);
25082
- const cacheDir2 = path48.join(cwd, ".swarm", "cache");
25083
- const cachePath = path48.join(cacheDir2, "impact-map.json");
25177
+ const cacheDir2 = path49.join(cwd, ".swarm", "cache");
25178
+ const cachePath = path49.join(cacheDir2, "impact-map.json");
25084
25179
  if (!fs18.existsSync(cacheDir2)) {
25085
25180
  fs18.mkdirSync(cacheDir2, { recursive: true });
25086
25181
  }
@@ -25112,7 +25207,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
25112
25207
  budgetExceeded = true;
25113
25208
  break;
25114
25209
  }
25115
- const normalizedChanged = normalizePath2(path48.resolve(changedFile));
25210
+ const normalizedChanged = normalizePath2(path49.resolve(changedFile));
25116
25211
  const tests = impactMap[normalizedChanged];
25117
25212
  if (tests && tests.length > 0) {
25118
25213
  for (const test of tests) {
@@ -25126,13 +25221,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
25126
25221
  if (budgetExceeded)
25127
25222
  break;
25128
25223
  } else {
25129
- const changedDir = normalizePath2(path48.dirname(normalizedChanged));
25130
- const changedInputDir = normalizePath2(path48.dirname(changedFile));
25224
+ const changedDir = normalizePath2(path49.dirname(normalizedChanged));
25225
+ const changedInputDir = normalizePath2(path49.dirname(changedFile));
25131
25226
  const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
25132
25227
  return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
25133
25228
  }).sort(([sourceA], [sourceB]) => {
25134
- const sourceDirA = normalizePath2(path48.dirname(sourceA));
25135
- const sourceDirB = normalizePath2(path48.dirname(sourceB));
25229
+ const sourceDirA = normalizePath2(path49.dirname(sourceA));
25230
+ const sourceDirB = normalizePath2(path49.dirname(sourceB));
25136
25231
  const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
25137
25232
  const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
25138
25233
  if (exactA !== exactB)
@@ -25464,7 +25559,7 @@ function detectFlakyTests(allHistory) {
25464
25559
 
25465
25560
  // src/test-impact/history-store.ts
25466
25561
  import fs19 from "fs";
25467
- import path49 from "path";
25562
+ import path50 from "path";
25468
25563
  var MAX_HISTORY_PER_TEST = 20;
25469
25564
  var MAX_ERROR_LENGTH = 500;
25470
25565
  var MAX_STACK_LENGTH = 200;
@@ -25476,10 +25571,10 @@ function getHistoryPath(workingDir) {
25476
25571
  if (!workingDir) {
25477
25572
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
25478
25573
  }
25479
- if (!path49.isAbsolute(workingDir)) {
25574
+ if (!path50.isAbsolute(workingDir)) {
25480
25575
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
25481
25576
  }
25482
- return path49.join(workingDir, ".swarm", "cache", "test-history.jsonl");
25577
+ return path50.join(workingDir, ".swarm", "cache", "test-history.jsonl");
25483
25578
  }
25484
25579
  function sanitizeErrorMessage(errorMessage) {
25485
25580
  if (errorMessage === undefined) {
@@ -25571,7 +25666,7 @@ function batchAppendTestRuns(records, workingDir) {
25571
25666
  }
25572
25667
  }
25573
25668
  const historyPath = getHistoryPath(workingDir);
25574
- const historyDir = path49.dirname(historyPath);
25669
+ const historyDir = path50.dirname(historyPath);
25575
25670
  _internals39.validateProjectRoot(workingDir);
25576
25671
  if (!fs19.existsSync(historyDir)) {
25577
25672
  fs19.mkdirSync(historyDir, { recursive: true });
@@ -25701,7 +25796,7 @@ var _internals39 = {
25701
25796
 
25702
25797
  // src/tools/resolve-working-directory.ts
25703
25798
  import * as fs20 from "fs";
25704
- import * as path50 from "path";
25799
+ import * as path51 from "path";
25705
25800
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
25706
25801
  if (workingDirectory == null || workingDirectory === "") {
25707
25802
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
@@ -25738,8 +25833,8 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
25738
25833
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
25739
25834
  };
25740
25835
  }
25741
- const normalizedDir = path50.normalize(workingDirectory);
25742
- const resolvedDir = path50.resolve(normalizedDir);
25836
+ const normalizedDir = path51.normalize(workingDirectory);
25837
+ const resolvedDir = path51.resolve(normalizedDir);
25743
25838
  let statResult;
25744
25839
  try {
25745
25840
  statResult = fs20.statSync(resolvedDir);
@@ -25758,7 +25853,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
25758
25853
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
25759
25854
  return { success: true, directory: resolvedDir };
25760
25855
  }
25761
- const resolvedFallback = path50.resolve(fallbackDirectory);
25856
+ const resolvedFallback = path51.resolve(fallbackDirectory);
25762
25857
  let fallbackExists = false;
25763
25858
  try {
25764
25859
  fs20.statSync(resolvedFallback);
@@ -25767,7 +25862,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
25767
25862
  fallbackExists = false;
25768
25863
  }
25769
25864
  if (fallbackExists) {
25770
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path50.sep);
25865
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path51.sep);
25771
25866
  if (isSubdirectory) {
25772
25867
  return {
25773
25868
  success: false,
@@ -25790,7 +25885,7 @@ async function estimateFanOut(sourceFiles, cwd) {
25790
25885
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
25791
25886
  const uniqueTestFiles = new Set;
25792
25887
  for (const sourceFile of sourceFiles) {
25793
- const resolvedPath = path51.resolve(cwd, sourceFile);
25888
+ const resolvedPath = path52.resolve(cwd, sourceFile);
25794
25889
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
25795
25890
  const testFiles = impactMap[normalizedPath];
25796
25891
  if (testFiles) {
@@ -25875,14 +25970,14 @@ function hasDevDependency(devDeps, ...patterns) {
25875
25970
  return hasPackageJsonDependency(devDeps, ...patterns);
25876
25971
  }
25877
25972
  function detectGoTest(cwd) {
25878
- return fs21.existsSync(path51.join(cwd, "go.mod")) && isCommandAvailable("go");
25973
+ return fs21.existsSync(path52.join(cwd, "go.mod")) && isCommandAvailable("go");
25879
25974
  }
25880
25975
  function detectJavaMaven(cwd) {
25881
- return fs21.existsSync(path51.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
25976
+ return fs21.existsSync(path52.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
25882
25977
  }
25883
25978
  function detectGradle(cwd) {
25884
- const hasBuildFile = fs21.existsSync(path51.join(cwd, "build.gradle")) || fs21.existsSync(path51.join(cwd, "build.gradle.kts"));
25885
- const hasGradlew = fs21.existsSync(path51.join(cwd, "gradlew")) || fs21.existsSync(path51.join(cwd, "gradlew.bat"));
25979
+ const hasBuildFile = fs21.existsSync(path52.join(cwd, "build.gradle")) || fs21.existsSync(path52.join(cwd, "build.gradle.kts"));
25980
+ const hasGradlew = fs21.existsSync(path52.join(cwd, "gradlew")) || fs21.existsSync(path52.join(cwd, "gradlew.bat"));
25886
25981
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
25887
25982
  }
25888
25983
  function detectDotnetTest(cwd) {
@@ -25895,25 +25990,25 @@ function detectDotnetTest(cwd) {
25895
25990
  }
25896
25991
  }
25897
25992
  function detectCTest(cwd) {
25898
- const hasSource = fs21.existsSync(path51.join(cwd, "CMakeLists.txt"));
25899
- const hasBuildCache = fs21.existsSync(path51.join(cwd, "CMakeCache.txt")) || fs21.existsSync(path51.join(cwd, "build", "CMakeCache.txt"));
25993
+ const hasSource = fs21.existsSync(path52.join(cwd, "CMakeLists.txt"));
25994
+ const hasBuildCache = fs21.existsSync(path52.join(cwd, "CMakeCache.txt")) || fs21.existsSync(path52.join(cwd, "build", "CMakeCache.txt"));
25900
25995
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
25901
25996
  }
25902
25997
  function detectSwiftTest(cwd) {
25903
- return fs21.existsSync(path51.join(cwd, "Package.swift")) && isCommandAvailable("swift");
25998
+ return fs21.existsSync(path52.join(cwd, "Package.swift")) && isCommandAvailable("swift");
25904
25999
  }
25905
26000
  function detectDartTest(cwd) {
25906
- return fs21.existsSync(path51.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
26001
+ return fs21.existsSync(path52.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
25907
26002
  }
25908
26003
  function detectRSpec(cwd) {
25909
- const hasRSpecFile = fs21.existsSync(path51.join(cwd, ".rspec"));
25910
- const hasGemfile = fs21.existsSync(path51.join(cwd, "Gemfile"));
25911
- const hasSpecDir = fs21.existsSync(path51.join(cwd, "spec"));
26004
+ const hasRSpecFile = fs21.existsSync(path52.join(cwd, ".rspec"));
26005
+ const hasGemfile = fs21.existsSync(path52.join(cwd, "Gemfile"));
26006
+ const hasSpecDir = fs21.existsSync(path52.join(cwd, "spec"));
25912
26007
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
25913
26008
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
25914
26009
  }
25915
26010
  function detectMinitest(cwd) {
25916
- return fs21.existsSync(path51.join(cwd, "test")) && (fs21.existsSync(path51.join(cwd, "Gemfile")) || fs21.existsSync(path51.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
26011
+ return fs21.existsSync(path52.join(cwd, "test")) && (fs21.existsSync(path52.join(cwd, "Gemfile")) || fs21.existsSync(path52.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
25917
26012
  }
25918
26013
  var DISPATCH_FRAMEWORK_MAP = {
25919
26014
  bun: "bun",
@@ -26003,7 +26098,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
26003
26098
  async function detectTestFramework(cwd) {
26004
26099
  const baseDir = cwd;
26005
26100
  try {
26006
- const packageJsonPath = path51.join(baseDir, "package.json");
26101
+ const packageJsonPath = path52.join(baseDir, "package.json");
26007
26102
  if (fs21.existsSync(packageJsonPath)) {
26008
26103
  const content = fs21.readFileSync(packageJsonPath, "utf-8");
26009
26104
  const pkg = JSON.parse(content);
@@ -26024,16 +26119,16 @@ async function detectTestFramework(cwd) {
26024
26119
  return "jest";
26025
26120
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
26026
26121
  return "mocha";
26027
- if (fs21.existsSync(path51.join(baseDir, "bun.lockb")) || fs21.existsSync(path51.join(baseDir, "bun.lock"))) {
26122
+ if (fs21.existsSync(path52.join(baseDir, "bun.lockb")) || fs21.existsSync(path52.join(baseDir, "bun.lock"))) {
26028
26123
  if (scripts.test?.includes("bun"))
26029
26124
  return "bun";
26030
26125
  }
26031
26126
  }
26032
26127
  } catch {}
26033
26128
  try {
26034
- const pyprojectTomlPath = path51.join(baseDir, "pyproject.toml");
26035
- const setupCfgPath = path51.join(baseDir, "setup.cfg");
26036
- const requirementsTxtPath = path51.join(baseDir, "requirements.txt");
26129
+ const pyprojectTomlPath = path52.join(baseDir, "pyproject.toml");
26130
+ const setupCfgPath = path52.join(baseDir, "setup.cfg");
26131
+ const requirementsTxtPath = path52.join(baseDir, "requirements.txt");
26037
26132
  if (fs21.existsSync(pyprojectTomlPath)) {
26038
26133
  const content = fs21.readFileSync(pyprojectTomlPath, "utf-8");
26039
26134
  if (content.includes("[tool.pytest"))
@@ -26053,7 +26148,7 @@ async function detectTestFramework(cwd) {
26053
26148
  }
26054
26149
  } catch {}
26055
26150
  try {
26056
- const cargoTomlPath = path51.join(baseDir, "Cargo.toml");
26151
+ const cargoTomlPath = path52.join(baseDir, "Cargo.toml");
26057
26152
  if (fs21.existsSync(cargoTomlPath)) {
26058
26153
  const content = fs21.readFileSync(cargoTomlPath, "utf-8");
26059
26154
  if (content.includes("[dev-dependencies]")) {
@@ -26064,9 +26159,9 @@ async function detectTestFramework(cwd) {
26064
26159
  }
26065
26160
  } catch {}
26066
26161
  try {
26067
- const pesterConfigPath = path51.join(baseDir, "pester.config.ps1");
26068
- const pesterConfigJsonPath = path51.join(baseDir, "pester.config.ps1.json");
26069
- const pesterPs1Path = path51.join(baseDir, "tests.ps1");
26162
+ const pesterConfigPath = path52.join(baseDir, "pester.config.ps1");
26163
+ const pesterConfigJsonPath = path52.join(baseDir, "pester.config.ps1.json");
26164
+ const pesterPs1Path = path52.join(baseDir, "tests.ps1");
26070
26165
  if (fs21.existsSync(pesterConfigPath) || fs21.existsSync(pesterConfigJsonPath) || fs21.existsSync(pesterPs1Path)) {
26071
26166
  return "pester";
26072
26167
  }
@@ -26095,12 +26190,12 @@ async function detectTestFramework(cwd) {
26095
26190
  return "none";
26096
26191
  }
26097
26192
  function detectPhpTest(cwd) {
26098
- if (fs21.existsSync(path51.join(cwd, "artisan")) && fs21.existsSync(path51.join(cwd, "composer.json"))) {
26193
+ if (fs21.existsSync(path52.join(cwd, "artisan")) && fs21.existsSync(path52.join(cwd, "composer.json"))) {
26099
26194
  return "php-artisan";
26100
26195
  }
26101
- if (fs21.existsSync(path51.join(cwd, "Pest.php")))
26196
+ if (fs21.existsSync(path52.join(cwd, "Pest.php")))
26102
26197
  return "pest";
26103
- if (fs21.existsSync(path51.join(cwd, "phpunit.xml")) || fs21.existsSync(path51.join(cwd, "phpunit.xml.dist"))) {
26198
+ if (fs21.existsSync(path52.join(cwd, "phpunit.xml")) || fs21.existsSync(path52.join(cwd, "phpunit.xml.dist"))) {
26104
26199
  return "phpunit";
26105
26200
  }
26106
26201
  return null;
@@ -26123,12 +26218,12 @@ function isTestDirectoryPath(normalizedPath) {
26123
26218
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
26124
26219
  }
26125
26220
  function resolveWorkspacePath(file, workingDir) {
26126
- return path51.isAbsolute(file) ? path51.resolve(file) : path51.resolve(workingDir, file);
26221
+ return path52.isAbsolute(file) ? path52.resolve(file) : path52.resolve(workingDir, file);
26127
26222
  }
26128
26223
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
26129
26224
  if (!preferRelative)
26130
26225
  return absolutePath;
26131
- return path51.relative(workingDir, absolutePath);
26226
+ return path52.relative(workingDir, absolutePath);
26132
26227
  }
26133
26228
  function dedupePush(target, value) {
26134
26229
  if (!target.includes(value)) {
@@ -26171,18 +26266,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
26171
26266
  }
26172
26267
  }
26173
26268
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
26174
- const relativeDir = path51.dirname(relativePath);
26269
+ const relativeDir = path52.dirname(relativePath);
26175
26270
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
26176
26271
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
26177
- const rootDir = path51.join(workingDir, dirName);
26178
- return nestedRelativeDir ? [rootDir, path51.join(rootDir, nestedRelativeDir)] : [rootDir];
26272
+ const rootDir = path52.join(workingDir, dirName);
26273
+ return nestedRelativeDir ? [rootDir, path52.join(rootDir, nestedRelativeDir)] : [rootDir];
26179
26274
  });
26180
26275
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
26181
26276
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
26182
- directories.push(path51.join(workingDir, "src/test/java", path51.dirname(normalizedRelativePath.slice("src/main/java/".length))));
26277
+ directories.push(path52.join(workingDir, "src/test/java", path52.dirname(normalizedRelativePath.slice("src/main/java/".length))));
26183
26278
  }
26184
26279
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
26185
- directories.push(path51.join(workingDir, "src/test/kotlin", path51.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
26280
+ directories.push(path52.join(workingDir, "src/test/kotlin", path52.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
26186
26281
  }
26187
26282
  return [...new Set(directories)];
26188
26283
  }
@@ -26190,21 +26285,21 @@ function hasCompoundTestExtension(filename) {
26190
26285
  const lower = filename.toLowerCase();
26191
26286
  return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
26192
26287
  }
26193
- function isLanguageSpecificTestFile(basename11) {
26194
- const lower = basename11.toLowerCase();
26288
+ function isLanguageSpecificTestFile(basename12) {
26289
+ const lower = basename12.toLowerCase();
26195
26290
  if (lower.endsWith("_test.go"))
26196
26291
  return true;
26197
26292
  if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
26198
26293
  return true;
26199
26294
  if (lower.endsWith("_spec.rb"))
26200
26295
  return true;
26201
- if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename11) || basename11.endsWith("Test.java") || basename11.endsWith("Tests.java") || lower.endsWith("it.java")))
26296
+ if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename12) || basename12.endsWith("Test.java") || basename12.endsWith("Tests.java") || lower.endsWith("it.java")))
26202
26297
  return true;
26203
26298
  if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
26204
26299
  return true;
26205
- if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename11) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
26300
+ if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename12) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
26206
26301
  return true;
26207
- if (lower.endsWith(".php") && (/^Test[A-Z]/.test(basename11) || basename11.endsWith("Test.php") || basename11.endsWith("Tests.php")))
26302
+ if (lower.endsWith(".php") && (/^Test[A-Z]/.test(basename12) || basename12.endsWith("Test.php") || basename12.endsWith("Tests.php")))
26208
26303
  return true;
26209
26304
  if (lower.endsWith(".tests.ps1"))
26210
26305
  return true;
@@ -26212,23 +26307,23 @@ function isLanguageSpecificTestFile(basename11) {
26212
26307
  }
26213
26308
  function isConventionTestFilePath(filePath) {
26214
26309
  const normalizedPath = filePath.replace(/\\/g, "/");
26215
- const basename11 = path51.basename(filePath);
26216
- return hasCompoundTestExtension(basename11) || basename11.includes(".spec.") || basename11.includes(".test.") || isLanguageSpecificTestFile(basename11) || isTestDirectoryPath(normalizedPath);
26310
+ const basename12 = path52.basename(filePath);
26311
+ return hasCompoundTestExtension(basename12) || basename12.includes(".spec.") || basename12.includes(".test.") || isLanguageSpecificTestFile(basename12) || isTestDirectoryPath(normalizedPath);
26217
26312
  }
26218
26313
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
26219
26314
  const testFiles = [];
26220
26315
  for (const file of sourceFiles) {
26221
26316
  const absoluteFile = resolveWorkspacePath(file, workingDir);
26222
- const relativeFile = path51.relative(workingDir, absoluteFile);
26223
- const basename11 = path51.basename(absoluteFile);
26224
- const dirname25 = path51.dirname(absoluteFile);
26225
- const preferRelativeOutput = !path51.isAbsolute(file);
26317
+ const relativeFile = path52.relative(workingDir, absoluteFile);
26318
+ const basename12 = path52.basename(absoluteFile);
26319
+ const dirname25 = path52.dirname(absoluteFile);
26320
+ const preferRelativeOutput = !path52.isAbsolute(file);
26226
26321
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
26227
26322
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
26228
26323
  continue;
26229
26324
  }
26230
- const nameWithoutExt = basename11.replace(/\.[^.]+$/, "");
26231
- const ext = path51.extname(basename11);
26325
+ const nameWithoutExt = basename12.replace(/\.[^.]+$/, "");
26326
+ const ext = path52.extname(basename12);
26232
26327
  const genericTestNames = [
26233
26328
  `${nameWithoutExt}.spec${ext}`,
26234
26329
  `${nameWithoutExt}.test${ext}`
@@ -26237,17 +26332,17 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
26237
26332
  const colocatedCandidates = [
26238
26333
  ...genericTestNames,
26239
26334
  ...languageSpecificTestNames
26240
- ].map((candidateName) => path51.join(dirname25, candidateName));
26335
+ ].map((candidateName) => path52.join(dirname25, candidateName));
26241
26336
  const testDirectoryNames = [
26242
- basename11,
26337
+ basename12,
26243
26338
  ...genericTestNames,
26244
26339
  ...languageSpecificTestNames
26245
26340
  ];
26246
26341
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
26247
26342
  const possibleTestFiles = [
26248
26343
  ...colocatedCandidates,
26249
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path51.join(dirname25, dirName, candidateName))),
26250
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path51.join(candidateDir, candidateName)))
26344
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path52.join(dirname25, dirName, candidateName))),
26345
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path52.join(candidateDir, candidateName)))
26251
26346
  ];
26252
26347
  for (const testFile of possibleTestFiles) {
26253
26348
  if (fs21.existsSync(testFile)) {
@@ -26268,7 +26363,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26268
26363
  try {
26269
26364
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
26270
26365
  const content = fs21.readFileSync(absoluteTestFile, "utf-8");
26271
- const testDir = path51.dirname(absoluteTestFile);
26366
+ const testDir = path52.dirname(absoluteTestFile);
26272
26367
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
26273
26368
  let match;
26274
26369
  match = importRegex.exec(content);
@@ -26276,8 +26371,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26276
26371
  const importPath = match[1];
26277
26372
  let resolvedImport;
26278
26373
  if (importPath.startsWith(".")) {
26279
- resolvedImport = path51.resolve(testDir, importPath);
26280
- const existingExt = path51.extname(resolvedImport);
26374
+ resolvedImport = path52.resolve(testDir, importPath);
26375
+ const existingExt = path52.extname(resolvedImport);
26281
26376
  if (!existingExt) {
26282
26377
  for (const extToTry of [
26283
26378
  ".ts",
@@ -26297,12 +26392,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26297
26392
  } else {
26298
26393
  continue;
26299
26394
  }
26300
- const importBasename = path51.basename(resolvedImport, path51.extname(resolvedImport));
26301
- const importDir = path51.dirname(resolvedImport);
26395
+ const importBasename = path52.basename(resolvedImport, path52.extname(resolvedImport));
26396
+ const importDir = path52.dirname(resolvedImport);
26302
26397
  for (const sourceFile of absoluteSourceFiles) {
26303
- const sourceDir = path51.dirname(sourceFile);
26304
- const sourceBasename = path51.basename(sourceFile, path51.extname(sourceFile));
26305
- const isRelatedDir = importDir === sourceDir || importDir === path51.join(sourceDir, "__tests__") || importDir === path51.join(sourceDir, "tests") || importDir === path51.join(sourceDir, "test") || importDir === path51.join(sourceDir, "spec");
26398
+ const sourceDir = path52.dirname(sourceFile);
26399
+ const sourceBasename = path52.basename(sourceFile, path52.extname(sourceFile));
26400
+ const isRelatedDir = importDir === sourceDir || importDir === path52.join(sourceDir, "__tests__") || importDir === path52.join(sourceDir, "tests") || importDir === path52.join(sourceDir, "test") || importDir === path52.join(sourceDir, "spec");
26306
26401
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
26307
26402
  dedupePush(testFiles, testFile);
26308
26403
  break;
@@ -26315,8 +26410,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26315
26410
  while (match !== null) {
26316
26411
  const importPath = match[1];
26317
26412
  if (importPath.startsWith(".")) {
26318
- let resolvedImport = path51.resolve(testDir, importPath);
26319
- const existingExt = path51.extname(resolvedImport);
26413
+ let resolvedImport = path52.resolve(testDir, importPath);
26414
+ const existingExt = path52.extname(resolvedImport);
26320
26415
  if (!existingExt) {
26321
26416
  for (const extToTry of [
26322
26417
  ".ts",
@@ -26333,12 +26428,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
26333
26428
  }
26334
26429
  }
26335
26430
  }
26336
- const importDir = path51.dirname(resolvedImport);
26337
- const importBasename = path51.basename(resolvedImport, path51.extname(resolvedImport));
26431
+ const importDir = path52.dirname(resolvedImport);
26432
+ const importBasename = path52.basename(resolvedImport, path52.extname(resolvedImport));
26338
26433
  for (const sourceFile of absoluteSourceFiles) {
26339
- const sourceDir = path51.dirname(sourceFile);
26340
- const sourceBasename = path51.basename(sourceFile, path51.extname(sourceFile));
26341
- const isRelatedDir = importDir === sourceDir || importDir === path51.join(sourceDir, "__tests__") || importDir === path51.join(sourceDir, "tests") || importDir === path51.join(sourceDir, "test") || importDir === path51.join(sourceDir, "spec");
26434
+ const sourceDir = path52.dirname(sourceFile);
26435
+ const sourceBasename = path52.basename(sourceFile, path52.extname(sourceFile));
26436
+ const isRelatedDir = importDir === sourceDir || importDir === path52.join(sourceDir, "__tests__") || importDir === path52.join(sourceDir, "tests") || importDir === path52.join(sourceDir, "test") || importDir === path52.join(sourceDir, "spec");
26342
26437
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
26343
26438
  dedupePush(testFiles, testFile);
26344
26439
  break;
@@ -26458,8 +26553,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
26458
26553
  return ["mvn", "test"];
26459
26554
  case "gradle": {
26460
26555
  const isWindows = process.platform === "win32";
26461
- const hasGradlewBat = fs21.existsSync(path51.join(baseDir, "gradlew.bat"));
26462
- const hasGradlew = fs21.existsSync(path51.join(baseDir, "gradlew"));
26556
+ const hasGradlewBat = fs21.existsSync(path52.join(baseDir, "gradlew.bat"));
26557
+ const hasGradlew = fs21.existsSync(path52.join(baseDir, "gradlew"));
26463
26558
  if (hasGradlewBat && isWindows)
26464
26559
  return ["gradlew.bat", "test"];
26465
26560
  if (hasGradlew)
@@ -26476,7 +26571,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
26476
26571
  "cmake-build-release",
26477
26572
  "out"
26478
26573
  ];
26479
- const actualBuildDir = buildDirCandidates.find((d) => fs21.existsSync(path51.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
26574
+ const actualBuildDir = buildDirCandidates.find((d) => fs21.existsSync(path52.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
26480
26575
  return ["ctest", "--test-dir", actualBuildDir];
26481
26576
  }
26482
26577
  case "swift-test":
@@ -26526,7 +26621,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
26526
26621
  }
26527
26622
  }
26528
26623
  function phpVendorBin2(name) {
26529
- return path51.join("vendor", "bin", process.platform === "win32" ? `${name}.bat` : name);
26624
+ return path52.join("vendor", "bin", process.platform === "win32" ? `${name}.bat` : name);
26530
26625
  }
26531
26626
  function mapFrameworkStatusToResult(status) {
26532
26627
  if (typeof status !== "string")
@@ -26949,11 +27044,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
26949
27044
  };
26950
27045
  }
26951
27046
  const startTime = Date.now();
26952
- const vitestJsonOutputPath = framework === "vitest" ? path51.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
27047
+ const vitestJsonOutputPath = framework === "vitest" ? path52.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
26953
27048
  try {
26954
27049
  if (vitestJsonOutputPath) {
26955
27050
  try {
26956
- fs21.mkdirSync(path51.dirname(vitestJsonOutputPath), { recursive: true });
27051
+ fs21.mkdirSync(path52.dirname(vitestJsonOutputPath), { recursive: true });
26957
27052
  if (fs21.existsSync(vitestJsonOutputPath)) {
26958
27053
  fs21.unlinkSync(vitestJsonOutputPath);
26959
27054
  }
@@ -27122,10 +27217,10 @@ var SKIP_DIRECTORIES = new Set([
27122
27217
  ]);
27123
27218
  function normalizeHistoryTestFile(testFile, workingDir) {
27124
27219
  const normalized = testFile.replace(/\\/g, "/");
27125
- if (!path51.isAbsolute(testFile))
27220
+ if (!path52.isAbsolute(testFile))
27126
27221
  return normalized;
27127
- const relative6 = path51.relative(workingDir, testFile);
27128
- if (relative6.startsWith("..") || path51.isAbsolute(relative6)) {
27222
+ const relative6 = path52.relative(workingDir, testFile);
27223
+ if (relative6.startsWith("..") || path52.isAbsolute(relative6)) {
27129
27224
  return normalized;
27130
27225
  }
27131
27226
  return relative6.replace(/\\/g, "/");
@@ -27364,7 +27459,7 @@ var test_runner = createSwarmTool({
27364
27459
  const sourceFiles = args.files.filter((file) => {
27365
27460
  if (directTestFiles.includes(file))
27366
27461
  return false;
27367
- const ext = path51.extname(file).toLowerCase();
27462
+ const ext = path52.extname(file).toLowerCase();
27368
27463
  return SOURCE_EXTENSIONS.has(ext);
27369
27464
  });
27370
27465
  const invalidFiles = args.files.filter((file) => !directTestFiles.includes(file) && !sourceFiles.includes(file));
@@ -27410,7 +27505,7 @@ var test_runner = createSwarmTool({
27410
27505
  if (isConventionTestFilePath(f)) {
27411
27506
  return false;
27412
27507
  }
27413
- const ext = path51.extname(f).toLowerCase();
27508
+ const ext = path52.extname(f).toLowerCase();
27414
27509
  return SOURCE_EXTENSIONS.has(ext);
27415
27510
  });
27416
27511
  if (sourceFiles.length === 0) {
@@ -27460,7 +27555,7 @@ var test_runner = createSwarmTool({
27460
27555
  if (isConventionTestFilePath(f)) {
27461
27556
  return false;
27462
27557
  }
27463
- const ext = path51.extname(f).toLowerCase();
27558
+ const ext = path52.extname(f).toLowerCase();
27464
27559
  return SOURCE_EXTENSIONS.has(ext);
27465
27560
  });
27466
27561
  if (sourceFiles.length === 0) {
@@ -27512,8 +27607,8 @@ var test_runner = createSwarmTool({
27512
27607
  }
27513
27608
  if (impactResult.impactedTests.length > 0) {
27514
27609
  testFiles = impactResult.impactedTests.map((absPath) => {
27515
- const relativePath = path51.relative(workingDir, absPath);
27516
- return path51.isAbsolute(relativePath) ? absPath : relativePath;
27610
+ const relativePath = path52.relative(workingDir, absPath);
27611
+ return path52.isAbsolute(relativePath) ? absPath : relativePath;
27517
27612
  });
27518
27613
  } else {
27519
27614
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -27608,8 +27703,8 @@ function validateDirectoryPath(dir) {
27608
27703
  if (dir.includes("..")) {
27609
27704
  throw new Error("Directory path must not contain path traversal sequences");
27610
27705
  }
27611
- const normalized = path52.normalize(dir);
27612
- const absolutePath = path52.isAbsolute(normalized) ? normalized : path52.resolve(normalized);
27706
+ const normalized = path53.normalize(dir);
27707
+ const absolutePath = path53.isAbsolute(normalized) ? normalized : path53.resolve(normalized);
27613
27708
  return absolutePath;
27614
27709
  }
27615
27710
  function validateTimeout(timeoutMs, defaultValue) {
@@ -27632,7 +27727,7 @@ function validateTimeout(timeoutMs, defaultValue) {
27632
27727
  }
27633
27728
  function getPackageVersion(dir) {
27634
27729
  try {
27635
- const packagePath = path52.join(dir, "package.json");
27730
+ const packagePath = path53.join(dir, "package.json");
27636
27731
  if (fs22.existsSync(packagePath)) {
27637
27732
  const content = fs22.readFileSync(packagePath, "utf-8");
27638
27733
  const pkg = JSON.parse(content);
@@ -27643,7 +27738,7 @@ function getPackageVersion(dir) {
27643
27738
  }
27644
27739
  function getChangelogVersion(dir) {
27645
27740
  try {
27646
- const changelogPath = path52.join(dir, "CHANGELOG.md");
27741
+ const changelogPath = path53.join(dir, "CHANGELOG.md");
27647
27742
  if (fs22.existsSync(changelogPath)) {
27648
27743
  const content = fs22.readFileSync(changelogPath, "utf-8");
27649
27744
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
@@ -27657,7 +27752,7 @@ function getChangelogVersion(dir) {
27657
27752
  function getVersionFileVersion(dir) {
27658
27753
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
27659
27754
  for (const file of possibleFiles) {
27660
- const filePath = path52.join(dir, file);
27755
+ const filePath = path53.join(dir, file);
27661
27756
  if (fs22.existsSync(filePath)) {
27662
27757
  try {
27663
27758
  const content = fs22.readFileSync(filePath, "utf-8").trim();
@@ -28395,7 +28490,7 @@ async function handleQaGatesCommand(directory, args, sessionID) {
28395
28490
 
28396
28491
  // src/commands/reset.ts
28397
28492
  import * as fs23 from "fs";
28398
- import * as path53 from "path";
28493
+ import * as path54 from "path";
28399
28494
 
28400
28495
  // src/background/circuit-breaker.ts
28401
28496
  class CircuitBreaker {
@@ -29114,7 +29209,7 @@ async function handleResetCommand(directory, args) {
29114
29209
  }
29115
29210
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
29116
29211
  try {
29117
- const rootPath = path53.join(directory, filename);
29212
+ const rootPath = path54.join(directory, filename);
29118
29213
  if (fs23.existsSync(rootPath)) {
29119
29214
  fs23.unlinkSync(rootPath);
29120
29215
  results.push(`- \u2705 Deleted ${filename} (root)`);
@@ -29152,14 +29247,14 @@ async function handleResetCommand(directory, args) {
29152
29247
 
29153
29248
  // src/commands/reset-session.ts
29154
29249
  import * as fs26 from "fs";
29155
- import * as path56 from "path";
29250
+ import * as path57 from "path";
29156
29251
 
29157
29252
  // src/prm/trajectory-store.ts
29158
29253
  import * as fs24 from "fs/promises";
29159
- import * as path54 from "path";
29254
+ import * as path55 from "path";
29160
29255
  var MAX_TRACKED_TRAJECTORY_SESSIONS = 500;
29161
29256
  function getTrajectoryPath(sessionId, directory) {
29162
- const relativePath = path54.join("trajectories", `${sessionId}.jsonl`);
29257
+ const relativePath = path55.join("trajectories", `${sessionId}.jsonl`);
29163
29258
  return validateSwarmPath(directory, relativePath);
29164
29259
  }
29165
29260
  var _inMemoryTrajectoryCache = new Map;
@@ -29218,7 +29313,7 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
29218
29313
  for (const entry of entries) {
29219
29314
  if (!entry.isFile())
29220
29315
  continue;
29221
- const filePath = path54.join(dirPath, entry.name);
29316
+ const filePath = path55.join(dirPath, entry.name);
29222
29317
  try {
29223
29318
  const stat6 = await fs24.stat(filePath);
29224
29319
  if (now - stat6.mtimeMs > cutoffMs) {
@@ -29645,16 +29740,16 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
29645
29740
  }
29646
29741
  // src/prm/replay.ts
29647
29742
  import { promises as fs25 } from "fs";
29648
- import path55 from "path";
29743
+ import path56 from "path";
29649
29744
  function isPathSafe(targetPath, basePath) {
29650
- const resolvedTarget = path55.resolve(targetPath);
29651
- const resolvedBase = path55.resolve(basePath);
29652
- const rel = path55.relative(resolvedBase, resolvedTarget);
29653
- return !rel.startsWith("..") && !path55.isAbsolute(rel);
29745
+ const resolvedTarget = path56.resolve(targetPath);
29746
+ const resolvedBase = path56.resolve(basePath);
29747
+ const rel = path56.relative(resolvedBase, resolvedTarget);
29748
+ return !rel.startsWith("..") && !path56.isAbsolute(rel);
29654
29749
  }
29655
29750
  function isWithinReplaysDir(targetPath) {
29656
- const resolved = path55.resolve(targetPath);
29657
- const parts = resolved.split(path55.sep);
29751
+ const resolved = path56.resolve(targetPath);
29752
+ const parts = resolved.split(path56.sep);
29658
29753
  for (let i = 0;i < parts.length - 1; i++) {
29659
29754
  if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
29660
29755
  return true;
@@ -29667,10 +29762,10 @@ function sanitizeFilename(input) {
29667
29762
  }
29668
29763
  async function startReplayRecording(sessionID, directory) {
29669
29764
  try {
29670
- const replayDir = path55.join(directory, ".swarm", "replays");
29765
+ const replayDir = path56.join(directory, ".swarm", "replays");
29671
29766
  const safeSessionID = sanitizeFilename(sessionID);
29672
29767
  const filename = `${safeSessionID}-${Date.now()}.jsonl`;
29673
- const filepath = path55.join(replayDir, filename);
29768
+ const filepath = path56.join(replayDir, filename);
29674
29769
  if (!isPathSafe(filepath, replayDir)) {
29675
29770
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
29676
29771
  return null;
@@ -29752,7 +29847,7 @@ async function handleResetSessionCommand(directory, _args) {
29752
29847
  } catch {
29753
29848
  results.push("\u274C Failed to delete state.json");
29754
29849
  }
29755
- const sessionDir = statePath ? path56.dirname(statePath) : undefined;
29850
+ const sessionDir = statePath ? path57.dirname(statePath) : undefined;
29756
29851
  let sessionFiles = [];
29757
29852
  if (sessionDir && fs26.existsSync(sessionDir)) {
29758
29853
  try {
@@ -29764,7 +29859,7 @@ async function handleResetSessionCommand(directory, _args) {
29764
29859
  for (const file of sessionFiles) {
29765
29860
  if (file === "state.json")
29766
29861
  continue;
29767
- const filePath = path56.join(sessionDir, file);
29862
+ const filePath = path57.join(sessionDir, file);
29768
29863
  try {
29769
29864
  if (!fs26.existsSync(filePath))
29770
29865
  continue;
@@ -29786,7 +29881,7 @@ async function handleResetSessionCommand(directory, _args) {
29786
29881
  const chainCount = swarmState.delegationChains.size;
29787
29882
  swarmState.delegationChains.clear();
29788
29883
  results.push(`\u2705 Cleared ${chainCount} delegation chain(s)`);
29789
- const worktreesDir = path56.resolve(path56.dirname(directory), ".swarm-worktrees");
29884
+ const worktreesDir = path57.resolve(path57.dirname(directory), ".swarm-worktrees");
29790
29885
  try {
29791
29886
  if (fs26.existsSync(worktreesDir)) {
29792
29887
  fs26.rmSync(worktreesDir, { recursive: true, force: true });
@@ -29819,7 +29914,7 @@ async function handleResetSessionCommand(directory, _args) {
29819
29914
  }
29820
29915
 
29821
29916
  // src/summaries/manager.ts
29822
- import * as path57 from "path";
29917
+ import * as path58 from "path";
29823
29918
  var SUMMARY_ID_REGEX = /^S\d+$/;
29824
29919
  function sanitizeSummaryId(id) {
29825
29920
  if (!id || id.length === 0) {
@@ -29843,7 +29938,7 @@ function sanitizeSummaryId(id) {
29843
29938
  }
29844
29939
  async function loadFullOutput(directory, id) {
29845
29940
  const sanitizedId = sanitizeSummaryId(id);
29846
- const relativePath = path57.join("summaries", `${sanitizedId}.json`);
29941
+ const relativePath = path58.join("summaries", `${sanitizedId}.json`);
29847
29942
  validateSwarmPath(directory, relativePath);
29848
29943
  const content = await readSwarmFileAsync(directory, relativePath);
29849
29944
  if (content === null) {
@@ -29896,7 +29991,7 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
29896
29991
 
29897
29992
  // src/commands/rollback.ts
29898
29993
  import * as fs27 from "fs";
29899
- import * as path58 from "path";
29994
+ import * as path59 from "path";
29900
29995
  function safeParseToolJson(result) {
29901
29996
  try {
29902
29997
  const jsonStr = typeof result === "string" ? result : result.output;
@@ -30051,8 +30146,8 @@ async function handleRollbackCommand(directory, args) {
30051
30146
  if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
30052
30147
  continue;
30053
30148
  }
30054
- const src = path58.join(checkpointDir, file);
30055
- const dest = path58.join(swarmDir, file);
30149
+ const src = path59.join(checkpointDir, file);
30150
+ const dest = path59.join(swarmDir, file);
30056
30151
  try {
30057
30152
  fs27.cpSync(src, dest, { recursive: true, force: true });
30058
30153
  successes.push(file);
@@ -30071,7 +30166,7 @@ async function handleRollbackCommand(directory, args) {
30071
30166
  ].join(`
30072
30167
  `);
30073
30168
  }
30074
- const existingLedgerPath = path58.join(swarmDir, "plan-ledger.jsonl");
30169
+ const existingLedgerPath = path59.join(swarmDir, "plan-ledger.jsonl");
30075
30170
  let ledgerDeletionFailed = false;
30076
30171
  if (fs27.existsSync(existingLedgerPath)) {
30077
30172
  try {
@@ -30084,7 +30179,7 @@ async function handleRollbackCommand(directory, args) {
30084
30179
  }
30085
30180
  if (!ledgerDeletionFailed) {
30086
30181
  try {
30087
- const planJsonPath = path58.join(swarmDir, "plan.json");
30182
+ const planJsonPath = path59.join(swarmDir, "plan.json");
30088
30183
  if (fs27.existsSync(planJsonPath)) {
30089
30184
  const planRaw = fs27.readFileSync(planJsonPath, "utf-8");
30090
30185
  const plan = PlanSchema.parse(JSON.parse(planRaw));
@@ -30132,11 +30227,11 @@ async function handleRollbackCommand(directory, args) {
30132
30227
 
30133
30228
  // src/commands/sdd.ts
30134
30229
  import * as fs28 from "fs";
30135
- import * as path59 from "path";
30230
+ import * as path60 from "path";
30136
30231
  var _internals43 = {
30137
30232
  writeProjectedSpecSync
30138
30233
  };
30139
- var SWARM_SPEC_REL = path59.join(".swarm", "spec.md");
30234
+ var SWARM_SPEC_REL = path60.join(".swarm", "spec.md");
30140
30235
  var USAGE9 = `Usage:
30141
30236
  /swarm sdd status [--json] [--source <provider>]
30142
30237
  /swarm sdd validate [--json] [--change <id>] [--source <provider>] [--feature <id>]
@@ -30258,7 +30353,7 @@ ${USAGE9}`;
30258
30353
  }
30259
30354
  const speckitDetection = detectSpeckit(directory);
30260
30355
  const speckitPresent = speckitDetection.features.length > 0;
30261
- const nativeSpecExists = fs28.existsSync(path59.join(directory, SWARM_SPEC_REL));
30356
+ const nativeSpecExists = fs28.existsSync(path60.join(directory, SWARM_SPEC_REL));
30262
30357
  if (speckitPresent && !parsed.source && !nativeSpecExists) {
30263
30358
  const openspecProjection = buildOpenSpecProjectionSync(directory);
30264
30359
  if (openspecProjection !== null) {
@@ -30328,7 +30423,7 @@ ${USAGE9}`;
30328
30423
  ${USAGE9}`;
30329
30424
  }
30330
30425
  let useSpeckit = false;
30331
- const nativeSpecExists = fs28.existsSync(path59.join(directory, SWARM_SPEC_REL));
30426
+ const nativeSpecExists = fs28.existsSync(path60.join(directory, SWARM_SPEC_REL));
30332
30427
  if (parsed.source === "speckit") {
30333
30428
  useSpeckit = true;
30334
30429
  } else if (!parsed.source && !nativeSpecExists) {
@@ -30482,7 +30577,7 @@ ${USAGE9}`;
30482
30577
  ${USAGE9}`;
30483
30578
  }
30484
30579
  if (!parsed.dryRun) {
30485
- const nativeSpecPath = path59.join(directory, SWARM_SPEC_REL);
30580
+ const nativeSpecPath = path60.join(directory, SWARM_SPEC_REL);
30486
30581
  if (fs28.existsSync(nativeSpecPath)) {
30487
30582
  if (!parsed.overwrite) {
30488
30583
  return [
@@ -30698,10 +30793,10 @@ Ensure this is a git repository with commit history.`;
30698
30793
  `);
30699
30794
  try {
30700
30795
  const fs29 = await import("fs/promises");
30701
- const path60 = await import("path");
30702
- const reportPath = path60.join(directory, ".swarm", "simulate-report.md");
30703
- await fs29.mkdir(path60.dirname(reportPath), { recursive: true });
30704
- const reportTempPath = path60.join(path60.dirname(reportPath), `${path60.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
30796
+ const path61 = await import("path");
30797
+ const reportPath = path61.join(directory, ".swarm", "simulate-report.md");
30798
+ await fs29.mkdir(path61.dirname(reportPath), { recursive: true });
30799
+ const reportTempPath = path61.join(path61.dirname(reportPath), `${path61.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
30705
30800
  try {
30706
30801
  await fs29.writeFile(reportTempPath, report, "utf-8");
30707
30802
  renameSync10(reportTempPath, reportPath);
@@ -30730,7 +30825,7 @@ async function handleSpecifyCommand(_directory, args) {
30730
30825
  // src/services/status-service.ts
30731
30826
  import * as fsSync2 from "fs";
30732
30827
  import { readFile as readFile17 } from "fs/promises";
30733
- import * as path61 from "path";
30828
+ import * as path62 from "path";
30734
30829
 
30735
30830
  // src/hooks/extractors.ts
30736
30831
  function extractCurrentPhase(planContent) {
@@ -30775,13 +30870,13 @@ function extractCurrentPhaseFromPlan2(plan) {
30775
30870
  // src/turbo/lean/state.ts
30776
30871
  init_logger();
30777
30872
  import * as fs29 from "fs";
30778
- import * as path60 from "path";
30873
+ import * as path61 from "path";
30779
30874
  var STATE_FILE3 = "turbo-state.json";
30780
30875
  function nowISO3() {
30781
30876
  return new Date().toISOString();
30782
30877
  }
30783
30878
  function ensureSwarmDir2(directory) {
30784
- const swarmDir = path60.resolve(directory, ".swarm");
30879
+ const swarmDir = path61.resolve(directory, ".swarm");
30785
30880
  if (!fs29.existsSync(swarmDir)) {
30786
30881
  fs29.mkdirSync(swarmDir, { recursive: true });
30787
30882
  }
@@ -30826,7 +30921,7 @@ function markStateUnreadable2(directory, reason) {
30826
30921
  }
30827
30922
  function readPersisted2(directory) {
30828
30923
  try {
30829
- const filePath = path60.join(directory, ".swarm", STATE_FILE3);
30924
+ const filePath = path61.join(directory, ".swarm", STATE_FILE3);
30830
30925
  if (!fs29.existsSync(filePath)) {
30831
30926
  const seed = emptyPersisted2();
30832
30927
  try {
@@ -30862,7 +30957,7 @@ function writePersisted2(directory, persisted) {
30862
30957
  let payload;
30863
30958
  try {
30864
30959
  ensureSwarmDir2(directory);
30865
- filePath = path60.join(directory, ".swarm", STATE_FILE3);
30960
+ filePath = path61.join(directory, ".swarm", STATE_FILE3);
30866
30961
  tmpPath = `${filePath}.tmp.${Date.now()}`;
30867
30962
  persisted.updatedAt = nowISO3();
30868
30963
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -30980,7 +31075,7 @@ var _internals44 = {
30980
31075
  };
30981
31076
  function readSpecStalenessSnapshot(directory) {
30982
31077
  try {
30983
- const p = path61.join(directory, ".swarm", "spec-staleness.json");
31078
+ const p = path62.join(directory, ".swarm", "spec-staleness.json");
30984
31079
  if (!fsSync2.existsSync(p))
30985
31080
  return { stale: false };
30986
31081
  const raw = fsSync2.readFileSync(p, "utf-8");
@@ -31513,11 +31608,11 @@ function buildStatusMessage2(session, directory, sessionID) {
31513
31608
 
31514
31609
  // src/commands/unlink.ts
31515
31610
  import { existsSync as existsSync40 } from "fs";
31516
- import * as path62 from "path";
31611
+ import * as path63 from "path";
31517
31612
  var DEDUP_THRESHOLD2 = 0.6;
31518
31613
  async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
31519
- const sharedPath = path62.join(linkDir, "knowledge.jsonl");
31520
- const localPath = path62.join(localSwarmDir, "knowledge.jsonl");
31614
+ const sharedPath = path63.join(linkDir, "knowledge.jsonl");
31615
+ const localPath = path63.join(localSwarmDir, "knowledge.jsonl");
31521
31616
  if (!existsSync40(sharedPath))
31522
31617
  return 0;
31523
31618
  const sharedEntries = await readKnowledge(sharedPath);
@@ -31552,7 +31647,7 @@ async function handleUnlinkCommand(directory, args) {
31552
31647
  let copied = 0;
31553
31648
  if (copyBack) {
31554
31649
  try {
31555
- copied = await copySharedKnowledgeToLocal(linkDir, path62.join(directory, ".swarm"));
31650
+ copied = await copySharedKnowledgeToLocal(linkDir, path63.join(directory, ".swarm"));
31556
31651
  } catch (error2) {
31557
31652
  return `\u274C Failed to copy shared knowledge back to local: ${error2 instanceof Error ? error2.message : String(error2)}`;
31558
31653
  }
@@ -31714,7 +31809,7 @@ function buildDetailedHelp(commandName, entry) {
31714
31809
  async function handleHelpCommand(ctx) {
31715
31810
  const targetCommand = ctx.args.join(" ");
31716
31811
  if (!targetCommand) {
31717
- const { buildHelpText } = await import("./index-3qwaydq1.js");
31812
+ const { buildHelpText } = await import("./index-3nd7bz90.js");
31718
31813
  return buildHelpText();
31719
31814
  }
31720
31815
  const tokens = targetCommand.split(/\s+/);
@@ -31723,7 +31818,7 @@ async function handleHelpCommand(ctx) {
31723
31818
  return _internals46.buildDetailedHelp(resolved.key, resolved.entry);
31724
31819
  }
31725
31820
  const similar = _internals46.findSimilarCommands(targetCommand);
31726
- const { buildHelpText: fullHelp } = await import("./index-3qwaydq1.js");
31821
+ const { buildHelpText: fullHelp } = await import("./index-3nd7bz90.js");
31727
31822
  if (similar.length > 0) {
31728
31823
  return `Command '/swarm ${targetCommand}' not found.
31729
31824
 
@@ -31856,7 +31951,7 @@ var COMMAND_REGISTRY = {
31856
31951
  },
31857
31952
  "guardrail explain": {
31858
31953
  handler: async (ctx) => {
31859
- const { handleGuardrailExplain } = await import("./guardrail-explain-ynge4ww3.js");
31954
+ const { handleGuardrailExplain } = await import("./guardrail-explain-csnawe0d.js");
31860
31955
  return handleGuardrailExplain(ctx.directory, ctx.args);
31861
31956
  },
31862
31957
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -32646,24 +32741,24 @@ function validateAliases() {
32646
32741
  continue;
32647
32742
  }
32648
32743
  const visited = new Set;
32649
- const path63 = [];
32744
+ const path64 = [];
32650
32745
  let current = target;
32651
32746
  while (current) {
32652
32747
  const currentEntry = COMMAND_REGISTRY[current];
32653
32748
  if (!currentEntry)
32654
32749
  break;
32655
32750
  if (visited.has(current)) {
32656
- const cycleStart = path63.indexOf(current);
32751
+ const cycleStart = path64.indexOf(current);
32657
32752
  const fullChain = [
32658
32753
  name,
32659
- ...path63.slice(0, cycleStart > 0 ? cycleStart : path63.length),
32754
+ ...path64.slice(0, cycleStart > 0 ? cycleStart : path64.length),
32660
32755
  current
32661
32756
  ].join(" \u2192 ");
32662
32757
  errors.push(`Circular alias detected: ${fullChain}`);
32663
32758
  break;
32664
32759
  }
32665
32760
  visited.add(current);
32666
- path63.push(current);
32761
+ path64.push(current);
32667
32762
  current = currentEntry.aliasOf || "";
32668
32763
  }
32669
32764
  }
@@ -34002,7 +34097,7 @@ init_logger();
34002
34097
 
34003
34098
  // src/hooks/guardrails/destructive-command.ts
34004
34099
  import * as fsSync3 from "fs";
34005
- import * as path63 from "path";
34100
+ import * as path64 from "path";
34006
34101
  var DC_MAX_UNWRAP_DEPTH = 5;
34007
34102
  var DC_SAFE_TARGETS = new Set([
34008
34103
  "node_modules",
@@ -34166,16 +34261,16 @@ function dcIsRemotePath(p) {
34166
34261
  return DC_REMOTE_PREFIXES.some((pfx) => p.startsWith(pfx));
34167
34262
  }
34168
34263
  function dcLstatAncestorWalk(targetPath, cwd) {
34169
- const normalizedTarget = path63.resolve(cwd, targetPath);
34170
- const normalizedCwd = path63.resolve(cwd);
34264
+ const normalizedTarget = path64.resolve(cwd, targetPath);
34265
+ const normalizedCwd = path64.resolve(cwd);
34171
34266
  const ancestors = [];
34172
34267
  let current = normalizedTarget;
34173
34268
  while (true) {
34174
34269
  ancestors.push(current);
34175
- const parent = path63.dirname(current);
34270
+ const parent = path64.dirname(current);
34176
34271
  if (parent === current)
34177
34272
  break;
34178
- const rel = path63.relative(normalizedCwd, current);
34273
+ const rel = path64.relative(normalizedCwd, current);
34179
34274
  if (rel === "" || rel.startsWith(".."))
34180
34275
  break;
34181
34276
  current = parent;
@@ -34214,14 +34309,14 @@ function dcValidateTargets(targets, cwd) {
34214
34309
  const lstatBlock = dcLstatAncestorWalk(t, cwd);
34215
34310
  if (lstatBlock)
34216
34311
  return lstatBlock;
34217
- const basename12 = path63.basename(t);
34218
- if (t === basename12 && DC_SAFE_TARGETS.has(t)) {
34312
+ const basename13 = path64.basename(t);
34313
+ if (t === basename13 && DC_SAFE_TARGETS.has(t)) {
34219
34314
  continue;
34220
34315
  }
34221
34316
  if (DC_FS_ROOTS.has(t) || DC_FS_ROOTS.has(t.replace(/\//g, "\\"))) {
34222
34317
  return `BLOCKED: Destructive command targets filesystem root "${t}"`;
34223
34318
  }
34224
- if (path63.isAbsolute(t) || /^[A-Za-z]:/.test(t)) {
34319
+ if (path64.isAbsolute(t) || /^[A-Za-z]:/.test(t)) {
34225
34320
  for (const blocked of DC_BLOCKED_ABSOLUTE_PREFIXES) {
34226
34321
  if (t.startsWith(blocked)) {
34227
34322
  return `BLOCKED: Destructive command targets system path "${t}" which is under protected prefix "${blocked}"`;
@@ -34236,9 +34331,9 @@ function dcCheckJunctionCreation(segment, cwd) {
34236
34331
  if (mklinkMatch) {
34237
34332
  const target = mklinkMatch[2].trim();
34238
34333
  if (!dcHasUnresolvableVars(target)) {
34239
- const resolved = path63.resolve(cwd, target);
34240
- const rel = path63.relative(cwd, resolved);
34241
- if (rel.startsWith("..") || path63.isAbsolute(rel)) {
34334
+ const resolved = path64.resolve(cwd, target);
34335
+ const rel = path64.relative(cwd, resolved);
34336
+ if (rel.startsWith("..") || path64.isAbsolute(rel)) {
34242
34337
  return `BLOCKED: Junction/symlink creation targeting path outside working directory: mklink target "${target}" resolves to "${resolved}" which is outside "${cwd}". Creating junctions to external paths and then deleting them recursively can destroy data.`;
34243
34338
  }
34244
34339
  }
@@ -34250,9 +34345,9 @@ function dcCheckJunctionCreation(segment, cwd) {
34250
34345
  if (newItemMatch) {
34251
34346
  const target = newItemMatch[1].trim();
34252
34347
  if (!dcHasUnresolvableVars(target)) {
34253
- const resolved = path63.resolve(cwd, target);
34254
- const rel = path63.relative(cwd, resolved);
34255
- if (rel.startsWith("..") || path63.isAbsolute(rel)) {
34348
+ const resolved = path64.resolve(cwd, target);
34349
+ const rel = path64.relative(cwd, resolved);
34350
+ if (rel.startsWith("..") || path64.isAbsolute(rel)) {
34256
34351
  return `BLOCKED: Junction/symlink creation targeting path outside working directory: New-Item target "${target}" resolves to "${resolved}" which is outside "${cwd}". This pattern caused the K2.6 data-loss incident.`;
34257
34352
  }
34258
34353
  }
@@ -34262,9 +34357,9 @@ function dcCheckJunctionCreation(segment, cwd) {
34262
34357
  if (lnMatch) {
34263
34358
  const target = lnMatch[1].trim();
34264
34359
  if (!dcHasUnresolvableVars(target)) {
34265
- const resolved = path63.resolve(cwd, target);
34266
- const rel = path63.relative(cwd, resolved);
34267
- if (rel.startsWith("..") || path63.isAbsolute(rel)) {
34360
+ const resolved = path64.resolve(cwd, target);
34361
+ const rel = path64.relative(cwd, resolved);
34362
+ if (rel.startsWith("..") || path64.isAbsolute(rel)) {
34268
34363
  return `BLOCKED: Symlink creation targeting path outside working directory: ln -s target "${target}" resolves to "${resolved}" which is outside "${cwd}". Symlinks to external paths combined with recursive deletion can destroy data.`;
34269
34364
  }
34270
34365
  }
@@ -34635,10 +34730,10 @@ function classifySwarmCommandChatFallbackUse(resolved) {
34635
34730
  init_executor();
34636
34731
 
34637
34732
  // src/hooks/shell-write-detect.ts
34638
- import * as path64 from "path";
34733
+ import * as path65 from "path";
34639
34734
  import parse from "bash-parser";
34640
- function buildDedupeKey(category, operator, path65) {
34641
- return `${category}|${operator}|${path65 ?? "null"}`;
34735
+ function buildDedupeKey(category, operator, path66) {
34736
+ return `${category}|${operator}|${path66 ?? "null"}`;
34642
34737
  }
34643
34738
  var REDIRECT_WRITE_TOKENS = new Set([
34644
34739
  "GREAT",
@@ -34698,16 +34793,16 @@ function detectProcessSubstitutionWrites(command) {
34698
34793
  results.push(builtinResult);
34699
34794
  const appendMatch = stage.match(/^\s*(.*?)\s*>>(\s*)(\S+)\s*$/);
34700
34795
  if (appendMatch) {
34701
- const path65 = appendMatch[3];
34702
- if (path65 && !isNullDevice(path65)) {
34703
- results.push({ category: "redirect", operator: ">>", path: path65 });
34796
+ const path66 = appendMatch[3];
34797
+ if (path66 && !isNullDevice(path66)) {
34798
+ results.push({ category: "redirect", operator: ">>", path: path66 });
34704
34799
  }
34705
34800
  } else {
34706
34801
  const writeMatch = stage.match(/^\s*(.*?)\s*>(?!>)(\s*)(\S+)\s*$/);
34707
34802
  if (writeMatch) {
34708
- const path65 = writeMatch[3];
34709
- if (path65 && !isNullDevice(path65)) {
34710
- results.push({ category: "redirect", operator: ">", path: path65 });
34803
+ const path66 = writeMatch[3];
34804
+ if (path66 && !isNullDevice(path66)) {
34805
+ results.push({ category: "redirect", operator: ">", path: path66 });
34711
34806
  }
34712
34807
  }
34713
34808
  }
@@ -34881,8 +34976,8 @@ function extractRedirectPath(fileNode) {
34881
34976
  return null;
34882
34977
  return text;
34883
34978
  }
34884
- function isNullDevice(path65) {
34885
- return path65 === "/dev/null" || path65 === "/dev/zero" || path65 === "/dev/urandom";
34979
+ function isNullDevice(path66) {
34980
+ return path66 === "/dev/null" || path66 === "/dev/zero" || path66 === "/dev/urandom";
34886
34981
  }
34887
34982
  function isNumeric(s) {
34888
34983
  return /^\d+$/.test(s);
@@ -34902,12 +34997,12 @@ function detectRedirects(cmd) {
34902
34997
  if (!opType || !REDIRECT_ALL_WRITE_TOKENS.has(opType))
34903
34998
  continue;
34904
34999
  const fileNode = r.file;
34905
- const path65 = extractRedirectPath(fileNode);
35000
+ const path66 = extractRedirectPath(fileNode);
34906
35001
  const opLabel = operatorLabel(opNode);
34907
35002
  if (REDIRECT_WRITE_TOKENS.has(opType)) {
34908
- results.push({ category: "redirect", operator: opLabel, path: path65 });
35003
+ results.push({ category: "redirect", operator: opLabel, path: path66 });
34909
35004
  } else if (REDIRECT_HERE_TOKENS.has(opType)) {
34910
- results.push({ category: "here_doc", operator: opLabel, path: path65 });
35005
+ results.push({ category: "here_doc", operator: opLabel, path: path66 });
34911
35006
  }
34912
35007
  }
34913
35008
  return results;
@@ -34950,9 +35045,9 @@ function detectBuiltinWrites(cmd) {
34950
35045
  const suffixWords2 = getSuffixWords(cmd);
34951
35046
  for (const word of suffixWords2) {
34952
35047
  if (word.startsWith("of=")) {
34953
- const path65 = word.slice(3);
34954
- if (path65 && !isNullDevice(path65)) {
34955
- results.push({ category: "builtin_write", operator: "dd of=", path: path65 });
35048
+ const path66 = word.slice(3);
35049
+ if (path66 && !isNullDevice(path66)) {
35050
+ results.push({ category: "builtin_write", operator: "dd of=", path: path66 });
34956
35051
  }
34957
35052
  }
34958
35053
  }
@@ -35071,12 +35166,12 @@ function detectNetworkDownloaders(cmd) {
35071
35166
  for (let i = 0;i < suffixWords.length; i++) {
35072
35167
  const word = suffixWords[i];
35073
35168
  if (word === "-o" && i + 1 < suffixWords.length) {
35074
- const path65 = suffixWords[i + 1];
35075
- if (!path65.startsWith("-")) {
35169
+ const path66 = suffixWords[i + 1];
35170
+ if (!path66.startsWith("-")) {
35076
35171
  results.push({
35077
35172
  category: "network_download",
35078
35173
  operator: "curl -o",
35079
- path: path65
35174
+ path: path66
35080
35175
  });
35081
35176
  }
35082
35177
  } else if (word.startsWith("-o") && word.length > 2) {
@@ -35091,12 +35186,12 @@ function detectNetworkDownloaders(cmd) {
35091
35186
  for (let i = 0;i < suffixWords.length; i++) {
35092
35187
  const word = suffixWords[i];
35093
35188
  if (word === "-O" && i + 1 < suffixWords.length) {
35094
- const path65 = suffixWords[i + 1];
35095
- if (!path65.startsWith("-")) {
35189
+ const path66 = suffixWords[i + 1];
35190
+ if (!path66.startsWith("-")) {
35096
35191
  results.push({
35097
35192
  category: "network_download",
35098
35193
  operator: "wget -O",
35099
- path: path65
35194
+ path: path66
35100
35195
  });
35101
35196
  }
35102
35197
  } else if (word.startsWith("-O") && word.length > 2) {
@@ -35205,9 +35300,9 @@ function detectGitDestructive(cmd) {
35205
35300
  if (first === "checkout") {
35206
35301
  const dashDashIdx = suffixWords.indexOf("--");
35207
35302
  if (dashDashIdx !== -1 && dashDashIdx + 1 < suffixWords.length) {
35208
- const path65 = suffixWords[dashDashIdx + 1];
35209
- const op = path65 === "." ? "git checkout -- ." : "git checkout --";
35210
- results.push({ category: "git_destructive", operator: op, path: path65 });
35303
+ const path66 = suffixWords[dashDashIdx + 1];
35304
+ const op = path66 === "." ? "git checkout -- ." : "git checkout --";
35305
+ results.push({ category: "git_destructive", operator: op, path: path66 });
35211
35306
  }
35212
35307
  } else if (first === "restore") {
35213
35308
  const hasHard = suffixWords.some((w) => w === "--hard" || w === "-H" || w.startsWith("-") && w.includes("H"));
@@ -35327,10 +35422,10 @@ function detectPowerShellWrites(command) {
35327
35422
  if (redirectMatch) {
35328
35423
  const beforeRedirect = redirectMatch[1];
35329
35424
  const op = redirectMatch[2];
35330
- const path65 = redirectMatch[3];
35425
+ const path66 = redirectMatch[3];
35331
35426
  const fdRedirectPattern = /\d>\s*$|\s\d>&$/;
35332
35427
  if (!fdRedirectPattern.test(`${beforeRedirect} ${op}`)) {
35333
- results.push({ category: "redirect", operator: op, path: path65 });
35428
+ results.push({ category: "redirect", operator: op, path: path66 });
35334
35429
  }
35335
35430
  }
35336
35431
  const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
@@ -35343,12 +35438,12 @@ function detectPowerShellWrites(command) {
35343
35438
  }
35344
35439
  const iwrMatch = trimmed.match(/^(?:Invoke-WebRequest|curl)\s.*?(?:-OutFile\s+(\S+)|-o\s+(\S+))/i);
35345
35440
  if (iwrMatch) {
35346
- const path65 = iwrMatch[1] || iwrMatch[2];
35347
- if (path65) {
35441
+ const path66 = iwrMatch[1] || iwrMatch[2];
35442
+ if (path66) {
35348
35443
  results.push({
35349
35444
  category: "network_download",
35350
35445
  operator: "Invoke-WebRequest -OutFile",
35351
- path: path65
35446
+ path: path66
35352
35447
  });
35353
35448
  }
35354
35449
  }
@@ -35360,15 +35455,15 @@ function detectPowerShellWrites(command) {
35360
35455
  const rest = cmd.slice(cmdletMatch[0].length).trim();
35361
35456
  const pathFlagMatch = rest.match(/(?:-Path|-FilePath|-LiteralPath)\s+("([^"]+)"|'([^']+)'|(\S+))/i);
35362
35457
  if (pathFlagMatch) {
35363
- const path65 = pathFlagMatch[2] ?? pathFlagMatch[3] ?? pathFlagMatch[4] ?? "";
35364
- return { category: "redirect", operator: cmdletName, path: path65 };
35458
+ const path66 = pathFlagMatch[2] ?? pathFlagMatch[3] ?? pathFlagMatch[4] ?? "";
35459
+ return { category: "redirect", operator: cmdletName, path: path66 };
35365
35460
  }
35366
35461
  const tokens = rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
35367
35462
  for (const token of tokens) {
35368
35463
  if (token.startsWith("-"))
35369
35464
  continue;
35370
- const path65 = token.replace(/^["']|["']$/g, "");
35371
- return { category: "redirect", operator: cmdletName, path: path65 };
35465
+ const path66 = token.replace(/^["']|["']$/g, "");
35466
+ return { category: "redirect", operator: cmdletName, path: path66 };
35372
35467
  }
35373
35468
  return null;
35374
35469
  }
@@ -35384,9 +35479,9 @@ function detectPowerShellWrites(command) {
35384
35479
  for (const token of tokens) {
35385
35480
  if (token.startsWith("-"))
35386
35481
  continue;
35387
- const path65 = token.replace(/^["']|["']$/g, "");
35388
- if (path65) {
35389
- results.push({ category: "redirect", operator: cmdletName, path: path65 });
35482
+ const path66 = token.replace(/^["']|["']$/g, "");
35483
+ if (path66) {
35484
+ results.push({ category: "redirect", operator: cmdletName, path: path66 });
35390
35485
  break;
35391
35486
  }
35392
35487
  }
@@ -35399,8 +35494,8 @@ function detectPowerShellWrites(command) {
35399
35494
  const rest = cmd.slice(opMatch[0].length).trim();
35400
35495
  const destFlagMatch = rest.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);
35401
35496
  if (destFlagMatch) {
35402
- const path65 = destFlagMatch[1].replace(/^["']|["']$/g, "");
35403
- return { category: "builtin_write", operator: cmdletName, path: path65 };
35497
+ const path66 = destFlagMatch[1].replace(/^["']|["']$/g, "");
35498
+ return { category: "builtin_write", operator: cmdletName, path: path66 };
35404
35499
  }
35405
35500
  const tokens = [];
35406
35501
  const flagTakingValue = new Set([
@@ -35439,11 +35534,11 @@ function detectPowerShellWrites(command) {
35439
35534
  }
35440
35535
  }
35441
35536
  if (tokens.length >= 2) {
35442
- const path65 = tokens[tokens.length - 1].replace(/^["']|["']$/g, "");
35443
- return { category: "builtin_write", operator: cmdletName, path: path65 };
35537
+ const path66 = tokens[tokens.length - 1].replace(/^["']|["']$/g, "");
35538
+ return { category: "builtin_write", operator: cmdletName, path: path66 };
35444
35539
  } else if (tokens.length === 1) {
35445
- const path65 = tokens[0].replace(/^["']|["']$/g, "");
35446
- return { category: "builtin_write", operator: cmdletName, path: path65 };
35540
+ const path66 = tokens[0].replace(/^["']|["']$/g, "");
35541
+ return { category: "builtin_write", operator: cmdletName, path: path66 };
35447
35542
  }
35448
35543
  return null;
35449
35544
  }
@@ -35457,14 +35552,14 @@ function detectPowerShellWrites(command) {
35457
35552
  const afterCmdlet = pipeFileOpMatch[2].trim();
35458
35553
  const destFlagMatch = afterCmdlet.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);
35459
35554
  if (destFlagMatch) {
35460
- const path65 = destFlagMatch[1].replace(/^["']|["']$/g, "");
35461
- results.push({ category: "builtin_write", operator: cmdletName, path: path65 });
35555
+ const path66 = destFlagMatch[1].replace(/^["']|["']$/g, "");
35556
+ results.push({ category: "builtin_write", operator: cmdletName, path: path66 });
35462
35557
  } else {
35463
35558
  const tokens = afterCmdlet.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
35464
35559
  const nonFlagTokens = tokens.filter((t) => !t.startsWith("-") && t.length > 0);
35465
35560
  if (nonFlagTokens.length > 0) {
35466
- const path65 = nonFlagTokens[nonFlagTokens.length - 1].replace(/^["']|["']$/g, "");
35467
- results.push({ category: "builtin_write", operator: cmdletName, path: path65 });
35561
+ const path66 = nonFlagTokens[nonFlagTokens.length - 1].replace(/^["']|["']$/g, "");
35562
+ results.push({ category: "builtin_write", operator: cmdletName, path: path66 });
35468
35563
  }
35469
35564
  }
35470
35565
  }
@@ -35517,10 +35612,10 @@ function detectCmdWrites(command) {
35517
35612
  if (redirectMatch) {
35518
35613
  const beforeRedirect = redirectMatch[1];
35519
35614
  const op = redirectMatch[2];
35520
- const path65 = redirectMatch[3];
35615
+ const path66 = redirectMatch[3];
35521
35616
  const fdRedirectPattern = /\d>&?$/;
35522
35617
  if (!fdRedirectPattern.test(beforeRedirect)) {
35523
- results.push({ category: "redirect", operator: op, path: path65 });
35618
+ results.push({ category: "redirect", operator: op, path: path66 });
35524
35619
  }
35525
35620
  }
35526
35621
  const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
@@ -35578,8 +35673,8 @@ function detectCmdWrites(command) {
35578
35673
  const rawTokens = rest.match(/(\/?[^\s]+|"[^"]*"|'[^']*')/g) ?? [];
35579
35674
  const tokens = rawTokens.filter((t) => !t.startsWith("/"));
35580
35675
  if (tokens.length > 0) {
35581
- const path65 = tokens[0].replace(/^["']|["']$/g, "");
35582
- return { category: "builtin_write", operator: "del", path: path65 };
35676
+ const path66 = tokens[0].replace(/^["']|["']$/g, "");
35677
+ return { category: "builtin_write", operator: "del", path: path66 };
35583
35678
  }
35584
35679
  return null;
35585
35680
  }
@@ -35589,16 +35684,16 @@ function detectCmdWrites(command) {
35589
35684
  }
35590
35685
  const rdMatch = innerCommand.match(/^rd\s+(?:\/s\s+|\/q\s+)*(\S+)/i);
35591
35686
  if (rdMatch) {
35592
- const path65 = rdMatch[1].replace(/^["']|["']$/g, "");
35593
- if (!path65.startsWith("/")) {
35594
- results.push({ category: "builtin_write", operator: "rd", path: path65 });
35687
+ const path66 = rdMatch[1].replace(/^["']|["']$/g, "");
35688
+ if (!path66.startsWith("/")) {
35689
+ results.push({ category: "builtin_write", operator: "rd", path: path66 });
35595
35690
  }
35596
35691
  }
35597
35692
  const mdMatch = trimmed.match(/^md\s+(\S+)/i);
35598
35693
  if (mdMatch) {
35599
- const path65 = mdMatch[1].replace(/^["']|["']$/g, "");
35600
- if (!path65.startsWith("/")) {
35601
- results.push({ category: "builtin_write", operator: "md", path: path65 });
35694
+ const path66 = mdMatch[1].replace(/^["']|["']$/g, "");
35695
+ if (!path66.startsWith("/")) {
35696
+ results.push({ category: "builtin_write", operator: "md", path: path66 });
35602
35697
  }
35603
35698
  }
35604
35699
  const echoMatch = trimmed.match(/^echo\s+(\S+.*?)\s+((?:>){1,2})\s*(\S+)$/i);
@@ -35714,10 +35809,10 @@ function resolvePath(pathText, cwd) {
35714
35809
  return null;
35715
35810
  const isWindowsPath = /^[a-zA-Z]:[\\\\/]/.test(cwd) || cwd.includes("\\");
35716
35811
  if (isWindowsPath) {
35717
- return path64.win32.resolve(cwd, pathText);
35812
+ return path65.win32.resolve(cwd, pathText);
35718
35813
  }
35719
- const normalizedRelativeWindowsPath = !path64.posix.isAbsolute(pathText) && !/^[a-zA-Z]:[\\/]/.test(pathText) ? pathText.replace(/\\/g, "/") : pathText;
35720
- return path64.posix.resolve(cwd, normalizedRelativeWindowsPath);
35814
+ const normalizedRelativeWindowsPath = !path65.posix.isAbsolute(pathText) && !/^[a-zA-Z]:[\\/]/.test(pathText) ? pathText.replace(/\\/g, "/") : pathText;
35815
+ return path65.posix.resolve(cwd, normalizedRelativeWindowsPath);
35721
35816
  }
35722
35817
  function getCdTarget(cmd) {
35723
35818
  if (!cmd || typeof cmd !== "object")
@@ -35784,7 +35879,7 @@ function collectWritesWithNodes(node, out, cwdStack) {
35784
35879
  for (const cmd of node.commands) {
35785
35880
  const cdTarget = getCdTarget(cmd);
35786
35881
  if (cdTarget) {
35787
- currentStack[0] = path64.posix.resolve(currentStack[0] ?? "/", cdTarget);
35882
+ currentStack[0] = path65.posix.resolve(currentStack[0] ?? "/", cdTarget);
35788
35883
  collectWritesWithNodes(cmd, out, currentStack);
35789
35884
  } else {
35790
35885
  collectWritesWithNodes(cmd, out, currentStack);
@@ -35830,7 +35925,7 @@ function collectWritesWithNodes(node, out, cwdStack) {
35830
35925
  const effectiveCwd = cwdStack[0] ?? "/";
35831
35926
  const cdTarget = getCdTarget(node);
35832
35927
  if (cdTarget) {
35833
- cwdStack[0] = path64.posix.resolve(cwdStack[0] ?? "/", cdTarget);
35928
+ cwdStack[0] = path65.posix.resolve(cwdStack[0] ?? "/", cdTarget);
35834
35929
  return;
35835
35930
  }
35836
35931
  const writesFromRedirs = getWritesFromCommandRedirs(node, effectiveCwd);
@@ -35876,12 +35971,12 @@ function getWritesFromRedirectNode(redirect, _context) {
35876
35971
  if (!opType || !REDIRECT_ALL_WRITE_TOKENS.has(opType))
35877
35972
  return [];
35878
35973
  const fileNode = r.file;
35879
- const path65 = extractRedirectPath(fileNode);
35974
+ const path66 = extractRedirectPath(fileNode);
35880
35975
  const opLabel = operatorLabel(opNode);
35881
35976
  if (REDIRECT_WRITE_TOKENS.has(opType)) {
35882
- return [{ category: "redirect", operator: opLabel, path: path65 }];
35977
+ return [{ category: "redirect", operator: opLabel, path: path66 }];
35883
35978
  } else if (REDIRECT_HERE_TOKENS.has(opType)) {
35884
- return [{ category: "here_doc", operator: opLabel, path: path65 }];
35979
+ return [{ category: "here_doc", operator: opLabel, path: path66 }];
35885
35980
  }
35886
35981
  return [];
35887
35982
  }
@@ -36635,7 +36730,7 @@ function evidenceToWorkflowState(evidence) {
36635
36730
  }
36636
36731
  async function readPlanFromDisk(directory) {
36637
36732
  try {
36638
- const planPath = path65.join(directory, ".swarm", "plan.json");
36733
+ const planPath = path66.join(directory, ".swarm", "plan.json");
36639
36734
  const content = await fs30.readFile(planPath, "utf-8");
36640
36735
  const parsed = JSON.parse(content);
36641
36736
  return PlanSchema.parse(parsed);
@@ -36646,7 +36741,7 @@ async function readPlanFromDisk(directory) {
36646
36741
  async function readGateEvidenceFromDisk(directory) {
36647
36742
  const evidenceMap = new Map;
36648
36743
  try {
36649
- const evidenceDir = path65.join(directory, ".swarm", "evidence");
36744
+ const evidenceDir = path66.join(directory, ".swarm", "evidence");
36650
36745
  const entries = await fs30.readdir(evidenceDir, { withFileTypes: true });
36651
36746
  for (const entry of entries) {
36652
36747
  if (!entry.isFile() || !entry.name.endsWith(".json")) {
@@ -36657,7 +36752,7 @@ async function readGateEvidenceFromDisk(directory) {
36657
36752
  continue;
36658
36753
  }
36659
36754
  try {
36660
- const filePath = path65.join(evidenceDir, entry.name);
36755
+ const filePath = path66.join(evidenceDir, entry.name);
36661
36756
  const content = await fs30.readFile(filePath, "utf-8");
36662
36757
  const parsed = JSON.parse(content);
36663
36758
  if (parsed && typeof parsed.taskId === "string" && Array.isArray(parsed.required_gates)) {