opencode-swarm 7.43.0 → 7.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -5,25 +5,43 @@ var __getProtoOf = Object.getPrototypeOf;
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
8
13
  var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
9
21
  target = mod != null ? __create(__getProtoOf(mod)) : {};
10
22
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
23
  for (let key of __getOwnPropNames(mod))
12
24
  if (!__hasOwnProp.call(to, key))
13
25
  __defProp(to, key, {
14
- get: () => mod[key],
26
+ get: __accessProp.bind(mod, key),
15
27
  enumerable: true
16
28
  });
29
+ if (canCache)
30
+ cache.set(mod, to);
17
31
  return to;
18
32
  };
19
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __returnValue = (v) => v;
35
+ function __exportSetter(name, newValue) {
36
+ this[name] = __returnValue.bind(null, newValue);
37
+ }
20
38
  var __export = (target, all) => {
21
39
  for (var name in all)
22
40
  __defProp(target, name, {
23
41
  get: all[name],
24
42
  enumerable: true,
25
43
  configurable: true,
26
- set: (newValue) => all[name] = () => newValue
44
+ set: __exportSetter.bind(all, name)
27
45
  });
28
46
  };
29
47
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
@@ -34,7 +52,7 @@ var package_default;
34
52
  var init_package = __esm(() => {
35
53
  package_default = {
36
54
  name: "opencode-swarm",
37
- version: "7.43.0",
55
+ version: "7.44.0",
38
56
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
39
57
  main: "dist/index.js",
40
58
  types: "dist/index.d.ts",
@@ -80,6 +98,7 @@ var init_package = __esm(() => {
80
98
  format: "biome format . --write",
81
99
  check: "biome check --write .",
82
100
  dev: "bun run build && opencode",
101
+ "package:smoke": "node scripts/package-smoke.mjs",
83
102
  prepublishOnly: "bun run build",
84
103
  "repro:704": "node scripts/repro-704.mjs"
85
104
  },
@@ -16503,6 +16522,8 @@ var init_tool_names = __esm(() => {
16503
16522
  "skill_improve",
16504
16523
  "spec_write",
16505
16524
  "knowledge_ack",
16525
+ "knowledge_receipt",
16526
+ "knowledge_archive",
16506
16527
  "swarm_memory_recall",
16507
16528
  "swarm_memory_propose",
16508
16529
  "swarm_command",
@@ -16747,6 +16768,7 @@ var init_constants = __esm(() => {
16747
16768
  "knowledge_add",
16748
16769
  "knowledge_recall",
16749
16770
  "knowledge_remove",
16771
+ "knowledge_archive",
16750
16772
  "co_change_analyzer",
16751
16773
  "suggest_patch",
16752
16774
  "repo_map",
@@ -16763,6 +16785,7 @@ var init_constants = __esm(() => {
16763
16785
  "skill_retire",
16764
16786
  "skill_improve",
16765
16787
  "knowledge_ack",
16788
+ "knowledge_receipt",
16766
16789
  "summarize_work",
16767
16790
  "write_architecture_supervisor_evidence",
16768
16791
  "swarm_command",
@@ -16803,6 +16826,7 @@ var init_constants = __esm(() => {
16803
16826
  "syntax_check",
16804
16827
  "knowledge_add",
16805
16828
  "knowledge_recall",
16829
+ "knowledge_receipt",
16806
16830
  "repo_map",
16807
16831
  "summarize_work",
16808
16832
  "swarm_command"
@@ -17026,6 +17050,7 @@ var init_constants = __esm(() => {
17026
17050
  knowledge_add: "store a new lesson in the knowledge base",
17027
17051
  knowledge_recall: "search the knowledge base for relevant past decisions",
17028
17052
  knowledge_remove: "delete an outdated swarm knowledge entry by ID (swarm tier only)",
17053
+ knowledge_archive: "archive (default), quarantine, or purge a swarm knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",
17029
17054
  knowledge_query: "query swarm or hive knowledge with optional filters",
17030
17055
  co_change_analyzer: "detect hidden couplings by analyzing git history",
17031
17056
  check_gate_status: "check the gate status of a specific task",
@@ -17059,6 +17084,7 @@ var init_constants = __esm(() => {
17059
17084
  skill_retire: "retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",
17060
17085
  spec_write: "author or update .swarm/spec.md for the current project",
17061
17086
  knowledge_ack: "record an explicit KNOWLEDGE_APPLIED/IGNORED/VIOLATED acknowledgment",
17087
+ knowledge_receipt: "file a receipt for retrieved knowledge (applied/ignored/contradicted + new lessons), recorded as immutable knowledge events",
17062
17088
  swarm_memory_recall: "recall scoped Swarm memory for the current repository as untrusted background",
17063
17089
  swarm_memory_propose: "create a pending Swarm memory proposal; does not write durable memory directly",
17064
17090
  swarm_command: "run supported /swarm commands through the canonical command registry",
@@ -35850,8 +35876,12 @@ function normalizeEntry(raw) {
35850
35876
  const obj = raw;
35851
35877
  if (!("retrieval_outcomes" in obj))
35852
35878
  return raw;
35853
- const ro = obj.retrieval_outcomes;
35854
- if (ro && typeof ro === "object") {
35879
+ let ro = obj.retrieval_outcomes;
35880
+ if (!ro || typeof ro !== "object") {
35881
+ ro = {};
35882
+ obj.retrieval_outcomes = ro;
35883
+ }
35884
+ {
35855
35885
  if (typeof ro.shown_count !== "number") {
35856
35886
  ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
35857
35887
  }
@@ -35864,6 +35894,8 @@ function normalizeEntry(raw) {
35864
35894
  ro.ignored_count = 0;
35865
35895
  if (typeof ro.violated_count !== "number")
35866
35896
  ro.violated_count = 0;
35897
+ if (typeof ro.contradicted_count !== "number")
35898
+ ro.contradicted_count = 0;
35867
35899
  if (typeof ro.succeeded_after_shown_count !== "number") {
35868
35900
  ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
35869
35901
  }
@@ -35901,6 +35933,9 @@ function normalizeEntry(raw) {
35901
35933
  delete obj[f];
35902
35934
  }
35903
35935
  }
35936
+ if (!Array.isArray(obj.tags)) {
35937
+ obj.tags = [];
35938
+ }
35904
35939
  return raw;
35905
35940
  }
35906
35941
  async function readRejectedLessons(directory) {
@@ -35990,7 +36025,8 @@ async function appendRejectedLesson(directory, lesson) {
35990
36025
  }
35991
36026
  }
35992
36027
  function normalize2(text) {
35993
- return text.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
36028
+ const s = typeof text === "string" ? text : String(text ?? "");
36029
+ return s.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
35994
36030
  }
35995
36031
  function wordBigrams(text) {
35996
36032
  const words = normalize2(text).split(" ").filter(Boolean);
@@ -36022,6 +36058,16 @@ function computeConfidence(confirmedByCount, autoGenerated) {
36022
36058
  score += 0.1;
36023
36059
  return Math.min(score, 1);
36024
36060
  }
36061
+ function computeOutcomeSignal(outcomes) {
36062
+ if (!outcomes)
36063
+ return 0;
36064
+ const positives = (outcomes.applied_explicit_count ?? 0) + (outcomes.succeeded_after_shown_count ?? 0);
36065
+ const negatives = (outcomes.ignored_count ?? 0) + (outcomes.violated_count ?? 0) + (outcomes.contradicted_count ?? 0) + (outcomes.failed_after_shown_count ?? 0);
36066
+ const total = positives + negatives;
36067
+ if (total === 0)
36068
+ return 0;
36069
+ return (positives - negatives) / (total + OUTCOME_SIGNAL_SMOOTHING);
36070
+ }
36025
36071
  function inferTags(lesson) {
36026
36072
  const lower = lesson.toLowerCase();
36027
36073
  const tags = [];
@@ -36117,7 +36163,7 @@ async function applyConfidenceDeltas(filePath, deltas) {
36117
36163
  }
36118
36164
  }
36119
36165
  }
36120
- var import_proper_lockfile3, CONFIDENCE_FLOOR = 0.1, CONFIDENCE_CEILING = 1;
36166
+ var import_proper_lockfile3, OUTCOME_SIGNAL_SMOOTHING = 4, CONFIDENCE_FLOOR = 0.1, CONFIDENCE_CEILING = 1;
36121
36167
  var init_knowledge_store = __esm(() => {
36122
36168
  init_task_file();
36123
36169
  import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
@@ -37551,6 +37597,9 @@ async function runAutoPromotion(directory, config3) {
37551
37597
  for (const entry of entries) {
37552
37598
  if (entry.status === "promoted")
37553
37599
  continue;
37600
+ if (computeOutcomeSignal(entry.retrieval_outcomes) <= OUTCOME_PROMOTION_BLOCK) {
37601
+ continue;
37602
+ }
37554
37603
  const distinctPhases = new Set((entry.confirmed_by ?? []).map((c) => c.phase_number)).size;
37555
37604
  if (entry.status === "candidate" && distinctPhases >= 3) {
37556
37605
  entry.status = "established";
@@ -37648,7 +37697,7 @@ function createKnowledgeCuratorHook(directory, config3) {
37648
37697
  };
37649
37698
  return safeHook(handler);
37650
37699
  }
37651
- var seenRetroSections, _internals11;
37700
+ var seenRetroSections, OUTCOME_PROMOTION_BLOCK = -0.3, _internals11;
37652
37701
  var init_knowledge_curator = __esm(() => {
37653
37702
  init_knowledge_store();
37654
37703
  init_knowledge_validator();
@@ -40222,24 +40271,63 @@ var init_gate_bridge = __esm(() => {
40222
40271
  };
40223
40272
  });
40224
40273
 
40274
+ // src/hooks/knowledge-events.ts
40275
+ import { existsSync as existsSync12 } from "fs";
40276
+ import { appendFile as appendFile4, mkdir as mkdir7, readFile as readFile7 } from "fs/promises";
40277
+ import * as path23 from "path";
40278
+ function resolveKnowledgeEventsPath(directory) {
40279
+ return path23.join(directory, ".swarm", "knowledge-events.jsonl");
40280
+ }
40281
+ async function readKnowledgeEvents(directory) {
40282
+ const filePath = resolveKnowledgeEventsPath(directory);
40283
+ if (!existsSync12(filePath))
40284
+ return [];
40285
+ const content = await readFile7(filePath, "utf-8");
40286
+ const out = [];
40287
+ for (const line of content.split(`
40288
+ `)) {
40289
+ const trimmed = line.trim();
40290
+ if (!trimmed)
40291
+ continue;
40292
+ try {
40293
+ out.push(JSON.parse(trimmed));
40294
+ } catch {
40295
+ warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
40296
+ }
40297
+ }
40298
+ return out;
40299
+ }
40300
+ var RECEIPT_EVENT_TYPES;
40301
+ var init_knowledge_events = __esm(() => {
40302
+ init_logger();
40303
+ init_knowledge_store();
40304
+ RECEIPT_EVENT_TYPES = new Set([
40305
+ "acknowledged",
40306
+ "applied",
40307
+ "ignored",
40308
+ "contradicted",
40309
+ "violated"
40310
+ ]);
40311
+ });
40312
+
40225
40313
  // src/services/version-check.ts
40226
- import { existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
40314
+ import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
40227
40315
  import { homedir as homedir5 } from "os";
40228
- import { join as join21 } from "path";
40316
+ import { join as join22 } from "path";
40229
40317
  function cacheDir() {
40230
40318
  const xdg = process.env.XDG_CACHE_HOME;
40231
- const base = xdg && xdg.length > 0 ? xdg : join21(homedir5(), ".cache");
40232
- return join21(base, "opencode-swarm");
40319
+ const base = xdg && xdg.length > 0 ? xdg : join22(homedir5(), ".cache");
40320
+ return join22(base, "opencode-swarm");
40233
40321
  }
40234
40322
  function cacheFile() {
40235
- return join21(cacheDir(), "version-check.json");
40323
+ return join22(cacheDir(), "version-check.json");
40236
40324
  }
40237
40325
  function readVersionCache() {
40238
40326
  try {
40239
- const path23 = cacheFile();
40240
- if (!existsSync12(path23))
40327
+ const path24 = cacheFile();
40328
+ if (!existsSync13(path24))
40241
40329
  return null;
40242
- const raw = readFileSync8(path23, "utf-8");
40330
+ const raw = readFileSync8(path24, "utf-8");
40243
40331
  const parsed = JSON.parse(raw);
40244
40332
  if (typeof parsed?.checkedAt !== "number")
40245
40333
  return null;
@@ -40276,10 +40364,156 @@ var init_version_check = __esm(() => {
40276
40364
  CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
40277
40365
  });
40278
40366
 
40367
+ // src/services/knowledge-diagnostics.ts
40368
+ import { existsSync as existsSync14 } from "fs";
40369
+ import { readFile as readFile8 } from "fs/promises";
40370
+ async function readRawLines(filePath) {
40371
+ if (!existsSync14(filePath))
40372
+ return { entries: [], corrupt: 0 };
40373
+ const content = await readFile8(filePath, "utf-8");
40374
+ const entries = [];
40375
+ let corrupt = 0;
40376
+ for (const line of content.split(`
40377
+ `)) {
40378
+ const trimmed = line.trim();
40379
+ if (!trimmed)
40380
+ continue;
40381
+ try {
40382
+ entries.push(JSON.parse(trimmed));
40383
+ } catch {
40384
+ corrupt++;
40385
+ }
40386
+ }
40387
+ return { entries, corrupt };
40388
+ }
40389
+ function hasV2Counters(entry) {
40390
+ const ro = entry.retrieval_outcomes;
40391
+ if (!ro || typeof ro !== "object")
40392
+ return false;
40393
+ return typeof ro.shown_count === "number" && typeof ro.applied_explicit_count === "number" && typeof ro.ignored_count === "number";
40394
+ }
40395
+ function cacheStatus() {
40396
+ const cache = readVersionCache();
40397
+ if (!cache?.npmLatest)
40398
+ return "unknown";
40399
+ return compareVersions(cache.npmLatest, version3) > 0 ? "stale" : "fresh";
40400
+ }
40401
+ async function computeKnowledgeDebug(directory) {
40402
+ const swarmPath = resolveSwarmKnowledgePath(directory);
40403
+ const hivePath = resolveHiveKnowledgePath();
40404
+ const eventsPath = resolveKnowledgeEventsPath(directory);
40405
+ const [swarmRaw, hiveRaw] = await Promise.all([
40406
+ readRawLines(swarmPath),
40407
+ readRawLines(hivePath)
40408
+ ]);
40409
+ const rawEntries = [...swarmRaw.entries, ...hiveRaw.entries];
40410
+ const corrupt = swarmRaw.corrupt + hiveRaw.corrupt;
40411
+ const schemaVersions = {};
40412
+ let missingV2 = 0;
40413
+ for (const e of rawEntries) {
40414
+ const sv = String(typeof e.schema_version === "number" ? e.schema_version : "unknown");
40415
+ schemaVersions[sv] = (schemaVersions[sv] ?? 0) + 1;
40416
+ if (!hasV2Counters(e))
40417
+ missingV2++;
40418
+ }
40419
+ let normalizedCount = 0;
40420
+ let active = 0;
40421
+ let archived = 0;
40422
+ let quarantined = 0;
40423
+ try {
40424
+ const swarm = await readKnowledge(swarmPath);
40425
+ const hive = await readKnowledge(hivePath);
40426
+ for (const e of [...swarm, ...hive]) {
40427
+ normalizedCount++;
40428
+ if (e.status === "archived")
40429
+ archived++;
40430
+ else if (e.status === "quarantined")
40431
+ quarantined++;
40432
+ else
40433
+ active++;
40434
+ }
40435
+ } catch {}
40436
+ let rejected = 0;
40437
+ try {
40438
+ rejected = (await readRejectedLessons(directory)).length;
40439
+ } catch {}
40440
+ let eventCount = 0;
40441
+ let retrieval7d = 0;
40442
+ try {
40443
+ const events = await readKnowledgeEvents(directory);
40444
+ eventCount = events.length;
40445
+ const cutoff = Date.now() - SEVEN_DAYS_MS;
40446
+ for (const ev of events) {
40447
+ if (ev.type !== "retrieved")
40448
+ continue;
40449
+ const t = Date.parse(ev.timestamp);
40450
+ if (!Number.isNaN(t) && t >= cutoff)
40451
+ retrieval7d++;
40452
+ }
40453
+ } catch {}
40454
+ return {
40455
+ plugin_version: version3,
40456
+ directory,
40457
+ swarm_path: swarmPath,
40458
+ hive_path: hivePath,
40459
+ events_path: eventsPath,
40460
+ raw_entry_count: rawEntries.length,
40461
+ normalized_entry_count: normalizedCount,
40462
+ corrupt_line_count: corrupt,
40463
+ schema_versions: schemaVersions,
40464
+ entries_missing_v2_counters: missingV2,
40465
+ status_breakdown: { active, archived, quarantined, rejected },
40466
+ event_count: eventCount,
40467
+ retrieval_events_7d: retrieval7d,
40468
+ cache_status: cacheStatus()
40469
+ };
40470
+ }
40471
+ async function checkKnowledgeHealth(directory) {
40472
+ let debug;
40473
+ try {
40474
+ debug = await computeKnowledgeDebug(directory);
40475
+ } catch {
40476
+ return {
40477
+ name: "Knowledge health",
40478
+ status: "\u26A0\uFE0F",
40479
+ detail: "Could not compute knowledge diagnostics"
40480
+ };
40481
+ }
40482
+ const sb = debug.status_breakdown;
40483
+ const summary = `active=${sb.active} archived=${sb.archived} quarantined=${sb.quarantined} ` + `rejected=${sb.rejected} | events=${debug.event_count} (retrieved/7d=${debug.retrieval_events_7d}) | ` + `schema=${JSON.stringify(debug.schema_versions)}`;
40484
+ const warnings = [];
40485
+ if (debug.corrupt_line_count > 0) {
40486
+ warnings.push(`${debug.corrupt_line_count} corrupt JSONL line(s) (raw=${debug.raw_entry_count} vs normalized=${debug.normalized_entry_count})`);
40487
+ }
40488
+ if (debug.entries_missing_v2_counters > 0) {
40489
+ warnings.push(`${debug.entries_missing_v2_counters} entr(y/ies) missing v2 counters (normalized on read)`);
40490
+ }
40491
+ if (debug.cache_status === "stale") {
40492
+ warnings.push("stale plugin cache \u2014 run `bunx opencode-swarm update` (knowledge tools may be running old code)");
40493
+ }
40494
+ if (warnings.length > 0) {
40495
+ return {
40496
+ name: "Knowledge health",
40497
+ status: "\u26A0\uFE0F",
40498
+ detail: `${summary} \u2014 ${warnings.join("; ")}`
40499
+ };
40500
+ }
40501
+ return { name: "Knowledge health", status: "\u2705", detail: summary };
40502
+ }
40503
+ var version3, SEVEN_DAYS_MS;
40504
+ var init_knowledge_diagnostics = __esm(() => {
40505
+ init_package();
40506
+ init_knowledge_events();
40507
+ init_knowledge_store();
40508
+ init_version_check();
40509
+ ({ version: version3 } = package_default);
40510
+ SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
40511
+ });
40512
+
40279
40513
  // src/services/diagnose-service.ts
40280
40514
  import * as child_process4 from "child_process";
40281
- import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync9, statSync as statSync7 } from "fs";
40282
- import path23 from "path";
40515
+ import { existsSync as existsSync15, readdirSync as readdirSync4, readFileSync as readFileSync9, statSync as statSync7 } from "fs";
40516
+ import path24 from "path";
40283
40517
  import { fileURLToPath } from "url";
40284
40518
  function validateTaskDag(plan) {
40285
40519
  const allTaskIds = new Set;
@@ -40526,7 +40760,7 @@ async function checkConfigBackups(directory) {
40526
40760
  }
40527
40761
  async function checkGitRepository(directory) {
40528
40762
  try {
40529
- if (!existsSync13(directory) || !statSync7(directory).isDirectory()) {
40763
+ if (!existsSync15(directory) || !statSync7(directory).isDirectory()) {
40530
40764
  return {
40531
40765
  name: "Git Repository",
40532
40766
  status: "\u274C",
@@ -40590,8 +40824,8 @@ async function checkSpecStaleness(directory, plan) {
40590
40824
  };
40591
40825
  }
40592
40826
  async function checkConfigParseability(directory) {
40593
- const configPath = path23.join(directory, ".opencode/opencode-swarm.json");
40594
- if (!existsSync13(configPath)) {
40827
+ const configPath = path24.join(directory, ".opencode/opencode-swarm.json");
40828
+ if (!existsSync15(configPath)) {
40595
40829
  return {
40596
40830
  name: "Config Parseability",
40597
40831
  status: "\u2705",
@@ -40619,7 +40853,7 @@ function resolveGrammarDir(thisDir) {
40619
40853
  const normalized = thisDir.replace(/\\/g, "/");
40620
40854
  const isSource = normalized.endsWith("/src/services");
40621
40855
  const isCliBundle = normalized.endsWith("/cli");
40622
- return isSource || isCliBundle ? path23.join(thisDir, "..", "lang", "grammars") : path23.join(thisDir, "lang", "grammars");
40856
+ return isSource || isCliBundle ? path24.join(thisDir, "..", "lang", "grammars") : path24.join(thisDir, "lang", "grammars");
40623
40857
  }
40624
40858
  async function checkGrammarWasmFiles() {
40625
40859
  const grammarFiles = [
@@ -40643,14 +40877,14 @@ async function checkGrammarWasmFiles() {
40643
40877
  "tree-sitter-ini.wasm",
40644
40878
  "tree-sitter-regex.wasm"
40645
40879
  ];
40646
- const thisDir = path23.dirname(fileURLToPath(import.meta.url));
40880
+ const thisDir = path24.dirname(fileURLToPath(import.meta.url));
40647
40881
  const grammarDir = resolveGrammarDir(thisDir);
40648
40882
  const missing = [];
40649
- if (!existsSync13(path23.join(grammarDir, "tree-sitter.wasm"))) {
40883
+ if (!existsSync15(path24.join(grammarDir, "tree-sitter.wasm"))) {
40650
40884
  missing.push("tree-sitter.wasm (core runtime)");
40651
40885
  }
40652
40886
  for (const file3 of grammarFiles) {
40653
- if (!existsSync13(path23.join(grammarDir, file3))) {
40887
+ if (!existsSync15(path24.join(grammarDir, file3))) {
40654
40888
  missing.push(file3);
40655
40889
  }
40656
40890
  }
@@ -40668,8 +40902,8 @@ async function checkGrammarWasmFiles() {
40668
40902
  };
40669
40903
  }
40670
40904
  async function checkCheckpointManifest(directory) {
40671
- const manifestPath = path23.join(directory, ".swarm/checkpoints.json");
40672
- if (!existsSync13(manifestPath)) {
40905
+ const manifestPath = path24.join(directory, ".swarm/checkpoints.json");
40906
+ if (!existsSync15(manifestPath)) {
40673
40907
  return {
40674
40908
  name: "Checkpoint Manifest",
40675
40909
  status: "\u2705",
@@ -40720,8 +40954,8 @@ async function checkCheckpointManifest(directory) {
40720
40954
  }
40721
40955
  }
40722
40956
  async function checkEventStreamIntegrity(directory) {
40723
- const eventsPath = path23.join(directory, ".swarm/events.jsonl");
40724
- if (!existsSync13(eventsPath)) {
40957
+ const eventsPath = path24.join(directory, ".swarm/events.jsonl");
40958
+ if (!existsSync15(eventsPath)) {
40725
40959
  return {
40726
40960
  name: "Event Stream",
40727
40961
  status: "\u2705",
@@ -40761,8 +40995,8 @@ async function checkEventStreamIntegrity(directory) {
40761
40995
  }
40762
40996
  }
40763
40997
  async function checkSteeringDirectives(directory) {
40764
- const eventsPath = path23.join(directory, ".swarm/events.jsonl");
40765
- if (!existsSync13(eventsPath)) {
40998
+ const eventsPath = path24.join(directory, ".swarm/events.jsonl");
40999
+ if (!existsSync15(eventsPath)) {
40766
41000
  return {
40767
41001
  name: "Steering Directives",
40768
41002
  status: "\u2705",
@@ -40817,8 +41051,8 @@ async function checkCurator(directory) {
40817
41051
  detail: "Disabled (enable via curator.enabled)"
40818
41052
  };
40819
41053
  }
40820
- const summaryPath = path23.join(directory, ".swarm/curator-summary.json");
40821
- if (!existsSync13(summaryPath)) {
41054
+ const summaryPath = path24.join(directory, ".swarm/curator-summary.json");
41055
+ if (!existsSync15(summaryPath)) {
40822
41056
  return {
40823
41057
  name: "Curator",
40824
41058
  status: "\u2705",
@@ -40862,16 +41096,16 @@ async function checkCurator(directory) {
40862
41096
  async function getDiagnoseData(directory) {
40863
41097
  const checks5 = [];
40864
41098
  const versionCache = readVersionCache();
40865
- let versionDetail = version3;
41099
+ let versionDetail = version4;
40866
41100
  let versionStatus = "\u2705";
40867
41101
  if (versionCache?.npmLatest) {
40868
41102
  const ageMs = Date.now() - versionCache.checkedAt;
40869
41103
  const ageMin = Math.max(0, Math.round(ageMs / 60000));
40870
- if (compareVersions(versionCache.npmLatest, version3) > 0) {
41104
+ if (compareVersions(versionCache.npmLatest, version4) > 0) {
40871
41105
  versionStatus = "\u26A0\uFE0F";
40872
- versionDetail = `${version3} (npm latest: ${versionCache.npmLatest}, checked ${ageMin}m ago) ` + "\u2014 run `bunx opencode-swarm update` to refresh";
41106
+ versionDetail = `${version4} (npm latest: ${versionCache.npmLatest}, checked ${ageMin}m ago) ` + "\u2014 run `bunx opencode-swarm update` to refresh";
40873
41107
  } else {
40874
- versionDetail = `${version3} (npm latest: ${versionCache.npmLatest}, checked ${ageMin}m ago)`;
41108
+ versionDetail = `${version4} (npm latest: ${versionCache.npmLatest}, checked ${ageMin}m ago)`;
40875
41109
  }
40876
41110
  }
40877
41111
  checks5.push({
@@ -40982,9 +41216,10 @@ async function getDiagnoseData(directory) {
40982
41216
  checks5.push(await checkEventStreamIntegrity(directory));
40983
41217
  checks5.push(await checkSteeringDirectives(directory));
40984
41218
  checks5.push(await checkCurator(directory));
41219
+ checks5.push(await checkKnowledgeHealth(directory));
40985
41220
  try {
40986
- const evidenceDir = path23.join(directory, ".swarm", "evidence");
40987
- const snapshotFiles = existsSync13(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
41221
+ const evidenceDir = path24.join(directory, ".swarm", "evidence");
41222
+ const snapshotFiles = existsSync15(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
40988
41223
  if (snapshotFiles.length > 0) {
40989
41224
  const latest = snapshotFiles.sort().pop();
40990
41225
  checks5.push({
@@ -41017,11 +41252,11 @@ async function getDiagnoseData(directory) {
41017
41252
  const cacheRows = [];
41018
41253
  for (const cachePath of cachePaths) {
41019
41254
  try {
41020
- if (!existsSync13(cachePath)) {
41255
+ if (!existsSync15(cachePath)) {
41021
41256
  cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
41022
41257
  continue;
41023
41258
  }
41024
- const pkgJsonPath = path23.join(cachePath, "package.json");
41259
+ const pkgJsonPath = path24.join(cachePath, "package.json");
41025
41260
  try {
41026
41261
  const raw = readFileSync9(pkgJsonPath, "utf-8");
41027
41262
  const parsed = JSON.parse(raw);
@@ -41036,10 +41271,10 @@ async function getDiagnoseData(directory) {
41036
41271
  }
41037
41272
  const hasCacheEntry = cacheRows.some((r) => r.startsWith("\u2705"));
41038
41273
  const hasCacheWarning = cacheRows.some((r) => r.startsWith("\u26A0\uFE0F"));
41039
- const cacheStatus = hasCacheWarning ? "\u26A0\uFE0F" : hasCacheEntry ? "\u2705" : "\u2B1C";
41274
+ const cacheStatus2 = hasCacheWarning ? "\u26A0\uFE0F" : hasCacheEntry ? "\u2705" : "\u2B1C";
41040
41275
  checks5.push({
41041
41276
  name: "Plugin Caches",
41042
- status: cacheStatus,
41277
+ status: cacheStatus2,
41043
41278
  detail: cacheRows.join(" | ")
41044
41279
  });
41045
41280
  const passCount = checks5.filter((c) => c.status === "\u2705" || c.status === "\u2B1C").length;
@@ -41075,7 +41310,7 @@ async function handleDiagnoseCommand(directory, _args) {
41075
41310
  const diagnoseData = await getDiagnoseData(directory);
41076
41311
  return formatDiagnoseMarkdown(diagnoseData);
41077
41312
  }
41078
- var version3;
41313
+ var version4;
41079
41314
  var init_diagnose_service = __esm(() => {
41080
41315
  init_package();
41081
41316
  init_cache_paths();
@@ -41084,9 +41319,10 @@ var init_diagnose_service = __esm(() => {
41084
41319
  init_manager2();
41085
41320
  init_utils2();
41086
41321
  init_manager();
41322
+ init_knowledge_diagnostics();
41087
41323
  init_version_check();
41088
41324
  init_warning_buffer();
41089
- ({ version: version3 } = package_default);
41325
+ ({ version: version4 } = package_default);
41090
41326
  });
41091
41327
 
41092
41328
  // src/commands/diagnose.ts
@@ -41112,13 +41348,13 @@ __export(exports_config_doctor, {
41112
41348
  import * as crypto4 from "crypto";
41113
41349
  import * as fs9 from "fs";
41114
41350
  import * as os6 from "os";
41115
- import * as path24 from "path";
41351
+ import * as path25 from "path";
41116
41352
  function getUserConfigDir3() {
41117
- return process.env.XDG_CONFIG_HOME || path24.join(os6.homedir(), ".config");
41353
+ return process.env.XDG_CONFIG_HOME || path25.join(os6.homedir(), ".config");
41118
41354
  }
41119
41355
  function getConfigPaths(directory) {
41120
- const userConfigPath = path24.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
41121
- const projectConfigPath = path24.join(directory, ".opencode", "opencode-swarm.json");
41356
+ const userConfigPath = path25.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
41357
+ const projectConfigPath = path25.join(directory, ".opencode", "opencode-swarm.json");
41122
41358
  return { userConfigPath, projectConfigPath };
41123
41359
  }
41124
41360
  function computeHash(content) {
@@ -41143,9 +41379,9 @@ function isValidConfigPath(configPath, directory) {
41143
41379
  const normalizedUser = userConfigPath.replace(/\\/g, "/");
41144
41380
  const normalizedProject = projectConfigPath.replace(/\\/g, "/");
41145
41381
  try {
41146
- const resolvedConfig = path24.resolve(configPath);
41147
- const resolvedUser = path24.resolve(normalizedUser);
41148
- const resolvedProject = path24.resolve(normalizedProject);
41382
+ const resolvedConfig = path25.resolve(configPath);
41383
+ const resolvedUser = path25.resolve(normalizedUser);
41384
+ const resolvedProject = path25.resolve(normalizedProject);
41149
41385
  return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
41150
41386
  } catch {
41151
41387
  return false;
@@ -41185,12 +41421,12 @@ function createConfigBackup(directory) {
41185
41421
  };
41186
41422
  }
41187
41423
  function writeBackupArtifact(directory, backup) {
41188
- const swarmDir = path24.join(directory, ".swarm");
41424
+ const swarmDir = path25.join(directory, ".swarm");
41189
41425
  if (!fs9.existsSync(swarmDir)) {
41190
41426
  fs9.mkdirSync(swarmDir, { recursive: true });
41191
41427
  }
41192
41428
  const backupFilename = `config-backup-${backup.createdAt}.json`;
41193
- const backupPath = path24.join(swarmDir, backupFilename);
41429
+ const backupPath = path25.join(swarmDir, backupFilename);
41194
41430
  const artifact = {
41195
41431
  createdAt: backup.createdAt,
41196
41432
  configPath: backup.configPath,
@@ -41220,7 +41456,7 @@ function restoreFromBackup(backupPath, directory) {
41220
41456
  return null;
41221
41457
  }
41222
41458
  const targetPath = artifact.configPath;
41223
- const targetDir = path24.dirname(targetPath);
41459
+ const targetDir = path25.dirname(targetPath);
41224
41460
  if (!fs9.existsSync(targetDir)) {
41225
41461
  fs9.mkdirSync(targetDir, { recursive: true });
41226
41462
  }
@@ -41251,9 +41487,9 @@ function readConfigFromFile(directory) {
41251
41487
  return null;
41252
41488
  }
41253
41489
  }
41254
- function validateConfigKey(path25, value, _config) {
41490
+ function validateConfigKey(path26, value, _config) {
41255
41491
  const findings = [];
41256
- switch (path25) {
41492
+ switch (path26) {
41257
41493
  case "agents": {
41258
41494
  if (value !== undefined) {
41259
41495
  findings.push({
@@ -41490,27 +41726,27 @@ function validateConfigKey(path25, value, _config) {
41490
41726
  }
41491
41727
  return findings;
41492
41728
  }
41493
- function walkConfigAndValidate(obj, path25, config3, findings) {
41729
+ function walkConfigAndValidate(obj, path26, config3, findings) {
41494
41730
  if (obj === null || obj === undefined) {
41495
41731
  return;
41496
41732
  }
41497
- if (path25 && typeof obj === "object" && !Array.isArray(obj)) {
41498
- const keyFindings = validateConfigKey(path25, obj, config3);
41733
+ if (path26 && typeof obj === "object" && !Array.isArray(obj)) {
41734
+ const keyFindings = validateConfigKey(path26, obj, config3);
41499
41735
  findings.push(...keyFindings);
41500
41736
  }
41501
41737
  if (typeof obj !== "object") {
41502
- const keyFindings = validateConfigKey(path25, obj, config3);
41738
+ const keyFindings = validateConfigKey(path26, obj, config3);
41503
41739
  findings.push(...keyFindings);
41504
41740
  return;
41505
41741
  }
41506
41742
  if (Array.isArray(obj)) {
41507
41743
  obj.forEach((item, index) => {
41508
- walkConfigAndValidate(item, `${path25}[${index}]`, config3, findings);
41744
+ walkConfigAndValidate(item, `${path26}[${index}]`, config3, findings);
41509
41745
  });
41510
41746
  return;
41511
41747
  }
41512
41748
  for (const [key, value] of Object.entries(obj)) {
41513
- const newPath = path25 ? `${path25}.${key}` : key;
41749
+ const newPath = path26 ? `${path26}.${key}` : key;
41514
41750
  walkConfigAndValidate(value, newPath, config3, findings);
41515
41751
  }
41516
41752
  }
@@ -41630,7 +41866,7 @@ function applySafeAutoFixes(directory, result) {
41630
41866
  }
41631
41867
  }
41632
41868
  if (appliedFixes.length > 0) {
41633
- const configDir = path24.dirname(configPath);
41869
+ const configDir = path25.dirname(configPath);
41634
41870
  if (!fs9.existsSync(configDir)) {
41635
41871
  fs9.mkdirSync(configDir, { recursive: true });
41636
41872
  }
@@ -41640,12 +41876,12 @@ function applySafeAutoFixes(directory, result) {
41640
41876
  return { appliedFixes, updatedConfigPath };
41641
41877
  }
41642
41878
  function writeDoctorArtifact(directory, result) {
41643
- const swarmDir = path24.join(directory, ".swarm");
41879
+ const swarmDir = path25.join(directory, ".swarm");
41644
41880
  if (!fs9.existsSync(swarmDir)) {
41645
41881
  fs9.mkdirSync(swarmDir, { recursive: true });
41646
41882
  }
41647
41883
  const artifactFilename = "config-doctor.json";
41648
- const artifactPath = path24.join(swarmDir, artifactFilename);
41884
+ const artifactPath = path25.join(swarmDir, artifactFilename);
41649
41885
  const guiOutput = {
41650
41886
  timestamp: result.timestamp,
41651
41887
  summary: result.summary,
@@ -41741,17 +41977,17 @@ function detectStraySwarmDirs(projectRoot) {
41741
41977
  if (!entry.isDirectory())
41742
41978
  continue;
41743
41979
  const name = entry.name;
41744
- const fullPath = path24.join(dir, name);
41980
+ const fullPath = path25.join(dir, name);
41745
41981
  if (SKIP_DIRS.has(name))
41746
41982
  continue;
41747
- const gitPath = path24.join(fullPath, ".git");
41983
+ const gitPath = path25.join(fullPath, ".git");
41748
41984
  try {
41749
41985
  const gitStat = fs9.statSync(gitPath);
41750
41986
  if (gitStat.isFile() || gitStat.isDirectory())
41751
41987
  continue;
41752
41988
  } catch {}
41753
41989
  if (name === ".swarm") {
41754
- const parentDir = path24.dirname(fullPath);
41990
+ const parentDir = path25.dirname(fullPath);
41755
41991
  if (parentDir === projectRoot)
41756
41992
  continue;
41757
41993
  let contents = [];
@@ -41761,7 +41997,7 @@ function detectStraySwarmDirs(projectRoot) {
41761
41997
  contents = ["<unreadable>"];
41762
41998
  }
41763
41999
  findings.push({
41764
- path: path24.relative(projectRoot, fullPath).replace(/\\/g, "/"),
42000
+ path: path25.relative(projectRoot, fullPath).replace(/\\/g, "/"),
41765
42001
  absolutePath: fullPath,
41766
42002
  contents: contents.slice(0, MAX_CONTENTS_ENTRIES),
41767
42003
  totalEntries: contents.length
@@ -41779,21 +42015,21 @@ function removeStraySwarmDir(projectRoot, strayPath) {
41779
42015
  let canonicalStray;
41780
42016
  try {
41781
42017
  canonicalRoot = fs9.realpathSync(projectRoot);
41782
- canonicalStray = fs9.realpathSync(path24.isAbsolute(strayPath) ? strayPath : path24.resolve(projectRoot, strayPath));
42018
+ canonicalStray = fs9.realpathSync(path25.isAbsolute(strayPath) ? strayPath : path25.resolve(projectRoot, strayPath));
41783
42019
  } catch (err) {
41784
42020
  return {
41785
42021
  success: false,
41786
42022
  message: `Failed to resolve paths: ${err instanceof Error ? err.message : String(err)}`
41787
42023
  };
41788
42024
  }
41789
- const rootSwarm = path24.join(canonicalRoot, ".swarm");
42025
+ const rootSwarm = path25.join(canonicalRoot, ".swarm");
41790
42026
  if (canonicalStray === rootSwarm || canonicalStray === canonicalRoot) {
41791
42027
  return {
41792
42028
  success: false,
41793
42029
  message: "Refusing to remove root .swarm/ directory"
41794
42030
  };
41795
42031
  }
41796
- if (!canonicalStray.startsWith(canonicalRoot + path24.sep)) {
42032
+ if (!canonicalStray.startsWith(canonicalRoot + path25.sep)) {
41797
42033
  return {
41798
42034
  success: false,
41799
42035
  message: "Path is outside project root \u2014 refusing to remove"
@@ -42882,7 +43118,7 @@ var init_profiles = __esm(() => {
42882
43118
 
42883
43119
  // src/lang/detector.ts
42884
43120
  import { access as access3, readdir as readdir2 } from "fs/promises";
42885
- import { extname as extname2, join as join23 } from "path";
43121
+ import { extname as extname2, join as join24 } from "path";
42886
43122
  async function detectProjectLanguages(projectDir) {
42887
43123
  const detected = new Set;
42888
43124
  async function scanDir(dir) {
@@ -42898,7 +43134,7 @@ async function detectProjectLanguages(projectDir) {
42898
43134
  if (detectFile.includes("*") || detectFile.includes("?"))
42899
43135
  continue;
42900
43136
  try {
42901
- await access3(join23(dir, detectFile));
43137
+ await access3(join24(dir, detectFile));
42902
43138
  detected.add(profile.id);
42903
43139
  break;
42904
43140
  } catch {}
@@ -42919,7 +43155,7 @@ async function detectProjectLanguages(projectDir) {
42919
43155
  const topEntries = await readdir2(projectDir, { withFileTypes: true });
42920
43156
  for (const entry of topEntries) {
42921
43157
  if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
42922
- await scanDir(join23(projectDir, entry.name));
43158
+ await scanDir(join24(projectDir, entry.name));
42923
43159
  }
42924
43160
  }
42925
43161
  } catch {}
@@ -42938,7 +43174,7 @@ var init_detector = __esm(() => {
42938
43174
 
42939
43175
  // src/build/discovery.ts
42940
43176
  import * as fs10 from "fs";
42941
- import * as path25 from "path";
43177
+ import * as path26 from "path";
42942
43178
  function isCommandAvailable(command) {
42943
43179
  if (toolchainCache.has(command)) {
42944
43180
  return toolchainCache.get(command);
@@ -42973,11 +43209,11 @@ function findBuildFiles(workingDir, patterns) {
42973
43209
  const regex = simpleGlobToRegex(pattern);
42974
43210
  const matches = files.filter((f) => regex.test(f));
42975
43211
  if (matches.length > 0) {
42976
- return path25.join(dir, matches[0]);
43212
+ return path26.join(dir, matches[0]);
42977
43213
  }
42978
43214
  } catch {}
42979
43215
  } else {
42980
- const filePath = path25.join(workingDir, pattern);
43216
+ const filePath = path26.join(workingDir, pattern);
42981
43217
  if (fs10.existsSync(filePath)) {
42982
43218
  return filePath;
42983
43219
  }
@@ -42986,7 +43222,7 @@ function findBuildFiles(workingDir, patterns) {
42986
43222
  return null;
42987
43223
  }
42988
43224
  function getRepoDefinedScripts(workingDir, scripts) {
42989
- const packageJsonPath = path25.join(workingDir, "package.json");
43225
+ const packageJsonPath = path26.join(workingDir, "package.json");
42990
43226
  if (!fs10.existsSync(packageJsonPath)) {
42991
43227
  return [];
42992
43228
  }
@@ -43027,7 +43263,7 @@ function findAllBuildFiles(workingDir) {
43027
43263
  const regex = simpleGlobToRegex(pattern);
43028
43264
  findFilesRecursive(workingDir, regex, allBuildFiles);
43029
43265
  } else {
43030
- const filePath = path25.join(workingDir, pattern);
43266
+ const filePath = path26.join(workingDir, pattern);
43031
43267
  if (fs10.existsSync(filePath)) {
43032
43268
  allBuildFiles.add(filePath);
43033
43269
  }
@@ -43040,7 +43276,7 @@ function findFilesRecursive(dir, regex, results) {
43040
43276
  try {
43041
43277
  const entries = fs10.readdirSync(dir, { withFileTypes: true });
43042
43278
  for (const entry of entries) {
43043
- const fullPath = path25.join(dir, entry.name);
43279
+ const fullPath = path26.join(dir, entry.name);
43044
43280
  if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
43045
43281
  findFilesRecursive(fullPath, regex, results);
43046
43282
  } else if (entry.isFile() && regex.test(entry.name)) {
@@ -43063,7 +43299,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
43063
43299
  let foundCommand = false;
43064
43300
  for (const cmd of sortedCommands) {
43065
43301
  if (cmd.detectFile) {
43066
- const detectFilePath = path25.join(workingDir, cmd.detectFile);
43302
+ const detectFilePath = path26.join(workingDir, cmd.detectFile);
43067
43303
  if (!fs10.existsSync(detectFilePath)) {
43068
43304
  continue;
43069
43305
  }
@@ -43304,7 +43540,7 @@ var init_discovery = __esm(() => {
43304
43540
 
43305
43541
  // src/services/tool-doctor.ts
43306
43542
  import * as fs11 from "fs";
43307
- import * as path26 from "path";
43543
+ import * as path27 from "path";
43308
43544
  function extractRegisteredToolKeys(indexPath) {
43309
43545
  const registeredKeys = new Set;
43310
43546
  try {
@@ -43359,8 +43595,8 @@ function checkBinaryReadiness() {
43359
43595
  }
43360
43596
  function runToolDoctor(_directory, pluginRoot) {
43361
43597
  const findings = [];
43362
- const resolvedPluginRoot = pluginRoot ?? path26.resolve(import.meta.dir, "..", "..");
43363
- const indexPath = path26.join(resolvedPluginRoot, "src", "index.ts");
43598
+ const resolvedPluginRoot = pluginRoot ?? path27.resolve(import.meta.dir, "..", "..");
43599
+ const indexPath = path27.join(resolvedPluginRoot, "src", "index.ts");
43364
43600
  if (!fs11.existsSync(indexPath)) {
43365
43601
  return {
43366
43602
  findings: [
@@ -44118,12 +44354,12 @@ var init_export = __esm(() => {
44118
44354
 
44119
44355
  // src/full-auto/state.ts
44120
44356
  import * as fs12 from "fs";
44121
- import * as path27 from "path";
44357
+ import * as path28 from "path";
44122
44358
  function nowISO() {
44123
44359
  return new Date().toISOString();
44124
44360
  }
44125
44361
  function ensureSwarmDir(directory) {
44126
- const swarmDir = path27.resolve(directory, ".swarm");
44362
+ const swarmDir = path28.resolve(directory, ".swarm");
44127
44363
  if (!fs12.existsSync(swarmDir)) {
44128
44364
  fs12.mkdirSync(swarmDir, { recursive: true });
44129
44365
  }
@@ -44824,7 +45060,7 @@ var init_handoff_service = __esm(() => {
44824
45060
 
44825
45061
  // src/session/snapshot-writer.ts
44826
45062
  import { closeSync as closeSync4, fsyncSync as fsyncSync2, mkdirSync as mkdirSync12, openSync as openSync4, renameSync as renameSync8 } from "fs";
44827
- import * as path28 from "path";
45063
+ import * as path29 from "path";
44828
45064
  function serializeAgentSession(s) {
44829
45065
  const gateLog = {};
44830
45066
  const rawGateLog = s.gateLog ?? new Map;
@@ -44924,7 +45160,7 @@ async function writeSnapshot(directory, state) {
44924
45160
  }
44925
45161
  const content = JSON.stringify(snapshot, null, 2);
44926
45162
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
44927
- const dir = path28.dirname(resolvedPath);
45163
+ const dir = path29.dirname(resolvedPath);
44928
45164
  mkdirSync12(dir, { recursive: true });
44929
45165
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
44930
45166
  await bunWrite(tempPath, content);
@@ -45384,9 +45620,9 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
45384
45620
 
45385
45621
  // src/hooks/knowledge-migrator.ts
45386
45622
  import { randomUUID as randomUUID3 } from "crypto";
45387
- import { existsSync as existsSync18, readFileSync as readFileSync14 } from "fs";
45388
- import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
45389
- import * as path29 from "path";
45623
+ import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
45624
+ import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile8 } from "fs/promises";
45625
+ import * as path30 from "path";
45390
45626
  async function migrateKnowledgeToExternal(_directory, _config) {
45391
45627
  return {
45392
45628
  migrated: false,
@@ -45397,10 +45633,10 @@ async function migrateKnowledgeToExternal(_directory, _config) {
45397
45633
  };
45398
45634
  }
45399
45635
  async function migrateContextToKnowledge(directory, config3) {
45400
- const sentinelPath = path29.join(directory, ".swarm", ".knowledge-migrated");
45401
- const contextPath = path29.join(directory, ".swarm", "context.md");
45636
+ const sentinelPath = path30.join(directory, ".swarm", ".knowledge-migrated");
45637
+ const contextPath = path30.join(directory, ".swarm", "context.md");
45402
45638
  const knowledgePath = resolveSwarmKnowledgePath(directory);
45403
- if (existsSync18(sentinelPath)) {
45639
+ if (existsSync20(sentinelPath)) {
45404
45640
  return {
45405
45641
  migrated: false,
45406
45642
  entriesMigrated: 0,
@@ -45409,7 +45645,7 @@ async function migrateContextToKnowledge(directory, config3) {
45409
45645
  skippedReason: "sentinel-exists"
45410
45646
  };
45411
45647
  }
45412
- if (!existsSync18(contextPath)) {
45648
+ if (!existsSync20(contextPath)) {
45413
45649
  return {
45414
45650
  migrated: false,
45415
45651
  entriesMigrated: 0,
@@ -45418,7 +45654,7 @@ async function migrateContextToKnowledge(directory, config3) {
45418
45654
  skippedReason: "no-context-file"
45419
45655
  };
45420
45656
  }
45421
- const contextContent = await readFile7(contextPath, "utf-8");
45657
+ const contextContent = await readFile9(contextPath, "utf-8");
45422
45658
  if (contextContent.trim().length === 0) {
45423
45659
  return {
45424
45660
  migrated: false,
@@ -45594,8 +45830,8 @@ function truncateLesson(text) {
45594
45830
  return `${text.slice(0, 277)}...`;
45595
45831
  }
45596
45832
  function inferProjectName(directory) {
45597
- const packageJsonPath = path29.join(directory, "package.json");
45598
- if (existsSync18(packageJsonPath)) {
45833
+ const packageJsonPath = path30.join(directory, "package.json");
45834
+ if (existsSync20(packageJsonPath)) {
45599
45835
  try {
45600
45836
  const pkg = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
45601
45837
  if (pkg.name && typeof pkg.name === "string") {
@@ -45603,7 +45839,7 @@ function inferProjectName(directory) {
45603
45839
  }
45604
45840
  } catch {}
45605
45841
  }
45606
- return path29.basename(directory);
45842
+ return path30.basename(directory);
45607
45843
  }
45608
45844
  async function writeSentinel(sentinelPath, migrated, dropped) {
45609
45845
  const sentinel = {
@@ -45615,7 +45851,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
45615
45851
  schema_version: 1,
45616
45852
  migration_tool: "knowledge-migrator.ts"
45617
45853
  };
45618
- await mkdir7(path29.dirname(sentinelPath), { recursive: true });
45854
+ await mkdir8(path30.dirname(sentinelPath), { recursive: true });
45619
45855
  await writeFile8(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
45620
45856
  }
45621
45857
  var _internals19;
@@ -45637,7 +45873,7 @@ var init_knowledge_migrator = __esm(() => {
45637
45873
  });
45638
45874
 
45639
45875
  // src/commands/knowledge.ts
45640
- import { join as join27 } from "path";
45876
+ import { join as join28 } from "path";
45641
45877
  function resolveEntryByPrefix(entries, inputId) {
45642
45878
  const exact = entries.find((e) => e.id === inputId);
45643
45879
  if (exact)
@@ -45688,7 +45924,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
45688
45924
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
45689
45925
  }
45690
45926
  try {
45691
- const quarantinePath = join27(directory, ".swarm", "knowledge-quarantined.jsonl");
45927
+ const quarantinePath = join28(directory, ".swarm", "knowledge-quarantined.jsonl");
45692
45928
  const entries = await readKnowledge(quarantinePath);
45693
45929
  const resolved = resolveEntryByPrefix(entries, inputId);
45694
45930
  if ("error" in resolved) {
@@ -46663,15 +46899,15 @@ var init_scoring = __esm(() => {
46663
46899
 
46664
46900
  // src/memory/local-jsonl-provider.ts
46665
46901
  import { randomUUID as randomUUID4 } from "crypto";
46666
- import { existsSync as existsSync19 } from "fs";
46902
+ import { existsSync as existsSync21 } from "fs";
46667
46903
  import {
46668
- appendFile as appendFile4,
46669
- mkdir as mkdir8,
46670
- readFile as readFile8,
46904
+ appendFile as appendFile5,
46905
+ mkdir as mkdir9,
46906
+ readFile as readFile10,
46671
46907
  rename as rename6,
46672
46908
  writeFile as writeFile9
46673
46909
  } from "fs/promises";
46674
- import * as path30 from "path";
46910
+ import * as path31 from "path";
46675
46911
 
46676
46912
  class LocalJsonlMemoryProvider {
46677
46913
  name = "local-jsonl";
@@ -46687,7 +46923,7 @@ class LocalJsonlMemoryProvider {
46687
46923
  pathFor(file3) {
46688
46924
  const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
46689
46925
  const filename = file3 === "memories" ? "memories.jsonl" : file3 === "proposals" ? "proposals.jsonl" : "audit.jsonl";
46690
- return validateSwarmPath(this.rootDirectory, path30.join(storageDir, filename));
46926
+ return validateSwarmPath(this.rootDirectory, path31.join(storageDir, filename));
46691
46927
  }
46692
46928
  async initialize() {
46693
46929
  if (this.initialized)
@@ -47014,9 +47250,9 @@ function validateLoadedProposals(values, config3) {
47014
47250
  return { records, invalidCount };
47015
47251
  }
47016
47252
  async function readJsonl(filePath) {
47017
- if (!existsSync19(filePath))
47253
+ if (!existsSync21(filePath))
47018
47254
  return [];
47019
- const content = await readFile8(filePath, "utf-8");
47255
+ const content = await readFile10(filePath, "utf-8");
47020
47256
  const records = [];
47021
47257
  for (const line of content.split(`
47022
47258
  `)) {
@@ -47070,12 +47306,12 @@ function parseRecallUsageEvent(event) {
47070
47306
  }
47071
47307
  }
47072
47308
  async function appendJsonl(filePath, value) {
47073
- await mkdir8(path30.dirname(filePath), { recursive: true });
47074
- await appendFile4(filePath, `${JSON.stringify(value)}
47309
+ await mkdir9(path31.dirname(filePath), { recursive: true });
47310
+ await appendFile5(filePath, `${JSON.stringify(value)}
47075
47311
  `, "utf-8");
47076
47312
  }
47077
47313
  async function writeJsonlAtomic(filePath, values) {
47078
- await mkdir8(path30.dirname(filePath), { recursive: true });
47314
+ await mkdir9(path31.dirname(filePath), { recursive: true });
47079
47315
  const tmp = `${filePath}.tmp.${randomUUID4()}`;
47080
47316
  const content = values.map((value) => JSON.stringify(value)).join(`
47081
47317
  `) + (values.length > 0 ? `
@@ -47100,9 +47336,9 @@ var init_prompt_block = __esm(() => {
47100
47336
  });
47101
47337
 
47102
47338
  // src/memory/jsonl-migration.ts
47103
- import { existsSync as existsSync20 } from "fs";
47104
- import { copyFile, mkdir as mkdir9, readFile as readFile9, stat as stat3, writeFile as writeFile10 } from "fs/promises";
47105
- import * as path31 from "path";
47339
+ import { existsSync as existsSync22 } from "fs";
47340
+ import { copyFile, mkdir as mkdir10, readFile as readFile11, stat as stat3, writeFile as writeFile10 } from "fs/promises";
47341
+ import * as path32 from "path";
47106
47342
  function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
47107
47343
  const resolved = resolveConfig(config3);
47108
47344
  const storageDir = resolved.storageDir.replace(/^\.swarm[/\\]?/, "");
@@ -47116,8 +47352,8 @@ function resolveSqliteDatabasePath(rootDirectory, config3 = {}) {
47116
47352
  async function readLegacyJsonl(rootDirectory, config3 = {}) {
47117
47353
  const resolved = resolveConfig(config3);
47118
47354
  const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
47119
- const memoryLoad = await readMemoryJsonl(path31.join(storageDir, "memories.jsonl"), resolved);
47120
- const proposalLoad = await readProposalJsonl(path31.join(storageDir, "proposals.jsonl"), resolved);
47355
+ const memoryLoad = await readMemoryJsonl(path32.join(storageDir, "memories.jsonl"), resolved);
47356
+ const proposalLoad = await readProposalJsonl(path32.join(storageDir, "proposals.jsonl"), resolved);
47121
47357
  return {
47122
47358
  memories: memoryLoad.records,
47123
47359
  proposals: proposalLoad.records,
@@ -47127,15 +47363,15 @@ async function readLegacyJsonl(rootDirectory, config3 = {}) {
47127
47363
  }
47128
47364
  async function backupLegacyJsonl(rootDirectory, config3 = {}) {
47129
47365
  const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
47130
- const backupDir = path31.join(storageDir, "backups");
47131
- await mkdir9(backupDir, { recursive: true });
47366
+ const backupDir = path32.join(storageDir, "backups");
47367
+ await mkdir10(backupDir, { recursive: true });
47132
47368
  const results = [];
47133
47369
  for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
47134
- const source = path31.join(storageDir, filename);
47135
- if (!existsSync20(source))
47370
+ const source = path32.join(storageDir, filename);
47371
+ if (!existsSync22(source))
47136
47372
  continue;
47137
- const backup = path31.join(backupDir, `${filename}.pre-sqlite-migration`);
47138
- if (existsSync20(backup)) {
47373
+ const backup = path32.join(backupDir, `${filename}.pre-sqlite-migration`);
47374
+ if (existsSync22(backup)) {
47139
47375
  results.push({ source, backup, created: false });
47140
47376
  continue;
47141
47377
  }
@@ -47145,27 +47381,27 @@ async function backupLegacyJsonl(rootDirectory, config3 = {}) {
47145
47381
  return results;
47146
47382
  }
47147
47383
  async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
47148
- const exportDir = path31.join(resolveMemoryStorageDir(rootDirectory, config3), "export");
47149
- await mkdir9(exportDir, { recursive: true });
47150
- const memoriesPath = path31.join(exportDir, "memories.jsonl");
47151
- const proposalsPath = path31.join(exportDir, "proposals.jsonl");
47384
+ const exportDir = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "export");
47385
+ await mkdir10(exportDir, { recursive: true });
47386
+ const memoriesPath = path32.join(exportDir, "memories.jsonl");
47387
+ const proposalsPath = path32.join(exportDir, "proposals.jsonl");
47152
47388
  await writeFile10(memoriesPath, toJsonl(memories), "utf-8");
47153
47389
  await writeFile10(proposalsPath, toJsonl(proposals), "utf-8");
47154
47390
  return { directory: exportDir, memoriesPath, proposalsPath };
47155
47391
  }
47156
47392
  async function writeMigrationReport(rootDirectory, report, config3 = {}) {
47157
- const reportPath = path31.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
47158
- await mkdir9(path31.dirname(reportPath), { recursive: true });
47393
+ const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
47394
+ await mkdir10(path32.dirname(reportPath), { recursive: true });
47159
47395
  await writeFile10(reportPath, `${JSON.stringify(report, null, 2)}
47160
47396
  `, "utf-8");
47161
47397
  return reportPath;
47162
47398
  }
47163
47399
  async function readMigrationReport(rootDirectory, config3 = {}) {
47164
- const reportPath = path31.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
47165
- if (!existsSync20(reportPath))
47400
+ const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
47401
+ if (!existsSync22(reportPath))
47166
47402
  return null;
47167
47403
  try {
47168
- return JSON.parse(await readFile9(reportPath, "utf-8"));
47404
+ return JSON.parse(await readFile11(reportPath, "utf-8"));
47169
47405
  } catch {
47170
47406
  return null;
47171
47407
  }
@@ -47174,15 +47410,15 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
47174
47410
  const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
47175
47411
  const statuses = [];
47176
47412
  for (const file3 of ["memories.jsonl", "proposals.jsonl"]) {
47177
- const filePath = path31.join(storageDir, file3);
47413
+ const filePath = path32.join(storageDir, file3);
47178
47414
  let sizeBytes = 0;
47179
- if (existsSync20(filePath)) {
47415
+ if (existsSync22(filePath)) {
47180
47416
  sizeBytes = (await stat3(filePath)).size;
47181
47417
  }
47182
47418
  statuses.push({
47183
47419
  file: file3,
47184
47420
  path: filePath,
47185
- exists: existsSync20(filePath),
47421
+ exists: existsSync22(filePath),
47186
47422
  sizeBytes
47187
47423
  });
47188
47424
  }
@@ -47263,10 +47499,10 @@ async function readProposalJsonl(filePath, config3) {
47263
47499
  return { records, invalidRows, totalRows: rows.totalRows };
47264
47500
  }
47265
47501
  async function readJsonlRows(filePath) {
47266
- if (!existsSync20(filePath)) {
47502
+ if (!existsSync22(filePath)) {
47267
47503
  return { rows: [], invalidRows: [], totalRows: 0 };
47268
47504
  }
47269
- const content = await readFile9(filePath, "utf-8");
47505
+ const content = await readFile11(filePath, "utf-8");
47270
47506
  const rows = [];
47271
47507
  const invalidRows = [];
47272
47508
  let totalRows = 0;
@@ -47303,7 +47539,7 @@ var init_jsonl_migration = __esm(() => {
47303
47539
  import { randomUUID as randomUUID5 } from "crypto";
47304
47540
  import { mkdirSync as mkdirSync13 } from "fs";
47305
47541
  import { createRequire as createRequire2 } from "module";
47306
- import * as path32 from "path";
47542
+ import * as path33 from "path";
47307
47543
  function loadDatabaseCtor2() {
47308
47544
  if (_DatabaseCtor2)
47309
47545
  return _DatabaseCtor2;
@@ -47361,7 +47597,7 @@ class SQLiteMemoryProvider {
47361
47597
  if (this.initialized)
47362
47598
  return;
47363
47599
  const dbPath = this.databasePath();
47364
- mkdirSync13(path32.dirname(dbPath), { recursive: true });
47600
+ mkdirSync13(path33.dirname(dbPath), { recursive: true });
47365
47601
  const Db = loadDatabaseCtor2();
47366
47602
  this.db = new Db(dbPath);
47367
47603
  this.db.run("PRAGMA journal_mode = WAL;");
@@ -47626,8 +47862,8 @@ class SQLiteMemoryProvider {
47626
47862
  const row = this.requireDb().query("SELECT version, name FROM schema_migrations WHERE name = ? LIMIT 1").get(name);
47627
47863
  return Boolean(row);
47628
47864
  }
47629
- markMigration(version4, name) {
47630
- this.requireDb().run("INSERT OR IGNORE INTO schema_migrations (version, name) VALUES (?, ?)", [version4, name]);
47865
+ markMigration(version5, name) {
47866
+ this.requireDb().run("INSERT OR IGNORE INTO schema_migrations (version, name) VALUES (?, ?)", [version5, name]);
47631
47867
  }
47632
47868
  selectRecallCandidates(request, scopedRecords) {
47633
47869
  const ftsQuery = buildFtsQuery(request);
@@ -48247,9 +48483,9 @@ var init_gateway = __esm(() => {
48247
48483
  // src/memory/evaluation.ts
48248
48484
  import * as fs13 from "fs/promises";
48249
48485
  import * as os7 from "os";
48250
- import * as path33 from "path";
48486
+ import * as path34 from "path";
48251
48487
  async function evaluateMemoryRecallFixtures(options) {
48252
- const fixtureDirectory = path33.resolve(options.fixtureDirectory);
48488
+ const fixtureDirectory = path34.resolve(options.fixtureDirectory);
48253
48489
  const providers = options.providers ?? DEFAULT_PROVIDERS;
48254
48490
  const modes = options.modes ?? DEFAULT_MODES;
48255
48491
  const generatedAt = new Date().toISOString();
@@ -48258,7 +48494,7 @@ async function evaluateMemoryRecallFixtures(options) {
48258
48494
  for (const fixture of fixtures) {
48259
48495
  const materialized = materializeFixture(fixture);
48260
48496
  for (const providerName of providers) {
48261
- const tempRoot = await fs13.realpath(await fs13.mkdtemp(path33.join(os7.tmpdir(), "swarm-memory-eval-")));
48497
+ const tempRoot = await fs13.realpath(await fs13.mkdtemp(path34.join(os7.tmpdir(), "swarm-memory-eval-")));
48262
48498
  const provider = createEvaluationProvider(providerName, tempRoot);
48263
48499
  try {
48264
48500
  await provider.initialize?.();
@@ -48302,7 +48538,7 @@ async function loadRecallEvaluationFixtures(fixtureDirectory) {
48302
48538
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
48303
48539
  const fixtures = [];
48304
48540
  for (const file3 of files) {
48305
- const raw = await fs13.readFile(path33.join(fixtureDirectory, file3), "utf-8");
48541
+ const raw = await fs13.readFile(path34.join(fixtureDirectory, file3), "utf-8");
48306
48542
  fixtures.push(validateFixture(JSON.parse(raw), file3));
48307
48543
  }
48308
48544
  return fixtures;
@@ -48640,8 +48876,8 @@ var init_memory = __esm(() => {
48640
48876
  });
48641
48877
 
48642
48878
  // src/commands/memory.ts
48643
- import { existsSync as existsSync21 } from "fs";
48644
- import * as path34 from "path";
48879
+ import { existsSync as existsSync23 } from "fs";
48880
+ import * as path35 from "path";
48645
48881
  import { fileURLToPath as fileURLToPath2 } from "url";
48646
48882
  async function handleMemoryCommand(_directory, _args) {
48647
48883
  return [
@@ -48672,7 +48908,7 @@ async function handleMemoryStatusCommand(directory, _args) {
48672
48908
  `- Provider: \`${config3.provider}\``,
48673
48909
  `- Storage: \`${storageDir}\``,
48674
48910
  `- SQLite path: \`${sqlitePath}\``,
48675
- `- SQLite database exists: \`${existsSync21(sqlitePath)}\``,
48911
+ `- SQLite database exists: \`${existsSync23(sqlitePath)}\``,
48676
48912
  `- Automatic destructive cleanup: \`disabled\``,
48677
48913
  "",
48678
48914
  "### Legacy JSONL"
@@ -48911,7 +49147,7 @@ function resolveCommandMemoryConfig(directory) {
48911
49147
  }
48912
49148
  function parseEvaluateArgs(directory, args) {
48913
49149
  let json3 = false;
48914
- let fixtureDirectory = path34.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
49150
+ let fixtureDirectory = path35.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
48915
49151
  for (let i = 0;i < args.length; i++) {
48916
49152
  const arg = args[i];
48917
49153
  if (arg === "--json") {
@@ -48925,7 +49161,7 @@ function parseEvaluateArgs(directory, args) {
48925
49161
  error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
48926
49162
  };
48927
49163
  }
48928
- fixtureDirectory = path34.resolve(directory, next);
49164
+ fixtureDirectory = path35.resolve(directory, next);
48929
49165
  i++;
48930
49166
  continue;
48931
49167
  }
@@ -48958,15 +49194,15 @@ function parseMaintenanceArgs(args, options) {
48958
49194
  return { limit, confirm };
48959
49195
  }
48960
49196
  function resolvePackageRootFromModule(modulePath) {
48961
- const moduleDir = path34.dirname(modulePath);
48962
- const leaf = path34.basename(moduleDir);
49197
+ const moduleDir = path35.dirname(modulePath);
49198
+ const leaf = path35.basename(moduleDir);
48963
49199
  if (leaf === "commands" || leaf === "cli") {
48964
- return path34.resolve(moduleDir, "..", "..");
49200
+ return path35.resolve(moduleDir, "..", "..");
48965
49201
  }
48966
49202
  if (leaf === "dist") {
48967
- return path34.resolve(moduleDir, "..");
49203
+ return path35.resolve(moduleDir, "..");
48968
49204
  }
48969
- return path34.resolve(moduleDir, "..");
49205
+ return path35.resolve(moduleDir, "..");
48970
49206
  }
48971
49207
  function formatMigrationResult(label, report) {
48972
49208
  if (!report) {
@@ -49085,7 +49321,7 @@ var PACKAGE_ROOT;
49085
49321
  var init_memory2 = __esm(() => {
49086
49322
  init_loader();
49087
49323
  init_memory();
49088
- PACKAGE_ROOT = path34.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
49324
+ PACKAGE_ROOT = path35.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
49089
49325
  });
49090
49326
 
49091
49327
  // src/services/plan-service.ts
@@ -49473,7 +49709,7 @@ var init_path_security = () => {};
49473
49709
 
49474
49710
  // src/tools/lint.ts
49475
49711
  import * as fs14 from "fs";
49476
- import * as path35 from "path";
49712
+ import * as path36 from "path";
49477
49713
  function validateArgs(args) {
49478
49714
  if (typeof args !== "object" || args === null)
49479
49715
  return false;
@@ -49484,9 +49720,9 @@ function validateArgs(args) {
49484
49720
  }
49485
49721
  function getLinterCommand(linter, mode, projectDir) {
49486
49722
  const isWindows = process.platform === "win32";
49487
- const binDir = path35.join(projectDir, "node_modules", ".bin");
49488
- const biomeBin = isWindows ? path35.join(binDir, "biome.EXE") : path35.join(binDir, "biome");
49489
- const eslintBin = isWindows ? path35.join(binDir, "eslint.cmd") : path35.join(binDir, "eslint");
49723
+ const binDir = path36.join(projectDir, "node_modules", ".bin");
49724
+ const biomeBin = isWindows ? path36.join(binDir, "biome.EXE") : path36.join(binDir, "biome");
49725
+ const eslintBin = isWindows ? path36.join(binDir, "eslint.cmd") : path36.join(binDir, "eslint");
49490
49726
  switch (linter) {
49491
49727
  case "biome":
49492
49728
  if (mode === "fix") {
@@ -49502,7 +49738,7 @@ function getLinterCommand(linter, mode, projectDir) {
49502
49738
  }
49503
49739
  function getAdditionalLinterCommand(linter, mode, cwd) {
49504
49740
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
49505
- const gradlew = fs14.existsSync(path35.join(cwd, gradlewName)) ? path35.join(cwd, gradlewName) : null;
49741
+ const gradlew = fs14.existsSync(path36.join(cwd, gradlewName)) ? path36.join(cwd, gradlewName) : null;
49506
49742
  switch (linter) {
49507
49743
  case "ruff":
49508
49744
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -49536,10 +49772,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
49536
49772
  }
49537
49773
  }
49538
49774
  function detectRuff(cwd) {
49539
- if (fs14.existsSync(path35.join(cwd, "ruff.toml")))
49775
+ if (fs14.existsSync(path36.join(cwd, "ruff.toml")))
49540
49776
  return isCommandAvailable("ruff");
49541
49777
  try {
49542
- const pyproject = path35.join(cwd, "pyproject.toml");
49778
+ const pyproject = path36.join(cwd, "pyproject.toml");
49543
49779
  if (fs14.existsSync(pyproject)) {
49544
49780
  const content = fs14.readFileSync(pyproject, "utf-8");
49545
49781
  if (content.includes("[tool.ruff]"))
@@ -49549,19 +49785,19 @@ function detectRuff(cwd) {
49549
49785
  return false;
49550
49786
  }
49551
49787
  function detectClippy(cwd) {
49552
- return fs14.existsSync(path35.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
49788
+ return fs14.existsSync(path36.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
49553
49789
  }
49554
49790
  function detectGolangciLint(cwd) {
49555
- return fs14.existsSync(path35.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
49791
+ return fs14.existsSync(path36.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
49556
49792
  }
49557
49793
  function detectCheckstyle(cwd) {
49558
- const hasMaven = fs14.existsSync(path35.join(cwd, "pom.xml"));
49559
- const hasGradle = fs14.existsSync(path35.join(cwd, "build.gradle")) || fs14.existsSync(path35.join(cwd, "build.gradle.kts"));
49560
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs14.existsSync(path35.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
49794
+ const hasMaven = fs14.existsSync(path36.join(cwd, "pom.xml"));
49795
+ const hasGradle = fs14.existsSync(path36.join(cwd, "build.gradle")) || fs14.existsSync(path36.join(cwd, "build.gradle.kts"));
49796
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs14.existsSync(path36.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
49561
49797
  return (hasMaven || hasGradle) && hasBinary;
49562
49798
  }
49563
49799
  function detectKtlint(cwd) {
49564
- const hasKotlin = fs14.existsSync(path35.join(cwd, "build.gradle.kts")) || fs14.existsSync(path35.join(cwd, "build.gradle")) || (() => {
49800
+ const hasKotlin = fs14.existsSync(path36.join(cwd, "build.gradle.kts")) || fs14.existsSync(path36.join(cwd, "build.gradle")) || (() => {
49565
49801
  try {
49566
49802
  return fs14.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
49567
49803
  } catch {
@@ -49580,11 +49816,11 @@ function detectDotnetFormat(cwd) {
49580
49816
  }
49581
49817
  }
49582
49818
  function detectCppcheck(cwd) {
49583
- if (fs14.existsSync(path35.join(cwd, "CMakeLists.txt"))) {
49819
+ if (fs14.existsSync(path36.join(cwd, "CMakeLists.txt"))) {
49584
49820
  return isCommandAvailable("cppcheck");
49585
49821
  }
49586
49822
  try {
49587
- const dirsToCheck = [cwd, path35.join(cwd, "src")];
49823
+ const dirsToCheck = [cwd, path36.join(cwd, "src")];
49588
49824
  const hasCpp = dirsToCheck.some((dir) => {
49589
49825
  try {
49590
49826
  return fs14.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
@@ -49598,13 +49834,13 @@ function detectCppcheck(cwd) {
49598
49834
  }
49599
49835
  }
49600
49836
  function detectSwiftlint(cwd) {
49601
- return fs14.existsSync(path35.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
49837
+ return fs14.existsSync(path36.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
49602
49838
  }
49603
49839
  function detectDartAnalyze(cwd) {
49604
- return fs14.existsSync(path35.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
49840
+ return fs14.existsSync(path36.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
49605
49841
  }
49606
49842
  function detectRubocop(cwd) {
49607
- return (fs14.existsSync(path35.join(cwd, "Gemfile")) || fs14.existsSync(path35.join(cwd, "gems.rb")) || fs14.existsSync(path35.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
49843
+ return (fs14.existsSync(path36.join(cwd, "Gemfile")) || fs14.existsSync(path36.join(cwd, "gems.rb")) || fs14.existsSync(path36.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
49608
49844
  }
49609
49845
  function detectAdditionalLinter(cwd) {
49610
49846
  if (detectRuff(cwd))
@@ -49632,10 +49868,10 @@ function detectAdditionalLinter(cwd) {
49632
49868
  function findBinInAncestors(startDir, binName) {
49633
49869
  let dir = startDir;
49634
49870
  while (true) {
49635
- const candidate = path35.join(dir, "node_modules", ".bin", binName);
49871
+ const candidate = path36.join(dir, "node_modules", ".bin", binName);
49636
49872
  if (fs14.existsSync(candidate))
49637
49873
  return candidate;
49638
- const parent = path35.dirname(dir);
49874
+ const parent = path36.dirname(dir);
49639
49875
  if (parent === dir)
49640
49876
  break;
49641
49877
  dir = parent;
@@ -49644,10 +49880,10 @@ function findBinInAncestors(startDir, binName) {
49644
49880
  }
49645
49881
  function findBinInEnvPath(binName) {
49646
49882
  const searchPath = process.env.PATH ?? "";
49647
- for (const dir of searchPath.split(path35.delimiter)) {
49883
+ for (const dir of searchPath.split(path36.delimiter)) {
49648
49884
  if (!dir)
49649
49885
  continue;
49650
- const candidate = path35.join(dir, binName);
49886
+ const candidate = path36.join(dir, binName);
49651
49887
  if (fs14.existsSync(candidate))
49652
49888
  return candidate;
49653
49889
  }
@@ -49660,13 +49896,13 @@ async function detectAvailableLinter(directory) {
49660
49896
  return null;
49661
49897
  const projectDir = directory;
49662
49898
  const isWindows = process.platform === "win32";
49663
- const biomeBin = isWindows ? path35.join(projectDir, "node_modules", ".bin", "biome.EXE") : path35.join(projectDir, "node_modules", ".bin", "biome");
49664
- const eslintBin = isWindows ? path35.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path35.join(projectDir, "node_modules", ".bin", "eslint");
49899
+ const biomeBin = isWindows ? path36.join(projectDir, "node_modules", ".bin", "biome.EXE") : path36.join(projectDir, "node_modules", ".bin", "biome");
49900
+ const eslintBin = isWindows ? path36.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path36.join(projectDir, "node_modules", ".bin", "eslint");
49665
49901
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
49666
49902
  if (localResult)
49667
49903
  return localResult;
49668
- const biomeAncestor = findBinInAncestors(path35.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
49669
- const eslintAncestor = findBinInAncestors(path35.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
49904
+ const biomeAncestor = findBinInAncestors(path36.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
49905
+ const eslintAncestor = findBinInAncestors(path36.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
49670
49906
  if (biomeAncestor || eslintAncestor) {
49671
49907
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
49672
49908
  }
@@ -49889,7 +50125,7 @@ For Rust: rustup component add clippy`
49889
50125
 
49890
50126
  // src/tools/secretscan.ts
49891
50127
  import * as fs15 from "fs";
49892
- import * as path36 from "path";
50128
+ import * as path37 from "path";
49893
50129
  function calculateShannonEntropy(str) {
49894
50130
  if (str.length === 0)
49895
50131
  return 0;
@@ -49937,7 +50173,7 @@ function isGlobOrPathPattern(pattern) {
49937
50173
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
49938
50174
  }
49939
50175
  function loadSecretScanIgnore(scanDir) {
49940
- const ignorePath = path36.join(scanDir, ".secretscanignore");
50176
+ const ignorePath = path37.join(scanDir, ".secretscanignore");
49941
50177
  try {
49942
50178
  if (!fs15.existsSync(ignorePath))
49943
50179
  return [];
@@ -49960,7 +50196,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
49960
50196
  if (exactNames.has(entry))
49961
50197
  return true;
49962
50198
  for (const pattern of globPatterns) {
49963
- if (path36.matchesGlob(relPath, pattern))
50199
+ if (path37.matchesGlob(relPath, pattern))
49964
50200
  return true;
49965
50201
  }
49966
50202
  return false;
@@ -49981,7 +50217,7 @@ function validateDirectoryInput(dir) {
49981
50217
  return null;
49982
50218
  }
49983
50219
  function isBinaryFile(filePath, buffer) {
49984
- const ext = path36.extname(filePath).toLowerCase();
50220
+ const ext = path37.extname(filePath).toLowerCase();
49985
50221
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
49986
50222
  return true;
49987
50223
  }
@@ -50117,9 +50353,9 @@ function isSymlinkLoop(realPath, visited) {
50117
50353
  return false;
50118
50354
  }
50119
50355
  function isPathWithinScope(realPath, scanDir) {
50120
- const resolvedScanDir = path36.resolve(scanDir);
50121
- const resolvedRealPath = path36.resolve(realPath);
50122
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path36.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
50356
+ const resolvedScanDir = path37.resolve(scanDir);
50357
+ const resolvedRealPath = path37.resolve(realPath);
50358
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path37.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
50123
50359
  }
50124
50360
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
50125
50361
  skippedDirs: 0,
@@ -50145,8 +50381,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
50145
50381
  return a.localeCompare(b);
50146
50382
  });
50147
50383
  for (const entry of entries) {
50148
- const fullPath = path36.join(dir, entry);
50149
- const relPath = path36.relative(scanDir, fullPath).replace(/\\/g, "/");
50384
+ const fullPath = path37.join(dir, entry);
50385
+ const relPath = path37.relative(scanDir, fullPath).replace(/\\/g, "/");
50150
50386
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
50151
50387
  stats.skippedDirs++;
50152
50388
  continue;
@@ -50181,7 +50417,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
50181
50417
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
50182
50418
  files.push(...subFiles);
50183
50419
  } else if (lstat.isFile()) {
50184
- const ext = path36.extname(fullPath).toLowerCase();
50420
+ const ext = path37.extname(fullPath).toLowerCase();
50185
50421
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
50186
50422
  files.push(fullPath);
50187
50423
  } else {
@@ -50441,7 +50677,7 @@ var init_secretscan = __esm(() => {
50441
50677
  }
50442
50678
  }
50443
50679
  try {
50444
- const _scanDirRaw = path36.resolve(directory);
50680
+ const _scanDirRaw = path37.resolve(directory);
50445
50681
  const scanDir = (() => {
50446
50682
  try {
50447
50683
  return fs15.realpathSync(_scanDirRaw);
@@ -50588,7 +50824,7 @@ var init_secretscan = __esm(() => {
50588
50824
 
50589
50825
  // src/lang/default-backend.ts
50590
50826
  import * as fs16 from "fs";
50591
- import * as path37 from "path";
50827
+ import * as path38 from "path";
50592
50828
  function detectFileExists(dir, pattern) {
50593
50829
  if (pattern.includes("*") || pattern.includes("?")) {
50594
50830
  try {
@@ -50600,7 +50836,7 @@ function detectFileExists(dir, pattern) {
50600
50836
  }
50601
50837
  }
50602
50838
  try {
50603
- fs16.accessSync(path37.join(dir, pattern));
50839
+ fs16.accessSync(path38.join(dir, pattern));
50604
50840
  return true;
50605
50841
  } catch {
50606
50842
  return false;
@@ -50728,8 +50964,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
50728
50964
  return ["mvn", "test"];
50729
50965
  case "gradle": {
50730
50966
  const isWindows = process.platform === "win32";
50731
- const hasGradlewBat = fs16.existsSync(path37.join(dir, "gradlew.bat"));
50732
- const hasGradlew = fs16.existsSync(path37.join(dir, "gradlew"));
50967
+ const hasGradlewBat = fs16.existsSync(path38.join(dir, "gradlew.bat"));
50968
+ const hasGradlew = fs16.existsSync(path38.join(dir, "gradlew"));
50733
50969
  if (hasGradlewBat && isWindows)
50734
50970
  return ["gradlew.bat", "test"];
50735
50971
  if (hasGradlew)
@@ -50746,7 +50982,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
50746
50982
  "cmake-build-release",
50747
50983
  "out"
50748
50984
  ];
50749
- const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path37.join(dir, d, "CMakeCache.txt"))) ?? "build";
50985
+ const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path38.join(dir, d, "CMakeCache.txt"))) ?? "build";
50750
50986
  return ["ctest", "--test-dir", actualBuildDir];
50751
50987
  }
50752
50988
  case "swift-test":
@@ -51033,17 +51269,17 @@ async function defaultSelectBuildCommand(profile, dir) {
51033
51269
  return null;
51034
51270
  }
51035
51271
  async function defaultTestFilesFor(profile, sourceFile, dir) {
51036
- const ext = path37.extname(sourceFile);
51272
+ const ext = path38.extname(sourceFile);
51037
51273
  if (!profile.extensions.includes(ext))
51038
51274
  return [];
51039
- const base = path37.basename(sourceFile, ext);
51040
- const rel = path37.relative(dir, sourceFile);
51041
- const relDir = path37.dirname(rel);
51275
+ const base = path38.basename(sourceFile, ext);
51276
+ const rel = path38.relative(dir, sourceFile);
51277
+ const relDir = path38.dirname(rel);
51042
51278
  const stripSrc = relDir.replace(/^src(\/|\\)/, "");
51043
51279
  const candidates = new Set;
51044
51280
  for (const tDir of ["tests", "test", "__tests__", "spec"]) {
51045
51281
  for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
51046
- candidates.add(path37.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
51282
+ candidates.add(path38.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
51047
51283
  }
51048
51284
  }
51049
51285
  const existing = [];
@@ -51084,7 +51320,7 @@ var init_default_backend = __esm(() => {
51084
51320
 
51085
51321
  // src/lang/backends/go.ts
51086
51322
  import * as fs17 from "fs";
51087
- import * as path38 from "path";
51323
+ import * as path39 from "path";
51088
51324
  function extractImports(_sourceFile, source) {
51089
51325
  const out = new Set;
51090
51326
  IMPORT_REGEX_SINGLE.lastIndex = 0;
@@ -51110,7 +51346,7 @@ function extractImports(_sourceFile, source) {
51110
51346
  async function selectFramework(dir) {
51111
51347
  let content;
51112
51348
  try {
51113
- content = fs17.readFileSync(path38.join(dir, "go.mod"), "utf-8");
51349
+ content = fs17.readFileSync(path39.join(dir, "go.mod"), "utf-8");
51114
51350
  } catch {
51115
51351
  return null;
51116
51352
  }
@@ -51131,16 +51367,16 @@ async function selectFramework(dir) {
51131
51367
  async function selectEntryPoints(dir) {
51132
51368
  const points = [];
51133
51369
  try {
51134
- fs17.accessSync(path38.join(dir, "main.go"));
51370
+ fs17.accessSync(path39.join(dir, "main.go"));
51135
51371
  points.push("main.go");
51136
51372
  } catch {}
51137
51373
  try {
51138
- const cmdDir = path38.join(dir, "cmd");
51374
+ const cmdDir = path39.join(dir, "cmd");
51139
51375
  const subdirs = fs17.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
51140
51376
  for (const sub of subdirs) {
51141
- const main = path38.join("cmd", sub.name, "main.go");
51377
+ const main = path39.join("cmd", sub.name, "main.go");
51142
51378
  try {
51143
- fs17.accessSync(path38.join(dir, main));
51379
+ fs17.accessSync(path39.join(dir, main));
51144
51380
  points.push(main);
51145
51381
  } catch {}
51146
51382
  }
@@ -51171,7 +51407,7 @@ var init_go = __esm(() => {
51171
51407
 
51172
51408
  // src/lang/backends/python.ts
51173
51409
  import * as fs18 from "fs";
51174
- import * as path39 from "path";
51410
+ import * as path40 from "path";
51175
51411
  function parseImportTargets(rawTargets) {
51176
51412
  const cleaned = rawTargets.replace(/[()]/g, "").split(`
51177
51413
  `).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
@@ -51231,7 +51467,7 @@ async function selectFramework2(dir) {
51231
51467
  ];
51232
51468
  for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
51233
51469
  try {
51234
- const content = fs18.readFileSync(path39.join(dir, candidate), "utf-8");
51470
+ const content = fs18.readFileSync(path40.join(dir, candidate), "utf-8");
51235
51471
  const lower = content.toLowerCase();
51236
51472
  for (const [pkg, name] of candidates) {
51237
51473
  if (lower.includes(pkg)) {
@@ -51245,7 +51481,7 @@ async function selectFramework2(dir) {
51245
51481
  async function selectEntryPoints2(dir) {
51246
51482
  const points = new Set;
51247
51483
  try {
51248
- const content = fs18.readFileSync(path39.join(dir, "pyproject.toml"), "utf-8");
51484
+ const content = fs18.readFileSync(path40.join(dir, "pyproject.toml"), "utf-8");
51249
51485
  const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
51250
51486
  if (scriptsBlock) {
51251
51487
  for (const line of scriptsBlock[0].split(`
@@ -51260,7 +51496,7 @@ async function selectEntryPoints2(dir) {
51260
51496
  } catch {}
51261
51497
  for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
51262
51498
  try {
51263
- fs18.accessSync(path39.join(dir, name));
51499
+ fs18.accessSync(path40.join(dir, name));
51264
51500
  points.add(name);
51265
51501
  } catch {}
51266
51502
  }
@@ -51289,7 +51525,7 @@ var init_python = __esm(() => {
51289
51525
 
51290
51526
  // src/test-impact/analyzer.ts
51291
51527
  import fs19 from "fs";
51292
- import path40 from "path";
51528
+ import path41 from "path";
51293
51529
  function normalizePath(p) {
51294
51530
  return p.replace(/\\/g, "/");
51295
51531
  }
@@ -51310,8 +51546,8 @@ function resolveRelativeImport(fromDir, importPath) {
51310
51546
  if (!importPath.startsWith(".")) {
51311
51547
  return null;
51312
51548
  }
51313
- const resolved = path40.resolve(fromDir, importPath);
51314
- if (path40.extname(resolved)) {
51549
+ const resolved = path41.resolve(fromDir, importPath);
51550
+ if (path41.extname(resolved)) {
51315
51551
  if (fs19.existsSync(resolved) && fs19.statSync(resolved).isFile()) {
51316
51552
  return normalizePath(resolved);
51317
51553
  }
@@ -51331,20 +51567,20 @@ function resolvePythonImport(fromDir, module) {
51331
51567
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
51332
51568
  let baseDir = fromDir;
51333
51569
  for (let i = 1;i < leadingDots; i++) {
51334
- baseDir = path40.dirname(baseDir);
51570
+ baseDir = path41.dirname(baseDir);
51335
51571
  }
51336
51572
  const rest = module.slice(leadingDots);
51337
51573
  if (rest.length === 0) {
51338
- const initPath = path40.join(baseDir, "__init__.py");
51574
+ const initPath = path41.join(baseDir, "__init__.py");
51339
51575
  if (fs19.existsSync(initPath) && fs19.statSync(initPath).isFile()) {
51340
51576
  return normalizePath(initPath);
51341
51577
  }
51342
51578
  return null;
51343
51579
  }
51344
- const subpath = rest.replace(/\./g, path40.sep);
51580
+ const subpath = rest.replace(/\./g, path41.sep);
51345
51581
  const candidates = [
51346
- `${path40.join(baseDir, subpath)}.py`,
51347
- path40.join(baseDir, subpath, "__init__.py")
51582
+ `${path41.join(baseDir, subpath)}.py`,
51583
+ path41.join(baseDir, subpath, "__init__.py")
51348
51584
  ];
51349
51585
  for (const c of candidates) {
51350
51586
  if (fs19.existsSync(c) && fs19.statSync(c).isFile())
@@ -51353,7 +51589,7 @@ function resolvePythonImport(fromDir, module) {
51353
51589
  return null;
51354
51590
  }
51355
51591
  function findGoModule(fromDir) {
51356
- const resolved = path40.resolve(fromDir);
51592
+ const resolved = path41.resolve(fromDir);
51357
51593
  let cur = resolved;
51358
51594
  const walked = [];
51359
51595
  for (let i = 0;i < 16; i++) {
@@ -51365,7 +51601,7 @@ function findGoModule(fromDir) {
51365
51601
  }
51366
51602
  walked.push(cur);
51367
51603
  try {
51368
- const goMod = path40.join(cur, "go.mod");
51604
+ const goMod = path41.join(cur, "go.mod");
51369
51605
  const content = fs19.readFileSync(goMod, "utf-8");
51370
51606
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
51371
51607
  if (moduleMatch) {
@@ -51376,10 +51612,10 @@ function findGoModule(fromDir) {
51376
51612
  }
51377
51613
  } catch {}
51378
51614
  try {
51379
- fs19.accessSync(path40.join(cur, ".git"));
51615
+ fs19.accessSync(path41.join(cur, ".git"));
51380
51616
  break;
51381
51617
  } catch {}
51382
- const parent = path40.dirname(cur);
51618
+ const parent = path41.dirname(cur);
51383
51619
  if (parent === cur)
51384
51620
  break;
51385
51621
  cur = parent;
@@ -51391,12 +51627,12 @@ function findGoModule(fromDir) {
51391
51627
  function resolveGoImport(fromDir, importPath) {
51392
51628
  let dir = null;
51393
51629
  if (importPath.startsWith(".")) {
51394
- dir = path40.resolve(fromDir, importPath);
51630
+ dir = path41.resolve(fromDir, importPath);
51395
51631
  } else {
51396
51632
  const mod = findGoModule(fromDir);
51397
51633
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
51398
51634
  const subpath = importPath.slice(mod.modulePath.length);
51399
- dir = path40.join(mod.moduleRoot, subpath);
51635
+ dir = path41.join(mod.moduleRoot, subpath);
51400
51636
  }
51401
51637
  }
51402
51638
  if (dir === null)
@@ -51404,7 +51640,7 @@ function resolveGoImport(fromDir, importPath) {
51404
51640
  if (!fs19.existsSync(dir) || !fs19.statSync(dir).isDirectory())
51405
51641
  return [];
51406
51642
  try {
51407
- return fs19.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path40.join(dir, f)));
51643
+ return fs19.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path41.join(dir, f)));
51408
51644
  } catch {
51409
51645
  return [];
51410
51646
  }
@@ -51443,15 +51679,15 @@ function findTestFilesSync(cwd) {
51443
51679
  for (const entry of entries) {
51444
51680
  if (entry.isDirectory()) {
51445
51681
  if (!skipDirs.has(entry.name)) {
51446
- walk(path40.join(dir, entry.name), visitedInodes);
51682
+ walk(path41.join(dir, entry.name), visitedInodes);
51447
51683
  }
51448
51684
  } else if (entry.isFile()) {
51449
51685
  const name = entry.name;
51450
51686
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
51451
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path40.sep}tests${path40.sep}`) && name.endsWith(".py");
51687
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path41.sep}tests${path41.sep}`) && name.endsWith(".py");
51452
51688
  const isGoTest = /.+_test\.go$/.test(name);
51453
51689
  if (isTsTest || isPyTest || isGoTest) {
51454
- testFiles.push(normalizePath(path40.join(dir, entry.name)));
51690
+ testFiles.push(normalizePath(path41.join(dir, entry.name)));
51455
51691
  }
51456
51692
  }
51457
51693
  }
@@ -51476,8 +51712,8 @@ function extractImports3(content) {
51476
51712
  ];
51477
51713
  }
51478
51714
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
51479
- const ext = path40.extname(testFile).toLowerCase();
51480
- const testDir = path40.dirname(testFile);
51715
+ const ext = path41.extname(testFile).toLowerCase();
51716
+ const testDir = path41.dirname(testFile);
51481
51717
  function addEdge(source) {
51482
51718
  if (!impactMap[source])
51483
51719
  impactMap[source] = [];
@@ -51536,7 +51772,7 @@ async function buildImpactMap(cwd) {
51536
51772
  return impactMap;
51537
51773
  }
51538
51774
  async function loadImpactMap(cwd, options) {
51539
- const cachePath = path40.join(cwd, ".swarm", "cache", "impact-map.json");
51775
+ const cachePath = path41.join(cwd, ".swarm", "cache", "impact-map.json");
51540
51776
  if (fs19.existsSync(cachePath)) {
51541
51777
  try {
51542
51778
  const content = fs19.readFileSync(cachePath, "utf-8");
@@ -51569,12 +51805,12 @@ async function loadImpactMap(cwd, options) {
51569
51805
  return _internals25.buildImpactMap(cwd);
51570
51806
  }
51571
51807
  async function saveImpactMap(cwd, impactMap) {
51572
- if (!path40.isAbsolute(cwd)) {
51808
+ if (!path41.isAbsolute(cwd)) {
51573
51809
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
51574
51810
  }
51575
51811
  _internals25.validateProjectRoot(cwd);
51576
- const cacheDir2 = path40.join(cwd, ".swarm", "cache");
51577
- const cachePath = path40.join(cacheDir2, "impact-map.json");
51812
+ const cacheDir2 = path41.join(cwd, ".swarm", "cache");
51813
+ const cachePath = path41.join(cacheDir2, "impact-map.json");
51578
51814
  if (!fs19.existsSync(cacheDir2)) {
51579
51815
  fs19.mkdirSync(cacheDir2, { recursive: true });
51580
51816
  }
@@ -51606,7 +51842,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
51606
51842
  budgetExceeded = true;
51607
51843
  break;
51608
51844
  }
51609
- const normalizedChanged = normalizePath(path40.resolve(changedFile));
51845
+ const normalizedChanged = normalizePath(path41.resolve(changedFile));
51610
51846
  const tests = impactMap[normalizedChanged];
51611
51847
  if (tests && tests.length > 0) {
51612
51848
  for (const test of tests) {
@@ -51899,15 +52135,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
51899
52135
 
51900
52136
  // src/test-impact/history-store.ts
51901
52137
  import fs20 from "fs";
51902
- import path41 from "path";
52138
+ import path42 from "path";
51903
52139
  function getHistoryPath(workingDir) {
51904
52140
  if (!workingDir) {
51905
52141
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
51906
52142
  }
51907
- if (!path41.isAbsolute(workingDir)) {
52143
+ if (!path42.isAbsolute(workingDir)) {
51908
52144
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
51909
52145
  }
51910
- return path41.join(workingDir, ".swarm", "cache", "test-history.jsonl");
52146
+ return path42.join(workingDir, ".swarm", "cache", "test-history.jsonl");
51911
52147
  }
51912
52148
  function sanitizeErrorMessage(errorMessage) {
51913
52149
  if (errorMessage === undefined) {
@@ -51994,7 +52230,7 @@ function batchAppendTestRuns(records, workingDir) {
51994
52230
  }
51995
52231
  }
51996
52232
  const historyPath = getHistoryPath(workingDir);
51997
- const historyDir = path41.dirname(historyPath);
52233
+ const historyDir = path42.dirname(historyPath);
51998
52234
  _internals26.validateProjectRoot(workingDir);
51999
52235
  if (!fs20.existsSync(historyDir)) {
52000
52236
  fs20.mkdirSync(historyDir, { recursive: true });
@@ -52090,7 +52326,7 @@ var init_history_store = __esm(() => {
52090
52326
 
52091
52327
  // src/tools/resolve-working-directory.ts
52092
52328
  import * as fs21 from "fs";
52093
- import * as path42 from "path";
52329
+ import * as path43 from "path";
52094
52330
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
52095
52331
  if (workingDirectory == null || workingDirectory === "") {
52096
52332
  return { success: true, directory: fallbackDirectory };
@@ -52110,15 +52346,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
52110
52346
  };
52111
52347
  }
52112
52348
  }
52113
- const normalizedDir = path42.normalize(workingDirectory);
52114
- const pathParts = normalizedDir.split(path42.sep);
52349
+ const normalizedDir = path43.normalize(workingDirectory);
52350
+ const pathParts = normalizedDir.split(path43.sep);
52115
52351
  if (pathParts.includes("..")) {
52116
52352
  return {
52117
52353
  success: false,
52118
52354
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
52119
52355
  };
52120
52356
  }
52121
- const resolvedDir = path42.resolve(normalizedDir);
52357
+ const resolvedDir = path43.resolve(normalizedDir);
52122
52358
  let statResult;
52123
52359
  try {
52124
52360
  statResult = fs21.statSync(resolvedDir);
@@ -52134,7 +52370,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
52134
52370
  message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
52135
52371
  };
52136
52372
  }
52137
- const resolvedFallback = path42.resolve(fallbackDirectory);
52373
+ const resolvedFallback = path43.resolve(fallbackDirectory);
52138
52374
  let fallbackExists = false;
52139
52375
  try {
52140
52376
  fs21.statSync(resolvedFallback);
@@ -52144,7 +52380,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
52144
52380
  }
52145
52381
  if (workingDirectory != null && workingDirectory !== "") {
52146
52382
  if (fallbackExists) {
52147
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path42.sep);
52383
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path43.sep);
52148
52384
  if (isSubdirectory) {
52149
52385
  return {
52150
52386
  success: false,
@@ -52199,10 +52435,10 @@ var init_registry_backend = __esm(() => {
52199
52435
 
52200
52436
  // src/lang/backends/typescript.ts
52201
52437
  import * as fs22 from "fs";
52202
- import * as path43 from "path";
52438
+ import * as path44 from "path";
52203
52439
  function readPackageJsonRaw(dir) {
52204
52440
  try {
52205
- const content = fs22.readFileSync(path43.join(dir, "package.json"), "utf-8");
52441
+ const content = fs22.readFileSync(path44.join(dir, "package.json"), "utf-8");
52206
52442
  return JSON.parse(content);
52207
52443
  } catch {
52208
52444
  return null;
@@ -52422,7 +52658,7 @@ __export(exports_dispatch, {
52422
52658
  _internals: () => _internals28
52423
52659
  });
52424
52660
  import * as fs23 from "fs";
52425
- import * as path44 from "path";
52661
+ import * as path45 from "path";
52426
52662
  function safeReaddirSet(dir) {
52427
52663
  try {
52428
52664
  return new Set(fs23.readdirSync(dir));
@@ -52439,14 +52675,14 @@ function manifestHash(dir) {
52439
52675
  if (!entries.has(name))
52440
52676
  continue;
52441
52677
  try {
52442
- const stat4 = fs23.statSync(path44.join(dir, name));
52678
+ const stat4 = fs23.statSync(path45.join(dir, name));
52443
52679
  parts.push(`${name}:${stat4.size}:${stat4.mtimeMs}:${stat4.ino}`);
52444
52680
  } catch {}
52445
52681
  }
52446
52682
  return parts.join("|");
52447
52683
  }
52448
52684
  function findManifestRoot(start) {
52449
- const resolved = path44.resolve(start);
52685
+ const resolved = path45.resolve(start);
52450
52686
  const cached3 = manifestRootCache.get(resolved);
52451
52687
  if (cached3 !== undefined)
52452
52688
  return cached3;
@@ -52465,7 +52701,7 @@ function findManifestRoot(start) {
52465
52701
  return cur;
52466
52702
  }
52467
52703
  }
52468
- const parent = path44.dirname(cur);
52704
+ const parent = path45.dirname(cur);
52469
52705
  if (parent === cur)
52470
52706
  break;
52471
52707
  cur = parent;
@@ -52575,13 +52811,13 @@ var init_dispatch = __esm(() => {
52575
52811
 
52576
52812
  // src/tools/test-runner.ts
52577
52813
  import * as fs24 from "fs";
52578
- import * as path45 from "path";
52814
+ import * as path46 from "path";
52579
52815
  async function estimateFanOut(sourceFiles, cwd) {
52580
52816
  try {
52581
52817
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
52582
52818
  const uniqueTestFiles = new Set;
52583
52819
  for (const sourceFile of sourceFiles) {
52584
- const resolvedPath = path45.resolve(cwd, sourceFile);
52820
+ const resolvedPath = path46.resolve(cwd, sourceFile);
52585
52821
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
52586
52822
  const testFiles = impactMap[normalizedPath];
52587
52823
  if (testFiles) {
@@ -52659,14 +52895,14 @@ function hasDevDependency(devDeps, ...patterns) {
52659
52895
  return hasPackageJsonDependency(devDeps, ...patterns);
52660
52896
  }
52661
52897
  function detectGoTest(cwd) {
52662
- return fs24.existsSync(path45.join(cwd, "go.mod")) && isCommandAvailable("go");
52898
+ return fs24.existsSync(path46.join(cwd, "go.mod")) && isCommandAvailable("go");
52663
52899
  }
52664
52900
  function detectJavaMaven(cwd) {
52665
- return fs24.existsSync(path45.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
52901
+ return fs24.existsSync(path46.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
52666
52902
  }
52667
52903
  function detectGradle(cwd) {
52668
- const hasBuildFile = fs24.existsSync(path45.join(cwd, "build.gradle")) || fs24.existsSync(path45.join(cwd, "build.gradle.kts"));
52669
- const hasGradlew = fs24.existsSync(path45.join(cwd, "gradlew")) || fs24.existsSync(path45.join(cwd, "gradlew.bat"));
52904
+ const hasBuildFile = fs24.existsSync(path46.join(cwd, "build.gradle")) || fs24.existsSync(path46.join(cwd, "build.gradle.kts"));
52905
+ const hasGradlew = fs24.existsSync(path46.join(cwd, "gradlew")) || fs24.existsSync(path46.join(cwd, "gradlew.bat"));
52670
52906
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
52671
52907
  }
52672
52908
  function detectDotnetTest(cwd) {
@@ -52679,25 +52915,25 @@ function detectDotnetTest(cwd) {
52679
52915
  }
52680
52916
  }
52681
52917
  function detectCTest(cwd) {
52682
- const hasSource = fs24.existsSync(path45.join(cwd, "CMakeLists.txt"));
52683
- const hasBuildCache = fs24.existsSync(path45.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path45.join(cwd, "build", "CMakeCache.txt"));
52918
+ const hasSource = fs24.existsSync(path46.join(cwd, "CMakeLists.txt"));
52919
+ const hasBuildCache = fs24.existsSync(path46.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path46.join(cwd, "build", "CMakeCache.txt"));
52684
52920
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
52685
52921
  }
52686
52922
  function detectSwiftTest(cwd) {
52687
- return fs24.existsSync(path45.join(cwd, "Package.swift")) && isCommandAvailable("swift");
52923
+ return fs24.existsSync(path46.join(cwd, "Package.swift")) && isCommandAvailable("swift");
52688
52924
  }
52689
52925
  function detectDartTest(cwd) {
52690
- return fs24.existsSync(path45.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
52926
+ return fs24.existsSync(path46.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
52691
52927
  }
52692
52928
  function detectRSpec(cwd) {
52693
- const hasRSpecFile = fs24.existsSync(path45.join(cwd, ".rspec"));
52694
- const hasGemfile = fs24.existsSync(path45.join(cwd, "Gemfile"));
52695
- const hasSpecDir = fs24.existsSync(path45.join(cwd, "spec"));
52929
+ const hasRSpecFile = fs24.existsSync(path46.join(cwd, ".rspec"));
52930
+ const hasGemfile = fs24.existsSync(path46.join(cwd, "Gemfile"));
52931
+ const hasSpecDir = fs24.existsSync(path46.join(cwd, "spec"));
52696
52932
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
52697
52933
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
52698
52934
  }
52699
52935
  function detectMinitest(cwd) {
52700
- return fs24.existsSync(path45.join(cwd, "test")) && (fs24.existsSync(path45.join(cwd, "Gemfile")) || fs24.existsSync(path45.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
52936
+ return fs24.existsSync(path46.join(cwd, "test")) && (fs24.existsSync(path46.join(cwd, "Gemfile")) || fs24.existsSync(path46.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
52701
52937
  }
52702
52938
  async function detectTestFrameworkViaDispatch(cwd) {
52703
52939
  try {
@@ -52759,7 +52995,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
52759
52995
  async function detectTestFramework(cwd) {
52760
52996
  const baseDir = cwd;
52761
52997
  try {
52762
- const packageJsonPath = path45.join(baseDir, "package.json");
52998
+ const packageJsonPath = path46.join(baseDir, "package.json");
52763
52999
  if (fs24.existsSync(packageJsonPath)) {
52764
53000
  const content = fs24.readFileSync(packageJsonPath, "utf-8");
52765
53001
  const pkg = JSON.parse(content);
@@ -52780,16 +53016,16 @@ async function detectTestFramework(cwd) {
52780
53016
  return "jest";
52781
53017
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
52782
53018
  return "mocha";
52783
- if (fs24.existsSync(path45.join(baseDir, "bun.lockb")) || fs24.existsSync(path45.join(baseDir, "bun.lock"))) {
53019
+ if (fs24.existsSync(path46.join(baseDir, "bun.lockb")) || fs24.existsSync(path46.join(baseDir, "bun.lock"))) {
52784
53020
  if (scripts.test?.includes("bun"))
52785
53021
  return "bun";
52786
53022
  }
52787
53023
  }
52788
53024
  } catch {}
52789
53025
  try {
52790
- const pyprojectTomlPath = path45.join(baseDir, "pyproject.toml");
52791
- const setupCfgPath = path45.join(baseDir, "setup.cfg");
52792
- const requirementsTxtPath = path45.join(baseDir, "requirements.txt");
53026
+ const pyprojectTomlPath = path46.join(baseDir, "pyproject.toml");
53027
+ const setupCfgPath = path46.join(baseDir, "setup.cfg");
53028
+ const requirementsTxtPath = path46.join(baseDir, "requirements.txt");
52793
53029
  if (fs24.existsSync(pyprojectTomlPath)) {
52794
53030
  const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
52795
53031
  if (content.includes("[tool.pytest"))
@@ -52809,7 +53045,7 @@ async function detectTestFramework(cwd) {
52809
53045
  }
52810
53046
  } catch {}
52811
53047
  try {
52812
- const cargoTomlPath = path45.join(baseDir, "Cargo.toml");
53048
+ const cargoTomlPath = path46.join(baseDir, "Cargo.toml");
52813
53049
  if (fs24.existsSync(cargoTomlPath)) {
52814
53050
  const content = fs24.readFileSync(cargoTomlPath, "utf-8");
52815
53051
  if (content.includes("[dev-dependencies]")) {
@@ -52820,9 +53056,9 @@ async function detectTestFramework(cwd) {
52820
53056
  }
52821
53057
  } catch {}
52822
53058
  try {
52823
- const pesterConfigPath = path45.join(baseDir, "pester.config.ps1");
52824
- const pesterConfigJsonPath = path45.join(baseDir, "pester.config.ps1.json");
52825
- const pesterPs1Path = path45.join(baseDir, "tests.ps1");
53059
+ const pesterConfigPath = path46.join(baseDir, "pester.config.ps1");
53060
+ const pesterConfigJsonPath = path46.join(baseDir, "pester.config.ps1.json");
53061
+ const pesterPs1Path = path46.join(baseDir, "tests.ps1");
52826
53062
  if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
52827
53063
  return "pester";
52828
53064
  }
@@ -52851,12 +53087,12 @@ function isTestDirectoryPath(normalizedPath) {
52851
53087
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
52852
53088
  }
52853
53089
  function resolveWorkspacePath(file3, workingDir) {
52854
- return path45.isAbsolute(file3) ? path45.resolve(file3) : path45.resolve(workingDir, file3);
53090
+ return path46.isAbsolute(file3) ? path46.resolve(file3) : path46.resolve(workingDir, file3);
52855
53091
  }
52856
53092
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
52857
53093
  if (!preferRelative)
52858
53094
  return absolutePath;
52859
- return path45.relative(workingDir, absolutePath);
53095
+ return path46.relative(workingDir, absolutePath);
52860
53096
  }
52861
53097
  function dedupePush(target, value) {
52862
53098
  if (!target.includes(value)) {
@@ -52893,18 +53129,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
52893
53129
  }
52894
53130
  }
52895
53131
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
52896
- const relativeDir = path45.dirname(relativePath);
53132
+ const relativeDir = path46.dirname(relativePath);
52897
53133
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
52898
53134
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
52899
- const rootDir = path45.join(workingDir, dirName);
52900
- return nestedRelativeDir ? [rootDir, path45.join(rootDir, nestedRelativeDir)] : [rootDir];
53135
+ const rootDir = path46.join(workingDir, dirName);
53136
+ return nestedRelativeDir ? [rootDir, path46.join(rootDir, nestedRelativeDir)] : [rootDir];
52901
53137
  });
52902
53138
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
52903
53139
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
52904
- directories.push(path45.join(workingDir, "src/test/java", path45.dirname(normalizedRelativePath.slice("src/main/java/".length))));
53140
+ directories.push(path46.join(workingDir, "src/test/java", path46.dirname(normalizedRelativePath.slice("src/main/java/".length))));
52905
53141
  }
52906
53142
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
52907
- directories.push(path45.join(workingDir, "src/test/kotlin", path45.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
53143
+ directories.push(path46.join(workingDir, "src/test/kotlin", path46.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
52908
53144
  }
52909
53145
  return [...new Set(directories)];
52910
53146
  }
@@ -52932,23 +53168,23 @@ function isLanguageSpecificTestFile(basename7) {
52932
53168
  }
52933
53169
  function isConventionTestFilePath(filePath) {
52934
53170
  const normalizedPath = filePath.replace(/\\/g, "/");
52935
- const basename7 = path45.basename(filePath);
53171
+ const basename7 = path46.basename(filePath);
52936
53172
  return hasCompoundTestExtension(basename7) || basename7.includes(".spec.") || basename7.includes(".test.") || isLanguageSpecificTestFile(basename7) || isTestDirectoryPath(normalizedPath);
52937
53173
  }
52938
53174
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
52939
53175
  const testFiles = [];
52940
53176
  for (const file3 of sourceFiles) {
52941
53177
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
52942
- const relativeFile = path45.relative(workingDir, absoluteFile);
52943
- const basename7 = path45.basename(absoluteFile);
52944
- const dirname22 = path45.dirname(absoluteFile);
52945
- const preferRelativeOutput = !path45.isAbsolute(file3);
53178
+ const relativeFile = path46.relative(workingDir, absoluteFile);
53179
+ const basename7 = path46.basename(absoluteFile);
53180
+ const dirname23 = path46.dirname(absoluteFile);
53181
+ const preferRelativeOutput = !path46.isAbsolute(file3);
52946
53182
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
52947
53183
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
52948
53184
  continue;
52949
53185
  }
52950
53186
  const nameWithoutExt = basename7.replace(/\.[^.]+$/, "");
52951
- const ext = path45.extname(basename7);
53187
+ const ext = path46.extname(basename7);
52952
53188
  const genericTestNames = [
52953
53189
  `${nameWithoutExt}.spec${ext}`,
52954
53190
  `${nameWithoutExt}.test${ext}`
@@ -52957,7 +53193,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
52957
53193
  const colocatedCandidates = [
52958
53194
  ...genericTestNames,
52959
53195
  ...languageSpecificTestNames
52960
- ].map((candidateName) => path45.join(dirname22, candidateName));
53196
+ ].map((candidateName) => path46.join(dirname23, candidateName));
52961
53197
  const testDirectoryNames = [
52962
53198
  basename7,
52963
53199
  ...genericTestNames,
@@ -52966,8 +53202,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
52966
53202
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
52967
53203
  const possibleTestFiles = [
52968
53204
  ...colocatedCandidates,
52969
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path45.join(dirname22, dirName, candidateName))),
52970
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path45.join(candidateDir, candidateName)))
53205
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path46.join(dirname23, dirName, candidateName))),
53206
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path46.join(candidateDir, candidateName)))
52971
53207
  ];
52972
53208
  for (const testFile of possibleTestFiles) {
52973
53209
  if (fs24.existsSync(testFile)) {
@@ -52988,7 +53224,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
52988
53224
  try {
52989
53225
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
52990
53226
  const content = fs24.readFileSync(absoluteTestFile, "utf-8");
52991
- const testDir = path45.dirname(absoluteTestFile);
53227
+ const testDir = path46.dirname(absoluteTestFile);
52992
53228
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
52993
53229
  let match;
52994
53230
  match = importRegex.exec(content);
@@ -52996,8 +53232,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
52996
53232
  const importPath = match[1];
52997
53233
  let resolvedImport;
52998
53234
  if (importPath.startsWith(".")) {
52999
- resolvedImport = path45.resolve(testDir, importPath);
53000
- const existingExt = path45.extname(resolvedImport);
53235
+ resolvedImport = path46.resolve(testDir, importPath);
53236
+ const existingExt = path46.extname(resolvedImport);
53001
53237
  if (!existingExt) {
53002
53238
  for (const extToTry of [
53003
53239
  ".ts",
@@ -53017,12 +53253,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53017
53253
  } else {
53018
53254
  continue;
53019
53255
  }
53020
- const importBasename = path45.basename(resolvedImport, path45.extname(resolvedImport));
53021
- const importDir = path45.dirname(resolvedImport);
53256
+ const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
53257
+ const importDir = path46.dirname(resolvedImport);
53022
53258
  for (const sourceFile of absoluteSourceFiles) {
53023
- const sourceDir = path45.dirname(sourceFile);
53024
- const sourceBasename = path45.basename(sourceFile, path45.extname(sourceFile));
53025
- const isRelatedDir = importDir === sourceDir || importDir === path45.join(sourceDir, "__tests__") || importDir === path45.join(sourceDir, "tests") || importDir === path45.join(sourceDir, "test") || importDir === path45.join(sourceDir, "spec");
53259
+ const sourceDir = path46.dirname(sourceFile);
53260
+ const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
53261
+ const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
53026
53262
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
53027
53263
  dedupePush(testFiles, testFile);
53028
53264
  break;
@@ -53035,8 +53271,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53035
53271
  while (match !== null) {
53036
53272
  const importPath = match[1];
53037
53273
  if (importPath.startsWith(".")) {
53038
- let resolvedImport = path45.resolve(testDir, importPath);
53039
- const existingExt = path45.extname(resolvedImport);
53274
+ let resolvedImport = path46.resolve(testDir, importPath);
53275
+ const existingExt = path46.extname(resolvedImport);
53040
53276
  if (!existingExt) {
53041
53277
  for (const extToTry of [
53042
53278
  ".ts",
@@ -53053,12 +53289,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53053
53289
  }
53054
53290
  }
53055
53291
  }
53056
- const importDir = path45.dirname(resolvedImport);
53057
- const importBasename = path45.basename(resolvedImport, path45.extname(resolvedImport));
53292
+ const importDir = path46.dirname(resolvedImport);
53293
+ const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
53058
53294
  for (const sourceFile of absoluteSourceFiles) {
53059
- const sourceDir = path45.dirname(sourceFile);
53060
- const sourceBasename = path45.basename(sourceFile, path45.extname(sourceFile));
53061
- const isRelatedDir = importDir === sourceDir || importDir === path45.join(sourceDir, "__tests__") || importDir === path45.join(sourceDir, "tests") || importDir === path45.join(sourceDir, "test") || importDir === path45.join(sourceDir, "spec");
53295
+ const sourceDir = path46.dirname(sourceFile);
53296
+ const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
53297
+ const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
53062
53298
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
53063
53299
  dedupePush(testFiles, testFile);
53064
53300
  break;
@@ -53168,8 +53404,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
53168
53404
  return ["mvn", "test"];
53169
53405
  case "gradle": {
53170
53406
  const isWindows = process.platform === "win32";
53171
- const hasGradlewBat = fs24.existsSync(path45.join(baseDir, "gradlew.bat"));
53172
- const hasGradlew = fs24.existsSync(path45.join(baseDir, "gradlew"));
53407
+ const hasGradlewBat = fs24.existsSync(path46.join(baseDir, "gradlew.bat"));
53408
+ const hasGradlew = fs24.existsSync(path46.join(baseDir, "gradlew"));
53173
53409
  if (hasGradlewBat && isWindows)
53174
53410
  return ["gradlew.bat", "test"];
53175
53411
  if (hasGradlew)
@@ -53186,7 +53422,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
53186
53422
  "cmake-build-release",
53187
53423
  "out"
53188
53424
  ];
53189
- const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path45.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
53425
+ const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path46.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
53190
53426
  return ["ctest", "--test-dir", actualBuildDir];
53191
53427
  }
53192
53428
  case "swift-test":
@@ -53618,11 +53854,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
53618
53854
  };
53619
53855
  }
53620
53856
  const startTime = Date.now();
53621
- const vitestJsonOutputPath = framework === "vitest" ? path45.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
53857
+ const vitestJsonOutputPath = framework === "vitest" ? path46.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
53622
53858
  try {
53623
53859
  if (vitestJsonOutputPath) {
53624
53860
  try {
53625
- fs24.mkdirSync(path45.dirname(vitestJsonOutputPath), { recursive: true });
53861
+ fs24.mkdirSync(path46.dirname(vitestJsonOutputPath), { recursive: true });
53626
53862
  if (fs24.existsSync(vitestJsonOutputPath)) {
53627
53863
  fs24.unlinkSync(vitestJsonOutputPath);
53628
53864
  }
@@ -53738,10 +53974,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
53738
53974
  }
53739
53975
  function normalizeHistoryTestFile(testFile, workingDir) {
53740
53976
  const normalized = testFile.replace(/\\/g, "/");
53741
- if (!path45.isAbsolute(testFile))
53977
+ if (!path46.isAbsolute(testFile))
53742
53978
  return normalized;
53743
- const relative9 = path45.relative(workingDir, testFile);
53744
- if (relative9.startsWith("..") || path45.isAbsolute(relative9)) {
53979
+ const relative9 = path46.relative(workingDir, testFile);
53980
+ if (relative9.startsWith("..") || path46.isAbsolute(relative9)) {
53745
53981
  return normalized;
53746
53982
  }
53747
53983
  return relative9.replace(/\\/g, "/");
@@ -54079,7 +54315,7 @@ var init_test_runner = __esm(() => {
54079
54315
  const sourceFiles = args.files.filter((file3) => {
54080
54316
  if (directTestFiles.includes(file3))
54081
54317
  return false;
54082
- const ext = path45.extname(file3).toLowerCase();
54318
+ const ext = path46.extname(file3).toLowerCase();
54083
54319
  return SOURCE_EXTENSIONS.has(ext);
54084
54320
  });
54085
54321
  const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
@@ -54125,7 +54361,7 @@ var init_test_runner = __esm(() => {
54125
54361
  if (isConventionTestFilePath(f)) {
54126
54362
  return false;
54127
54363
  }
54128
- const ext = path45.extname(f).toLowerCase();
54364
+ const ext = path46.extname(f).toLowerCase();
54129
54365
  return SOURCE_EXTENSIONS.has(ext);
54130
54366
  });
54131
54367
  if (sourceFiles.length === 0) {
@@ -54175,7 +54411,7 @@ var init_test_runner = __esm(() => {
54175
54411
  if (isConventionTestFilePath(f)) {
54176
54412
  return false;
54177
54413
  }
54178
- const ext = path45.extname(f).toLowerCase();
54414
+ const ext = path46.extname(f).toLowerCase();
54179
54415
  return SOURCE_EXTENSIONS.has(ext);
54180
54416
  });
54181
54417
  if (sourceFiles.length === 0) {
@@ -54227,8 +54463,8 @@ var init_test_runner = __esm(() => {
54227
54463
  }
54228
54464
  if (impactResult.impactedTests.length > 0) {
54229
54465
  testFiles = impactResult.impactedTests.map((absPath) => {
54230
- const relativePath = path45.relative(workingDir, absPath);
54231
- return path45.isAbsolute(relativePath) ? absPath : relativePath;
54466
+ const relativePath = path46.relative(workingDir, absPath);
54467
+ return path46.isAbsolute(relativePath) ? absPath : relativePath;
54232
54468
  });
54233
54469
  } else {
54234
54470
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -54304,7 +54540,7 @@ var init_test_runner = __esm(() => {
54304
54540
 
54305
54541
  // src/services/preflight-service.ts
54306
54542
  import * as fs25 from "fs";
54307
- import * as path46 from "path";
54543
+ import * as path47 from "path";
54308
54544
  function validateDirectoryPath(dir) {
54309
54545
  if (!dir || typeof dir !== "string") {
54310
54546
  throw new Error("Directory path is required");
@@ -54312,8 +54548,8 @@ function validateDirectoryPath(dir) {
54312
54548
  if (dir.includes("..")) {
54313
54549
  throw new Error("Directory path must not contain path traversal sequences");
54314
54550
  }
54315
- const normalized = path46.normalize(dir);
54316
- const absolutePath = path46.isAbsolute(normalized) ? normalized : path46.resolve(normalized);
54551
+ const normalized = path47.normalize(dir);
54552
+ const absolutePath = path47.isAbsolute(normalized) ? normalized : path47.resolve(normalized);
54317
54553
  return absolutePath;
54318
54554
  }
54319
54555
  function validateTimeout(timeoutMs, defaultValue) {
@@ -54336,7 +54572,7 @@ function validateTimeout(timeoutMs, defaultValue) {
54336
54572
  }
54337
54573
  function getPackageVersion(dir) {
54338
54574
  try {
54339
- const packagePath = path46.join(dir, "package.json");
54575
+ const packagePath = path47.join(dir, "package.json");
54340
54576
  if (fs25.existsSync(packagePath)) {
54341
54577
  const content = fs25.readFileSync(packagePath, "utf-8");
54342
54578
  const pkg = JSON.parse(content);
@@ -54347,7 +54583,7 @@ function getPackageVersion(dir) {
54347
54583
  }
54348
54584
  function getChangelogVersion(dir) {
54349
54585
  try {
54350
- const changelogPath = path46.join(dir, "CHANGELOG.md");
54586
+ const changelogPath = path47.join(dir, "CHANGELOG.md");
54351
54587
  if (fs25.existsSync(changelogPath)) {
54352
54588
  const content = fs25.readFileSync(changelogPath, "utf-8");
54353
54589
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
@@ -54361,7 +54597,7 @@ function getChangelogVersion(dir) {
54361
54597
  function getVersionFileVersion(dir) {
54362
54598
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
54363
54599
  for (const file3 of possibleFiles) {
54364
- const filePath = path46.join(dir, file3);
54600
+ const filePath = path47.join(dir, file3);
54365
54601
  if (fs25.existsSync(filePath)) {
54366
54602
  try {
54367
54603
  const content = fs25.readFileSync(filePath, "utf-8").trim();
@@ -54703,7 +54939,7 @@ async function runEvidenceCheck(dir) {
54703
54939
  async function runRequirementCoverageCheck(dir, currentPhase) {
54704
54940
  const startTime = Date.now();
54705
54941
  try {
54706
- const specPath = path46.join(dir, ".swarm", "spec.md");
54942
+ const specPath = path47.join(dir, ".swarm", "spec.md");
54707
54943
  if (!fs25.existsSync(specPath)) {
54708
54944
  return {
54709
54945
  type: "req_coverage",
@@ -55821,7 +56057,7 @@ var init_manager3 = __esm(() => {
55821
56057
 
55822
56058
  // src/commands/reset.ts
55823
56059
  import * as fs26 from "fs";
55824
- import * as path47 from "path";
56060
+ import * as path48 from "path";
55825
56061
  async function handleResetCommand(directory, args) {
55826
56062
  const hasConfirm = args.includes("--confirm");
55827
56063
  if (!hasConfirm) {
@@ -55861,7 +56097,7 @@ async function handleResetCommand(directory, args) {
55861
56097
  }
55862
56098
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
55863
56099
  try {
55864
- const rootPath = path47.join(directory, filename);
56100
+ const rootPath = path48.join(directory, filename);
55865
56101
  if (fs26.existsSync(rootPath)) {
55866
56102
  fs26.unlinkSync(rootPath);
55867
56103
  results.push(`- \u2705 Deleted ${filename} (root)`);
@@ -55901,7 +56137,7 @@ var init_reset = __esm(() => {
55901
56137
 
55902
56138
  // src/commands/reset-session.ts
55903
56139
  import * as fs27 from "fs";
55904
- import * as path48 from "path";
56140
+ import * as path49 from "path";
55905
56141
  async function handleResetSessionCommand(directory, _args) {
55906
56142
  const results = [];
55907
56143
  try {
@@ -55916,13 +56152,13 @@ async function handleResetSessionCommand(directory, _args) {
55916
56152
  results.push("\u274C Failed to delete state.json");
55917
56153
  }
55918
56154
  try {
55919
- const sessionDir = path48.dirname(validateSwarmPath(directory, "session/state.json"));
56155
+ const sessionDir = path49.dirname(validateSwarmPath(directory, "session/state.json"));
55920
56156
  if (fs27.existsSync(sessionDir)) {
55921
56157
  const files = fs27.readdirSync(sessionDir);
55922
56158
  const otherFiles = files.filter((f) => f !== "state.json");
55923
56159
  let deletedCount = 0;
55924
56160
  for (const file3 of otherFiles) {
55925
- const filePath = path48.join(sessionDir, file3);
56161
+ const filePath = path49.join(sessionDir, file3);
55926
56162
  if (fs27.lstatSync(filePath).isFile()) {
55927
56163
  fs27.unlinkSync(filePath);
55928
56164
  deletedCount++;
@@ -55954,7 +56190,7 @@ var init_reset_session = __esm(() => {
55954
56190
  });
55955
56191
 
55956
56192
  // src/summaries/manager.ts
55957
- import * as path49 from "path";
56193
+ import * as path50 from "path";
55958
56194
  function sanitizeSummaryId(id) {
55959
56195
  if (!id || id.length === 0) {
55960
56196
  throw new Error("Invalid summary ID: empty string");
@@ -55977,7 +56213,7 @@ function sanitizeSummaryId(id) {
55977
56213
  }
55978
56214
  async function loadFullOutput(directory, id) {
55979
56215
  const sanitizedId = sanitizeSummaryId(id);
55980
- const relativePath = path49.join("summaries", `${sanitizedId}.json`);
56216
+ const relativePath = path50.join("summaries", `${sanitizedId}.json`);
55981
56217
  validateSwarmPath(directory, relativePath);
55982
56218
  const content = await readSwarmFileAsync(directory, relativePath);
55983
56219
  if (content === null) {
@@ -56040,7 +56276,7 @@ var init_retrieve = __esm(() => {
56040
56276
 
56041
56277
  // src/commands/rollback.ts
56042
56278
  import * as fs28 from "fs";
56043
- import * as path50 from "path";
56279
+ import * as path51 from "path";
56044
56280
  async function handleRollbackCommand(directory, args) {
56045
56281
  const phaseArg = args[0];
56046
56282
  if (!phaseArg) {
@@ -56105,8 +56341,8 @@ async function handleRollbackCommand(directory, args) {
56105
56341
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
56106
56342
  continue;
56107
56343
  }
56108
- const src = path50.join(checkpointDir, file3);
56109
- const dest = path50.join(swarmDir, file3);
56344
+ const src = path51.join(checkpointDir, file3);
56345
+ const dest = path51.join(swarmDir, file3);
56110
56346
  try {
56111
56347
  fs28.cpSync(src, dest, { recursive: true, force: true });
56112
56348
  successes.push(file3);
@@ -56125,12 +56361,12 @@ async function handleRollbackCommand(directory, args) {
56125
56361
  ].join(`
56126
56362
  `);
56127
56363
  }
56128
- const existingLedgerPath = path50.join(swarmDir, "plan-ledger.jsonl");
56364
+ const existingLedgerPath = path51.join(swarmDir, "plan-ledger.jsonl");
56129
56365
  if (fs28.existsSync(existingLedgerPath)) {
56130
56366
  fs28.unlinkSync(existingLedgerPath);
56131
56367
  }
56132
56368
  try {
56133
- const planJsonPath = path50.join(swarmDir, "plan.json");
56369
+ const planJsonPath = path51.join(swarmDir, "plan.json");
56134
56370
  if (fs28.existsSync(planJsonPath)) {
56135
56371
  const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
56136
56372
  const plan = PlanSchema.parse(JSON.parse(planRaw));
@@ -56221,9 +56457,9 @@ Ensure this is a git repository with commit history.`;
56221
56457
  `);
56222
56458
  try {
56223
56459
  const fs29 = await import("fs/promises");
56224
- const path51 = await import("path");
56225
- const reportPath = path51.join(directory, ".swarm", "simulate-report.md");
56226
- await fs29.mkdir(path51.dirname(reportPath), { recursive: true });
56460
+ const path52 = await import("path");
56461
+ const reportPath = path52.join(directory, ".swarm", "simulate-report.md");
56462
+ await fs29.mkdir(path52.dirname(reportPath), { recursive: true });
56227
56463
  await fs29.writeFile(reportPath, report, "utf-8");
56228
56464
  } catch (err) {
56229
56465
  const writeErr = err instanceof Error ? err.message : String(err);
@@ -56247,12 +56483,12 @@ async function handleSpecifyCommand(_directory, args) {
56247
56483
 
56248
56484
  // src/turbo/lean/state.ts
56249
56485
  import * as fs29 from "fs";
56250
- import * as path51 from "path";
56486
+ import * as path52 from "path";
56251
56487
  function nowISO2() {
56252
56488
  return new Date().toISOString();
56253
56489
  }
56254
56490
  function ensureSwarmDir2(directory) {
56255
- const swarmDir = path51.resolve(directory, ".swarm");
56491
+ const swarmDir = path52.resolve(directory, ".swarm");
56256
56492
  if (!fs29.existsSync(swarmDir)) {
56257
56493
  fs29.mkdirSync(swarmDir, { recursive: true });
56258
56494
  }
@@ -56296,7 +56532,7 @@ function markStateUnreadable2(directory, reason) {
56296
56532
  }
56297
56533
  function readPersisted2(directory) {
56298
56534
  try {
56299
- const filePath = path51.join(directory, ".swarm", STATE_FILE2);
56535
+ const filePath = path52.join(directory, ".swarm", STATE_FILE2);
56300
56536
  if (!fs29.existsSync(filePath)) {
56301
56537
  const seed = emptyPersisted2();
56302
56538
  try {
@@ -56332,7 +56568,7 @@ function writePersisted2(directory, persisted) {
56332
56568
  let payload;
56333
56569
  try {
56334
56570
  ensureSwarmDir2(directory);
56335
- filePath = path51.join(directory, ".swarm", STATE_FILE2);
56571
+ filePath = path52.join(directory, ".swarm", STATE_FILE2);
56336
56572
  tmpPath = `${filePath}.tmp.${Date.now()}`;
56337
56573
  persisted.updatedAt = nowISO2();
56338
56574
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -56459,10 +56695,10 @@ var init_context_budget_service = __esm(() => {
56459
56695
 
56460
56696
  // src/services/status-service.ts
56461
56697
  import * as fsSync2 from "fs";
56462
- import * as path52 from "path";
56698
+ import * as path53 from "path";
56463
56699
  function readSpecStalenessSnapshot(directory) {
56464
56700
  try {
56465
- const p = path52.join(directory, ".swarm", "spec-staleness.json");
56701
+ const p = path53.join(directory, ".swarm", "spec-staleness.json");
56466
56702
  if (!fsSync2.existsSync(p))
56467
56703
  return { stale: false };
56468
56704
  const raw = fsSync2.readFileSync(p, "utf-8");
@@ -56988,7 +57224,7 @@ var init_write_retro2 = __esm(() => {
56988
57224
 
56989
57225
  // src/commands/command-dispatch.ts
56990
57226
  import fs30 from "fs";
56991
- import path53 from "path";
57227
+ import path54 from "path";
56992
57228
  function normalizeSwarmCommandInput(command, argumentText) {
56993
57229
  if (command !== "swarm" && !command.startsWith("swarm-")) {
56994
57230
  return { isSwarmCommand: false, tokens: [] };
@@ -57024,9 +57260,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
57024
57260
  `);
57025
57261
  }
57026
57262
  function maybeMarkFirstRun(directory) {
57027
- const sentinelPath = path53.join(directory, ".swarm", ".first-run-complete");
57263
+ const sentinelPath = path54.join(directory, ".swarm", ".first-run-complete");
57028
57264
  try {
57029
- const swarmDir = path53.join(directory, ".swarm");
57265
+ const swarmDir = path54.join(directory, ".swarm");
57030
57266
  fs30.mkdirSync(swarmDir, { recursive: true });
57031
57267
  fs30.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
57032
57268
  `, { flag: "wx" });
@@ -57768,24 +58004,24 @@ function validateAliases() {
57768
58004
  }
57769
58005
  aliasTargets.get(target).push(name);
57770
58006
  const visited = new Set;
57771
- const path54 = [];
58007
+ const path55 = [];
57772
58008
  let current = target;
57773
58009
  while (current) {
57774
58010
  const currentEntry = COMMAND_REGISTRY[current];
57775
58011
  if (!currentEntry)
57776
58012
  break;
57777
58013
  if (visited.has(current)) {
57778
- const cycleStart = path54.indexOf(current);
58014
+ const cycleStart = path55.indexOf(current);
57779
58015
  const fullChain = [
57780
58016
  name,
57781
- ...path54.slice(0, cycleStart > 0 ? cycleStart : path54.length),
58017
+ ...path55.slice(0, cycleStart > 0 ? cycleStart : path55.length),
57782
58018
  current
57783
58019
  ].join(" \u2192 ");
57784
58020
  errors5.push(`Circular alias detected: ${fullChain}`);
57785
58021
  break;
57786
58022
  }
57787
58023
  visited.add(current);
57788
- path54.push(current);
58024
+ path55.push(current);
57789
58025
  current = currentEntry.aliasOf || "";
57790
58026
  }
57791
58027
  }
@@ -58383,53 +58619,53 @@ init_cache_paths();
58383
58619
  init_constants();
58384
58620
  import * as fs31 from "fs";
58385
58621
  import * as os8 from "os";
58386
- import * as path54 from "path";
58387
- var { version: version4 } = package_default;
58622
+ import * as path55 from "path";
58623
+ var { version: version5 } = package_default;
58388
58624
  var CONFIG_DIR = getPluginConfigDir();
58389
- var OPENCODE_CONFIG_PATH = path54.join(CONFIG_DIR, "opencode.json");
58390
- var PLUGIN_CONFIG_PATH = path54.join(CONFIG_DIR, "opencode-swarm.json");
58391
- var PROMPTS_DIR = path54.join(CONFIG_DIR, "opencode-swarm");
58625
+ var OPENCODE_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode.json");
58626
+ var PLUGIN_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode-swarm.json");
58627
+ var PROMPTS_DIR = path55.join(CONFIG_DIR, "opencode-swarm");
58392
58628
  var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
58393
58629
  var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
58394
58630
  function isSafeCachePath(p) {
58395
- const resolved = path54.resolve(p);
58396
- const home = path54.resolve(os8.homedir());
58631
+ const resolved = path55.resolve(p);
58632
+ const home = path55.resolve(os8.homedir());
58397
58633
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
58398
58634
  return false;
58399
58635
  }
58400
- const segments = resolved.split(path54.sep).filter((s) => s.length > 0);
58636
+ const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
58401
58637
  if (segments.length < 4) {
58402
58638
  return false;
58403
58639
  }
58404
- const leaf = path54.basename(resolved);
58640
+ const leaf = path55.basename(resolved);
58405
58641
  if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
58406
58642
  return false;
58407
58643
  }
58408
- const parent = path54.basename(path54.dirname(resolved));
58644
+ const parent = path55.basename(path55.dirname(resolved));
58409
58645
  if (parent !== "packages" && parent !== "node_modules") {
58410
58646
  return false;
58411
58647
  }
58412
- const grandparent = path54.basename(path54.dirname(path54.dirname(resolved)));
58648
+ const grandparent = path55.basename(path55.dirname(path55.dirname(resolved)));
58413
58649
  if (grandparent !== "opencode") {
58414
58650
  return false;
58415
58651
  }
58416
58652
  return true;
58417
58653
  }
58418
58654
  function isSafeLockFilePath(p) {
58419
- const resolved = path54.resolve(p);
58420
- const home = path54.resolve(os8.homedir());
58655
+ const resolved = path55.resolve(p);
58656
+ const home = path55.resolve(os8.homedir());
58421
58657
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
58422
58658
  return false;
58423
58659
  }
58424
- const segments = resolved.split(path54.sep).filter((s) => s.length > 0);
58660
+ const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
58425
58661
  if (segments.length < 4) {
58426
58662
  return false;
58427
58663
  }
58428
- const leaf = path54.basename(resolved);
58664
+ const leaf = path55.basename(resolved);
58429
58665
  if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
58430
58666
  return false;
58431
58667
  }
58432
- const parent = path54.basename(path54.dirname(resolved));
58668
+ const parent = path55.basename(path55.dirname(resolved));
58433
58669
  if (parent !== "opencode") {
58434
58670
  return false;
58435
58671
  }
@@ -58455,8 +58691,8 @@ function saveJson(filepath, data) {
58455
58691
  }
58456
58692
  function writeProjectConfigIfMissing(cwd) {
58457
58693
  try {
58458
- const opencodeDir = path54.join(cwd, ".opencode");
58459
- const projectConfigPath = path54.join(opencodeDir, "opencode-swarm.json");
58694
+ const opencodeDir = path55.join(cwd, ".opencode");
58695
+ const projectConfigPath = path55.join(opencodeDir, "opencode-swarm.json");
58460
58696
  if (fs31.existsSync(projectConfigPath)) {
58461
58697
  return;
58462
58698
  }
@@ -58473,7 +58709,7 @@ async function install() {
58473
58709
  `);
58474
58710
  ensureDir(CONFIG_DIR);
58475
58711
  ensureDir(PROMPTS_DIR);
58476
- const LEGACY_CONFIG_PATH = path54.join(CONFIG_DIR, "config.json");
58712
+ const LEGACY_CONFIG_PATH = path55.join(CONFIG_DIR, "config.json");
58477
58713
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
58478
58714
  if (!opencodeConfig) {
58479
58715
  const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
@@ -58748,7 +58984,7 @@ Examples:
58748
58984
  async function main() {
58749
58985
  const args = process.argv.slice(2);
58750
58986
  if (args.includes("-v") || args.includes("--version")) {
58751
- console.log(`opencode-swarm ${version4}`);
58987
+ console.log(`opencode-swarm ${version5}`);
58752
58988
  process.exit(0);
58753
58989
  }
58754
58990
  if (args.includes("-h") || args.includes("--help")) {