opencode-swarm 7.30.0 → 7.31.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
@@ -34,7 +34,7 @@ var package_default;
34
34
  var init_package = __esm(() => {
35
35
  package_default = {
36
36
  name: "opencode-swarm",
37
- version: "7.30.0",
37
+ version: "7.31.0",
38
38
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
39
39
  main: "dist/index.js",
40
40
  types: "dist/index.d.ts",
@@ -35397,6 +35397,9 @@ function resolveSwarmKnowledgePath(directory) {
35397
35397
  function resolveSwarmRejectedPath(directory) {
35398
35398
  return path10.join(directory, ".swarm", "knowledge-rejected.jsonl");
35399
35399
  }
35400
+ function resolveSwarmRetractionsPath(directory) {
35401
+ return path10.join(directory, ".swarm", "knowledge-retractions.jsonl");
35402
+ }
35400
35403
  function resolveHiveKnowledgePath() {
35401
35404
  const platform = process.platform;
35402
35405
  const home = process.env.HOME || os3.homedir();
@@ -35495,6 +35498,12 @@ function normalizeEntry(raw) {
35495
35498
  async function readRejectedLessons(directory) {
35496
35499
  return readKnowledge(resolveSwarmRejectedPath(directory));
35497
35500
  }
35501
+ async function readRetractionRecords(directory) {
35502
+ return readKnowledge(resolveSwarmRetractionsPath(directory));
35503
+ }
35504
+ async function appendRetractionRecord(directory, record3) {
35505
+ await appendKnowledge(resolveSwarmRetractionsPath(directory), record3);
35506
+ }
35498
35507
  async function appendKnowledge(filePath, entry) {
35499
35508
  await mkdir2(path10.dirname(filePath), { recursive: true });
35500
35509
  await appendFile2(filePath, `${JSON.stringify(entry)}
@@ -36259,75 +36268,6 @@ var init_hive_promoter = __esm(() => {
36259
36268
  init_utils2();
36260
36269
  });
36261
36270
 
36262
- // src/hooks/knowledge-reader.ts
36263
- import { existsSync as existsSync8 } from "fs";
36264
- import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
36265
- import * as path13 from "path";
36266
- async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
36267
- const shownFile = path13.join(directory, ".swarm", ".knowledge-shown.json");
36268
- try {
36269
- if (!existsSync8(shownFile)) {
36270
- return;
36271
- }
36272
- const content = await readFile4(shownFile, "utf-8");
36273
- const shownData = JSON.parse(content);
36274
- const shownIds = shownData[phaseInfo];
36275
- if (!shownIds || shownIds.length === 0) {
36276
- return;
36277
- }
36278
- const swarmPath = resolveSwarmKnowledgePath(directory);
36279
- const entries = await readKnowledge(swarmPath);
36280
- let updated = false;
36281
- const foundInSwarm = new Set;
36282
- for (const entry of entries) {
36283
- if (shownIds.includes(entry.id)) {
36284
- const ro = entry.retrieval_outcomes;
36285
- if (phaseSucceeded) {
36286
- ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
36287
- } else {
36288
- ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
36289
- }
36290
- updated = true;
36291
- foundInSwarm.add(entry.id);
36292
- }
36293
- }
36294
- if (updated) {
36295
- await rewriteKnowledge(swarmPath, entries);
36296
- }
36297
- const remainingIds = shownIds.filter((id) => !foundInSwarm.has(id));
36298
- if (remainingIds.length === 0) {
36299
- delete shownData[phaseInfo];
36300
- await writeFile5(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
36301
- return;
36302
- }
36303
- const hivePath = resolveHiveKnowledgePath();
36304
- const hiveEntries = await readKnowledge(hivePath);
36305
- let hiveUpdated = false;
36306
- for (const entry of hiveEntries) {
36307
- if (remainingIds.includes(entry.id)) {
36308
- const ro = entry.retrieval_outcomes;
36309
- if (phaseSucceeded) {
36310
- ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
36311
- } else {
36312
- ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
36313
- }
36314
- hiveUpdated = true;
36315
- }
36316
- }
36317
- if (hiveUpdated) {
36318
- await rewriteKnowledge(hivePath, hiveEntries);
36319
- }
36320
- delete shownData[phaseInfo];
36321
- await writeFile5(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
36322
- } catch {
36323
- warn("[swarm] Knowledge: failed to update retrieval outcomes");
36324
- }
36325
- }
36326
- var init_knowledge_reader = __esm(() => {
36327
- init_logger();
36328
- init_knowledge_store();
36329
- });
36330
-
36331
36271
  // src/hooks/knowledge-curator.ts
36332
36272
  function pruneSeenRetroSections() {
36333
36273
  const cutoff = Date.now() - 86400000;
@@ -36444,17 +36384,39 @@ function extractRetractionsAndLessons(allLessons) {
36444
36384
  async function processRetractions(retractions, directory) {
36445
36385
  if (retractions.length === 0)
36446
36386
  return;
36447
- const knowledgePath = resolveSwarmKnowledgePath(directory);
36448
- const entries = await readKnowledge(knowledgePath) ?? [];
36387
+ const swarmEntries = await readKnowledge(resolveSwarmKnowledgePath(directory)) ?? [];
36388
+ const hiveEntries = await readKnowledge(resolveHiveKnowledgePath()) ?? [];
36389
+ const existingRetractions = await readRetractionRecords(directory);
36390
+ const existingSuppressedLessons = new Set(existingRetractions.map((record3) => record3.normalized_lesson).filter((value) => typeof value === "string" && value.length > 0));
36449
36391
  for (const retractionText of retractions) {
36450
36392
  const normalizedRetraction = normalize2(retractionText);
36451
- for (const entry of entries) {
36393
+ const matchedSwarmIds = [];
36394
+ const matchedHiveIds = [];
36395
+ for (const entry of swarmEntries) {
36452
36396
  const normalizedLesson = normalize2(entry.lesson);
36453
36397
  if (normalizedLesson === normalizedRetraction) {
36398
+ matchedSwarmIds.push(entry.id);
36454
36399
  await quarantineEntry(directory, entry.id, `Retracted by architect: ${retractionText}`, "architect");
36455
36400
  console.info(`[knowledge-curator] Quarantined entry ${entry.id}: "${entry.lesson}"`);
36456
36401
  }
36457
36402
  }
36403
+ for (const entry of hiveEntries) {
36404
+ if (normalize2(entry.lesson) === normalizedRetraction) {
36405
+ matchedHiveIds.push(entry.id);
36406
+ }
36407
+ }
36408
+ if (!existingSuppressedLessons.has(normalizedRetraction)) {
36409
+ await appendRetractionRecord(directory, {
36410
+ id: crypto.randomUUID(),
36411
+ retracted_lesson: retractionText,
36412
+ normalized_lesson: normalizedRetraction,
36413
+ recorded_at: new Date().toISOString(),
36414
+ reported_by: "architect",
36415
+ matched_swarm_ids: matchedSwarmIds,
36416
+ matched_hive_ids: matchedHiveIds
36417
+ });
36418
+ existingSuppressedLessons.add(normalizedRetraction);
36419
+ }
36458
36420
  }
36459
36421
  }
36460
36422
  async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, config3) {
@@ -36621,7 +36583,6 @@ function createKnowledgeCuratorHook(directory, config3) {
36621
36583
  const projectName2 = evidenceData.project_name ?? "unknown";
36622
36584
  const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
36623
36585
  await _internals8.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3);
36624
- await updateRetrievalOutcome(directory, `Phase ${phaseNumber2}`, true);
36625
36586
  return;
36626
36587
  }
36627
36588
  const planContent = await readSwarmFileAsync(directory, "plan.md");
@@ -36644,13 +36605,11 @@ function createKnowledgeCuratorHook(directory, config3) {
36644
36605
  const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
36645
36606
  const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
36646
36607
  await _internals8.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3);
36647
- await updateRetrievalOutcome(directory, `Phase ${phaseNumber}`, true);
36648
36608
  };
36649
36609
  return safeHook(handler);
36650
36610
  }
36651
36611
  var seenRetroSections, _internals8;
36652
36612
  var init_knowledge_curator = __esm(() => {
36653
- init_knowledge_reader();
36654
36613
  init_knowledge_store();
36655
36614
  init_knowledge_validator();
36656
36615
  init_utils2();
@@ -36773,9 +36732,9 @@ var init_skill_improver_llm_factory = __esm(() => {
36773
36732
  });
36774
36733
 
36775
36734
  // src/services/skill-generator.ts
36776
- import { existsSync as existsSync9 } from "fs";
36777
- import { mkdir as mkdir5, readFile as readFile5, rename as rename3, writeFile as writeFile6 } from "fs/promises";
36778
- import * as path14 from "path";
36735
+ import { existsSync as existsSync8 } from "fs";
36736
+ import { mkdir as mkdir4, readFile as readFile4, rename as rename3, writeFile as writeFile5 } from "fs/promises";
36737
+ import * as path13 from "path";
36779
36738
  function sanitizeSlug(input) {
36780
36739
  const lc = input.toLowerCase().trim();
36781
36740
  const mapped = lc.replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-");
@@ -36786,10 +36745,10 @@ function isValidSlug(slug) {
36786
36745
  return SLUG_PATTERN.test(slug);
36787
36746
  }
36788
36747
  function proposalPath(directory, slug) {
36789
- return path14.join(directory, ".swarm", "skills", "proposals", `${slug}.md`);
36748
+ return path13.join(directory, ".swarm", "skills", "proposals", `${slug}.md`);
36790
36749
  }
36791
36750
  function activePath(directory, slug) {
36792
- return path14.join(directory, ".opencode", "skills", "generated", slug, "SKILL.md");
36751
+ return path13.join(directory, ".opencode", "skills", "generated", slug, "SKILL.md");
36793
36752
  }
36794
36753
  function activeRepoRelativePath(slug) {
36795
36754
  return `.opencode/skills/generated/${slug}/SKILL.md`;
@@ -36797,7 +36756,7 @@ function activeRepoRelativePath(slug) {
36797
36756
  async function selectCandidateEntries(directory, opts) {
36798
36757
  const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
36799
36758
  const hivePath = resolveHiveKnowledgePath();
36800
- const hive = existsSync9(hivePath) ? await readKnowledge(hivePath) : [];
36759
+ const hive = existsSync8(hivePath) ? await readKnowledge(hivePath) : [];
36801
36760
  const all = [...swarm, ...hive];
36802
36761
  return all.filter((e) => {
36803
36762
  if (e.status === "archived")
@@ -36945,9 +36904,9 @@ function escapeMarkdown(s) {
36945
36904
  return s.replace(/[\r\n]+/g, " ").slice(0, 280);
36946
36905
  }
36947
36906
  async function atomicWrite(p, content) {
36948
- await mkdir5(path14.dirname(p), { recursive: true });
36907
+ await mkdir4(path13.dirname(p), { recursive: true });
36949
36908
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
36950
- await writeFile6(tmp, content, "utf-8");
36909
+ await writeFile5(tmp, content, "utf-8");
36951
36910
  await rename3(tmp, p);
36952
36911
  }
36953
36912
  async function generateSkills(req) {
@@ -36962,7 +36921,7 @@ async function generateSkills(req) {
36962
36921
  const idSet = new Set(req.sourceKnowledgeIds);
36963
36922
  const swarm = await readKnowledge(resolveSwarmKnowledgePath(req.directory));
36964
36923
  const hivePath = resolveHiveKnowledgePath();
36965
- const hive = existsSync9(hivePath) ? await readKnowledge(hivePath) : [];
36924
+ const hive = existsSync8(hivePath) ? await readKnowledge(hivePath) : [];
36966
36925
  pool = [...swarm, ...hive].filter((e) => idSet.has(e.id) && e.status !== "archived");
36967
36926
  } else {
36968
36927
  pool = candidates;
@@ -36990,7 +36949,7 @@ async function generateSkills(req) {
36990
36949
  continue;
36991
36950
  }
36992
36951
  const targetPath = req.mode === "active" ? activePath(req.directory, cluster.slug) : proposalPath(req.directory, cluster.slug);
36993
- const repoRel = path14.relative(req.directory, targetPath).replace(/\\/g, "/");
36952
+ const repoRel = path13.relative(req.directory, targetPath).replace(/\\/g, "/");
36994
36953
  if (!validateSkillPath(repoRel)) {
36995
36954
  result.skipped.push({
36996
36955
  slug: cluster.slug,
@@ -36999,8 +36958,8 @@ async function generateSkills(req) {
36999
36958
  continue;
37000
36959
  }
37001
36960
  let preserved = false;
37002
- if (req.mode === "active" && existsSync9(targetPath) && !req.force) {
37003
- const existing = await readFile5(targetPath, "utf-8");
36961
+ if (req.mode === "active" && existsSync8(targetPath) && !req.force) {
36962
+ const existing = await readFile4(targetPath, "utf-8");
37004
36963
  if (!existing.includes("generated by opencode-swarm skill-generator")) {
37005
36964
  preserved = true;
37006
36965
  result.skipped.push({
@@ -37044,7 +37003,7 @@ async function stampSourceEntries(directory, slug, ids) {
37044
37003
  if (touched)
37045
37004
  await rewriteKnowledge(swarmPath, swarm);
37046
37005
  const hivePath = resolveHiveKnowledgePath();
37047
- if (!existsSync9(hivePath))
37006
+ if (!existsSync8(hivePath))
37048
37007
  return;
37049
37008
  const hive = await readKnowledge(hivePath);
37050
37009
  let touchedHive = false;
@@ -37064,10 +37023,10 @@ async function listSkills(directory) {
37064
37023
  proposals: [],
37065
37024
  active: []
37066
37025
  };
37067
- const proposalsDir = path14.join(directory, ".swarm", "skills", "proposals");
37068
- const activeDir = path14.join(directory, ".opencode", "skills", "generated");
37026
+ const proposalsDir = path13.join(directory, ".swarm", "skills", "proposals");
37027
+ const activeDir = path13.join(directory, ".opencode", "skills", "generated");
37069
37028
  const fs7 = await import("fs/promises");
37070
- if (existsSync9(proposalsDir)) {
37029
+ if (existsSync8(proposalsDir)) {
37071
37030
  const entries = await fs7.readdir(proposalsDir);
37072
37031
  for (const f of entries) {
37073
37032
  if (!f.endsWith(".md"))
@@ -37075,17 +37034,17 @@ async function listSkills(directory) {
37075
37034
  const slug = f.replace(/\.md$/, "");
37076
37035
  result.proposals.push({
37077
37036
  slug,
37078
- path: path14.join(proposalsDir, f)
37037
+ path: path13.join(proposalsDir, f)
37079
37038
  });
37080
37039
  }
37081
37040
  }
37082
- if (existsSync9(activeDir)) {
37041
+ if (existsSync8(activeDir)) {
37083
37042
  const entries = await fs7.readdir(activeDir, { withFileTypes: true });
37084
37043
  for (const e of entries) {
37085
37044
  if (!e.isDirectory())
37086
37045
  continue;
37087
- const skillPath = path14.join(activeDir, e.name, "SKILL.md");
37088
- if (existsSync9(skillPath)) {
37046
+ const skillPath = path13.join(activeDir, e.name, "SKILL.md");
37047
+ if (existsSync8(skillPath)) {
37089
37048
  result.active.push({
37090
37049
  slug: e.name,
37091
37050
  path: skillPath
@@ -37104,9 +37063,9 @@ var init_skill_generator = __esm(() => {
37104
37063
  });
37105
37064
 
37106
37065
  // src/services/skill-improver-quota.ts
37107
- import { existsSync as existsSync10 } from "fs";
37108
- import { mkdir as mkdir6, readFile as readFile6, rename as rename4, writeFile as writeFile7 } from "fs/promises";
37109
- import * as path15 from "path";
37066
+ import { existsSync as existsSync9 } from "fs";
37067
+ import { mkdir as mkdir5, readFile as readFile5, rename as rename4, writeFile as writeFile6 } from "fs/promises";
37068
+ import * as path14 from "path";
37110
37069
  async function acquireLock(dir) {
37111
37070
  const acquire = import_proper_lockfile5.default.lock(dir, LOCK_RETRY_OPTS);
37112
37071
  let timer;
@@ -37124,7 +37083,7 @@ async function acquireLock(dir) {
37124
37083
  }
37125
37084
  }
37126
37085
  function resolveQuotaPath(directory) {
37127
- return path15.join(directory, ".swarm", "skill-improver-quota.json");
37086
+ return path14.join(directory, ".swarm", "skill-improver-quota.json");
37128
37087
  }
37129
37088
  function todayKey(window, now = new Date) {
37130
37089
  if (window === "utc") {
@@ -37136,10 +37095,10 @@ function todayKey(window, now = new Date) {
37136
37095
  return `${yr}-${m}-${d}`;
37137
37096
  }
37138
37097
  async function readState(filePath) {
37139
- if (!existsSync10(filePath))
37098
+ if (!existsSync9(filePath))
37140
37099
  return null;
37141
37100
  try {
37142
- const raw = await readFile6(filePath, "utf-8");
37101
+ const raw = await readFile5(filePath, "utf-8");
37143
37102
  const parsed = JSON.parse(raw);
37144
37103
  if (typeof parsed.date !== "string" || typeof parsed.calls_used !== "number" || typeof parsed.max_calls !== "number" || parsed.window !== "utc" && parsed.window !== "local") {
37145
37104
  return null;
@@ -37150,9 +37109,9 @@ async function readState(filePath) {
37150
37109
  }
37151
37110
  }
37152
37111
  async function writeState(filePath, state) {
37153
- await mkdir6(path15.dirname(filePath), { recursive: true });
37112
+ await mkdir5(path14.dirname(filePath), { recursive: true });
37154
37113
  const tmp = `${filePath}.tmp-${process.pid}`;
37155
- await writeFile7(tmp, JSON.stringify(state, null, 2), "utf-8");
37114
+ await writeFile6(tmp, JSON.stringify(state, null, 2), "utf-8");
37156
37115
  await rename4(tmp, filePath);
37157
37116
  }
37158
37117
  async function getQuotaState(directory, opts) {
@@ -37173,10 +37132,10 @@ async function getQuotaState(directory, opts) {
37173
37132
  }
37174
37133
  async function reserveQuota(directory, opts) {
37175
37134
  const filePath = resolveQuotaPath(directory);
37176
- await mkdir6(path15.dirname(filePath), { recursive: true });
37135
+ await mkdir5(path14.dirname(filePath), { recursive: true });
37177
37136
  let release = null;
37178
37137
  try {
37179
- release = await acquireLock(path15.dirname(filePath));
37138
+ release = await acquireLock(path14.dirname(filePath));
37180
37139
  const state = await getQuotaState(directory, opts);
37181
37140
  if (state.calls_used + opts.nCalls > opts.maxCalls) {
37182
37141
  return {
@@ -37203,10 +37162,10 @@ async function reserveQuota(directory, opts) {
37203
37162
  }
37204
37163
  async function releaseQuota(directory, opts) {
37205
37164
  const filePath = resolveQuotaPath(directory);
37206
- await mkdir6(path15.dirname(filePath), { recursive: true });
37165
+ await mkdir5(path14.dirname(filePath), { recursive: true });
37207
37166
  let release = null;
37208
37167
  try {
37209
- release = await acquireLock(path15.dirname(filePath));
37168
+ release = await acquireLock(path14.dirname(filePath));
37210
37169
  const state = await getQuotaState(directory, opts);
37211
37170
  const next = {
37212
37171
  ...state,
@@ -37238,22 +37197,22 @@ var init_skill_improver_quota = __esm(() => {
37238
37197
  });
37239
37198
 
37240
37199
  // src/services/skill-improver.ts
37241
- import { existsSync as existsSync11 } from "fs";
37242
- import { mkdir as mkdir7, rename as rename5, writeFile as writeFile8 } from "fs/promises";
37243
- import * as path16 from "path";
37200
+ import { existsSync as existsSync10 } from "fs";
37201
+ import { mkdir as mkdir6, rename as rename5, writeFile as writeFile7 } from "fs/promises";
37202
+ import * as path15 from "path";
37244
37203
  function timestampSlug(d) {
37245
37204
  return d.toISOString().replace(/[:.]/g, "-");
37246
37205
  }
37247
37206
  async function atomicWrite2(p, content) {
37248
- await mkdir7(path16.dirname(p), { recursive: true });
37207
+ await mkdir6(path15.dirname(p), { recursive: true });
37249
37208
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
37250
- await writeFile8(tmp, content, "utf-8");
37209
+ await writeFile7(tmp, content, "utf-8");
37251
37210
  await rename5(tmp, p);
37252
37211
  }
37253
37212
  async function gatherInventory(directory) {
37254
37213
  const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
37255
37214
  const hivePath = resolveHiveKnowledgePath();
37256
- const hive = existsSync11(hivePath) ? await readKnowledge(hivePath) : [];
37215
+ const hive = existsSync10(hivePath) ? await readKnowledge(hivePath) : [];
37257
37216
  const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
37258
37217
  const skills = await listSkills(directory);
37259
37218
  const matureCandidates = swarm.concat(hive).filter((e) => e.status !== "archived" && e.confidence >= 0.85 && !e.generated_skill_slug && (e.confirmed_by ?? []).length >= 2);
@@ -37526,8 +37485,8 @@ async function runSkillImprover(req) {
37526
37485
  }
37527
37486
  throw err;
37528
37487
  }
37529
- const proposalDir = path16.join(req.directory, ".swarm", "skill-improver", "proposals");
37530
- const proposalFile = path16.join(proposalDir, `${timestampSlug(now)}.md`);
37488
+ const proposalDir = path15.join(req.directory, ".swarm", "skill-improver", "proposals");
37489
+ const proposalFile = path15.join(proposalDir, `${timestampSlug(now)}.md`);
37531
37490
  const finalBody = source === "llm" ? buildLLMProposalFrame({
37532
37491
  body,
37533
37492
  targets,
@@ -37923,7 +37882,7 @@ var init_write_retro = __esm(() => {
37923
37882
 
37924
37883
  // src/commands/close.ts
37925
37884
  import { promises as fs7 } from "fs";
37926
- import path17 from "path";
37885
+ import path16 from "path";
37927
37886
  async function runAbortableSkillReview(req, timeoutMs) {
37928
37887
  const controller = new AbortController;
37929
37888
  let timeout;
@@ -37979,10 +37938,10 @@ function guaranteeAllPlansComplete(planData) {
37979
37938
  }
37980
37939
  async function handleCloseCommand(directory, args, options = {}) {
37981
37940
  const planPath = validateSwarmPath(directory, "plan.json");
37982
- const swarmDir = path17.join(directory, ".swarm");
37941
+ const swarmDir = path16.join(directory, ".swarm");
37983
37942
  let planExists = false;
37984
37943
  let planData = {
37985
- title: path17.basename(directory) || "Ad-hoc session",
37944
+ title: path16.basename(directory) || "Ad-hoc session",
37986
37945
  phases: []
37987
37946
  };
37988
37947
  try {
@@ -38091,7 +38050,7 @@ async function handleCloseCommand(directory, args, options = {}) {
38091
38050
  warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
38092
38051
  }
38093
38052
  }
38094
- const lessonsFilePath = path17.join(swarmDir, "close-lessons.md");
38053
+ const lessonsFilePath = path16.join(swarmDir, "close-lessons.md");
38095
38054
  let explicitLessons = [];
38096
38055
  try {
38097
38056
  const lessonsText = await fs7.readFile(lessonsFilePath, "utf-8");
@@ -38100,11 +38059,11 @@ async function handleCloseCommand(directory, args, options = {}) {
38100
38059
  } catch {}
38101
38060
  const retroLessons = [];
38102
38061
  try {
38103
- const evidenceDir = path17.join(swarmDir, "evidence");
38062
+ const evidenceDir = path16.join(swarmDir, "evidence");
38104
38063
  const evidenceEntries = await fs7.readdir(evidenceDir);
38105
38064
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
38106
38065
  for (const retroDir of retroDirs) {
38107
- const evidencePath = path17.join(evidenceDir, retroDir, "evidence.json");
38066
+ const evidencePath = path16.join(evidenceDir, retroDir, "evidence.json");
38108
38067
  try {
38109
38068
  const content = await fs7.readFile(evidencePath, "utf-8");
38110
38069
  const parsed = JSON.parse(content);
@@ -38229,7 +38188,7 @@ async function handleCloseCommand(directory, args, options = {}) {
38229
38188
  }
38230
38189
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
38231
38190
  const suffix = Math.random().toString(36).slice(2, 8);
38232
- const archiveDir = path17.join(swarmDir, "archive", `swarm-${timestamp}-${suffix}`);
38191
+ const archiveDir = path16.join(swarmDir, "archive", `swarm-${timestamp}-${suffix}`);
38233
38192
  let archiveResult = "";
38234
38193
  let archivedFileCount = 0;
38235
38194
  const archivedActiveStateFiles = new Set;
@@ -38237,8 +38196,8 @@ async function handleCloseCommand(directory, args, options = {}) {
38237
38196
  try {
38238
38197
  await fs7.mkdir(archiveDir, { recursive: true });
38239
38198
  for (const artifact of ARCHIVE_ARTIFACTS) {
38240
- const srcPath = path17.join(swarmDir, artifact);
38241
- const destPath = path17.join(archiveDir, artifact);
38199
+ const srcPath = path16.join(swarmDir, artifact);
38200
+ const destPath = path16.join(archiveDir, artifact);
38242
38201
  try {
38243
38202
  await fs7.copyFile(srcPath, destPath);
38244
38203
  archivedFileCount++;
@@ -38248,22 +38207,22 @@ async function handleCloseCommand(directory, args, options = {}) {
38248
38207
  } catch {}
38249
38208
  }
38250
38209
  for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
38251
- const srcDir = path17.join(swarmDir, dirName);
38252
- const destDir = path17.join(archiveDir, dirName);
38210
+ const srcDir = path16.join(swarmDir, dirName);
38211
+ const destDir = path16.join(archiveDir, dirName);
38253
38212
  try {
38254
38213
  const entries = await fs7.readdir(srcDir);
38255
38214
  if (entries.length > 0) {
38256
38215
  await fs7.mkdir(destDir, { recursive: true });
38257
38216
  for (const entry of entries) {
38258
- const srcEntry = path17.join(srcDir, entry);
38259
- const destEntry = path17.join(destDir, entry);
38217
+ const srcEntry = path16.join(srcDir, entry);
38218
+ const destEntry = path16.join(destDir, entry);
38260
38219
  try {
38261
38220
  const stat2 = await fs7.stat(srcEntry);
38262
38221
  if (stat2.isDirectory()) {
38263
38222
  await fs7.mkdir(destEntry, { recursive: true });
38264
38223
  const subEntries = await fs7.readdir(srcEntry);
38265
38224
  for (const sub of subEntries) {
38266
- await fs7.copyFile(path17.join(srcEntry, sub), path17.join(destEntry, sub)).catch(() => {});
38225
+ await fs7.copyFile(path16.join(srcEntry, sub), path16.join(destEntry, sub)).catch(() => {});
38267
38226
  }
38268
38227
  } else {
38269
38228
  await fs7.copyFile(srcEntry, destEntry);
@@ -38295,7 +38254,7 @@ async function handleCloseCommand(directory, args, options = {}) {
38295
38254
  warnings.push(`Preserved ${artifact} because it was not successfully archived.`);
38296
38255
  continue;
38297
38256
  }
38298
- const filePath = path17.join(swarmDir, artifact);
38257
+ const filePath = path16.join(swarmDir, artifact);
38299
38258
  try {
38300
38259
  await fs7.unlink(filePath);
38301
38260
  cleanedFiles.push(artifact);
@@ -38308,7 +38267,7 @@ async function handleCloseCommand(directory, args, options = {}) {
38308
38267
  if (!archivedActiveStateDirs.has(dirName)) {
38309
38268
  continue;
38310
38269
  }
38311
- const dirPath = path17.join(swarmDir, dirName);
38270
+ const dirPath = path16.join(swarmDir, dirName);
38312
38271
  try {
38313
38272
  await fs7.rm(dirPath, { recursive: true, force: true });
38314
38273
  cleanedFiles.push(`${dirName}/`);
@@ -38319,23 +38278,23 @@ async function handleCloseCommand(directory, args, options = {}) {
38319
38278
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
38320
38279
  for (const backup of configBackups) {
38321
38280
  try {
38322
- await fs7.unlink(path17.join(swarmDir, backup));
38281
+ await fs7.unlink(path16.join(swarmDir, backup));
38323
38282
  configBackupsRemoved++;
38324
38283
  } catch {}
38325
38284
  }
38326
38285
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
38327
38286
  for (const sibling of ledgerSiblings) {
38328
38287
  try {
38329
- await fs7.unlink(path17.join(swarmDir, sibling));
38288
+ await fs7.unlink(path16.join(swarmDir, sibling));
38330
38289
  } catch {}
38331
38290
  }
38332
38291
  } catch {}
38333
38292
  let swarmPlanFilesRemoved = 0;
38334
38293
  const candidates = [
38335
- path17.join(directory, ".swarm", "SWARM_PLAN.json"),
38336
- path17.join(directory, ".swarm", "SWARM_PLAN.md"),
38337
- path17.join(directory, "SWARM_PLAN.json"),
38338
- path17.join(directory, "SWARM_PLAN.md")
38294
+ path16.join(directory, ".swarm", "SWARM_PLAN.json"),
38295
+ path16.join(directory, ".swarm", "SWARM_PLAN.md"),
38296
+ path16.join(directory, "SWARM_PLAN.json"),
38297
+ path16.join(directory, "SWARM_PLAN.md")
38339
38298
  ];
38340
38299
  for (const candidate of candidates) {
38341
38300
  try {
@@ -38343,12 +38302,12 @@ async function handleCloseCommand(directory, args, options = {}) {
38343
38302
  swarmPlanFilesRemoved++;
38344
38303
  } catch (err) {
38345
38304
  if (err?.code !== "ENOENT") {
38346
- warnings.push(`Failed to remove ${path17.basename(candidate)}: ${err instanceof Error ? err.message : String(err)}`);
38305
+ warnings.push(`Failed to remove ${path16.basename(candidate)}: ${err instanceof Error ? err.message : String(err)}`);
38347
38306
  }
38348
38307
  }
38349
38308
  }
38350
38309
  clearAllScopes(directory);
38351
- const contextPath = path17.join(swarmDir, "context.md");
38310
+ const contextPath = path16.join(swarmDir, "context.md");
38352
38311
  const contextContent = [
38353
38312
  "# Context",
38354
38313
  "",
@@ -38567,14 +38526,14 @@ var init_close = __esm(() => {
38567
38526
 
38568
38527
  // src/commands/config.ts
38569
38528
  import * as os4 from "os";
38570
- import * as path18 from "path";
38529
+ import * as path17 from "path";
38571
38530
  function getUserConfigDir2() {
38572
- return process.env.XDG_CONFIG_HOME || path18.join(os4.homedir(), ".config");
38531
+ return process.env.XDG_CONFIG_HOME || path17.join(os4.homedir(), ".config");
38573
38532
  }
38574
38533
  async function handleConfigCommand(directory, _args) {
38575
38534
  const config3 = loadPluginConfig(directory);
38576
- const userConfigPath = path18.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
38577
- const projectConfigPath = path18.join(directory, ".opencode", "opencode-swarm.json");
38535
+ const userConfigPath = path17.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
38536
+ const projectConfigPath = path17.join(directory, ".opencode", "opencode-swarm.json");
38578
38537
  const lines = [
38579
38538
  "## Swarm Configuration",
38580
38539
  "",
@@ -38700,8 +38659,8 @@ var init_curate = __esm(() => {
38700
38659
  // src/tools/co-change-analyzer.ts
38701
38660
  import * as child_process3 from "child_process";
38702
38661
  import { randomUUID } from "crypto";
38703
- import { readdir, readFile as readFile7, stat as stat2 } from "fs/promises";
38704
- import * as path19 from "path";
38662
+ import { readdir, readFile as readFile6, stat as stat2 } from "fs/promises";
38663
+ import * as path18 from "path";
38705
38664
  import { promisify } from "util";
38706
38665
  function getExecFileAsync() {
38707
38666
  return promisify(child_process3.execFile);
@@ -38803,7 +38762,7 @@ async function scanSourceFiles(dir) {
38803
38762
  try {
38804
38763
  const entries = await readdir(dir, { withFileTypes: true });
38805
38764
  for (const entry of entries) {
38806
- const fullPath = path19.join(dir, entry.name);
38765
+ const fullPath = path18.join(dir, entry.name);
38807
38766
  if (entry.isDirectory()) {
38808
38767
  if (skipDirs.has(entry.name)) {
38809
38768
  continue;
@@ -38811,7 +38770,7 @@ async function scanSourceFiles(dir) {
38811
38770
  const subFiles = await scanSourceFiles(fullPath);
38812
38771
  results.push(...subFiles);
38813
38772
  } else if (entry.isFile()) {
38814
- const ext = path19.extname(entry.name);
38773
+ const ext = path18.extname(entry.name);
38815
38774
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
38816
38775
  results.push(fullPath);
38817
38776
  }
@@ -38825,7 +38784,7 @@ async function getStaticEdges(directory) {
38825
38784
  const sourceFiles = await scanSourceFiles(directory);
38826
38785
  for (const sourceFile of sourceFiles) {
38827
38786
  try {
38828
- const content = await readFile7(sourceFile, "utf-8");
38787
+ const content = await readFile6(sourceFile, "utf-8");
38829
38788
  const importRegex = /(?:import|require)\s*(?:\(?\s*['"`]|.*?from\s+['"`])([^'"`]+)['"`]/g;
38830
38789
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
38831
38790
  const importPath = match[1].trim();
@@ -38833,8 +38792,8 @@ async function getStaticEdges(directory) {
38833
38792
  continue;
38834
38793
  }
38835
38794
  try {
38836
- const sourceDir = path19.dirname(sourceFile);
38837
- const resolvedPath = path19.resolve(sourceDir, importPath);
38795
+ const sourceDir = path18.dirname(sourceFile);
38796
+ const resolvedPath = path18.resolve(sourceDir, importPath);
38838
38797
  const extensions = [
38839
38798
  "",
38840
38799
  ".ts",
@@ -38859,8 +38818,8 @@ async function getStaticEdges(directory) {
38859
38818
  if (!targetFile) {
38860
38819
  continue;
38861
38820
  }
38862
- const relSource = path19.relative(directory, sourceFile).replace(/\\/g, "/");
38863
- const relTarget = path19.relative(directory, targetFile).replace(/\\/g, "/");
38821
+ const relSource = path18.relative(directory, sourceFile).replace(/\\/g, "/");
38822
+ const relTarget = path18.relative(directory, targetFile).replace(/\\/g, "/");
38864
38823
  const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
38865
38824
  edges.add(key);
38866
38825
  } catch {}
@@ -38872,7 +38831,7 @@ async function getStaticEdges(directory) {
38872
38831
  function isTestImplementationPair(fileA, fileB) {
38873
38832
  const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
38874
38833
  const getBaseName = (filePath) => {
38875
- const base = path19.basename(filePath);
38834
+ const base = path18.basename(filePath);
38876
38835
  for (const pattern of testPatterns) {
38877
38836
  if (base.endsWith(pattern)) {
38878
38837
  return base.slice(0, -pattern.length);
@@ -38882,16 +38841,16 @@ function isTestImplementationPair(fileA, fileB) {
38882
38841
  };
38883
38842
  const baseA = getBaseName(fileA);
38884
38843
  const baseB = getBaseName(fileB);
38885
- return baseA === baseB && baseA !== path19.basename(fileA) && baseA !== path19.basename(fileB);
38844
+ return baseA === baseB && baseA !== path18.basename(fileA) && baseA !== path18.basename(fileB);
38886
38845
  }
38887
38846
  function hasSharedPrefix(fileA, fileB) {
38888
- const dirA = path19.dirname(fileA);
38889
- const dirB = path19.dirname(fileB);
38847
+ const dirA = path18.dirname(fileA);
38848
+ const dirB = path18.dirname(fileB);
38890
38849
  if (dirA !== dirB) {
38891
38850
  return false;
38892
38851
  }
38893
- const baseA = path19.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
38894
- const baseB = path19.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
38852
+ const baseA = path18.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
38853
+ const baseB = path18.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
38895
38854
  if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
38896
38855
  return true;
38897
38856
  }
@@ -38945,8 +38904,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
38945
38904
  const entries = [];
38946
38905
  const now = new Date().toISOString();
38947
38906
  for (const pair of pairs.slice(0, 10)) {
38948
- const baseA = path19.basename(pair.fileA);
38949
- const baseB = path19.basename(pair.fileB);
38907
+ const baseA = path18.basename(pair.fileA);
38908
+ const baseB = path18.basename(pair.fileB);
38950
38909
  let lesson = `Files ${pair.fileA} and ${pair.fileB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
38951
38910
  if (lesson.length > 280) {
38952
38911
  lesson = `Files ${baseA} and ${baseB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
@@ -39048,7 +39007,7 @@ var init_co_change_analyzer = __esm(() => {
39048
39007
  });
39049
39008
 
39050
39009
  // src/commands/dark-matter.ts
39051
- import path20 from "path";
39010
+ import path19 from "path";
39052
39011
  async function handleDarkMatterCommand(directory, args) {
39053
39012
  const options = {};
39054
39013
  for (let i = 0;i < args.length; i++) {
@@ -39080,7 +39039,7 @@ Ensure this is a git repository with commit history.`;
39080
39039
  const output = formatDarkMatterOutput(pairs);
39081
39040
  if (pairs.length > 0) {
39082
39041
  try {
39083
- const projectName = path20.basename(path20.resolve(directory));
39042
+ const projectName = path19.basename(path19.resolve(directory));
39084
39043
  const entries = darkMatterToKnowledgeEntries(pairs, projectName);
39085
39044
  if (entries.length > 0) {
39086
39045
  const knowledgePath = resolveSwarmKnowledgePath(directory);
@@ -39217,67 +39176,67 @@ var init_deep_dive = __esm(() => {
39217
39176
 
39218
39177
  // src/config/cache-paths.ts
39219
39178
  import * as os5 from "os";
39220
- import * as path21 from "path";
39179
+ import * as path20 from "path";
39221
39180
  function getPluginConfigDir() {
39222
- return path21.join(process.env.XDG_CONFIG_HOME || path21.join(os5.homedir(), ".config"), "opencode");
39181
+ return path20.join(process.env.XDG_CONFIG_HOME || path20.join(os5.homedir(), ".config"), "opencode");
39223
39182
  }
39224
39183
  function getPluginCachePaths() {
39225
- const cacheBase = process.env.XDG_CACHE_HOME || path21.join(os5.homedir(), ".cache");
39184
+ const cacheBase = process.env.XDG_CACHE_HOME || path20.join(os5.homedir(), ".cache");
39226
39185
  const configDir = getPluginConfigDir();
39227
39186
  const paths = [
39228
- path21.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
39229
- path21.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
39230
- path21.join(configDir, "node_modules", "opencode-swarm")
39187
+ path20.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
39188
+ path20.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
39189
+ path20.join(configDir, "node_modules", "opencode-swarm")
39231
39190
  ];
39232
39191
  if (process.platform === "darwin") {
39233
- const libCaches = path21.join(os5.homedir(), "Library", "Caches");
39234
- paths.push(path21.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path21.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
39192
+ const libCaches = path20.join(os5.homedir(), "Library", "Caches");
39193
+ paths.push(path20.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path20.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
39235
39194
  }
39236
39195
  if (process.platform === "win32") {
39237
- const localAppData = process.env.LOCALAPPDATA || path21.join(os5.homedir(), "AppData", "Local");
39238
- const appData = process.env.APPDATA || path21.join(os5.homedir(), "AppData", "Roaming");
39239
- paths.push(path21.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path21.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path21.join(appData, "opencode", "node_modules", "opencode-swarm"));
39196
+ const localAppData = process.env.LOCALAPPDATA || path20.join(os5.homedir(), "AppData", "Local");
39197
+ const appData = process.env.APPDATA || path20.join(os5.homedir(), "AppData", "Roaming");
39198
+ paths.push(path20.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path20.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path20.join(appData, "opencode", "node_modules", "opencode-swarm"));
39240
39199
  }
39241
39200
  return paths;
39242
39201
  }
39243
39202
  function getPluginLockFilePaths() {
39244
- const cacheBase = process.env.XDG_CACHE_HOME || path21.join(os5.homedir(), ".cache");
39203
+ const cacheBase = process.env.XDG_CACHE_HOME || path20.join(os5.homedir(), ".cache");
39245
39204
  const configDir = getPluginConfigDir();
39246
39205
  const paths = [
39247
- path21.join(cacheBase, "opencode", "bun.lock"),
39248
- path21.join(cacheBase, "opencode", "bun.lockb"),
39249
- path21.join(configDir, "package-lock.json")
39206
+ path20.join(cacheBase, "opencode", "bun.lock"),
39207
+ path20.join(cacheBase, "opencode", "bun.lockb"),
39208
+ path20.join(configDir, "package-lock.json")
39250
39209
  ];
39251
39210
  if (process.platform === "darwin") {
39252
- const libCaches = path21.join(os5.homedir(), "Library", "Caches");
39253
- paths.push(path21.join(libCaches, "opencode", "bun.lock"), path21.join(libCaches, "opencode", "bun.lockb"));
39211
+ const libCaches = path20.join(os5.homedir(), "Library", "Caches");
39212
+ paths.push(path20.join(libCaches, "opencode", "bun.lock"), path20.join(libCaches, "opencode", "bun.lockb"));
39254
39213
  }
39255
39214
  if (process.platform === "win32") {
39256
- const localAppData = process.env.LOCALAPPDATA || path21.join(os5.homedir(), "AppData", "Local");
39257
- paths.push(path21.join(localAppData, "opencode", "bun.lock"), path21.join(localAppData, "opencode", "bun.lockb"));
39215
+ const localAppData = process.env.LOCALAPPDATA || path20.join(os5.homedir(), "AppData", "Local");
39216
+ paths.push(path20.join(localAppData, "opencode", "bun.lock"), path20.join(localAppData, "opencode", "bun.lockb"));
39258
39217
  }
39259
39218
  return paths;
39260
39219
  }
39261
39220
  var init_cache_paths = () => {};
39262
39221
 
39263
39222
  // src/services/version-check.ts
39264
- import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
39223
+ import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
39265
39224
  import { homedir as homedir5 } from "os";
39266
- import { join as join20 } from "path";
39225
+ import { join as join19 } from "path";
39267
39226
  function cacheDir() {
39268
39227
  const xdg = process.env.XDG_CACHE_HOME;
39269
- const base = xdg && xdg.length > 0 ? xdg : join20(homedir5(), ".cache");
39270
- return join20(base, "opencode-swarm");
39228
+ const base = xdg && xdg.length > 0 ? xdg : join19(homedir5(), ".cache");
39229
+ return join19(base, "opencode-swarm");
39271
39230
  }
39272
39231
  function cacheFile() {
39273
- return join20(cacheDir(), "version-check.json");
39232
+ return join19(cacheDir(), "version-check.json");
39274
39233
  }
39275
39234
  function readVersionCache() {
39276
39235
  try {
39277
- const path22 = cacheFile();
39278
- if (!existsSync12(path22))
39236
+ const path21 = cacheFile();
39237
+ if (!existsSync11(path21))
39279
39238
  return null;
39280
- const raw = readFileSync6(path22, "utf-8");
39239
+ const raw = readFileSync6(path21, "utf-8");
39281
39240
  const parsed = JSON.parse(raw);
39282
39241
  if (typeof parsed?.checkedAt !== "number")
39283
39242
  return null;
@@ -39316,8 +39275,8 @@ var init_version_check = __esm(() => {
39316
39275
 
39317
39276
  // src/services/diagnose-service.ts
39318
39277
  import * as child_process4 from "child_process";
39319
- import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync6 } from "fs";
39320
- import path22 from "path";
39278
+ import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync6 } from "fs";
39279
+ import path21 from "path";
39321
39280
  import { fileURLToPath } from "url";
39322
39281
  function validateTaskDag(plan) {
39323
39282
  const allTaskIds = new Set;
@@ -39550,7 +39509,7 @@ async function checkConfigBackups(directory) {
39550
39509
  }
39551
39510
  async function checkGitRepository(directory) {
39552
39511
  try {
39553
- if (!existsSync13(directory) || !statSync6(directory).isDirectory()) {
39512
+ if (!existsSync12(directory) || !statSync6(directory).isDirectory()) {
39554
39513
  return {
39555
39514
  name: "Git Repository",
39556
39515
  status: "\u274C",
@@ -39614,8 +39573,8 @@ async function checkSpecStaleness(directory, plan) {
39614
39573
  };
39615
39574
  }
39616
39575
  async function checkConfigParseability(directory) {
39617
- const configPath = path22.join(directory, ".opencode/opencode-swarm.json");
39618
- if (!existsSync13(configPath)) {
39576
+ const configPath = path21.join(directory, ".opencode/opencode-swarm.json");
39577
+ if (!existsSync12(configPath)) {
39619
39578
  return {
39620
39579
  name: "Config Parseability",
39621
39580
  status: "\u2705",
@@ -39643,7 +39602,7 @@ function resolveGrammarDir(thisDir) {
39643
39602
  const normalized = thisDir.replace(/\\/g, "/");
39644
39603
  const isSource = normalized.endsWith("/src/services");
39645
39604
  const isCliBundle = normalized.endsWith("/cli");
39646
- return isSource || isCliBundle ? path22.join(thisDir, "..", "lang", "grammars") : path22.join(thisDir, "lang", "grammars");
39605
+ return isSource || isCliBundle ? path21.join(thisDir, "..", "lang", "grammars") : path21.join(thisDir, "lang", "grammars");
39647
39606
  }
39648
39607
  async function checkGrammarWasmFiles() {
39649
39608
  const grammarFiles = [
@@ -39667,14 +39626,14 @@ async function checkGrammarWasmFiles() {
39667
39626
  "tree-sitter-ini.wasm",
39668
39627
  "tree-sitter-regex.wasm"
39669
39628
  ];
39670
- const thisDir = path22.dirname(fileURLToPath(import.meta.url));
39629
+ const thisDir = path21.dirname(fileURLToPath(import.meta.url));
39671
39630
  const grammarDir = resolveGrammarDir(thisDir);
39672
39631
  const missing = [];
39673
- if (!existsSync13(path22.join(grammarDir, "tree-sitter.wasm"))) {
39632
+ if (!existsSync12(path21.join(grammarDir, "tree-sitter.wasm"))) {
39674
39633
  missing.push("tree-sitter.wasm (core runtime)");
39675
39634
  }
39676
39635
  for (const file3 of grammarFiles) {
39677
- if (!existsSync13(path22.join(grammarDir, file3))) {
39636
+ if (!existsSync12(path21.join(grammarDir, file3))) {
39678
39637
  missing.push(file3);
39679
39638
  }
39680
39639
  }
@@ -39692,8 +39651,8 @@ async function checkGrammarWasmFiles() {
39692
39651
  };
39693
39652
  }
39694
39653
  async function checkCheckpointManifest(directory) {
39695
- const manifestPath = path22.join(directory, ".swarm/checkpoints.json");
39696
- if (!existsSync13(manifestPath)) {
39654
+ const manifestPath = path21.join(directory, ".swarm/checkpoints.json");
39655
+ if (!existsSync12(manifestPath)) {
39697
39656
  return {
39698
39657
  name: "Checkpoint Manifest",
39699
39658
  status: "\u2705",
@@ -39744,8 +39703,8 @@ async function checkCheckpointManifest(directory) {
39744
39703
  }
39745
39704
  }
39746
39705
  async function checkEventStreamIntegrity(directory) {
39747
- const eventsPath = path22.join(directory, ".swarm/events.jsonl");
39748
- if (!existsSync13(eventsPath)) {
39706
+ const eventsPath = path21.join(directory, ".swarm/events.jsonl");
39707
+ if (!existsSync12(eventsPath)) {
39749
39708
  return {
39750
39709
  name: "Event Stream",
39751
39710
  status: "\u2705",
@@ -39785,8 +39744,8 @@ async function checkEventStreamIntegrity(directory) {
39785
39744
  }
39786
39745
  }
39787
39746
  async function checkSteeringDirectives(directory) {
39788
- const eventsPath = path22.join(directory, ".swarm/events.jsonl");
39789
- if (!existsSync13(eventsPath)) {
39747
+ const eventsPath = path21.join(directory, ".swarm/events.jsonl");
39748
+ if (!existsSync12(eventsPath)) {
39790
39749
  return {
39791
39750
  name: "Steering Directives",
39792
39751
  status: "\u2705",
@@ -39841,8 +39800,8 @@ async function checkCurator(directory) {
39841
39800
  detail: "Disabled (enable via curator.enabled)"
39842
39801
  };
39843
39802
  }
39844
- const summaryPath = path22.join(directory, ".swarm/curator-summary.json");
39845
- if (!existsSync13(summaryPath)) {
39803
+ const summaryPath = path21.join(directory, ".swarm/curator-summary.json");
39804
+ if (!existsSync12(summaryPath)) {
39846
39805
  return {
39847
39806
  name: "Curator",
39848
39807
  status: "\u2705",
@@ -40007,8 +39966,8 @@ async function getDiagnoseData(directory) {
40007
39966
  checks5.push(await checkSteeringDirectives(directory));
40008
39967
  checks5.push(await checkCurator(directory));
40009
39968
  try {
40010
- const evidenceDir = path22.join(directory, ".swarm", "evidence");
40011
- const snapshotFiles = existsSync13(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
39969
+ const evidenceDir = path21.join(directory, ".swarm", "evidence");
39970
+ const snapshotFiles = existsSync12(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
40012
39971
  if (snapshotFiles.length > 0) {
40013
39972
  const latest = snapshotFiles.sort().pop();
40014
39973
  checks5.push({
@@ -40041,11 +40000,11 @@ async function getDiagnoseData(directory) {
40041
40000
  const cacheRows = [];
40042
40001
  for (const cachePath of cachePaths) {
40043
40002
  try {
40044
- if (!existsSync13(cachePath)) {
40003
+ if (!existsSync12(cachePath)) {
40045
40004
  cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
40046
40005
  continue;
40047
40006
  }
40048
- const pkgJsonPath = path22.join(cachePath, "package.json");
40007
+ const pkgJsonPath = path21.join(cachePath, "package.json");
40049
40008
  try {
40050
40009
  const raw = readFileSync7(pkgJsonPath, "utf-8");
40051
40010
  const parsed = JSON.parse(raw);
@@ -40135,13 +40094,13 @@ __export(exports_config_doctor, {
40135
40094
  import * as crypto3 from "crypto";
40136
40095
  import * as fs8 from "fs";
40137
40096
  import * as os6 from "os";
40138
- import * as path23 from "path";
40097
+ import * as path22 from "path";
40139
40098
  function getUserConfigDir3() {
40140
- return process.env.XDG_CONFIG_HOME || path23.join(os6.homedir(), ".config");
40099
+ return process.env.XDG_CONFIG_HOME || path22.join(os6.homedir(), ".config");
40141
40100
  }
40142
40101
  function getConfigPaths(directory) {
40143
- const userConfigPath = path23.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
40144
- const projectConfigPath = path23.join(directory, ".opencode", "opencode-swarm.json");
40102
+ const userConfigPath = path22.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
40103
+ const projectConfigPath = path22.join(directory, ".opencode", "opencode-swarm.json");
40145
40104
  return { userConfigPath, projectConfigPath };
40146
40105
  }
40147
40106
  function computeHash(content) {
@@ -40166,9 +40125,9 @@ function isValidConfigPath(configPath, directory) {
40166
40125
  const normalizedUser = userConfigPath.replace(/\\/g, "/");
40167
40126
  const normalizedProject = projectConfigPath.replace(/\\/g, "/");
40168
40127
  try {
40169
- const resolvedConfig = path23.resolve(configPath);
40170
- const resolvedUser = path23.resolve(normalizedUser);
40171
- const resolvedProject = path23.resolve(normalizedProject);
40128
+ const resolvedConfig = path22.resolve(configPath);
40129
+ const resolvedUser = path22.resolve(normalizedUser);
40130
+ const resolvedProject = path22.resolve(normalizedProject);
40172
40131
  return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
40173
40132
  } catch {
40174
40133
  return false;
@@ -40208,12 +40167,12 @@ function createConfigBackup(directory) {
40208
40167
  };
40209
40168
  }
40210
40169
  function writeBackupArtifact(directory, backup) {
40211
- const swarmDir = path23.join(directory, ".swarm");
40170
+ const swarmDir = path22.join(directory, ".swarm");
40212
40171
  if (!fs8.existsSync(swarmDir)) {
40213
40172
  fs8.mkdirSync(swarmDir, { recursive: true });
40214
40173
  }
40215
40174
  const backupFilename = `config-backup-${backup.createdAt}.json`;
40216
- const backupPath = path23.join(swarmDir, backupFilename);
40175
+ const backupPath = path22.join(swarmDir, backupFilename);
40217
40176
  const artifact = {
40218
40177
  createdAt: backup.createdAt,
40219
40178
  configPath: backup.configPath,
@@ -40243,7 +40202,7 @@ function restoreFromBackup(backupPath, directory) {
40243
40202
  return null;
40244
40203
  }
40245
40204
  const targetPath = artifact.configPath;
40246
- const targetDir = path23.dirname(targetPath);
40205
+ const targetDir = path22.dirname(targetPath);
40247
40206
  if (!fs8.existsSync(targetDir)) {
40248
40207
  fs8.mkdirSync(targetDir, { recursive: true });
40249
40208
  }
@@ -40274,9 +40233,9 @@ function readConfigFromFile(directory) {
40274
40233
  return null;
40275
40234
  }
40276
40235
  }
40277
- function validateConfigKey(path24, value, _config) {
40236
+ function validateConfigKey(path23, value, _config) {
40278
40237
  const findings = [];
40279
- switch (path24) {
40238
+ switch (path23) {
40280
40239
  case "agents": {
40281
40240
  if (value !== undefined) {
40282
40241
  findings.push({
@@ -40513,27 +40472,27 @@ function validateConfigKey(path24, value, _config) {
40513
40472
  }
40514
40473
  return findings;
40515
40474
  }
40516
- function walkConfigAndValidate(obj, path24, config3, findings) {
40475
+ function walkConfigAndValidate(obj, path23, config3, findings) {
40517
40476
  if (obj === null || obj === undefined) {
40518
40477
  return;
40519
40478
  }
40520
- if (path24 && typeof obj === "object" && !Array.isArray(obj)) {
40521
- const keyFindings = validateConfigKey(path24, obj, config3);
40479
+ if (path23 && typeof obj === "object" && !Array.isArray(obj)) {
40480
+ const keyFindings = validateConfigKey(path23, obj, config3);
40522
40481
  findings.push(...keyFindings);
40523
40482
  }
40524
40483
  if (typeof obj !== "object") {
40525
- const keyFindings = validateConfigKey(path24, obj, config3);
40484
+ const keyFindings = validateConfigKey(path23, obj, config3);
40526
40485
  findings.push(...keyFindings);
40527
40486
  return;
40528
40487
  }
40529
40488
  if (Array.isArray(obj)) {
40530
40489
  obj.forEach((item, index) => {
40531
- walkConfigAndValidate(item, `${path24}[${index}]`, config3, findings);
40490
+ walkConfigAndValidate(item, `${path23}[${index}]`, config3, findings);
40532
40491
  });
40533
40492
  return;
40534
40493
  }
40535
40494
  for (const [key, value] of Object.entries(obj)) {
40536
- const newPath = path24 ? `${path24}.${key}` : key;
40495
+ const newPath = path23 ? `${path23}.${key}` : key;
40537
40496
  walkConfigAndValidate(value, newPath, config3, findings);
40538
40497
  }
40539
40498
  }
@@ -40653,7 +40612,7 @@ function applySafeAutoFixes(directory, result) {
40653
40612
  }
40654
40613
  }
40655
40614
  if (appliedFixes.length > 0) {
40656
- const configDir = path23.dirname(configPath);
40615
+ const configDir = path22.dirname(configPath);
40657
40616
  if (!fs8.existsSync(configDir)) {
40658
40617
  fs8.mkdirSync(configDir, { recursive: true });
40659
40618
  }
@@ -40663,12 +40622,12 @@ function applySafeAutoFixes(directory, result) {
40663
40622
  return { appliedFixes, updatedConfigPath };
40664
40623
  }
40665
40624
  function writeDoctorArtifact(directory, result) {
40666
- const swarmDir = path23.join(directory, ".swarm");
40625
+ const swarmDir = path22.join(directory, ".swarm");
40667
40626
  if (!fs8.existsSync(swarmDir)) {
40668
40627
  fs8.mkdirSync(swarmDir, { recursive: true });
40669
40628
  }
40670
40629
  const artifactFilename = "config-doctor.json";
40671
- const artifactPath = path23.join(swarmDir, artifactFilename);
40630
+ const artifactPath = path22.join(swarmDir, artifactFilename);
40672
40631
  const guiOutput = {
40673
40632
  timestamp: result.timestamp,
40674
40633
  summary: result.summary,
@@ -40764,17 +40723,17 @@ function detectStraySwarmDirs(projectRoot) {
40764
40723
  if (!entry.isDirectory())
40765
40724
  continue;
40766
40725
  const name = entry.name;
40767
- const fullPath = path23.join(dir, name);
40726
+ const fullPath = path22.join(dir, name);
40768
40727
  if (SKIP_DIRS.has(name))
40769
40728
  continue;
40770
- const gitPath = path23.join(fullPath, ".git");
40729
+ const gitPath = path22.join(fullPath, ".git");
40771
40730
  try {
40772
40731
  const gitStat = fs8.statSync(gitPath);
40773
40732
  if (gitStat.isFile() || gitStat.isDirectory())
40774
40733
  continue;
40775
40734
  } catch {}
40776
40735
  if (name === ".swarm") {
40777
- const parentDir = path23.dirname(fullPath);
40736
+ const parentDir = path22.dirname(fullPath);
40778
40737
  if (parentDir === projectRoot)
40779
40738
  continue;
40780
40739
  let contents = [];
@@ -40784,7 +40743,7 @@ function detectStraySwarmDirs(projectRoot) {
40784
40743
  contents = ["<unreadable>"];
40785
40744
  }
40786
40745
  findings.push({
40787
- path: path23.relative(projectRoot, fullPath).replace(/\\/g, "/"),
40746
+ path: path22.relative(projectRoot, fullPath).replace(/\\/g, "/"),
40788
40747
  absolutePath: fullPath,
40789
40748
  contents: contents.slice(0, MAX_CONTENTS_ENTRIES),
40790
40749
  totalEntries: contents.length
@@ -40802,21 +40761,21 @@ function removeStraySwarmDir(projectRoot, strayPath) {
40802
40761
  let canonicalStray;
40803
40762
  try {
40804
40763
  canonicalRoot = fs8.realpathSync(projectRoot);
40805
- canonicalStray = fs8.realpathSync(path23.isAbsolute(strayPath) ? strayPath : path23.resolve(projectRoot, strayPath));
40764
+ canonicalStray = fs8.realpathSync(path22.isAbsolute(strayPath) ? strayPath : path22.resolve(projectRoot, strayPath));
40806
40765
  } catch (err) {
40807
40766
  return {
40808
40767
  success: false,
40809
40768
  message: `Failed to resolve paths: ${err instanceof Error ? err.message : String(err)}`
40810
40769
  };
40811
40770
  }
40812
- const rootSwarm = path23.join(canonicalRoot, ".swarm");
40771
+ const rootSwarm = path22.join(canonicalRoot, ".swarm");
40813
40772
  if (canonicalStray === rootSwarm || canonicalStray === canonicalRoot) {
40814
40773
  return {
40815
40774
  success: false,
40816
40775
  message: "Refusing to remove root .swarm/ directory"
40817
40776
  };
40818
40777
  }
40819
- if (!canonicalStray.startsWith(canonicalRoot + path23.sep)) {
40778
+ if (!canonicalStray.startsWith(canonicalRoot + path22.sep)) {
40820
40779
  return {
40821
40780
  success: false,
40822
40781
  message: "Path is outside project root \u2014 refusing to remove"
@@ -41905,7 +41864,7 @@ var init_profiles = __esm(() => {
41905
41864
 
41906
41865
  // src/lang/detector.ts
41907
41866
  import { access as access3, readdir as readdir2 } from "fs/promises";
41908
- import { extname as extname2, join as join22 } from "path";
41867
+ import { extname as extname2, join as join21 } from "path";
41909
41868
  async function detectProjectLanguages(projectDir) {
41910
41869
  const detected = new Set;
41911
41870
  async function scanDir(dir) {
@@ -41921,7 +41880,7 @@ async function detectProjectLanguages(projectDir) {
41921
41880
  if (detectFile.includes("*") || detectFile.includes("?"))
41922
41881
  continue;
41923
41882
  try {
41924
- await access3(join22(dir, detectFile));
41883
+ await access3(join21(dir, detectFile));
41925
41884
  detected.add(profile.id);
41926
41885
  break;
41927
41886
  } catch {}
@@ -41942,7 +41901,7 @@ async function detectProjectLanguages(projectDir) {
41942
41901
  const topEntries = await readdir2(projectDir, { withFileTypes: true });
41943
41902
  for (const entry of topEntries) {
41944
41903
  if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
41945
- await scanDir(join22(projectDir, entry.name));
41904
+ await scanDir(join21(projectDir, entry.name));
41946
41905
  }
41947
41906
  }
41948
41907
  } catch {}
@@ -41961,7 +41920,7 @@ var init_detector = __esm(() => {
41961
41920
 
41962
41921
  // src/build/discovery.ts
41963
41922
  import * as fs9 from "fs";
41964
- import * as path24 from "path";
41923
+ import * as path23 from "path";
41965
41924
  function isCommandAvailable(command) {
41966
41925
  if (toolchainCache.has(command)) {
41967
41926
  return toolchainCache.get(command);
@@ -41996,11 +41955,11 @@ function findBuildFiles(workingDir, patterns) {
41996
41955
  const regex = simpleGlobToRegex(pattern);
41997
41956
  const matches = files.filter((f) => regex.test(f));
41998
41957
  if (matches.length > 0) {
41999
- return path24.join(dir, matches[0]);
41958
+ return path23.join(dir, matches[0]);
42000
41959
  }
42001
41960
  } catch {}
42002
41961
  } else {
42003
- const filePath = path24.join(workingDir, pattern);
41962
+ const filePath = path23.join(workingDir, pattern);
42004
41963
  if (fs9.existsSync(filePath)) {
42005
41964
  return filePath;
42006
41965
  }
@@ -42009,7 +41968,7 @@ function findBuildFiles(workingDir, patterns) {
42009
41968
  return null;
42010
41969
  }
42011
41970
  function getRepoDefinedScripts(workingDir, scripts) {
42012
- const packageJsonPath = path24.join(workingDir, "package.json");
41971
+ const packageJsonPath = path23.join(workingDir, "package.json");
42013
41972
  if (!fs9.existsSync(packageJsonPath)) {
42014
41973
  return [];
42015
41974
  }
@@ -42050,7 +42009,7 @@ function findAllBuildFiles(workingDir) {
42050
42009
  const regex = simpleGlobToRegex(pattern);
42051
42010
  findFilesRecursive(workingDir, regex, allBuildFiles);
42052
42011
  } else {
42053
- const filePath = path24.join(workingDir, pattern);
42012
+ const filePath = path23.join(workingDir, pattern);
42054
42013
  if (fs9.existsSync(filePath)) {
42055
42014
  allBuildFiles.add(filePath);
42056
42015
  }
@@ -42063,7 +42022,7 @@ function findFilesRecursive(dir, regex, results) {
42063
42022
  try {
42064
42023
  const entries = fs9.readdirSync(dir, { withFileTypes: true });
42065
42024
  for (const entry of entries) {
42066
- const fullPath = path24.join(dir, entry.name);
42025
+ const fullPath = path23.join(dir, entry.name);
42067
42026
  if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
42068
42027
  findFilesRecursive(fullPath, regex, results);
42069
42028
  } else if (entry.isFile() && regex.test(entry.name)) {
@@ -42086,7 +42045,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
42086
42045
  let foundCommand = false;
42087
42046
  for (const cmd of sortedCommands) {
42088
42047
  if (cmd.detectFile) {
42089
- const detectFilePath = path24.join(workingDir, cmd.detectFile);
42048
+ const detectFilePath = path23.join(workingDir, cmd.detectFile);
42090
42049
  if (!fs9.existsSync(detectFilePath)) {
42091
42050
  continue;
42092
42051
  }
@@ -42327,7 +42286,7 @@ var init_discovery = __esm(() => {
42327
42286
 
42328
42287
  // src/services/tool-doctor.ts
42329
42288
  import * as fs10 from "fs";
42330
- import * as path25 from "path";
42289
+ import * as path24 from "path";
42331
42290
  function extractRegisteredToolKeys(indexPath) {
42332
42291
  const registeredKeys = new Set;
42333
42292
  try {
@@ -42382,8 +42341,8 @@ function checkBinaryReadiness() {
42382
42341
  }
42383
42342
  function runToolDoctor(_directory, pluginRoot) {
42384
42343
  const findings = [];
42385
- const resolvedPluginRoot = pluginRoot ?? path25.resolve(import.meta.dir, "..", "..");
42386
- const indexPath = path25.join(resolvedPluginRoot, "src", "index.ts");
42344
+ const resolvedPluginRoot = pluginRoot ?? path24.resolve(import.meta.dir, "..", "..");
42345
+ const indexPath = path24.join(resolvedPluginRoot, "src", "index.ts");
42387
42346
  if (!fs10.existsSync(indexPath)) {
42388
42347
  return {
42389
42348
  findings: [
@@ -43129,12 +43088,12 @@ var init_export = __esm(() => {
43129
43088
 
43130
43089
  // src/full-auto/state.ts
43131
43090
  import * as fs11 from "fs";
43132
- import * as path26 from "path";
43091
+ import * as path25 from "path";
43133
43092
  function nowISO() {
43134
43093
  return new Date().toISOString();
43135
43094
  }
43136
43095
  function ensureSwarmDir(directory) {
43137
- const swarmDir = path26.resolve(directory, ".swarm");
43096
+ const swarmDir = path25.resolve(directory, ".swarm");
43138
43097
  if (!fs11.existsSync(swarmDir)) {
43139
43098
  fs11.mkdirSync(swarmDir, { recursive: true });
43140
43099
  }
@@ -43835,7 +43794,7 @@ var init_handoff_service = __esm(() => {
43835
43794
 
43836
43795
  // src/session/snapshot-writer.ts
43837
43796
  import { closeSync as closeSync3, fsyncSync as fsyncSync2, mkdirSync as mkdirSync10, openSync as openSync3, renameSync as renameSync6 } from "fs";
43838
- import * as path27 from "path";
43797
+ import * as path26 from "path";
43839
43798
  function serializeAgentSession(s) {
43840
43799
  const gateLog = {};
43841
43800
  const rawGateLog = s.gateLog ?? new Map;
@@ -43932,7 +43891,7 @@ async function writeSnapshot(directory, state) {
43932
43891
  }
43933
43892
  const content = JSON.stringify(snapshot, null, 2);
43934
43893
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
43935
- const dir = path27.dirname(resolvedPath);
43894
+ const dir = path26.dirname(resolvedPath);
43936
43895
  mkdirSync10(dir, { recursive: true });
43937
43896
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
43938
43897
  await bunWrite(tempPath, content);
@@ -44389,9 +44348,9 @@ var init_issue = __esm(() => {
44389
44348
 
44390
44349
  // src/hooks/knowledge-migrator.ts
44391
44350
  import { randomUUID as randomUUID2 } from "crypto";
44392
- import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
44393
- import { mkdir as mkdir8, readFile as readFile8, writeFile as writeFile9 } from "fs/promises";
44394
- import * as path28 from "path";
44351
+ import { existsSync as existsSync17, readFileSync as readFileSync12 } from "fs";
44352
+ import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
44353
+ import * as path27 from "path";
44395
44354
  async function migrateKnowledgeToExternal(_directory, _config) {
44396
44355
  return {
44397
44356
  migrated: false,
@@ -44402,10 +44361,10 @@ async function migrateKnowledgeToExternal(_directory, _config) {
44402
44361
  };
44403
44362
  }
44404
44363
  async function migrateContextToKnowledge(directory, config3) {
44405
- const sentinelPath = path28.join(directory, ".swarm", ".knowledge-migrated");
44406
- const contextPath = path28.join(directory, ".swarm", "context.md");
44364
+ const sentinelPath = path27.join(directory, ".swarm", ".knowledge-migrated");
44365
+ const contextPath = path27.join(directory, ".swarm", "context.md");
44407
44366
  const knowledgePath = resolveSwarmKnowledgePath(directory);
44408
- if (existsSync18(sentinelPath)) {
44367
+ if (existsSync17(sentinelPath)) {
44409
44368
  return {
44410
44369
  migrated: false,
44411
44370
  entriesMigrated: 0,
@@ -44414,7 +44373,7 @@ async function migrateContextToKnowledge(directory, config3) {
44414
44373
  skippedReason: "sentinel-exists"
44415
44374
  };
44416
44375
  }
44417
- if (!existsSync18(contextPath)) {
44376
+ if (!existsSync17(contextPath)) {
44418
44377
  return {
44419
44378
  migrated: false,
44420
44379
  entriesMigrated: 0,
@@ -44423,7 +44382,7 @@ async function migrateContextToKnowledge(directory, config3) {
44423
44382
  skippedReason: "no-context-file"
44424
44383
  };
44425
44384
  }
44426
- const contextContent = await readFile8(contextPath, "utf-8");
44385
+ const contextContent = await readFile7(contextPath, "utf-8");
44427
44386
  if (contextContent.trim().length === 0) {
44428
44387
  return {
44429
44388
  migrated: false,
@@ -44599,8 +44558,8 @@ function truncateLesson(text) {
44599
44558
  return `${text.slice(0, 277)}...`;
44600
44559
  }
44601
44560
  function inferProjectName(directory) {
44602
- const packageJsonPath = path28.join(directory, "package.json");
44603
- if (existsSync18(packageJsonPath)) {
44561
+ const packageJsonPath = path27.join(directory, "package.json");
44562
+ if (existsSync17(packageJsonPath)) {
44604
44563
  try {
44605
44564
  const pkg = JSON.parse(readFileSync12(packageJsonPath, "utf-8"));
44606
44565
  if (pkg.name && typeof pkg.name === "string") {
@@ -44608,7 +44567,7 @@ function inferProjectName(directory) {
44608
44567
  }
44609
44568
  } catch {}
44610
44569
  }
44611
- return path28.basename(directory);
44570
+ return path27.basename(directory);
44612
44571
  }
44613
44572
  async function writeSentinel(sentinelPath, migrated, dropped) {
44614
44573
  const sentinel = {
@@ -44620,8 +44579,8 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
44620
44579
  schema_version: 1,
44621
44580
  migration_tool: "knowledge-migrator.ts"
44622
44581
  };
44623
- await mkdir8(path28.dirname(sentinelPath), { recursive: true });
44624
- await writeFile9(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
44582
+ await mkdir7(path27.dirname(sentinelPath), { recursive: true });
44583
+ await writeFile8(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
44625
44584
  }
44626
44585
  var _internals16;
44627
44586
  var init_knowledge_migrator = __esm(() => {
@@ -44642,7 +44601,7 @@ var init_knowledge_migrator = __esm(() => {
44642
44601
  });
44643
44602
 
44644
44603
  // src/commands/knowledge.ts
44645
- import { join as join26 } from "path";
44604
+ import { join as join25 } from "path";
44646
44605
  function resolveEntryByPrefix(entries, inputId) {
44647
44606
  const exact = entries.find((e) => e.id === inputId);
44648
44607
  if (exact)
@@ -44693,7 +44652,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
44693
44652
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
44694
44653
  }
44695
44654
  try {
44696
- const quarantinePath = join26(directory, ".swarm", "knowledge-quarantined.jsonl");
44655
+ const quarantinePath = join25(directory, ".swarm", "knowledge-quarantined.jsonl");
44697
44656
  const entries = await readKnowledge(quarantinePath);
44698
44657
  const resolved = resolveEntryByPrefix(entries, inputId);
44699
44658
  if ("error" in resolved) {
@@ -45148,7 +45107,7 @@ var init_path_security = () => {};
45148
45107
 
45149
45108
  // src/tools/lint.ts
45150
45109
  import * as fs12 from "fs";
45151
- import * as path29 from "path";
45110
+ import * as path28 from "path";
45152
45111
  function validateArgs(args) {
45153
45112
  if (typeof args !== "object" || args === null)
45154
45113
  return false;
@@ -45159,9 +45118,9 @@ function validateArgs(args) {
45159
45118
  }
45160
45119
  function getLinterCommand(linter, mode, projectDir) {
45161
45120
  const isWindows = process.platform === "win32";
45162
- const binDir = path29.join(projectDir, "node_modules", ".bin");
45163
- const biomeBin = isWindows ? path29.join(binDir, "biome.EXE") : path29.join(binDir, "biome");
45164
- const eslintBin = isWindows ? path29.join(binDir, "eslint.cmd") : path29.join(binDir, "eslint");
45121
+ const binDir = path28.join(projectDir, "node_modules", ".bin");
45122
+ const biomeBin = isWindows ? path28.join(binDir, "biome.EXE") : path28.join(binDir, "biome");
45123
+ const eslintBin = isWindows ? path28.join(binDir, "eslint.cmd") : path28.join(binDir, "eslint");
45165
45124
  switch (linter) {
45166
45125
  case "biome":
45167
45126
  if (mode === "fix") {
@@ -45177,7 +45136,7 @@ function getLinterCommand(linter, mode, projectDir) {
45177
45136
  }
45178
45137
  function getAdditionalLinterCommand(linter, mode, cwd) {
45179
45138
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
45180
- const gradlew = fs12.existsSync(path29.join(cwd, gradlewName)) ? path29.join(cwd, gradlewName) : null;
45139
+ const gradlew = fs12.existsSync(path28.join(cwd, gradlewName)) ? path28.join(cwd, gradlewName) : null;
45181
45140
  switch (linter) {
45182
45141
  case "ruff":
45183
45142
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -45211,10 +45170,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
45211
45170
  }
45212
45171
  }
45213
45172
  function detectRuff(cwd) {
45214
- if (fs12.existsSync(path29.join(cwd, "ruff.toml")))
45173
+ if (fs12.existsSync(path28.join(cwd, "ruff.toml")))
45215
45174
  return isCommandAvailable("ruff");
45216
45175
  try {
45217
- const pyproject = path29.join(cwd, "pyproject.toml");
45176
+ const pyproject = path28.join(cwd, "pyproject.toml");
45218
45177
  if (fs12.existsSync(pyproject)) {
45219
45178
  const content = fs12.readFileSync(pyproject, "utf-8");
45220
45179
  if (content.includes("[tool.ruff]"))
@@ -45224,19 +45183,19 @@ function detectRuff(cwd) {
45224
45183
  return false;
45225
45184
  }
45226
45185
  function detectClippy(cwd) {
45227
- return fs12.existsSync(path29.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
45186
+ return fs12.existsSync(path28.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
45228
45187
  }
45229
45188
  function detectGolangciLint(cwd) {
45230
- return fs12.existsSync(path29.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
45189
+ return fs12.existsSync(path28.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
45231
45190
  }
45232
45191
  function detectCheckstyle(cwd) {
45233
- const hasMaven = fs12.existsSync(path29.join(cwd, "pom.xml"));
45234
- const hasGradle = fs12.existsSync(path29.join(cwd, "build.gradle")) || fs12.existsSync(path29.join(cwd, "build.gradle.kts"));
45235
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(path29.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
45192
+ const hasMaven = fs12.existsSync(path28.join(cwd, "pom.xml"));
45193
+ const hasGradle = fs12.existsSync(path28.join(cwd, "build.gradle")) || fs12.existsSync(path28.join(cwd, "build.gradle.kts"));
45194
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(path28.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
45236
45195
  return (hasMaven || hasGradle) && hasBinary;
45237
45196
  }
45238
45197
  function detectKtlint(cwd) {
45239
- const hasKotlin = fs12.existsSync(path29.join(cwd, "build.gradle.kts")) || fs12.existsSync(path29.join(cwd, "build.gradle")) || (() => {
45198
+ const hasKotlin = fs12.existsSync(path28.join(cwd, "build.gradle.kts")) || fs12.existsSync(path28.join(cwd, "build.gradle")) || (() => {
45240
45199
  try {
45241
45200
  return fs12.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
45242
45201
  } catch {
@@ -45255,11 +45214,11 @@ function detectDotnetFormat(cwd) {
45255
45214
  }
45256
45215
  }
45257
45216
  function detectCppcheck(cwd) {
45258
- if (fs12.existsSync(path29.join(cwd, "CMakeLists.txt"))) {
45217
+ if (fs12.existsSync(path28.join(cwd, "CMakeLists.txt"))) {
45259
45218
  return isCommandAvailable("cppcheck");
45260
45219
  }
45261
45220
  try {
45262
- const dirsToCheck = [cwd, path29.join(cwd, "src")];
45221
+ const dirsToCheck = [cwd, path28.join(cwd, "src")];
45263
45222
  const hasCpp = dirsToCheck.some((dir) => {
45264
45223
  try {
45265
45224
  return fs12.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
@@ -45273,13 +45232,13 @@ function detectCppcheck(cwd) {
45273
45232
  }
45274
45233
  }
45275
45234
  function detectSwiftlint(cwd) {
45276
- return fs12.existsSync(path29.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
45235
+ return fs12.existsSync(path28.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
45277
45236
  }
45278
45237
  function detectDartAnalyze(cwd) {
45279
- return fs12.existsSync(path29.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
45238
+ return fs12.existsSync(path28.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
45280
45239
  }
45281
45240
  function detectRubocop(cwd) {
45282
- return (fs12.existsSync(path29.join(cwd, "Gemfile")) || fs12.existsSync(path29.join(cwd, "gems.rb")) || fs12.existsSync(path29.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
45241
+ return (fs12.existsSync(path28.join(cwd, "Gemfile")) || fs12.existsSync(path28.join(cwd, "gems.rb")) || fs12.existsSync(path28.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
45283
45242
  }
45284
45243
  function detectAdditionalLinter(cwd) {
45285
45244
  if (detectRuff(cwd))
@@ -45307,10 +45266,10 @@ function detectAdditionalLinter(cwd) {
45307
45266
  function findBinInAncestors(startDir, binName) {
45308
45267
  let dir = startDir;
45309
45268
  while (true) {
45310
- const candidate = path29.join(dir, "node_modules", ".bin", binName);
45269
+ const candidate = path28.join(dir, "node_modules", ".bin", binName);
45311
45270
  if (fs12.existsSync(candidate))
45312
45271
  return candidate;
45313
- const parent = path29.dirname(dir);
45272
+ const parent = path28.dirname(dir);
45314
45273
  if (parent === dir)
45315
45274
  break;
45316
45275
  dir = parent;
@@ -45319,10 +45278,10 @@ function findBinInAncestors(startDir, binName) {
45319
45278
  }
45320
45279
  function findBinInEnvPath(binName) {
45321
45280
  const searchPath = process.env.PATH ?? "";
45322
- for (const dir of searchPath.split(path29.delimiter)) {
45281
+ for (const dir of searchPath.split(path28.delimiter)) {
45323
45282
  if (!dir)
45324
45283
  continue;
45325
- const candidate = path29.join(dir, binName);
45284
+ const candidate = path28.join(dir, binName);
45326
45285
  if (fs12.existsSync(candidate))
45327
45286
  return candidate;
45328
45287
  }
@@ -45335,13 +45294,13 @@ async function detectAvailableLinter(directory) {
45335
45294
  return null;
45336
45295
  const projectDir = directory;
45337
45296
  const isWindows = process.platform === "win32";
45338
- const biomeBin = isWindows ? path29.join(projectDir, "node_modules", ".bin", "biome.EXE") : path29.join(projectDir, "node_modules", ".bin", "biome");
45339
- const eslintBin = isWindows ? path29.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path29.join(projectDir, "node_modules", ".bin", "eslint");
45297
+ const biomeBin = isWindows ? path28.join(projectDir, "node_modules", ".bin", "biome.EXE") : path28.join(projectDir, "node_modules", ".bin", "biome");
45298
+ const eslintBin = isWindows ? path28.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path28.join(projectDir, "node_modules", ".bin", "eslint");
45340
45299
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
45341
45300
  if (localResult)
45342
45301
  return localResult;
45343
- const biomeAncestor = findBinInAncestors(path29.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
45344
- const eslintAncestor = findBinInAncestors(path29.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
45302
+ const biomeAncestor = findBinInAncestors(path28.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
45303
+ const eslintAncestor = findBinInAncestors(path28.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
45345
45304
  if (biomeAncestor || eslintAncestor) {
45346
45305
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
45347
45306
  }
@@ -45564,7 +45523,7 @@ For Rust: rustup component add clippy`
45564
45523
 
45565
45524
  // src/tools/secretscan.ts
45566
45525
  import * as fs13 from "fs";
45567
- import * as path30 from "path";
45526
+ import * as path29 from "path";
45568
45527
  function calculateShannonEntropy(str) {
45569
45528
  if (str.length === 0)
45570
45529
  return 0;
@@ -45612,7 +45571,7 @@ function isGlobOrPathPattern(pattern) {
45612
45571
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
45613
45572
  }
45614
45573
  function loadSecretScanIgnore(scanDir) {
45615
- const ignorePath = path30.join(scanDir, ".secretscanignore");
45574
+ const ignorePath = path29.join(scanDir, ".secretscanignore");
45616
45575
  try {
45617
45576
  if (!fs13.existsSync(ignorePath))
45618
45577
  return [];
@@ -45635,7 +45594,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
45635
45594
  if (exactNames.has(entry))
45636
45595
  return true;
45637
45596
  for (const pattern of globPatterns) {
45638
- if (path30.matchesGlob(relPath, pattern))
45597
+ if (path29.matchesGlob(relPath, pattern))
45639
45598
  return true;
45640
45599
  }
45641
45600
  return false;
@@ -45656,7 +45615,7 @@ function validateDirectoryInput(dir) {
45656
45615
  return null;
45657
45616
  }
45658
45617
  function isBinaryFile(filePath, buffer) {
45659
- const ext = path30.extname(filePath).toLowerCase();
45618
+ const ext = path29.extname(filePath).toLowerCase();
45660
45619
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
45661
45620
  return true;
45662
45621
  }
@@ -45792,9 +45751,9 @@ function isSymlinkLoop(realPath, visited) {
45792
45751
  return false;
45793
45752
  }
45794
45753
  function isPathWithinScope(realPath, scanDir) {
45795
- const resolvedScanDir = path30.resolve(scanDir);
45796
- const resolvedRealPath = path30.resolve(realPath);
45797
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path30.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
45754
+ const resolvedScanDir = path29.resolve(scanDir);
45755
+ const resolvedRealPath = path29.resolve(realPath);
45756
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path29.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
45798
45757
  }
45799
45758
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
45800
45759
  skippedDirs: 0,
@@ -45820,8 +45779,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
45820
45779
  return a.localeCompare(b);
45821
45780
  });
45822
45781
  for (const entry of entries) {
45823
- const fullPath = path30.join(dir, entry);
45824
- const relPath = path30.relative(scanDir, fullPath).replace(/\\/g, "/");
45782
+ const fullPath = path29.join(dir, entry);
45783
+ const relPath = path29.relative(scanDir, fullPath).replace(/\\/g, "/");
45825
45784
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
45826
45785
  stats.skippedDirs++;
45827
45786
  continue;
@@ -45856,7 +45815,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
45856
45815
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
45857
45816
  files.push(...subFiles);
45858
45817
  } else if (lstat.isFile()) {
45859
- const ext = path30.extname(fullPath).toLowerCase();
45818
+ const ext = path29.extname(fullPath).toLowerCase();
45860
45819
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
45861
45820
  files.push(fullPath);
45862
45821
  } else {
@@ -46116,7 +46075,7 @@ var init_secretscan = __esm(() => {
46116
46075
  }
46117
46076
  }
46118
46077
  try {
46119
- const _scanDirRaw = path30.resolve(directory);
46078
+ const _scanDirRaw = path29.resolve(directory);
46120
46079
  const scanDir = (() => {
46121
46080
  try {
46122
46081
  return fs13.realpathSync(_scanDirRaw);
@@ -46263,7 +46222,7 @@ var init_secretscan = __esm(() => {
46263
46222
 
46264
46223
  // src/lang/default-backend.ts
46265
46224
  import * as fs14 from "fs";
46266
- import * as path31 from "path";
46225
+ import * as path30 from "path";
46267
46226
  function detectFileExists(dir, pattern) {
46268
46227
  if (pattern.includes("*") || pattern.includes("?")) {
46269
46228
  try {
@@ -46275,7 +46234,7 @@ function detectFileExists(dir, pattern) {
46275
46234
  }
46276
46235
  }
46277
46236
  try {
46278
- fs14.accessSync(path31.join(dir, pattern));
46237
+ fs14.accessSync(path30.join(dir, pattern));
46279
46238
  return true;
46280
46239
  } catch {
46281
46240
  return false;
@@ -46403,8 +46362,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
46403
46362
  return ["mvn", "test"];
46404
46363
  case "gradle": {
46405
46364
  const isWindows = process.platform === "win32";
46406
- const hasGradlewBat = fs14.existsSync(path31.join(dir, "gradlew.bat"));
46407
- const hasGradlew = fs14.existsSync(path31.join(dir, "gradlew"));
46365
+ const hasGradlewBat = fs14.existsSync(path30.join(dir, "gradlew.bat"));
46366
+ const hasGradlew = fs14.existsSync(path30.join(dir, "gradlew"));
46408
46367
  if (hasGradlewBat && isWindows)
46409
46368
  return ["gradlew.bat", "test"];
46410
46369
  if (hasGradlew)
@@ -46421,7 +46380,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
46421
46380
  "cmake-build-release",
46422
46381
  "out"
46423
46382
  ];
46424
- const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(path31.join(dir, d, "CMakeCache.txt"))) ?? "build";
46383
+ const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(path30.join(dir, d, "CMakeCache.txt"))) ?? "build";
46425
46384
  return ["ctest", "--test-dir", actualBuildDir];
46426
46385
  }
46427
46386
  case "swift-test":
@@ -46708,17 +46667,17 @@ async function defaultSelectBuildCommand(profile, dir) {
46708
46667
  return null;
46709
46668
  }
46710
46669
  async function defaultTestFilesFor(profile, sourceFile, dir) {
46711
- const ext = path31.extname(sourceFile);
46670
+ const ext = path30.extname(sourceFile);
46712
46671
  if (!profile.extensions.includes(ext))
46713
46672
  return [];
46714
- const base = path31.basename(sourceFile, ext);
46715
- const rel = path31.relative(dir, sourceFile);
46716
- const relDir = path31.dirname(rel);
46673
+ const base = path30.basename(sourceFile, ext);
46674
+ const rel = path30.relative(dir, sourceFile);
46675
+ const relDir = path30.dirname(rel);
46717
46676
  const stripSrc = relDir.replace(/^src(\/|\\)/, "");
46718
46677
  const candidates = new Set;
46719
46678
  for (const tDir of ["tests", "test", "__tests__", "spec"]) {
46720
46679
  for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
46721
- candidates.add(path31.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
46680
+ candidates.add(path30.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
46722
46681
  }
46723
46682
  }
46724
46683
  const existing = [];
@@ -46759,7 +46718,7 @@ var init_default_backend = __esm(() => {
46759
46718
 
46760
46719
  // src/lang/backends/go.ts
46761
46720
  import * as fs15 from "fs";
46762
- import * as path32 from "path";
46721
+ import * as path31 from "path";
46763
46722
  function extractImports(_sourceFile, source) {
46764
46723
  const out = new Set;
46765
46724
  IMPORT_REGEX_SINGLE.lastIndex = 0;
@@ -46785,7 +46744,7 @@ function extractImports(_sourceFile, source) {
46785
46744
  async function selectFramework(dir) {
46786
46745
  let content;
46787
46746
  try {
46788
- content = fs15.readFileSync(path32.join(dir, "go.mod"), "utf-8");
46747
+ content = fs15.readFileSync(path31.join(dir, "go.mod"), "utf-8");
46789
46748
  } catch {
46790
46749
  return null;
46791
46750
  }
@@ -46806,16 +46765,16 @@ async function selectFramework(dir) {
46806
46765
  async function selectEntryPoints(dir) {
46807
46766
  const points = [];
46808
46767
  try {
46809
- fs15.accessSync(path32.join(dir, "main.go"));
46768
+ fs15.accessSync(path31.join(dir, "main.go"));
46810
46769
  points.push("main.go");
46811
46770
  } catch {}
46812
46771
  try {
46813
- const cmdDir = path32.join(dir, "cmd");
46772
+ const cmdDir = path31.join(dir, "cmd");
46814
46773
  const subdirs = fs15.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
46815
46774
  for (const sub of subdirs) {
46816
- const main = path32.join("cmd", sub.name, "main.go");
46775
+ const main = path31.join("cmd", sub.name, "main.go");
46817
46776
  try {
46818
- fs15.accessSync(path32.join(dir, main));
46777
+ fs15.accessSync(path31.join(dir, main));
46819
46778
  points.push(main);
46820
46779
  } catch {}
46821
46780
  }
@@ -46846,7 +46805,7 @@ var init_go = __esm(() => {
46846
46805
 
46847
46806
  // src/lang/backends/python.ts
46848
46807
  import * as fs16 from "fs";
46849
- import * as path33 from "path";
46808
+ import * as path32 from "path";
46850
46809
  function parseImportTargets(rawTargets) {
46851
46810
  const cleaned = rawTargets.replace(/[()]/g, "").split(`
46852
46811
  `).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
@@ -46906,7 +46865,7 @@ async function selectFramework2(dir) {
46906
46865
  ];
46907
46866
  for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
46908
46867
  try {
46909
- const content = fs16.readFileSync(path33.join(dir, candidate), "utf-8");
46868
+ const content = fs16.readFileSync(path32.join(dir, candidate), "utf-8");
46910
46869
  const lower = content.toLowerCase();
46911
46870
  for (const [pkg, name] of candidates) {
46912
46871
  if (lower.includes(pkg)) {
@@ -46920,7 +46879,7 @@ async function selectFramework2(dir) {
46920
46879
  async function selectEntryPoints2(dir) {
46921
46880
  const points = new Set;
46922
46881
  try {
46923
- const content = fs16.readFileSync(path33.join(dir, "pyproject.toml"), "utf-8");
46882
+ const content = fs16.readFileSync(path32.join(dir, "pyproject.toml"), "utf-8");
46924
46883
  const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
46925
46884
  if (scriptsBlock) {
46926
46885
  for (const line of scriptsBlock[0].split(`
@@ -46935,7 +46894,7 @@ async function selectEntryPoints2(dir) {
46935
46894
  } catch {}
46936
46895
  for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
46937
46896
  try {
46938
- fs16.accessSync(path33.join(dir, name));
46897
+ fs16.accessSync(path32.join(dir, name));
46939
46898
  points.add(name);
46940
46899
  } catch {}
46941
46900
  }
@@ -46964,7 +46923,7 @@ var init_python = __esm(() => {
46964
46923
 
46965
46924
  // src/test-impact/analyzer.ts
46966
46925
  import fs17 from "fs";
46967
- import path34 from "path";
46926
+ import path33 from "path";
46968
46927
  function normalizePath(p) {
46969
46928
  return p.replace(/\\/g, "/");
46970
46929
  }
@@ -46985,8 +46944,8 @@ function resolveRelativeImport(fromDir, importPath) {
46985
46944
  if (!importPath.startsWith(".")) {
46986
46945
  return null;
46987
46946
  }
46988
- const resolved = path34.resolve(fromDir, importPath);
46989
- if (path34.extname(resolved)) {
46947
+ const resolved = path33.resolve(fromDir, importPath);
46948
+ if (path33.extname(resolved)) {
46990
46949
  if (fs17.existsSync(resolved) && fs17.statSync(resolved).isFile()) {
46991
46950
  return normalizePath(resolved);
46992
46951
  }
@@ -47006,20 +46965,20 @@ function resolvePythonImport(fromDir, module) {
47006
46965
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
47007
46966
  let baseDir = fromDir;
47008
46967
  for (let i = 1;i < leadingDots; i++) {
47009
- baseDir = path34.dirname(baseDir);
46968
+ baseDir = path33.dirname(baseDir);
47010
46969
  }
47011
46970
  const rest = module.slice(leadingDots);
47012
46971
  if (rest.length === 0) {
47013
- const initPath = path34.join(baseDir, "__init__.py");
46972
+ const initPath = path33.join(baseDir, "__init__.py");
47014
46973
  if (fs17.existsSync(initPath) && fs17.statSync(initPath).isFile()) {
47015
46974
  return normalizePath(initPath);
47016
46975
  }
47017
46976
  return null;
47018
46977
  }
47019
- const subpath = rest.replace(/\./g, path34.sep);
46978
+ const subpath = rest.replace(/\./g, path33.sep);
47020
46979
  const candidates = [
47021
- `${path34.join(baseDir, subpath)}.py`,
47022
- path34.join(baseDir, subpath, "__init__.py")
46980
+ `${path33.join(baseDir, subpath)}.py`,
46981
+ path33.join(baseDir, subpath, "__init__.py")
47023
46982
  ];
47024
46983
  for (const c of candidates) {
47025
46984
  if (fs17.existsSync(c) && fs17.statSync(c).isFile())
@@ -47028,7 +46987,7 @@ function resolvePythonImport(fromDir, module) {
47028
46987
  return null;
47029
46988
  }
47030
46989
  function findGoModule(fromDir) {
47031
- const resolved = path34.resolve(fromDir);
46990
+ const resolved = path33.resolve(fromDir);
47032
46991
  let cur = resolved;
47033
46992
  const walked = [];
47034
46993
  for (let i = 0;i < 16; i++) {
@@ -47040,7 +46999,7 @@ function findGoModule(fromDir) {
47040
46999
  }
47041
47000
  walked.push(cur);
47042
47001
  try {
47043
- const goMod = path34.join(cur, "go.mod");
47002
+ const goMod = path33.join(cur, "go.mod");
47044
47003
  const content = fs17.readFileSync(goMod, "utf-8");
47045
47004
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
47046
47005
  if (moduleMatch) {
@@ -47051,10 +47010,10 @@ function findGoModule(fromDir) {
47051
47010
  }
47052
47011
  } catch {}
47053
47012
  try {
47054
- fs17.accessSync(path34.join(cur, ".git"));
47013
+ fs17.accessSync(path33.join(cur, ".git"));
47055
47014
  break;
47056
47015
  } catch {}
47057
- const parent = path34.dirname(cur);
47016
+ const parent = path33.dirname(cur);
47058
47017
  if (parent === cur)
47059
47018
  break;
47060
47019
  cur = parent;
@@ -47066,12 +47025,12 @@ function findGoModule(fromDir) {
47066
47025
  function resolveGoImport(fromDir, importPath) {
47067
47026
  let dir = null;
47068
47027
  if (importPath.startsWith(".")) {
47069
- dir = path34.resolve(fromDir, importPath);
47028
+ dir = path33.resolve(fromDir, importPath);
47070
47029
  } else {
47071
47030
  const mod = findGoModule(fromDir);
47072
47031
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
47073
47032
  const subpath = importPath.slice(mod.modulePath.length);
47074
- dir = path34.join(mod.moduleRoot, subpath);
47033
+ dir = path33.join(mod.moduleRoot, subpath);
47075
47034
  }
47076
47035
  }
47077
47036
  if (dir === null)
@@ -47079,7 +47038,7 @@ function resolveGoImport(fromDir, importPath) {
47079
47038
  if (!fs17.existsSync(dir) || !fs17.statSync(dir).isDirectory())
47080
47039
  return [];
47081
47040
  try {
47082
- return fs17.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path34.join(dir, f)));
47041
+ return fs17.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path33.join(dir, f)));
47083
47042
  } catch {
47084
47043
  return [];
47085
47044
  }
@@ -47118,15 +47077,15 @@ function findTestFilesSync(cwd) {
47118
47077
  for (const entry of entries) {
47119
47078
  if (entry.isDirectory()) {
47120
47079
  if (!skipDirs.has(entry.name)) {
47121
- walk(path34.join(dir, entry.name), visitedInodes);
47080
+ walk(path33.join(dir, entry.name), visitedInodes);
47122
47081
  }
47123
47082
  } else if (entry.isFile()) {
47124
47083
  const name = entry.name;
47125
47084
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
47126
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path34.sep}tests${path34.sep}`) && name.endsWith(".py");
47085
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path33.sep}tests${path33.sep}`) && name.endsWith(".py");
47127
47086
  const isGoTest = /.+_test\.go$/.test(name);
47128
47087
  if (isTsTest || isPyTest || isGoTest) {
47129
- testFiles.push(normalizePath(path34.join(dir, entry.name)));
47088
+ testFiles.push(normalizePath(path33.join(dir, entry.name)));
47130
47089
  }
47131
47090
  }
47132
47091
  }
@@ -47151,8 +47110,8 @@ function extractImports3(content) {
47151
47110
  ];
47152
47111
  }
47153
47112
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
47154
- const ext = path34.extname(testFile).toLowerCase();
47155
- const testDir = path34.dirname(testFile);
47113
+ const ext = path33.extname(testFile).toLowerCase();
47114
+ const testDir = path33.dirname(testFile);
47156
47115
  function addEdge(source) {
47157
47116
  if (!impactMap[source])
47158
47117
  impactMap[source] = [];
@@ -47211,7 +47170,7 @@ async function buildImpactMap(cwd) {
47211
47170
  return impactMap;
47212
47171
  }
47213
47172
  async function loadImpactMap(cwd, options) {
47214
- const cachePath = path34.join(cwd, ".swarm", "cache", "impact-map.json");
47173
+ const cachePath = path33.join(cwd, ".swarm", "cache", "impact-map.json");
47215
47174
  if (fs17.existsSync(cachePath)) {
47216
47175
  try {
47217
47176
  const content = fs17.readFileSync(cachePath, "utf-8");
@@ -47244,12 +47203,12 @@ async function loadImpactMap(cwd, options) {
47244
47203
  return _internals22.buildImpactMap(cwd);
47245
47204
  }
47246
47205
  async function saveImpactMap(cwd, impactMap) {
47247
- if (!path34.isAbsolute(cwd)) {
47206
+ if (!path33.isAbsolute(cwd)) {
47248
47207
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
47249
47208
  }
47250
47209
  _internals22.validateProjectRoot(cwd);
47251
- const cacheDir2 = path34.join(cwd, ".swarm", "cache");
47252
- const cachePath = path34.join(cacheDir2, "impact-map.json");
47210
+ const cacheDir2 = path33.join(cwd, ".swarm", "cache");
47211
+ const cachePath = path33.join(cacheDir2, "impact-map.json");
47253
47212
  if (!fs17.existsSync(cacheDir2)) {
47254
47213
  fs17.mkdirSync(cacheDir2, { recursive: true });
47255
47214
  }
@@ -47281,7 +47240,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
47281
47240
  budgetExceeded = true;
47282
47241
  break;
47283
47242
  }
47284
- const normalizedChanged = normalizePath(path34.resolve(changedFile));
47243
+ const normalizedChanged = normalizePath(path33.resolve(changedFile));
47285
47244
  const tests = impactMap[normalizedChanged];
47286
47245
  if (tests && tests.length > 0) {
47287
47246
  for (const test of tests) {
@@ -47574,15 +47533,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
47574
47533
 
47575
47534
  // src/test-impact/history-store.ts
47576
47535
  import fs18 from "fs";
47577
- import path35 from "path";
47536
+ import path34 from "path";
47578
47537
  function getHistoryPath(workingDir) {
47579
47538
  if (!workingDir) {
47580
47539
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
47581
47540
  }
47582
- if (!path35.isAbsolute(workingDir)) {
47541
+ if (!path34.isAbsolute(workingDir)) {
47583
47542
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
47584
47543
  }
47585
- return path35.join(workingDir, ".swarm", "cache", "test-history.jsonl");
47544
+ return path34.join(workingDir, ".swarm", "cache", "test-history.jsonl");
47586
47545
  }
47587
47546
  function sanitizeErrorMessage(errorMessage) {
47588
47547
  if (errorMessage === undefined) {
@@ -47669,7 +47628,7 @@ function batchAppendTestRuns(records, workingDir) {
47669
47628
  }
47670
47629
  }
47671
47630
  const historyPath = getHistoryPath(workingDir);
47672
- const historyDir = path35.dirname(historyPath);
47631
+ const historyDir = path34.dirname(historyPath);
47673
47632
  _internals23.validateProjectRoot(workingDir);
47674
47633
  if (!fs18.existsSync(historyDir)) {
47675
47634
  fs18.mkdirSync(historyDir, { recursive: true });
@@ -47765,7 +47724,7 @@ var init_history_store = __esm(() => {
47765
47724
 
47766
47725
  // src/tools/resolve-working-directory.ts
47767
47726
  import * as fs19 from "fs";
47768
- import * as path36 from "path";
47727
+ import * as path35 from "path";
47769
47728
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
47770
47729
  if (workingDirectory == null || workingDirectory === "") {
47771
47730
  return { success: true, directory: fallbackDirectory };
@@ -47785,15 +47744,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
47785
47744
  };
47786
47745
  }
47787
47746
  }
47788
- const normalizedDir = path36.normalize(workingDirectory);
47789
- const pathParts = normalizedDir.split(path36.sep);
47747
+ const normalizedDir = path35.normalize(workingDirectory);
47748
+ const pathParts = normalizedDir.split(path35.sep);
47790
47749
  if (pathParts.includes("..")) {
47791
47750
  return {
47792
47751
  success: false,
47793
47752
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
47794
47753
  };
47795
47754
  }
47796
- const resolvedDir = path36.resolve(normalizedDir);
47755
+ const resolvedDir = path35.resolve(normalizedDir);
47797
47756
  let statResult;
47798
47757
  try {
47799
47758
  statResult = fs19.statSync(resolvedDir);
@@ -47809,7 +47768,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
47809
47768
  message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
47810
47769
  };
47811
47770
  }
47812
- const resolvedFallback = path36.resolve(fallbackDirectory);
47771
+ const resolvedFallback = path35.resolve(fallbackDirectory);
47813
47772
  let fallbackExists = false;
47814
47773
  try {
47815
47774
  fs19.statSync(resolvedFallback);
@@ -47819,7 +47778,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
47819
47778
  }
47820
47779
  if (workingDirectory != null && workingDirectory !== "") {
47821
47780
  if (fallbackExists) {
47822
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path36.sep);
47781
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path35.sep);
47823
47782
  if (isSubdirectory) {
47824
47783
  return {
47825
47784
  success: false,
@@ -47874,10 +47833,10 @@ var init_registry_backend = __esm(() => {
47874
47833
 
47875
47834
  // src/lang/backends/typescript.ts
47876
47835
  import * as fs20 from "fs";
47877
- import * as path37 from "path";
47836
+ import * as path36 from "path";
47878
47837
  function readPackageJsonRaw(dir) {
47879
47838
  try {
47880
- const content = fs20.readFileSync(path37.join(dir, "package.json"), "utf-8");
47839
+ const content = fs20.readFileSync(path36.join(dir, "package.json"), "utf-8");
47881
47840
  return JSON.parse(content);
47882
47841
  } catch {
47883
47842
  return null;
@@ -48097,7 +48056,7 @@ __export(exports_dispatch, {
48097
48056
  _internals: () => _internals25
48098
48057
  });
48099
48058
  import * as fs21 from "fs";
48100
- import * as path38 from "path";
48059
+ import * as path37 from "path";
48101
48060
  function safeReaddirSet(dir) {
48102
48061
  try {
48103
48062
  return new Set(fs21.readdirSync(dir));
@@ -48114,14 +48073,14 @@ function manifestHash(dir) {
48114
48073
  if (!entries.has(name))
48115
48074
  continue;
48116
48075
  try {
48117
- const stat3 = fs21.statSync(path38.join(dir, name));
48076
+ const stat3 = fs21.statSync(path37.join(dir, name));
48118
48077
  parts.push(`${name}:${stat3.size}:${stat3.mtimeMs}:${stat3.ino}`);
48119
48078
  } catch {}
48120
48079
  }
48121
48080
  return parts.join("|");
48122
48081
  }
48123
48082
  function findManifestRoot(start) {
48124
- const resolved = path38.resolve(start);
48083
+ const resolved = path37.resolve(start);
48125
48084
  const cached3 = manifestRootCache.get(resolved);
48126
48085
  if (cached3 !== undefined)
48127
48086
  return cached3;
@@ -48140,7 +48099,7 @@ function findManifestRoot(start) {
48140
48099
  return cur;
48141
48100
  }
48142
48101
  }
48143
- const parent = path38.dirname(cur);
48102
+ const parent = path37.dirname(cur);
48144
48103
  if (parent === cur)
48145
48104
  break;
48146
48105
  cur = parent;
@@ -48250,13 +48209,13 @@ var init_dispatch = __esm(() => {
48250
48209
 
48251
48210
  // src/tools/test-runner.ts
48252
48211
  import * as fs22 from "fs";
48253
- import * as path39 from "path";
48212
+ import * as path38 from "path";
48254
48213
  async function estimateFanOut(sourceFiles, cwd) {
48255
48214
  try {
48256
48215
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
48257
48216
  const uniqueTestFiles = new Set;
48258
48217
  for (const sourceFile of sourceFiles) {
48259
- const resolvedPath = path39.resolve(cwd, sourceFile);
48218
+ const resolvedPath = path38.resolve(cwd, sourceFile);
48260
48219
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
48261
48220
  const testFiles = impactMap[normalizedPath];
48262
48221
  if (testFiles) {
@@ -48334,14 +48293,14 @@ function hasDevDependency(devDeps, ...patterns) {
48334
48293
  return hasPackageJsonDependency(devDeps, ...patterns);
48335
48294
  }
48336
48295
  function detectGoTest(cwd) {
48337
- return fs22.existsSync(path39.join(cwd, "go.mod")) && isCommandAvailable("go");
48296
+ return fs22.existsSync(path38.join(cwd, "go.mod")) && isCommandAvailable("go");
48338
48297
  }
48339
48298
  function detectJavaMaven(cwd) {
48340
- return fs22.existsSync(path39.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
48299
+ return fs22.existsSync(path38.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
48341
48300
  }
48342
48301
  function detectGradle(cwd) {
48343
- const hasBuildFile = fs22.existsSync(path39.join(cwd, "build.gradle")) || fs22.existsSync(path39.join(cwd, "build.gradle.kts"));
48344
- const hasGradlew = fs22.existsSync(path39.join(cwd, "gradlew")) || fs22.existsSync(path39.join(cwd, "gradlew.bat"));
48302
+ const hasBuildFile = fs22.existsSync(path38.join(cwd, "build.gradle")) || fs22.existsSync(path38.join(cwd, "build.gradle.kts"));
48303
+ const hasGradlew = fs22.existsSync(path38.join(cwd, "gradlew")) || fs22.existsSync(path38.join(cwd, "gradlew.bat"));
48345
48304
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
48346
48305
  }
48347
48306
  function detectDotnetTest(cwd) {
@@ -48354,25 +48313,25 @@ function detectDotnetTest(cwd) {
48354
48313
  }
48355
48314
  }
48356
48315
  function detectCTest(cwd) {
48357
- const hasSource = fs22.existsSync(path39.join(cwd, "CMakeLists.txt"));
48358
- const hasBuildCache = fs22.existsSync(path39.join(cwd, "CMakeCache.txt")) || fs22.existsSync(path39.join(cwd, "build", "CMakeCache.txt"));
48316
+ const hasSource = fs22.existsSync(path38.join(cwd, "CMakeLists.txt"));
48317
+ const hasBuildCache = fs22.existsSync(path38.join(cwd, "CMakeCache.txt")) || fs22.existsSync(path38.join(cwd, "build", "CMakeCache.txt"));
48359
48318
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
48360
48319
  }
48361
48320
  function detectSwiftTest(cwd) {
48362
- return fs22.existsSync(path39.join(cwd, "Package.swift")) && isCommandAvailable("swift");
48321
+ return fs22.existsSync(path38.join(cwd, "Package.swift")) && isCommandAvailable("swift");
48363
48322
  }
48364
48323
  function detectDartTest(cwd) {
48365
- return fs22.existsSync(path39.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
48324
+ return fs22.existsSync(path38.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
48366
48325
  }
48367
48326
  function detectRSpec(cwd) {
48368
- const hasRSpecFile = fs22.existsSync(path39.join(cwd, ".rspec"));
48369
- const hasGemfile = fs22.existsSync(path39.join(cwd, "Gemfile"));
48370
- const hasSpecDir = fs22.existsSync(path39.join(cwd, "spec"));
48327
+ const hasRSpecFile = fs22.existsSync(path38.join(cwd, ".rspec"));
48328
+ const hasGemfile = fs22.existsSync(path38.join(cwd, "Gemfile"));
48329
+ const hasSpecDir = fs22.existsSync(path38.join(cwd, "spec"));
48371
48330
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
48372
48331
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
48373
48332
  }
48374
48333
  function detectMinitest(cwd) {
48375
- return fs22.existsSync(path39.join(cwd, "test")) && (fs22.existsSync(path39.join(cwd, "Gemfile")) || fs22.existsSync(path39.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
48334
+ return fs22.existsSync(path38.join(cwd, "test")) && (fs22.existsSync(path38.join(cwd, "Gemfile")) || fs22.existsSync(path38.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
48376
48335
  }
48377
48336
  async function detectTestFrameworkViaDispatch(cwd) {
48378
48337
  try {
@@ -48434,7 +48393,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
48434
48393
  async function detectTestFramework(cwd) {
48435
48394
  const baseDir = cwd;
48436
48395
  try {
48437
- const packageJsonPath = path39.join(baseDir, "package.json");
48396
+ const packageJsonPath = path38.join(baseDir, "package.json");
48438
48397
  if (fs22.existsSync(packageJsonPath)) {
48439
48398
  const content = fs22.readFileSync(packageJsonPath, "utf-8");
48440
48399
  const pkg = JSON.parse(content);
@@ -48455,16 +48414,16 @@ async function detectTestFramework(cwd) {
48455
48414
  return "jest";
48456
48415
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
48457
48416
  return "mocha";
48458
- if (fs22.existsSync(path39.join(baseDir, "bun.lockb")) || fs22.existsSync(path39.join(baseDir, "bun.lock"))) {
48417
+ if (fs22.existsSync(path38.join(baseDir, "bun.lockb")) || fs22.existsSync(path38.join(baseDir, "bun.lock"))) {
48459
48418
  if (scripts.test?.includes("bun"))
48460
48419
  return "bun";
48461
48420
  }
48462
48421
  }
48463
48422
  } catch {}
48464
48423
  try {
48465
- const pyprojectTomlPath = path39.join(baseDir, "pyproject.toml");
48466
- const setupCfgPath = path39.join(baseDir, "setup.cfg");
48467
- const requirementsTxtPath = path39.join(baseDir, "requirements.txt");
48424
+ const pyprojectTomlPath = path38.join(baseDir, "pyproject.toml");
48425
+ const setupCfgPath = path38.join(baseDir, "setup.cfg");
48426
+ const requirementsTxtPath = path38.join(baseDir, "requirements.txt");
48468
48427
  if (fs22.existsSync(pyprojectTomlPath)) {
48469
48428
  const content = fs22.readFileSync(pyprojectTomlPath, "utf-8");
48470
48429
  if (content.includes("[tool.pytest"))
@@ -48484,7 +48443,7 @@ async function detectTestFramework(cwd) {
48484
48443
  }
48485
48444
  } catch {}
48486
48445
  try {
48487
- const cargoTomlPath = path39.join(baseDir, "Cargo.toml");
48446
+ const cargoTomlPath = path38.join(baseDir, "Cargo.toml");
48488
48447
  if (fs22.existsSync(cargoTomlPath)) {
48489
48448
  const content = fs22.readFileSync(cargoTomlPath, "utf-8");
48490
48449
  if (content.includes("[dev-dependencies]")) {
@@ -48495,9 +48454,9 @@ async function detectTestFramework(cwd) {
48495
48454
  }
48496
48455
  } catch {}
48497
48456
  try {
48498
- const pesterConfigPath = path39.join(baseDir, "pester.config.ps1");
48499
- const pesterConfigJsonPath = path39.join(baseDir, "pester.config.ps1.json");
48500
- const pesterPs1Path = path39.join(baseDir, "tests.ps1");
48457
+ const pesterConfigPath = path38.join(baseDir, "pester.config.ps1");
48458
+ const pesterConfigJsonPath = path38.join(baseDir, "pester.config.ps1.json");
48459
+ const pesterPs1Path = path38.join(baseDir, "tests.ps1");
48501
48460
  if (fs22.existsSync(pesterConfigPath) || fs22.existsSync(pesterConfigJsonPath) || fs22.existsSync(pesterPs1Path)) {
48502
48461
  return "pester";
48503
48462
  }
@@ -48526,12 +48485,12 @@ function isTestDirectoryPath(normalizedPath) {
48526
48485
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
48527
48486
  }
48528
48487
  function resolveWorkspacePath(file3, workingDir) {
48529
- return path39.isAbsolute(file3) ? path39.resolve(file3) : path39.resolve(workingDir, file3);
48488
+ return path38.isAbsolute(file3) ? path38.resolve(file3) : path38.resolve(workingDir, file3);
48530
48489
  }
48531
48490
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
48532
48491
  if (!preferRelative)
48533
48492
  return absolutePath;
48534
- return path39.relative(workingDir, absolutePath);
48493
+ return path38.relative(workingDir, absolutePath);
48535
48494
  }
48536
48495
  function dedupePush(target, value) {
48537
48496
  if (!target.includes(value)) {
@@ -48568,18 +48527,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
48568
48527
  }
48569
48528
  }
48570
48529
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
48571
- const relativeDir = path39.dirname(relativePath);
48530
+ const relativeDir = path38.dirname(relativePath);
48572
48531
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
48573
48532
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
48574
- const rootDir = path39.join(workingDir, dirName);
48575
- return nestedRelativeDir ? [rootDir, path39.join(rootDir, nestedRelativeDir)] : [rootDir];
48533
+ const rootDir = path38.join(workingDir, dirName);
48534
+ return nestedRelativeDir ? [rootDir, path38.join(rootDir, nestedRelativeDir)] : [rootDir];
48576
48535
  });
48577
48536
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
48578
48537
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
48579
- directories.push(path39.join(workingDir, "src/test/java", path39.dirname(normalizedRelativePath.slice("src/main/java/".length))));
48538
+ directories.push(path38.join(workingDir, "src/test/java", path38.dirname(normalizedRelativePath.slice("src/main/java/".length))));
48580
48539
  }
48581
48540
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
48582
- directories.push(path39.join(workingDir, "src/test/kotlin", path39.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
48541
+ directories.push(path38.join(workingDir, "src/test/kotlin", path38.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
48583
48542
  }
48584
48543
  return [...new Set(directories)];
48585
48544
  }
@@ -48607,23 +48566,23 @@ function isLanguageSpecificTestFile(basename6) {
48607
48566
  }
48608
48567
  function isConventionTestFilePath(filePath) {
48609
48568
  const normalizedPath = filePath.replace(/\\/g, "/");
48610
- const basename6 = path39.basename(filePath);
48569
+ const basename6 = path38.basename(filePath);
48611
48570
  return hasCompoundTestExtension(basename6) || basename6.includes(".spec.") || basename6.includes(".test.") || isLanguageSpecificTestFile(basename6) || isTestDirectoryPath(normalizedPath);
48612
48571
  }
48613
48572
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
48614
48573
  const testFiles = [];
48615
48574
  for (const file3 of sourceFiles) {
48616
48575
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
48617
- const relativeFile = path39.relative(workingDir, absoluteFile);
48618
- const basename6 = path39.basename(absoluteFile);
48619
- const dirname18 = path39.dirname(absoluteFile);
48620
- const preferRelativeOutput = !path39.isAbsolute(file3);
48576
+ const relativeFile = path38.relative(workingDir, absoluteFile);
48577
+ const basename6 = path38.basename(absoluteFile);
48578
+ const dirname17 = path38.dirname(absoluteFile);
48579
+ const preferRelativeOutput = !path38.isAbsolute(file3);
48621
48580
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
48622
48581
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
48623
48582
  continue;
48624
48583
  }
48625
48584
  const nameWithoutExt = basename6.replace(/\.[^.]+$/, "");
48626
- const ext = path39.extname(basename6);
48585
+ const ext = path38.extname(basename6);
48627
48586
  const genericTestNames = [
48628
48587
  `${nameWithoutExt}.spec${ext}`,
48629
48588
  `${nameWithoutExt}.test${ext}`
@@ -48632,7 +48591,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
48632
48591
  const colocatedCandidates = [
48633
48592
  ...genericTestNames,
48634
48593
  ...languageSpecificTestNames
48635
- ].map((candidateName) => path39.join(dirname18, candidateName));
48594
+ ].map((candidateName) => path38.join(dirname17, candidateName));
48636
48595
  const testDirectoryNames = [
48637
48596
  basename6,
48638
48597
  ...genericTestNames,
@@ -48641,8 +48600,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
48641
48600
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
48642
48601
  const possibleTestFiles = [
48643
48602
  ...colocatedCandidates,
48644
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path39.join(dirname18, dirName, candidateName))),
48645
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path39.join(candidateDir, candidateName)))
48603
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path38.join(dirname17, dirName, candidateName))),
48604
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path38.join(candidateDir, candidateName)))
48646
48605
  ];
48647
48606
  for (const testFile of possibleTestFiles) {
48648
48607
  if (fs22.existsSync(testFile)) {
@@ -48663,7 +48622,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48663
48622
  try {
48664
48623
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
48665
48624
  const content = fs22.readFileSync(absoluteTestFile, "utf-8");
48666
- const testDir = path39.dirname(absoluteTestFile);
48625
+ const testDir = path38.dirname(absoluteTestFile);
48667
48626
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
48668
48627
  let match;
48669
48628
  match = importRegex.exec(content);
@@ -48671,8 +48630,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48671
48630
  const importPath = match[1];
48672
48631
  let resolvedImport;
48673
48632
  if (importPath.startsWith(".")) {
48674
- resolvedImport = path39.resolve(testDir, importPath);
48675
- const existingExt = path39.extname(resolvedImport);
48633
+ resolvedImport = path38.resolve(testDir, importPath);
48634
+ const existingExt = path38.extname(resolvedImport);
48676
48635
  if (!existingExt) {
48677
48636
  for (const extToTry of [
48678
48637
  ".ts",
@@ -48692,12 +48651,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48692
48651
  } else {
48693
48652
  continue;
48694
48653
  }
48695
- const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
48696
- const importDir = path39.dirname(resolvedImport);
48654
+ const importBasename = path38.basename(resolvedImport, path38.extname(resolvedImport));
48655
+ const importDir = path38.dirname(resolvedImport);
48697
48656
  for (const sourceFile of absoluteSourceFiles) {
48698
- const sourceDir = path39.dirname(sourceFile);
48699
- const sourceBasename = path39.basename(sourceFile, path39.extname(sourceFile));
48700
- const isRelatedDir = importDir === sourceDir || importDir === path39.join(sourceDir, "__tests__") || importDir === path39.join(sourceDir, "tests") || importDir === path39.join(sourceDir, "test") || importDir === path39.join(sourceDir, "spec");
48657
+ const sourceDir = path38.dirname(sourceFile);
48658
+ const sourceBasename = path38.basename(sourceFile, path38.extname(sourceFile));
48659
+ const isRelatedDir = importDir === sourceDir || importDir === path38.join(sourceDir, "__tests__") || importDir === path38.join(sourceDir, "tests") || importDir === path38.join(sourceDir, "test") || importDir === path38.join(sourceDir, "spec");
48701
48660
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
48702
48661
  dedupePush(testFiles, testFile);
48703
48662
  break;
@@ -48710,8 +48669,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48710
48669
  while (match !== null) {
48711
48670
  const importPath = match[1];
48712
48671
  if (importPath.startsWith(".")) {
48713
- let resolvedImport = path39.resolve(testDir, importPath);
48714
- const existingExt = path39.extname(resolvedImport);
48672
+ let resolvedImport = path38.resolve(testDir, importPath);
48673
+ const existingExt = path38.extname(resolvedImport);
48715
48674
  if (!existingExt) {
48716
48675
  for (const extToTry of [
48717
48676
  ".ts",
@@ -48728,12 +48687,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48728
48687
  }
48729
48688
  }
48730
48689
  }
48731
- const importDir = path39.dirname(resolvedImport);
48732
- const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
48690
+ const importDir = path38.dirname(resolvedImport);
48691
+ const importBasename = path38.basename(resolvedImport, path38.extname(resolvedImport));
48733
48692
  for (const sourceFile of absoluteSourceFiles) {
48734
- const sourceDir = path39.dirname(sourceFile);
48735
- const sourceBasename = path39.basename(sourceFile, path39.extname(sourceFile));
48736
- const isRelatedDir = importDir === sourceDir || importDir === path39.join(sourceDir, "__tests__") || importDir === path39.join(sourceDir, "tests") || importDir === path39.join(sourceDir, "test") || importDir === path39.join(sourceDir, "spec");
48693
+ const sourceDir = path38.dirname(sourceFile);
48694
+ const sourceBasename = path38.basename(sourceFile, path38.extname(sourceFile));
48695
+ const isRelatedDir = importDir === sourceDir || importDir === path38.join(sourceDir, "__tests__") || importDir === path38.join(sourceDir, "tests") || importDir === path38.join(sourceDir, "test") || importDir === path38.join(sourceDir, "spec");
48737
48696
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
48738
48697
  dedupePush(testFiles, testFile);
48739
48698
  break;
@@ -48843,8 +48802,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
48843
48802
  return ["mvn", "test"];
48844
48803
  case "gradle": {
48845
48804
  const isWindows = process.platform === "win32";
48846
- const hasGradlewBat = fs22.existsSync(path39.join(baseDir, "gradlew.bat"));
48847
- const hasGradlew = fs22.existsSync(path39.join(baseDir, "gradlew"));
48805
+ const hasGradlewBat = fs22.existsSync(path38.join(baseDir, "gradlew.bat"));
48806
+ const hasGradlew = fs22.existsSync(path38.join(baseDir, "gradlew"));
48848
48807
  if (hasGradlewBat && isWindows)
48849
48808
  return ["gradlew.bat", "test"];
48850
48809
  if (hasGradlew)
@@ -48861,7 +48820,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
48861
48820
  "cmake-build-release",
48862
48821
  "out"
48863
48822
  ];
48864
- const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(path39.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
48823
+ const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(path38.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
48865
48824
  return ["ctest", "--test-dir", actualBuildDir];
48866
48825
  }
48867
48826
  case "swift-test":
@@ -49293,11 +49252,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
49293
49252
  };
49294
49253
  }
49295
49254
  const startTime = Date.now();
49296
- const vitestJsonOutputPath = framework === "vitest" ? path39.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
49255
+ const vitestJsonOutputPath = framework === "vitest" ? path38.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
49297
49256
  try {
49298
49257
  if (vitestJsonOutputPath) {
49299
49258
  try {
49300
- fs22.mkdirSync(path39.dirname(vitestJsonOutputPath), { recursive: true });
49259
+ fs22.mkdirSync(path38.dirname(vitestJsonOutputPath), { recursive: true });
49301
49260
  if (fs22.existsSync(vitestJsonOutputPath)) {
49302
49261
  fs22.unlinkSync(vitestJsonOutputPath);
49303
49262
  }
@@ -49413,10 +49372,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
49413
49372
  }
49414
49373
  function normalizeHistoryTestFile(testFile, workingDir) {
49415
49374
  const normalized = testFile.replace(/\\/g, "/");
49416
- if (!path39.isAbsolute(testFile))
49375
+ if (!path38.isAbsolute(testFile))
49417
49376
  return normalized;
49418
- const relative9 = path39.relative(workingDir, testFile);
49419
- if (relative9.startsWith("..") || path39.isAbsolute(relative9)) {
49377
+ const relative9 = path38.relative(workingDir, testFile);
49378
+ if (relative9.startsWith("..") || path38.isAbsolute(relative9)) {
49420
49379
  return normalized;
49421
49380
  }
49422
49381
  return relative9.replace(/\\/g, "/");
@@ -49754,7 +49713,7 @@ var init_test_runner = __esm(() => {
49754
49713
  const sourceFiles = args.files.filter((file3) => {
49755
49714
  if (directTestFiles.includes(file3))
49756
49715
  return false;
49757
- const ext = path39.extname(file3).toLowerCase();
49716
+ const ext = path38.extname(file3).toLowerCase();
49758
49717
  return SOURCE_EXTENSIONS.has(ext);
49759
49718
  });
49760
49719
  const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
@@ -49800,7 +49759,7 @@ var init_test_runner = __esm(() => {
49800
49759
  if (isConventionTestFilePath(f)) {
49801
49760
  return false;
49802
49761
  }
49803
- const ext = path39.extname(f).toLowerCase();
49762
+ const ext = path38.extname(f).toLowerCase();
49804
49763
  return SOURCE_EXTENSIONS.has(ext);
49805
49764
  });
49806
49765
  if (sourceFiles.length === 0) {
@@ -49850,7 +49809,7 @@ var init_test_runner = __esm(() => {
49850
49809
  if (isConventionTestFilePath(f)) {
49851
49810
  return false;
49852
49811
  }
49853
- const ext = path39.extname(f).toLowerCase();
49812
+ const ext = path38.extname(f).toLowerCase();
49854
49813
  return SOURCE_EXTENSIONS.has(ext);
49855
49814
  });
49856
49815
  if (sourceFiles.length === 0) {
@@ -49902,8 +49861,8 @@ var init_test_runner = __esm(() => {
49902
49861
  }
49903
49862
  if (impactResult.impactedTests.length > 0) {
49904
49863
  testFiles = impactResult.impactedTests.map((absPath) => {
49905
- const relativePath = path39.relative(workingDir, absPath);
49906
- return path39.isAbsolute(relativePath) ? absPath : relativePath;
49864
+ const relativePath = path38.relative(workingDir, absPath);
49865
+ return path38.isAbsolute(relativePath) ? absPath : relativePath;
49907
49866
  });
49908
49867
  } else {
49909
49868
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -49979,7 +49938,7 @@ var init_test_runner = __esm(() => {
49979
49938
 
49980
49939
  // src/services/preflight-service.ts
49981
49940
  import * as fs23 from "fs";
49982
- import * as path40 from "path";
49941
+ import * as path39 from "path";
49983
49942
  function validateDirectoryPath(dir) {
49984
49943
  if (!dir || typeof dir !== "string") {
49985
49944
  throw new Error("Directory path is required");
@@ -49987,8 +49946,8 @@ function validateDirectoryPath(dir) {
49987
49946
  if (dir.includes("..")) {
49988
49947
  throw new Error("Directory path must not contain path traversal sequences");
49989
49948
  }
49990
- const normalized = path40.normalize(dir);
49991
- const absolutePath = path40.isAbsolute(normalized) ? normalized : path40.resolve(normalized);
49949
+ const normalized = path39.normalize(dir);
49950
+ const absolutePath = path39.isAbsolute(normalized) ? normalized : path39.resolve(normalized);
49992
49951
  return absolutePath;
49993
49952
  }
49994
49953
  function validateTimeout(timeoutMs, defaultValue) {
@@ -50011,7 +49970,7 @@ function validateTimeout(timeoutMs, defaultValue) {
50011
49970
  }
50012
49971
  function getPackageVersion(dir) {
50013
49972
  try {
50014
- const packagePath = path40.join(dir, "package.json");
49973
+ const packagePath = path39.join(dir, "package.json");
50015
49974
  if (fs23.existsSync(packagePath)) {
50016
49975
  const content = fs23.readFileSync(packagePath, "utf-8");
50017
49976
  const pkg = JSON.parse(content);
@@ -50022,7 +49981,7 @@ function getPackageVersion(dir) {
50022
49981
  }
50023
49982
  function getChangelogVersion(dir) {
50024
49983
  try {
50025
- const changelogPath = path40.join(dir, "CHANGELOG.md");
49984
+ const changelogPath = path39.join(dir, "CHANGELOG.md");
50026
49985
  if (fs23.existsSync(changelogPath)) {
50027
49986
  const content = fs23.readFileSync(changelogPath, "utf-8");
50028
49987
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
@@ -50036,7 +49995,7 @@ function getChangelogVersion(dir) {
50036
49995
  function getVersionFileVersion(dir) {
50037
49996
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
50038
49997
  for (const file3 of possibleFiles) {
50039
- const filePath = path40.join(dir, file3);
49998
+ const filePath = path39.join(dir, file3);
50040
49999
  if (fs23.existsSync(filePath)) {
50041
50000
  try {
50042
50001
  const content = fs23.readFileSync(filePath, "utf-8").trim();
@@ -50363,7 +50322,7 @@ async function runEvidenceCheck(dir) {
50363
50322
  async function runRequirementCoverageCheck(dir, currentPhase) {
50364
50323
  const startTime = Date.now();
50365
50324
  try {
50366
- const specPath = path40.join(dir, ".swarm", "spec.md");
50325
+ const specPath = path39.join(dir, ".swarm", "spec.md");
50367
50326
  if (!fs23.existsSync(specPath)) {
50368
50327
  return {
50369
50328
  type: "req_coverage",
@@ -51480,7 +51439,7 @@ var init_manager3 = __esm(() => {
51480
51439
 
51481
51440
  // src/commands/reset.ts
51482
51441
  import * as fs24 from "fs";
51483
- import * as path41 from "path";
51442
+ import * as path40 from "path";
51484
51443
  async function handleResetCommand(directory, args) {
51485
51444
  const hasConfirm = args.includes("--confirm");
51486
51445
  if (!hasConfirm) {
@@ -51520,7 +51479,7 @@ async function handleResetCommand(directory, args) {
51520
51479
  }
51521
51480
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
51522
51481
  try {
51523
- const rootPath = path41.join(directory, filename);
51482
+ const rootPath = path40.join(directory, filename);
51524
51483
  if (fs24.existsSync(rootPath)) {
51525
51484
  fs24.unlinkSync(rootPath);
51526
51485
  results.push(`- \u2705 Deleted ${filename} (root)`);
@@ -51560,7 +51519,7 @@ var init_reset = __esm(() => {
51560
51519
 
51561
51520
  // src/commands/reset-session.ts
51562
51521
  import * as fs25 from "fs";
51563
- import * as path42 from "path";
51522
+ import * as path41 from "path";
51564
51523
  async function handleResetSessionCommand(directory, _args) {
51565
51524
  const results = [];
51566
51525
  try {
@@ -51575,13 +51534,13 @@ async function handleResetSessionCommand(directory, _args) {
51575
51534
  results.push("\u274C Failed to delete state.json");
51576
51535
  }
51577
51536
  try {
51578
- const sessionDir = path42.dirname(validateSwarmPath(directory, "session/state.json"));
51537
+ const sessionDir = path41.dirname(validateSwarmPath(directory, "session/state.json"));
51579
51538
  if (fs25.existsSync(sessionDir)) {
51580
51539
  const files = fs25.readdirSync(sessionDir);
51581
51540
  const otherFiles = files.filter((f) => f !== "state.json");
51582
51541
  let deletedCount = 0;
51583
51542
  for (const file3 of otherFiles) {
51584
- const filePath = path42.join(sessionDir, file3);
51543
+ const filePath = path41.join(sessionDir, file3);
51585
51544
  if (fs25.lstatSync(filePath).isFile()) {
51586
51545
  fs25.unlinkSync(filePath);
51587
51546
  deletedCount++;
@@ -51613,7 +51572,7 @@ var init_reset_session = __esm(() => {
51613
51572
  });
51614
51573
 
51615
51574
  // src/summaries/manager.ts
51616
- import * as path43 from "path";
51575
+ import * as path42 from "path";
51617
51576
  function sanitizeSummaryId(id) {
51618
51577
  if (!id || id.length === 0) {
51619
51578
  throw new Error("Invalid summary ID: empty string");
@@ -51636,7 +51595,7 @@ function sanitizeSummaryId(id) {
51636
51595
  }
51637
51596
  async function loadFullOutput(directory, id) {
51638
51597
  const sanitizedId = sanitizeSummaryId(id);
51639
- const relativePath = path43.join("summaries", `${sanitizedId}.json`);
51598
+ const relativePath = path42.join("summaries", `${sanitizedId}.json`);
51640
51599
  validateSwarmPath(directory, relativePath);
51641
51600
  const content = await readSwarmFileAsync(directory, relativePath);
51642
51601
  if (content === null) {
@@ -51699,7 +51658,7 @@ var init_retrieve = __esm(() => {
51699
51658
 
51700
51659
  // src/commands/rollback.ts
51701
51660
  import * as fs26 from "fs";
51702
- import * as path44 from "path";
51661
+ import * as path43 from "path";
51703
51662
  async function handleRollbackCommand(directory, args) {
51704
51663
  const phaseArg = args[0];
51705
51664
  if (!phaseArg) {
@@ -51764,8 +51723,8 @@ async function handleRollbackCommand(directory, args) {
51764
51723
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
51765
51724
  continue;
51766
51725
  }
51767
- const src = path44.join(checkpointDir, file3);
51768
- const dest = path44.join(swarmDir, file3);
51726
+ const src = path43.join(checkpointDir, file3);
51727
+ const dest = path43.join(swarmDir, file3);
51769
51728
  try {
51770
51729
  fs26.cpSync(src, dest, { recursive: true, force: true });
51771
51730
  successes.push(file3);
@@ -51784,12 +51743,12 @@ async function handleRollbackCommand(directory, args) {
51784
51743
  ].join(`
51785
51744
  `);
51786
51745
  }
51787
- const existingLedgerPath = path44.join(swarmDir, "plan-ledger.jsonl");
51746
+ const existingLedgerPath = path43.join(swarmDir, "plan-ledger.jsonl");
51788
51747
  if (fs26.existsSync(existingLedgerPath)) {
51789
51748
  fs26.unlinkSync(existingLedgerPath);
51790
51749
  }
51791
51750
  try {
51792
- const planJsonPath = path44.join(swarmDir, "plan.json");
51751
+ const planJsonPath = path43.join(swarmDir, "plan.json");
51793
51752
  if (fs26.existsSync(planJsonPath)) {
51794
51753
  const planRaw = fs26.readFileSync(planJsonPath, "utf-8");
51795
51754
  const plan = PlanSchema.parse(JSON.parse(planRaw));
@@ -51880,9 +51839,9 @@ Ensure this is a git repository with commit history.`;
51880
51839
  `);
51881
51840
  try {
51882
51841
  const fs27 = await import("fs/promises");
51883
- const path45 = await import("path");
51884
- const reportPath = path45.join(directory, ".swarm", "simulate-report.md");
51885
- await fs27.mkdir(path45.dirname(reportPath), { recursive: true });
51842
+ const path44 = await import("path");
51843
+ const reportPath = path44.join(directory, ".swarm", "simulate-report.md");
51844
+ await fs27.mkdir(path44.dirname(reportPath), { recursive: true });
51886
51845
  await fs27.writeFile(reportPath, report, "utf-8");
51887
51846
  } catch (err) {
51888
51847
  const writeErr = err instanceof Error ? err.message : String(err);
@@ -51906,12 +51865,12 @@ async function handleSpecifyCommand(_directory, args) {
51906
51865
 
51907
51866
  // src/turbo/lean/state.ts
51908
51867
  import * as fs27 from "fs";
51909
- import * as path45 from "path";
51868
+ import * as path44 from "path";
51910
51869
  function nowISO2() {
51911
51870
  return new Date().toISOString();
51912
51871
  }
51913
51872
  function ensureSwarmDir2(directory) {
51914
- const swarmDir = path45.resolve(directory, ".swarm");
51873
+ const swarmDir = path44.resolve(directory, ".swarm");
51915
51874
  if (!fs27.existsSync(swarmDir)) {
51916
51875
  fs27.mkdirSync(swarmDir, { recursive: true });
51917
51876
  }
@@ -51955,7 +51914,7 @@ function markStateUnreadable2(directory, reason) {
51955
51914
  }
51956
51915
  function readPersisted2(directory) {
51957
51916
  try {
51958
- const filePath = path45.join(directory, ".swarm", STATE_FILE2);
51917
+ const filePath = path44.join(directory, ".swarm", STATE_FILE2);
51959
51918
  if (!fs27.existsSync(filePath)) {
51960
51919
  const seed = emptyPersisted2();
51961
51920
  try {
@@ -51991,7 +51950,7 @@ function writePersisted2(directory, persisted) {
51991
51950
  let payload;
51992
51951
  try {
51993
51952
  ensureSwarmDir2(directory);
51994
- filePath = path45.join(directory, ".swarm", STATE_FILE2);
51953
+ filePath = path44.join(directory, ".swarm", STATE_FILE2);
51995
51954
  tmpPath = `${filePath}.tmp.${Date.now()}`;
51996
51955
  persisted.updatedAt = nowISO2();
51997
51956
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -52118,10 +52077,10 @@ var init_context_budget_service = __esm(() => {
52118
52077
 
52119
52078
  // src/services/status-service.ts
52120
52079
  import * as fsSync2 from "fs";
52121
- import * as path46 from "path";
52080
+ import * as path45 from "path";
52122
52081
  function readSpecStalenessSnapshot(directory) {
52123
52082
  try {
52124
- const p = path46.join(directory, ".swarm", "spec-staleness.json");
52083
+ const p = path45.join(directory, ".swarm", "spec-staleness.json");
52125
52084
  if (!fsSync2.existsSync(p))
52126
52085
  return { stale: false };
52127
52086
  const raw = fsSync2.readFileSync(p, "utf-8");
@@ -52647,7 +52606,7 @@ var init_write_retro2 = __esm(() => {
52647
52606
 
52648
52607
  // src/commands/command-dispatch.ts
52649
52608
  import fs28 from "fs";
52650
- import path47 from "path";
52609
+ import path46 from "path";
52651
52610
  function normalizeSwarmCommandInput(command, argumentText) {
52652
52611
  if (command !== "swarm" && !command.startsWith("swarm-")) {
52653
52612
  return { isSwarmCommand: false, tokens: [] };
@@ -52683,9 +52642,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
52683
52642
  `);
52684
52643
  }
52685
52644
  function maybeMarkFirstRun(directory) {
52686
- const sentinelPath = path47.join(directory, ".swarm", ".first-run-complete");
52645
+ const sentinelPath = path46.join(directory, ".swarm", ".first-run-complete");
52687
52646
  try {
52688
- const swarmDir = path47.join(directory, ".swarm");
52647
+ const swarmDir = path46.join(directory, ".swarm");
52689
52648
  fs28.mkdirSync(swarmDir, { recursive: true });
52690
52649
  fs28.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
52691
52650
  `, { flag: "wx" });
@@ -53367,24 +53326,24 @@ function validateAliases() {
53367
53326
  }
53368
53327
  aliasTargets.get(target).push(name);
53369
53328
  const visited = new Set;
53370
- const path48 = [];
53329
+ const path47 = [];
53371
53330
  let current = target;
53372
53331
  while (current) {
53373
53332
  const currentEntry = COMMAND_REGISTRY[current];
53374
53333
  if (!currentEntry)
53375
53334
  break;
53376
53335
  if (visited.has(current)) {
53377
- const cycleStart = path48.indexOf(current);
53336
+ const cycleStart = path47.indexOf(current);
53378
53337
  const fullChain = [
53379
53338
  name,
53380
- ...path48.slice(0, cycleStart > 0 ? cycleStart : path48.length),
53339
+ ...path47.slice(0, cycleStart > 0 ? cycleStart : path47.length),
53381
53340
  current
53382
53341
  ].join(" \u2192 ");
53383
53342
  errors5.push(`Circular alias detected: ${fullChain}`);
53384
53343
  break;
53385
53344
  }
53386
53345
  visited.add(current);
53387
- path48.push(current);
53346
+ path47.push(current);
53388
53347
  current = currentEntry.aliasOf || "";
53389
53348
  }
53390
53349
  }
@@ -53895,53 +53854,53 @@ init_cache_paths();
53895
53854
  init_constants();
53896
53855
  import * as fs29 from "fs";
53897
53856
  import * as os7 from "os";
53898
- import * as path48 from "path";
53857
+ import * as path47 from "path";
53899
53858
  var { version: version4 } = package_default;
53900
53859
  var CONFIG_DIR = getPluginConfigDir();
53901
- var OPENCODE_CONFIG_PATH = path48.join(CONFIG_DIR, "opencode.json");
53902
- var PLUGIN_CONFIG_PATH = path48.join(CONFIG_DIR, "opencode-swarm.json");
53903
- var PROMPTS_DIR = path48.join(CONFIG_DIR, "opencode-swarm");
53860
+ var OPENCODE_CONFIG_PATH = path47.join(CONFIG_DIR, "opencode.json");
53861
+ var PLUGIN_CONFIG_PATH = path47.join(CONFIG_DIR, "opencode-swarm.json");
53862
+ var PROMPTS_DIR = path47.join(CONFIG_DIR, "opencode-swarm");
53904
53863
  var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
53905
53864
  var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
53906
53865
  function isSafeCachePath(p) {
53907
- const resolved = path48.resolve(p);
53908
- const home = path48.resolve(os7.homedir());
53866
+ const resolved = path47.resolve(p);
53867
+ const home = path47.resolve(os7.homedir());
53909
53868
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
53910
53869
  return false;
53911
53870
  }
53912
- const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
53871
+ const segments = resolved.split(path47.sep).filter((s) => s.length > 0);
53913
53872
  if (segments.length < 4) {
53914
53873
  return false;
53915
53874
  }
53916
- const leaf = path48.basename(resolved);
53875
+ const leaf = path47.basename(resolved);
53917
53876
  if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
53918
53877
  return false;
53919
53878
  }
53920
- const parent = path48.basename(path48.dirname(resolved));
53879
+ const parent = path47.basename(path47.dirname(resolved));
53921
53880
  if (parent !== "packages" && parent !== "node_modules") {
53922
53881
  return false;
53923
53882
  }
53924
- const grandparent = path48.basename(path48.dirname(path48.dirname(resolved)));
53883
+ const grandparent = path47.basename(path47.dirname(path47.dirname(resolved)));
53925
53884
  if (grandparent !== "opencode") {
53926
53885
  return false;
53927
53886
  }
53928
53887
  return true;
53929
53888
  }
53930
53889
  function isSafeLockFilePath(p) {
53931
- const resolved = path48.resolve(p);
53932
- const home = path48.resolve(os7.homedir());
53890
+ const resolved = path47.resolve(p);
53891
+ const home = path47.resolve(os7.homedir());
53933
53892
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
53934
53893
  return false;
53935
53894
  }
53936
- const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
53895
+ const segments = resolved.split(path47.sep).filter((s) => s.length > 0);
53937
53896
  if (segments.length < 4) {
53938
53897
  return false;
53939
53898
  }
53940
- const leaf = path48.basename(resolved);
53899
+ const leaf = path47.basename(resolved);
53941
53900
  if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
53942
53901
  return false;
53943
53902
  }
53944
- const parent = path48.basename(path48.dirname(resolved));
53903
+ const parent = path47.basename(path47.dirname(resolved));
53945
53904
  if (parent !== "opencode") {
53946
53905
  return false;
53947
53906
  }
@@ -53967,8 +53926,8 @@ function saveJson(filepath, data) {
53967
53926
  }
53968
53927
  function writeProjectConfigIfMissing(cwd) {
53969
53928
  try {
53970
- const opencodeDir = path48.join(cwd, ".opencode");
53971
- const projectConfigPath = path48.join(opencodeDir, "opencode-swarm.json");
53929
+ const opencodeDir = path47.join(cwd, ".opencode");
53930
+ const projectConfigPath = path47.join(opencodeDir, "opencode-swarm.json");
53972
53931
  if (fs29.existsSync(projectConfigPath)) {
53973
53932
  return;
53974
53933
  }
@@ -53985,7 +53944,7 @@ async function install() {
53985
53944
  `);
53986
53945
  ensureDir(CONFIG_DIR);
53987
53946
  ensureDir(PROMPTS_DIR);
53988
- const LEGACY_CONFIG_PATH = path48.join(CONFIG_DIR, "config.json");
53947
+ const LEGACY_CONFIG_PATH = path47.join(CONFIG_DIR, "config.json");
53989
53948
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
53990
53949
  if (!opencodeConfig) {
53991
53950
  const legacyConfig = loadJson(LEGACY_CONFIG_PATH);