opencode-swarm 7.5.1 → 7.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/agents/critic.d.ts +13 -0
  2. package/dist/background/event-bus.d.ts +8 -0
  3. package/dist/background/manager.d.ts +9 -0
  4. package/dist/build/discovery.d.ts +7 -0
  5. package/dist/cli/index.js +940 -431
  6. package/dist/commands/registry.d.ts +16 -0
  7. package/dist/config/index.d.ts +13 -0
  8. package/dist/config/schema.d.ts +10 -0
  9. package/dist/db/qa-gate-profile.d.ts +13 -0
  10. package/dist/evidence/manager.d.ts +14 -0
  11. package/dist/git/branch.d.ts +19 -0
  12. package/dist/hooks/curator-drift.d.ts +6 -0
  13. package/dist/hooks/curator.d.ts +13 -0
  14. package/dist/hooks/extractors.d.ts +11 -0
  15. package/dist/hooks/knowledge-curator.d.ts +6 -0
  16. package/dist/hooks/knowledge-migrator.d.ts +52 -1
  17. package/dist/hooks/knowledge-reader.d.ts +4 -0
  18. package/dist/hooks/knowledge-store.d.ts +21 -0
  19. package/dist/hooks/knowledge-validator.d.ts +6 -0
  20. package/dist/hooks/utils.d.ts +14 -0
  21. package/dist/index.js +971 -570
  22. package/dist/lang/detector.d.ts +4 -0
  23. package/dist/lang/index.d.ts +3 -2
  24. package/dist/lang/registry.d.ts +6 -0
  25. package/dist/mutation/engine.d.ts +5 -0
  26. package/dist/mutation/equivalence.d.ts +5 -0
  27. package/dist/mutation/gate.d.ts +8 -0
  28. package/dist/parallel/file-locks.d.ts +15 -0
  29. package/dist/plan/checkpoint.d.ts +4 -0
  30. package/dist/plan/ledger.d.ts +36 -0
  31. package/dist/plan/manager.d.ts +13 -0
  32. package/dist/sast/rules/index.d.ts +14 -0
  33. package/dist/sast/semgrep.d.ts +8 -0
  34. package/dist/services/evidence-summary-service.d.ts +51 -1
  35. package/dist/services/handoff-service.d.ts +68 -0
  36. package/dist/services/preflight-service.d.ts +67 -0
  37. package/dist/services/run-memory.d.ts +22 -0
  38. package/dist/session/snapshot-writer.d.ts +9 -0
  39. package/dist/state.d.ts +26 -0
  40. package/dist/telemetry.d.ts +12 -0
  41. package/dist/test-impact/analyzer.d.ts +20 -0
  42. package/dist/tools/co-change-analyzer.d.ts +12 -0
  43. package/dist/tools/knowledge-recall.d.ts +7 -0
  44. package/dist/tools/lint.d.ts +10 -0
  45. package/dist/tools/quality-budget.d.ts +7 -0
  46. package/dist/tools/sast-baseline.d.ts +10 -0
  47. package/dist/tools/sast-scan.d.ts +8 -0
  48. package/dist/tools/secretscan.d.ts +8 -0
  49. package/dist/tools/write-retro.d.ts +9 -0
  50. package/dist/utils/logger.d.ts +12 -0
  51. package/dist/utils/path-security.d.ts +10 -0
  52. package/dist/utils/spec-hash.d.ts +8 -0
  53. package/package.json +2 -2
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.5.1",
37
+ version: "7.5.3",
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",
@@ -43,7 +43,7 @@ var init_package = __esm(() => {
43
43
  },
44
44
  type: "module",
45
45
  engines: {
46
- bun: ">=1.0.0"
46
+ bun: ">=1.3.13"
47
47
  },
48
48
  license: "MIT",
49
49
  repository: {
@@ -104,7 +104,19 @@ var init_package = __esm(() => {
104
104
  });
105
105
 
106
106
  // src/utils/errors.ts
107
- var init_errors = () => {};
107
+ var SwarmError;
108
+ var init_errors = __esm(() => {
109
+ SwarmError = class SwarmError extends Error {
110
+ code;
111
+ guidance;
112
+ constructor(message, code, guidance) {
113
+ super(message);
114
+ this.name = "SwarmError";
115
+ this.code = code;
116
+ this.guidance = guidance;
117
+ }
118
+ };
119
+ });
108
120
 
109
121
  // src/utils/logger.ts
110
122
  function isDebug() {
@@ -130,6 +142,7 @@ function warn(message, data) {
130
142
  console.warn(`[opencode-swarm ${timestamp}] WARN: ${message}`);
131
143
  }
132
144
  }
145
+ var init_logger = () => {};
133
146
 
134
147
  // src/utils/merge.ts
135
148
  function deepMergeInternal(base, override, depth) {
@@ -169,6 +182,7 @@ function simpleGlobToRegex(pattern, flags = "i") {
169
182
  // src/utils/index.ts
170
183
  var init_utils = __esm(() => {
171
184
  init_errors();
185
+ init_logger();
172
186
  });
173
187
 
174
188
  // src/utils/bun-compat.ts
@@ -500,6 +514,32 @@ var init_bun_compat = () => {};
500
514
 
501
515
  // src/hooks/utils.ts
502
516
  import * as path2 from "path";
517
+ function safeHook(fn) {
518
+ return async (input, output) => {
519
+ try {
520
+ await fn(input, output);
521
+ } catch (_error) {
522
+ const functionName = fn.name || "unknown";
523
+ if (_error instanceof SwarmError) {
524
+ warn(`Hook '${functionName}' failed: ${_error.message}
525
+ \u2192 ${_error.guidance}`);
526
+ } else {
527
+ warn(`Hook function '${functionName}' failed:`, _error);
528
+ }
529
+ }
530
+ };
531
+ }
532
+ function composeHandlers(...fns) {
533
+ if (fns.length === 0) {
534
+ return async () => {};
535
+ }
536
+ return async (input, output) => {
537
+ for (const fn of fns) {
538
+ const safeFn = _internals.safeHook(fn);
539
+ await safeFn(input, output);
540
+ }
541
+ };
542
+ }
503
543
  function validateSwarmPath(directory, filename) {
504
544
  if (/[\0]/.test(filename)) {
505
545
  throw new Error("Invalid filename: contains null bytes");
@@ -528,7 +568,7 @@ function validateSwarmPath(directory, filename) {
528
568
  }
529
569
  async function readSwarmFileAsync(directory, filename) {
530
570
  try {
531
- const resolvedPath = validateSwarmPath(directory, filename);
571
+ const resolvedPath = _internals.validateSwarmPath(directory, filename);
532
572
  const file = bunFile(resolvedPath);
533
573
  const content = await file.text();
534
574
  return content;
@@ -536,9 +576,11 @@ async function readSwarmFileAsync(directory, filename) {
536
576
  return null;
537
577
  }
538
578
  }
579
+ var _internals;
539
580
  var init_utils2 = __esm(() => {
540
581
  init_utils();
541
582
  init_bun_compat();
583
+ _internals = { safeHook, composeHandlers, validateSwarmPath, readSwarmFileAsync };
542
584
  });
543
585
 
544
586
  // node_modules/zod/v4/core/core.js
@@ -14519,7 +14561,7 @@ async function computeSpecHash(directory) {
14519
14561
  return hash2;
14520
14562
  }
14521
14563
  async function isSpecStale(directory, plan) {
14522
- const currentHash = await computeSpecHash(directory);
14564
+ const currentHash = await _internals2.computeSpecHash(directory);
14523
14565
  if (!plan.specHash) {
14524
14566
  return { stale: false };
14525
14567
  }
@@ -14539,7 +14581,13 @@ async function isSpecStale(directory, plan) {
14539
14581
  }
14540
14582
  return { stale: false };
14541
14583
  }
14542
- var init_spec_hash = () => {};
14584
+ var _internals2;
14585
+ var init_spec_hash = __esm(() => {
14586
+ _internals2 = {
14587
+ computeSpecHash,
14588
+ isSpecStale
14589
+ };
14590
+ });
14543
14591
 
14544
14592
  // src/plan/ledger.ts
14545
14593
  import * as crypto2 from "crypto";
@@ -15113,7 +15161,7 @@ async function loadPlan(directory) {
15113
15161
  const inSync = await isPlanMdInSync(directory, validated);
15114
15162
  if (!inSync) {
15115
15163
  try {
15116
- await regeneratePlanMarkdown(directory, validated);
15164
+ await _internals3.regeneratePlanMarkdown(directory, validated);
15117
15165
  } catch (regenError) {
15118
15166
  warn(`Failed to regenerate plan.md: ${regenError instanceof Error ? regenError.message : String(regenError)}. Proceeding with plan.json only.`);
15119
15167
  }
@@ -15246,7 +15294,7 @@ async function loadPlan(directory) {
15246
15294
  const existingMutex = recoveryMutexes.get(resolvedDir);
15247
15295
  if (existingMutex) {
15248
15296
  await existingMutex;
15249
- const postRecoveryPlan = await loadPlanJsonOnly(directory);
15297
+ const postRecoveryPlan = await _internals3.loadPlanJsonOnly(directory);
15250
15298
  if (postRecoveryPlan)
15251
15299
  return postRecoveryPlan;
15252
15300
  }
@@ -15300,7 +15348,7 @@ async function savePlan(directory, plan, options) {
15300
15348
  const validated = PlanSchema.parse(plan);
15301
15349
  if (options?.preserveCompletedStatuses !== false) {
15302
15350
  try {
15303
- const currentPlan2 = await loadPlanJsonOnly(directory);
15351
+ const currentPlan2 = await _internals3.loadPlanJsonOnly(directory);
15304
15352
  if (currentPlan2) {
15305
15353
  const completedTaskIds = new Set;
15306
15354
  for (const phase of currentPlan2.phases) {
@@ -15333,7 +15381,7 @@ async function savePlan(directory, plan, options) {
15333
15381
  phase.status = "pending";
15334
15382
  }
15335
15383
  }
15336
- const currentPlan = await loadPlanJsonOnly(directory);
15384
+ const currentPlan = await _internals3.loadPlanJsonOnly(directory);
15337
15385
  const planId = `${validated.swarm}-${validated.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
15338
15386
  const planHashForInit = computePlanHash(validated);
15339
15387
  if (!await ledgerExists(directory)) {
@@ -15449,7 +15497,7 @@ async function savePlan(directory, plan, options) {
15449
15497
  expectedHash: currentHash,
15450
15498
  planHashAfter: hashAfter,
15451
15499
  verifyValid: async () => {
15452
- const onDisk = await loadPlanJsonOnly(directory);
15500
+ const onDisk = await _internals3.loadPlanJsonOnly(directory);
15453
15501
  if (!onDisk)
15454
15502
  return true;
15455
15503
  for (const p of onDisk.phases) {
@@ -15829,7 +15877,7 @@ function migrateLegacyPlan(planContent, swarmId) {
15829
15877
  };
15830
15878
  return plan;
15831
15879
  }
15832
- var PlanConcurrentModificationError, startupLedgerCheckedWorkspaces, recoveryMutexes, CAS_BACKOFF_START_MS = 5, CAS_BACKOFF_CAP_MS = 250, CAS_BACKOFF_JITTER = 0.25, CAS_MAX_RETRIES = 3;
15880
+ var PlanConcurrentModificationError, startupLedgerCheckedWorkspaces, recoveryMutexes, _internals3, CAS_BACKOFF_START_MS = 5, CAS_BACKOFF_CAP_MS = 250, CAS_BACKOFF_JITTER = 0.25, CAS_MAX_RETRIES = 3;
15833
15881
  var init_manager = __esm(() => {
15834
15882
  init_plan_schema();
15835
15883
  init_utils2();
@@ -15846,6 +15894,11 @@ var init_manager = __esm(() => {
15846
15894
  };
15847
15895
  startupLedgerCheckedWorkspaces = new Set;
15848
15896
  recoveryMutexes = new Map;
15897
+ _internals3 = {
15898
+ loadPlan,
15899
+ loadPlanJsonOnly,
15900
+ regeneratePlanMarkdown
15901
+ };
15849
15902
  });
15850
15903
 
15851
15904
  // src/commands/acknowledge-spec-drift.ts
@@ -19360,7 +19413,7 @@ async function loadEvidence(directory, taskId) {
19360
19413
  return { status: "invalid_schema", errors: ["Invalid JSON"] };
19361
19414
  }
19362
19415
  if (isFlatRetrospective(parsed)) {
19363
- const wrappedBundle = wrapFlatRetrospective(parsed, sanitizedTaskId);
19416
+ const wrappedBundle = _internals4.wrapFlatRetrospective(parsed, sanitizedTaskId);
19364
19417
  try {
19365
19418
  const validated = EvidenceBundleSchema.parse(wrappedBundle);
19366
19419
  try {
@@ -19456,14 +19509,14 @@ async function checkRequirementCoverage(phase, directory) {
19456
19509
  }
19457
19510
  }
19458
19511
  async function archiveEvidence(directory, maxAgeDays, maxBundles) {
19459
- const taskIds = await listEvidenceTaskIds(directory);
19512
+ const taskIds = await _internals4.listEvidenceTaskIds(directory);
19460
19513
  const cutoffDate = new Date;
19461
19514
  cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);
19462
19515
  const cutoffIso = cutoffDate.toISOString();
19463
19516
  const archived = [];
19464
19517
  const remainingBundles = [];
19465
19518
  for (const taskId of taskIds) {
19466
- const result = await loadEvidence(directory, taskId);
19519
+ const result = await _internals4.loadEvidence(directory, taskId);
19467
19520
  if (result.status !== "found") {
19468
19521
  continue;
19469
19522
  }
@@ -19491,7 +19544,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles) {
19491
19544
  }
19492
19545
  return archived;
19493
19546
  }
19494
- var VALID_EVIDENCE_TYPES, sanitizeTaskId2, LEGACY_TASK_COMPLEXITY_MAP;
19547
+ var VALID_EVIDENCE_TYPES, sanitizeTaskId2, LEGACY_TASK_COMPLEXITY_MAP, _internals4;
19495
19548
  var init_manager2 = __esm(() => {
19496
19549
  init_zod();
19497
19550
  init_evidence_schema();
@@ -19521,6 +19574,11 @@ var init_manager2 = __esm(() => {
19521
19574
  medium: "moderate",
19522
19575
  high: "complex"
19523
19576
  };
19577
+ _internals4 = {
19578
+ wrapFlatRetrospective,
19579
+ loadEvidence,
19580
+ listEvidenceTaskIds
19581
+ };
19524
19582
  });
19525
19583
 
19526
19584
  // src/commands/archive.ts
@@ -19720,7 +19778,7 @@ function getProfile(directory, planId) {
19720
19778
  return row ? rowToProfile(row) : null;
19721
19779
  }
19722
19780
  function getOrCreateProfile(directory, planId, projectType) {
19723
- const existing = getProfile(directory, planId);
19781
+ const existing = _internals5.getProfile(directory, planId);
19724
19782
  if (existing)
19725
19783
  return existing;
19726
19784
  const db = getProjectDb(directory);
@@ -19736,14 +19794,14 @@ function getOrCreateProfile(directory, planId, projectType) {
19736
19794
  throw err;
19737
19795
  }
19738
19796
  }
19739
- const after = getProfile(directory, planId);
19797
+ const after = _internals5.getProfile(directory, planId);
19740
19798
  if (!after) {
19741
19799
  throw new Error(`Failed to create or load QA gate profile for plan_id=${planId}`);
19742
19800
  }
19743
19801
  return after;
19744
19802
  }
19745
19803
  function setGates(directory, planId, gates) {
19746
- const current = getProfile(directory, planId);
19804
+ const current = _internals5.getProfile(directory, planId);
19747
19805
  if (!current) {
19748
19806
  throw new Error(`No QA gate profile found for plan_id=${planId} \u2014 call getOrCreateProfile first`);
19749
19807
  }
@@ -19767,7 +19825,7 @@ function setGates(directory, planId, gates) {
19767
19825
  JSON.stringify(merged),
19768
19826
  planId
19769
19827
  ]);
19770
- const updated = getProfile(directory, planId);
19828
+ const updated = _internals5.getProfile(directory, planId);
19771
19829
  if (!updated) {
19772
19830
  throw new Error(`Failed to re-read QA gate profile after update for plan_id=${planId}`);
19773
19831
  }
@@ -19789,9 +19847,16 @@ function getEffectiveGates(profile, sessionOverrides) {
19789
19847
  }
19790
19848
  return merged;
19791
19849
  }
19792
- var DEFAULT_QA_GATES;
19850
+ var _internals5, DEFAULT_QA_GATES;
19793
19851
  var init_qa_gate_profile = __esm(() => {
19794
19852
  init_project_db();
19853
+ _internals5 = {
19854
+ getProfile,
19855
+ getOrCreateProfile,
19856
+ setGates,
19857
+ getEffectiveGates,
19858
+ computeProfileHash
19859
+ };
19795
19860
  DEFAULT_QA_GATES = {
19796
19861
  reviewer: true,
19797
19862
  test_engineer: true,
@@ -20121,6 +20186,7 @@ var init_config = __esm(() => {
20121
20186
  init_constants();
20122
20187
  init_evidence_schema();
20123
20188
  init_loader();
20189
+ init_loader();
20124
20190
  init_plan_schema();
20125
20191
  init_schema();
20126
20192
  init_spec_schema();
@@ -20245,12 +20311,15 @@ ${RESPONSE_FORMAT}
20245
20311
  ${HARD_RULES}
20246
20312
  `;
20247
20313
  });
20314
+
20315
+ // src/agents/critic.ts
20316
+ var init_critic = () => {};
20248
20317
  // src/agents/curator-agent.ts
20249
20318
  var init_curator_agent = () => {};
20250
20319
  // src/agents/reviewer.ts
20251
20320
  var init_reviewer = () => {};
20252
20321
  // src/agents/index.ts
20253
- var warnedAgents;
20322
+ var warnedAgents, KNOWN_VARIANT_VALUES;
20254
20323
  var init_agents2 = __esm(() => {
20255
20324
  init_config();
20256
20325
  init_constants();
@@ -20258,13 +20327,23 @@ var init_agents2 = __esm(() => {
20258
20327
  init_warning_buffer();
20259
20328
  init_architect();
20260
20329
  init_council_prompts();
20330
+ init_critic();
20261
20331
  init_curator_agent();
20262
20332
  init_reviewer();
20263
20333
  init_architect();
20264
20334
  init_council_prompts();
20335
+ init_critic();
20265
20336
  init_curator_agent();
20266
20337
  init_reviewer();
20267
20338
  warnedAgents = new Set;
20339
+ KNOWN_VARIANT_VALUES = new Set([
20340
+ "low",
20341
+ "medium",
20342
+ "high",
20343
+ "max",
20344
+ "xhigh",
20345
+ "thinking"
20346
+ ]);
20268
20347
  });
20269
20348
  // src/scope/scope-persistence.ts
20270
20349
  import * as fs5 from "fs";
@@ -20356,6 +20435,7 @@ function extractCurrentPhaseFromPlan(plan) {
20356
20435
  const statusText = statusMap[phase.status] || "PENDING";
20357
20436
  return `Phase ${phase.id}: ${phase.name} [${statusText}]`;
20358
20437
  }
20438
+ var init_extractors = () => {};
20359
20439
 
20360
20440
  // src/hooks/loop-detector.ts
20361
20441
  var init_loop_detector = __esm(() => {
@@ -20385,8 +20465,10 @@ var init_guardrails = __esm(() => {
20385
20465
  init_telemetry();
20386
20466
  init_utils();
20387
20467
  init_bun_compat();
20468
+ init_logger();
20388
20469
  init_conflict_resolution();
20389
20470
  init_delegation_gate();
20471
+ init_extractors();
20390
20472
  init_loop_detector();
20391
20473
  init_model_limits();
20392
20474
  init_normalize_tool_name();
@@ -20434,6 +20516,7 @@ var init_delegation_gate = __esm(() => {
20434
20516
  init_schema();
20435
20517
  init_state();
20436
20518
  init_telemetry();
20519
+ init_logger();
20437
20520
  init_guardrails();
20438
20521
  init_normalize_tool_name();
20439
20522
  init_utils2();
@@ -34022,6 +34105,19 @@ function getCurrentBranch(cwd) {
34022
34105
  const output = gitExec2(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
34023
34106
  return output.trim();
34024
34107
  }
34108
+ function getDefaultBaseBranch(cwd) {
34109
+ try {
34110
+ gitExec2(["rev-parse", "--verify", "origin/main"], cwd);
34111
+ return "origin/main";
34112
+ } catch {
34113
+ try {
34114
+ gitExec2(["rev-parse", "--verify", "origin/master"], cwd);
34115
+ return "origin/master";
34116
+ } catch {
34117
+ return "origin/main";
34118
+ }
34119
+ }
34120
+ }
34025
34121
  function hasUncommittedChanges(cwd) {
34026
34122
  const status = gitExec2(["status", "--porcelain"], cwd);
34027
34123
  return status.trim().length > 0;
@@ -34057,7 +34153,7 @@ function resetToRemoteBranch(cwd, options) {
34057
34153
  const prunedBranches = [];
34058
34154
  try {
34059
34155
  const currentBranch = getCurrentBranch(cwd);
34060
- const defaultRemoteBranch = detectDefaultRemoteBranch(cwd);
34156
+ const defaultRemoteBranch = _internals6.detectDefaultRemoteBranch(cwd);
34061
34157
  if (!defaultRemoteBranch) {
34062
34158
  return {
34063
34159
  success: false,
@@ -34236,8 +34332,16 @@ function resetToRemoteBranch(cwd, options) {
34236
34332
  };
34237
34333
  }
34238
34334
  }
34239
- var GIT_TIMEOUT_MS2 = 30000;
34240
- var init_branch = () => {};
34335
+ var GIT_TIMEOUT_MS2 = 30000, _internals6;
34336
+ var init_branch = __esm(() => {
34337
+ init_logger();
34338
+ _internals6 = {
34339
+ gitExec: gitExec2,
34340
+ detectDefaultRemoteBranch,
34341
+ getDefaultBaseBranch,
34342
+ resetToRemoteBranch
34343
+ };
34344
+ });
34241
34345
 
34242
34346
  // src/hooks/knowledge-store.ts
34243
34347
  import { existsSync as existsSync7 } from "fs";
@@ -34407,13 +34511,77 @@ var init_knowledge_store = __esm(() => {
34407
34511
  });
34408
34512
 
34409
34513
  // src/hooks/knowledge-reader.ts
34514
+ import { existsSync as existsSync8 } from "fs";
34515
+ import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
34516
+ import * as path11 from "path";
34517
+ async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
34518
+ const shownFile = path11.join(directory, ".swarm", ".knowledge-shown.json");
34519
+ try {
34520
+ if (!existsSync8(shownFile)) {
34521
+ return;
34522
+ }
34523
+ const content = await readFile4(shownFile, "utf-8");
34524
+ const shownData = JSON.parse(content);
34525
+ const shownIds = shownData[phaseInfo];
34526
+ if (!shownIds || shownIds.length === 0) {
34527
+ return;
34528
+ }
34529
+ const swarmPath = resolveSwarmKnowledgePath(directory);
34530
+ const entries = await readKnowledge(swarmPath);
34531
+ let updated = false;
34532
+ const foundInSwarm = new Set;
34533
+ for (const entry of entries) {
34534
+ if (shownIds.includes(entry.id)) {
34535
+ entry.retrieval_outcomes.applied_count++;
34536
+ if (phaseSucceeded) {
34537
+ entry.retrieval_outcomes.succeeded_after_count++;
34538
+ } else {
34539
+ entry.retrieval_outcomes.failed_after_count++;
34540
+ }
34541
+ updated = true;
34542
+ foundInSwarm.add(entry.id);
34543
+ }
34544
+ }
34545
+ if (updated) {
34546
+ await rewriteKnowledge(swarmPath, entries);
34547
+ }
34548
+ const remainingIds = shownIds.filter((id) => !foundInSwarm.has(id));
34549
+ if (remainingIds.length === 0) {
34550
+ delete shownData[phaseInfo];
34551
+ await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
34552
+ return;
34553
+ }
34554
+ const hivePath = resolveHiveKnowledgePath();
34555
+ const hiveEntries = await readKnowledge(hivePath);
34556
+ let hiveUpdated = false;
34557
+ for (const entry of hiveEntries) {
34558
+ if (remainingIds.includes(entry.id)) {
34559
+ entry.retrieval_outcomes.applied_count++;
34560
+ if (phaseSucceeded) {
34561
+ entry.retrieval_outcomes.succeeded_after_count++;
34562
+ } else {
34563
+ entry.retrieval_outcomes.failed_after_count++;
34564
+ }
34565
+ hiveUpdated = true;
34566
+ }
34567
+ }
34568
+ if (hiveUpdated) {
34569
+ await rewriteKnowledge(hivePath, hiveEntries);
34570
+ }
34571
+ delete shownData[phaseInfo];
34572
+ await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
34573
+ } catch {
34574
+ warn("[swarm] Knowledge: failed to update retrieval outcomes");
34575
+ }
34576
+ }
34410
34577
  var init_knowledge_reader = __esm(() => {
34578
+ init_logger();
34411
34579
  init_knowledge_store();
34412
34580
  });
34413
34581
 
34414
34582
  // src/hooks/knowledge-validator.ts
34415
- import { appendFile as appendFile3, mkdir as mkdir3, writeFile as writeFile4 } from "fs/promises";
34416
- import * as path11 from "path";
34583
+ import { appendFile as appendFile3, mkdir as mkdir4, writeFile as writeFile5 } from "fs/promises";
34584
+ import * as path12 from "path";
34417
34585
  function normalizeText(text) {
34418
34586
  return text.normalize("NFKC").toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
34419
34587
  }
@@ -34567,11 +34735,11 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
34567
34735
  return;
34568
34736
  }
34569
34737
  const sanitizedReason = reason.slice(0, 500).replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\x0d]/g, "");
34570
- const knowledgePath = path11.join(directory, ".swarm", "knowledge.jsonl");
34571
- const quarantinePath = path11.join(directory, ".swarm", "knowledge-quarantined.jsonl");
34572
- const rejectedPath = path11.join(directory, ".swarm", "knowledge-rejected.jsonl");
34573
- const swarmDir = path11.join(directory, ".swarm");
34574
- await mkdir3(swarmDir, { recursive: true });
34738
+ const knowledgePath = path12.join(directory, ".swarm", "knowledge.jsonl");
34739
+ const quarantinePath = path12.join(directory, ".swarm", "knowledge-quarantined.jsonl");
34740
+ const rejectedPath = path12.join(directory, ".swarm", "knowledge-rejected.jsonl");
34741
+ const swarmDir = path12.join(directory, ".swarm");
34742
+ await mkdir4(swarmDir, { recursive: true });
34575
34743
  let release;
34576
34744
  try {
34577
34745
  release = await import_proper_lockfile4.default.lock(swarmDir, {
@@ -34592,7 +34760,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
34592
34760
  const jsonlContent = remaining.length > 0 ? `${remaining.map((e) => JSON.stringify(e)).join(`
34593
34761
  `)}
34594
34762
  ` : "";
34595
- await writeFile4(knowledgePath, jsonlContent, "utf-8");
34763
+ await writeFile5(knowledgePath, jsonlContent, "utf-8");
34596
34764
  await appendFile3(quarantinePath, `${JSON.stringify(quarantined)}
34597
34765
  `, "utf-8");
34598
34766
  const quarantinedEntries = await readKnowledge(quarantinePath);
@@ -34601,7 +34769,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
34601
34769
  const capContent = trimmed.length > 0 ? `${trimmed.map((e) => JSON.stringify(e)).join(`
34602
34770
  `)}
34603
34771
  ` : "";
34604
- await writeFile4(quarantinePath, capContent, "utf-8");
34772
+ await writeFile5(quarantinePath, capContent, "utf-8");
34605
34773
  }
34606
34774
  const rejectedRecord = {
34607
34775
  id: entryId,
@@ -34627,11 +34795,11 @@ async function restoreEntry(directory, entryId) {
34627
34795
  warn("[knowledge-validator] restoreEntry: invalid entryId rejected");
34628
34796
  return;
34629
34797
  }
34630
- const knowledgePath = path11.join(directory, ".swarm", "knowledge.jsonl");
34631
- const quarantinePath = path11.join(directory, ".swarm", "knowledge-quarantined.jsonl");
34632
- const rejectedPath = path11.join(directory, ".swarm", "knowledge-rejected.jsonl");
34633
- const swarmDir = path11.join(directory, ".swarm");
34634
- await mkdir3(swarmDir, { recursive: true });
34798
+ const knowledgePath = path12.join(directory, ".swarm", "knowledge.jsonl");
34799
+ const quarantinePath = path12.join(directory, ".swarm", "knowledge-quarantined.jsonl");
34800
+ const rejectedPath = path12.join(directory, ".swarm", "knowledge-rejected.jsonl");
34801
+ const swarmDir = path12.join(directory, ".swarm");
34802
+ await mkdir4(swarmDir, { recursive: true });
34635
34803
  let release;
34636
34804
  try {
34637
34805
  release = await import_proper_lockfile4.default.lock(swarmDir, {
@@ -34647,7 +34815,7 @@ async function restoreEntry(directory, entryId) {
34647
34815
  const jsonlContent = remaining.length > 0 ? `${remaining.map((e) => JSON.stringify(e)).join(`
34648
34816
  `)}
34649
34817
  ` : "";
34650
- await writeFile4(quarantinePath, jsonlContent, "utf-8");
34818
+ await writeFile5(quarantinePath, jsonlContent, "utf-8");
34651
34819
  await appendFile3(knowledgePath, `${JSON.stringify(original)}
34652
34820
  `, "utf-8");
34653
34821
  const rejectedEntries = await readKnowledge(rejectedPath);
@@ -34655,7 +34823,7 @@ async function restoreEntry(directory, entryId) {
34655
34823
  const rejectedContent = filtered.length > 0 ? `${filtered.map((e) => JSON.stringify(e)).join(`
34656
34824
  `)}
34657
34825
  ` : "";
34658
- await writeFile4(rejectedPath, rejectedContent, "utf-8");
34826
+ await writeFile5(rejectedPath, rejectedContent, "utf-8");
34659
34827
  } finally {
34660
34828
  if (release) {
34661
34829
  await release();
@@ -34664,6 +34832,7 @@ async function restoreEntry(directory, entryId) {
34664
34832
  }
34665
34833
  var import_proper_lockfile4, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS;
34666
34834
  var init_knowledge_validator = __esm(() => {
34835
+ init_logger();
34667
34836
  init_knowledge_store();
34668
34837
  import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
34669
34838
  DANGEROUS_COMMAND_PATTERNS = [
@@ -34770,6 +34939,134 @@ var init_knowledge_validator = __esm(() => {
34770
34939
  });
34771
34940
 
34772
34941
  // src/hooks/knowledge-curator.ts
34942
+ function pruneSeenRetroSections() {
34943
+ const cutoff = Date.now() - 86400000;
34944
+ for (const [key, entry] of seenRetroSections) {
34945
+ if (entry.timestamp < cutoff) {
34946
+ seenRetroSections.delete(key);
34947
+ }
34948
+ }
34949
+ }
34950
+ function isWriteToSwarmPlan(input) {
34951
+ if (typeof input !== "object" || input === null)
34952
+ return false;
34953
+ const record3 = input;
34954
+ const toolName = record3.toolName;
34955
+ if (typeof toolName !== "string")
34956
+ return false;
34957
+ if (!["write", "edit", "apply_patch"].includes(toolName))
34958
+ return false;
34959
+ const rawPath = record3.path;
34960
+ const rawFile = record3.file;
34961
+ const pathField = typeof rawPath === "string" ? rawPath.replace(/\\/g, "/") : undefined;
34962
+ const fileField = typeof rawFile === "string" ? rawFile.replace(/\\/g, "/") : undefined;
34963
+ if (typeof pathField === "string" && pathField.includes(".swarm/plan.md")) {
34964
+ return true;
34965
+ }
34966
+ if (typeof fileField === "string" && fileField.includes(".swarm/plan.md")) {
34967
+ return true;
34968
+ }
34969
+ return false;
34970
+ }
34971
+ function isWriteToEvidenceFile(input) {
34972
+ if (typeof input !== "object" || input === null)
34973
+ return false;
34974
+ const record3 = input;
34975
+ const toolName = record3.toolName;
34976
+ if (typeof toolName !== "string")
34977
+ return false;
34978
+ if (!["write", "edit", "apply_patch"].includes(toolName))
34979
+ return false;
34980
+ const rawPath = record3.path;
34981
+ const rawFile = record3.file;
34982
+ const pathField = typeof rawPath === "string" ? rawPath.replace(/\\/g, "/") : undefined;
34983
+ const fileField = typeof rawFile === "string" ? rawFile.replace(/\\/g, "/") : undefined;
34984
+ const evidenceRegex = /\.swarm\/+evidence\/+/i;
34985
+ if (typeof pathField === "string" && evidenceRegex.test(pathField)) {
34986
+ return true;
34987
+ }
34988
+ if (typeof fileField === "string" && evidenceRegex.test(fileField)) {
34989
+ return true;
34990
+ }
34991
+ return false;
34992
+ }
34993
+ function extractRetrospectiveSection(planContent) {
34994
+ const headingRegex = /^###\s+Lessons\s+Learned$/m;
34995
+ const match = headingRegex.exec(planContent);
34996
+ if (!match)
34997
+ return null;
34998
+ const startIndex = match.index;
34999
+ const restOfContent = planContent.slice(startIndex);
35000
+ const firstNewline = restOfContent.indexOf(`
35001
+ `);
35002
+ const contentAfterHeading = firstNewline === -1 ? "" : restOfContent.slice(firstNewline + 1);
35003
+ const nextHeadingRegex = /^#{1,2}\s+/m;
35004
+ const nextMatch = nextHeadingRegex.exec(contentAfterHeading);
35005
+ let endIndex;
35006
+ if (nextMatch) {
35007
+ endIndex = startIndex + firstNewline + 1 + nextMatch.index;
35008
+ } else {
35009
+ endIndex = planContent.length;
35010
+ }
35011
+ return planContent.slice(startIndex, endIndex).trim();
35012
+ }
35013
+ function checkRetroChanged(sessionID, section) {
35014
+ const hash3 = `${section.length}:${section.slice(0, 100)}`;
35015
+ const lastSeen = seenRetroSections.get(sessionID);
35016
+ if (lastSeen?.value === hash3) {
35017
+ return false;
35018
+ }
35019
+ seenRetroSections.set(sessionID, { value: hash3, timestamp: Date.now() });
35020
+ return true;
35021
+ }
35022
+ function extractLessonsFromRetro(section) {
35023
+ const lessons = [];
35024
+ const lines = section.split(`
35025
+ `);
35026
+ for (const line of lines) {
35027
+ const trimmed = line.trim();
35028
+ const bulletMatch = /^[-*]\s+(.+)$/.exec(trimmed);
35029
+ if (bulletMatch) {
35030
+ const content = bulletMatch[1].trim();
35031
+ if (content) {
35032
+ lessons.push(content);
35033
+ }
35034
+ }
35035
+ }
35036
+ return lessons;
35037
+ }
35038
+ function extractRetractionsAndLessons(allLessons) {
35039
+ const retractions = [];
35040
+ const normalLessons = [];
35041
+ for (const lesson of allLessons) {
35042
+ const upper = lesson.trimStart().toUpperCase();
35043
+ if (upper.startsWith("RETRACT:") || upper.startsWith("BAD RULE:")) {
35044
+ const colonIdx = lesson.indexOf(":");
35045
+ const text = colonIdx !== -1 ? lesson.slice(colonIdx + 1).trim() : "";
35046
+ if (text)
35047
+ retractions.push(text);
35048
+ } else {
35049
+ normalLessons.push(lesson);
35050
+ }
35051
+ }
35052
+ return { retractions, normalLessons };
35053
+ }
35054
+ async function processRetractions(retractions, directory) {
35055
+ if (retractions.length === 0)
35056
+ return;
35057
+ const knowledgePath = resolveSwarmKnowledgePath(directory);
35058
+ const entries = await readKnowledge(knowledgePath) ?? [];
35059
+ for (const retractionText of retractions) {
35060
+ const normalizedRetraction = normalize2(retractionText);
35061
+ for (const entry of entries) {
35062
+ const normalizedLesson = normalize2(entry.lesson);
35063
+ if (normalizedLesson === normalizedRetraction) {
35064
+ await quarantineEntry(directory, entry.id, `Retracted by architect: ${retractionText}`, "architect");
35065
+ console.info(`[knowledge-curator] Quarantined entry ${entry.id}: "${entry.lesson}"`);
35066
+ }
35067
+ }
35068
+ }
35069
+ }
34773
35070
  async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, config3) {
34774
35071
  const knowledgePath = resolveSwarmKnowledgePath(directory);
34775
35072
  const existingEntries = await readKnowledge(knowledgePath) ?? [];
@@ -34852,7 +35149,7 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
34852
35149
  existingEntries.push(entry);
34853
35150
  }
34854
35151
  await enforceKnowledgeCap(knowledgePath, config3.swarm_max_entries);
34855
- await runAutoPromotion(directory, config3);
35152
+ await _internals7.runAutoPromotion(directory, config3);
34856
35153
  return { stored, skipped, rejected };
34857
35154
  }
34858
35155
  async function runAutoPromotion(directory, config3) {
@@ -34885,18 +35182,100 @@ async function runAutoPromotion(directory, config3) {
34885
35182
  await rewriteKnowledge(knowledgePath, entries);
34886
35183
  }
34887
35184
  }
34888
- var seenRetroSections;
35185
+ function createKnowledgeCuratorHook(directory, config3) {
35186
+ const handler = async (input, _output) => {
35187
+ pruneSeenRetroSections();
35188
+ if (!config3.enabled)
35189
+ return;
35190
+ if (!isWriteToSwarmPlan(input) && !isWriteToEvidenceFile(input))
35191
+ return;
35192
+ const sessionID = input?.sessionID ?? "default";
35193
+ const isEvidenceTrigger = isWriteToEvidenceFile(input) && !isWriteToSwarmPlan(input);
35194
+ if (isEvidenceTrigger) {
35195
+ const record3 = input;
35196
+ const rawPath = record3.path;
35197
+ const rawFile = record3.file;
35198
+ const filePath = typeof rawPath === "string" ? rawPath.replace(/\\/g, "/") : typeof rawFile === "string" ? rawFile.replace(/\\/g, "/") : null;
35199
+ if (!filePath)
35200
+ return;
35201
+ const evidenceKey = `evidence:${sessionID}:${filePath}`;
35202
+ const lastSeenEvidence = seenRetroSections.get(evidenceKey);
35203
+ const evidenceContent = await readSwarmFileAsync(directory, filePath.replace(/^.*\.swarm\//, ""));
35204
+ if (!evidenceContent)
35205
+ return;
35206
+ let evidenceData;
35207
+ try {
35208
+ evidenceData = JSON.parse(evidenceContent);
35209
+ } catch {
35210
+ return;
35211
+ }
35212
+ let lessons = [];
35213
+ if (Array.isArray(evidenceData.entries) && evidenceData.entries.length > 0) {
35214
+ const firstEntry = evidenceData.entries[0];
35215
+ if (Array.isArray(firstEntry.lessons_learned)) {
35216
+ lessons = firstEntry.lessons_learned;
35217
+ }
35218
+ } else if (Array.isArray(evidenceData.lessons_learned)) {
35219
+ lessons = evidenceData.lessons_learned;
35220
+ }
35221
+ if (lessons.length === 0)
35222
+ return;
35223
+ const evidenceHash = `${lessons.length}:${lessons.slice(0, 3).join("|")}`;
35224
+ if (lastSeenEvidence?.value === evidenceHash) {
35225
+ return;
35226
+ }
35227
+ seenRetroSections.set(evidenceKey, {
35228
+ value: evidenceHash,
35229
+ timestamp: Date.now()
35230
+ });
35231
+ const projectName2 = evidenceData.project_name ?? "unknown";
35232
+ const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
35233
+ await _internals7.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3);
35234
+ await updateRetrievalOutcome(directory, `Phase ${phaseNumber2}`, true);
35235
+ return;
35236
+ }
35237
+ const planContent = await readSwarmFileAsync(directory, "plan.md");
35238
+ if (!planContent)
35239
+ return;
35240
+ const section = extractRetrospectiveSection(planContent);
35241
+ if (!section)
35242
+ return;
35243
+ if (!checkRetroChanged(sessionID, section))
35244
+ return;
35245
+ const allLessons = extractLessonsFromRetro(section);
35246
+ if (allLessons.length === 0)
35247
+ return;
35248
+ const { retractions, normalLessons } = extractRetractionsAndLessons(allLessons);
35249
+ await processRetractions(retractions, directory);
35250
+ if (normalLessons.length === 0)
35251
+ return;
35252
+ const projectNameMatch = /^#\s+(.+)$/m.exec(planContent);
35253
+ const projectName = projectNameMatch ? projectNameMatch[1].trim() : "unknown";
35254
+ const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
35255
+ const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
35256
+ await _internals7.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3);
35257
+ await updateRetrievalOutcome(directory, `Phase ${phaseNumber}`, true);
35258
+ };
35259
+ return safeHook(handler);
35260
+ }
35261
+ var seenRetroSections, _internals7;
34889
35262
  var init_knowledge_curator = __esm(() => {
34890
35263
  init_knowledge_reader();
34891
35264
  init_knowledge_store();
34892
35265
  init_knowledge_validator();
34893
35266
  init_utils2();
34894
35267
  seenRetroSections = new Map;
35268
+ _internals7 = {
35269
+ isWriteToEvidenceFile,
35270
+ curateAndStoreSwarm,
35271
+ runAutoPromotion,
35272
+ createKnowledgeCuratorHook
35273
+ };
34895
35274
  });
34896
35275
 
34897
35276
  // src/session/snapshot-writer.ts
34898
35277
  import { mkdirSync as mkdirSync7, renameSync as renameSync5 } from "fs";
34899
- import * as path12 from "path";
35278
+ import * as path13 from "path";
34900
35279
  function serializeAgentSession(s) {
34901
35280
  const gateLog = {};
34902
35281
  const rawGateLog = s.gateLog ?? new Map;
@@ -34986,7 +35365,7 @@ async function writeSnapshot(directory, state) {
34986
35365
  }
34987
35366
  const content = JSON.stringify(snapshot, null, 2);
34988
35367
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
34989
- const dir = path12.dirname(resolvedPath);
35368
+ const dir = path13.dirname(resolvedPath);
34990
35369
  mkdirSync7(dir, { recursive: true });
34991
35370
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
34992
35371
  await bunWrite(tempPath, content);
@@ -34997,17 +35376,28 @@ async function writeSnapshot(directory, state) {
34997
35376
  });
34998
35377
  }
34999
35378
  }
35379
+ function createSnapshotWriterHook(directory) {
35380
+ return (_input, _output) => {
35381
+ _writeInFlight = _writeInFlight.then(() => _internals8.writeSnapshot(directory, swarmState), () => _internals8.writeSnapshot(directory, swarmState));
35382
+ return _writeInFlight;
35383
+ };
35384
+ }
35000
35385
  async function flushPendingSnapshot(directory) {
35001
- _writeInFlight = _writeInFlight.then(() => writeSnapshot(directory, swarmState), () => writeSnapshot(directory, swarmState));
35386
+ _writeInFlight = _writeInFlight.then(() => _internals8.writeSnapshot(directory, swarmState), () => _internals8.writeSnapshot(directory, swarmState));
35002
35387
  await _writeInFlight;
35003
35388
  }
35004
- var _writeInFlight;
35389
+ var _writeInFlight, _internals8;
35005
35390
  var init_snapshot_writer = __esm(() => {
35006
35391
  init_utils2();
35007
35392
  init_state();
35008
35393
  init_utils();
35009
35394
  init_bun_compat();
35010
35395
  _writeInFlight = Promise.resolve();
35396
+ _internals8 = {
35397
+ writeSnapshot,
35398
+ createSnapshotWriterHook,
35399
+ flushPendingSnapshot
35400
+ };
35011
35401
  });
35012
35402
 
35013
35403
  // src/tools/write-retro.ts
@@ -35311,7 +35701,7 @@ async function executeWriteRetro(args, directory) {
35311
35701
  }, null, 2);
35312
35702
  }
35313
35703
  }
35314
- var write_retro;
35704
+ var write_retro, _internals9;
35315
35705
  var init_write_retro = __esm(() => {
35316
35706
  init_zod();
35317
35707
  init_evidence_schema();
@@ -35358,17 +35748,21 @@ var init_write_retro = __esm(() => {
35358
35748
  task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
35359
35749
  metadata: args.metadata
35360
35750
  };
35361
- return await executeWriteRetro(writeRetroArgs, directory);
35751
+ return await _internals9.executeWriteRetro(writeRetroArgs, directory);
35362
35752
  } catch {
35363
35753
  return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
35364
35754
  }
35365
35755
  }
35366
35756
  });
35757
+ _internals9 = {
35758
+ executeWriteRetro,
35759
+ write_retro
35760
+ };
35367
35761
  });
35368
35762
 
35369
35763
  // src/commands/close.ts
35370
35764
  import { promises as fs7 } from "fs";
35371
- import path13 from "path";
35765
+ import path14 from "path";
35372
35766
  function guaranteeAllPlansComplete(planData) {
35373
35767
  const closedPhaseIds = [];
35374
35768
  const closedTaskIds = [];
@@ -35391,10 +35785,10 @@ function guaranteeAllPlansComplete(planData) {
35391
35785
  }
35392
35786
  async function handleCloseCommand(directory, args) {
35393
35787
  const planPath = validateSwarmPath(directory, "plan.json");
35394
- const swarmDir = path13.join(directory, ".swarm");
35788
+ const swarmDir = path14.join(directory, ".swarm");
35395
35789
  let planExists = false;
35396
35790
  let planData = {
35397
- title: path13.basename(directory) || "Ad-hoc session",
35791
+ title: path14.basename(directory) || "Ad-hoc session",
35398
35792
  phases: []
35399
35793
  };
35400
35794
  try {
@@ -35499,7 +35893,7 @@ async function handleCloseCommand(directory, args) {
35499
35893
  warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
35500
35894
  }
35501
35895
  }
35502
- const lessonsFilePath = path13.join(swarmDir, "close-lessons.md");
35896
+ const lessonsFilePath = path14.join(swarmDir, "close-lessons.md");
35503
35897
  let explicitLessons = [];
35504
35898
  try {
35505
35899
  const lessonsText = await fs7.readFile(lessonsFilePath, "utf-8");
@@ -35508,11 +35902,11 @@ async function handleCloseCommand(directory, args) {
35508
35902
  } catch {}
35509
35903
  const retroLessons = [];
35510
35904
  try {
35511
- const evidenceDir = path13.join(swarmDir, "evidence");
35905
+ const evidenceDir = path14.join(swarmDir, "evidence");
35512
35906
  const evidenceEntries = await fs7.readdir(evidenceDir);
35513
35907
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
35514
35908
  for (const retroDir of retroDirs) {
35515
- const evidencePath = path13.join(evidenceDir, retroDir, "evidence.json");
35909
+ const evidencePath = path14.join(evidenceDir, retroDir, "evidence.json");
35516
35910
  try {
35517
35911
  const content = await fs7.readFile(evidencePath, "utf-8");
35518
35912
  const parsed = JSON.parse(content);
@@ -35566,15 +35960,15 @@ async function handleCloseCommand(directory, args) {
35566
35960
  }
35567
35961
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
35568
35962
  const suffix = Math.random().toString(36).slice(2, 8);
35569
- const archiveDir = path13.join(swarmDir, "archive", `swarm-${timestamp}-${suffix}`);
35963
+ const archiveDir = path14.join(swarmDir, "archive", `swarm-${timestamp}-${suffix}`);
35570
35964
  let archiveResult = "";
35571
35965
  let archivedFileCount = 0;
35572
35966
  const archivedActiveStateFiles = new Set;
35573
35967
  try {
35574
35968
  await fs7.mkdir(archiveDir, { recursive: true });
35575
35969
  for (const artifact of ARCHIVE_ARTIFACTS) {
35576
- const srcPath = path13.join(swarmDir, artifact);
35577
- const destPath = path13.join(archiveDir, artifact);
35970
+ const srcPath = path14.join(swarmDir, artifact);
35971
+ const destPath = path14.join(archiveDir, artifact);
35578
35972
  try {
35579
35973
  await fs7.copyFile(srcPath, destPath);
35580
35974
  archivedFileCount++;
@@ -35583,22 +35977,22 @@ async function handleCloseCommand(directory, args) {
35583
35977
  }
35584
35978
  } catch {}
35585
35979
  }
35586
- const evidenceDir = path13.join(swarmDir, "evidence");
35587
- const archiveEvidenceDir = path13.join(archiveDir, "evidence");
35980
+ const evidenceDir = path14.join(swarmDir, "evidence");
35981
+ const archiveEvidenceDir = path14.join(archiveDir, "evidence");
35588
35982
  try {
35589
35983
  const evidenceEntries = await fs7.readdir(evidenceDir);
35590
35984
  if (evidenceEntries.length > 0) {
35591
35985
  await fs7.mkdir(archiveEvidenceDir, { recursive: true });
35592
35986
  for (const entry of evidenceEntries) {
35593
- const srcEntry = path13.join(evidenceDir, entry);
35594
- const destEntry = path13.join(archiveEvidenceDir, entry);
35987
+ const srcEntry = path14.join(evidenceDir, entry);
35988
+ const destEntry = path14.join(archiveEvidenceDir, entry);
35595
35989
  try {
35596
35990
  const stat2 = await fs7.stat(srcEntry);
35597
35991
  if (stat2.isDirectory()) {
35598
35992
  await fs7.mkdir(destEntry, { recursive: true });
35599
35993
  const subEntries = await fs7.readdir(srcEntry);
35600
35994
  for (const sub of subEntries) {
35601
- await fs7.copyFile(path13.join(srcEntry, sub), path13.join(destEntry, sub)).catch(() => {});
35995
+ await fs7.copyFile(path14.join(srcEntry, sub), path14.join(destEntry, sub)).catch(() => {});
35602
35996
  }
35603
35997
  } else {
35604
35998
  await fs7.copyFile(srcEntry, destEntry);
@@ -35608,11 +36002,11 @@ async function handleCloseCommand(directory, args) {
35608
36002
  }
35609
36003
  }
35610
36004
  } catch {}
35611
- const sessionStatePath = path13.join(swarmDir, "session", "state.json");
36005
+ const sessionStatePath = path14.join(swarmDir, "session", "state.json");
35612
36006
  try {
35613
- const archiveSessionDir = path13.join(archiveDir, "session");
36007
+ const archiveSessionDir = path14.join(archiveDir, "session");
35614
36008
  await fs7.mkdir(archiveSessionDir, { recursive: true });
35615
- await fs7.copyFile(sessionStatePath, path13.join(archiveSessionDir, "state.json"));
36009
+ await fs7.copyFile(sessionStatePath, path14.join(archiveSessionDir, "state.json"));
35616
36010
  archivedFileCount++;
35617
36011
  } catch {}
35618
36012
  archiveResult = `Archived ${archivedFileCount} artifact(s) to .swarm/archive/swarm-${timestamp}/`;
@@ -35635,7 +36029,7 @@ async function handleCloseCommand(directory, args) {
35635
36029
  warnings.push(`Preserved ${artifact} because it was not successfully archived.`);
35636
36030
  continue;
35637
36031
  }
35638
- const filePath = path13.join(swarmDir, artifact);
36032
+ const filePath = path14.join(swarmDir, artifact);
35639
36033
  try {
35640
36034
  await fs7.unlink(filePath);
35641
36035
  cleanedFiles.push(artifact);
@@ -35649,23 +36043,23 @@ async function handleCloseCommand(directory, args) {
35649
36043
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
35650
36044
  for (const backup of configBackups) {
35651
36045
  try {
35652
- await fs7.unlink(path13.join(swarmDir, backup));
36046
+ await fs7.unlink(path14.join(swarmDir, backup));
35653
36047
  configBackupsRemoved++;
35654
36048
  } catch {}
35655
36049
  }
35656
36050
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
35657
36051
  for (const sibling of ledgerSiblings) {
35658
36052
  try {
35659
- await fs7.unlink(path13.join(swarmDir, sibling));
36053
+ await fs7.unlink(path14.join(swarmDir, sibling));
35660
36054
  } catch {}
35661
36055
  }
35662
36056
  } catch {}
35663
36057
  let swarmPlanFilesRemoved = 0;
35664
36058
  const candidates = [
35665
- path13.join(directory, ".swarm", "SWARM_PLAN.json"),
35666
- path13.join(directory, ".swarm", "SWARM_PLAN.md"),
35667
- path13.join(directory, "SWARM_PLAN.json"),
35668
- path13.join(directory, "SWARM_PLAN.md")
36059
+ path14.join(directory, ".swarm", "SWARM_PLAN.json"),
36060
+ path14.join(directory, ".swarm", "SWARM_PLAN.md"),
36061
+ path14.join(directory, "SWARM_PLAN.json"),
36062
+ path14.join(directory, "SWARM_PLAN.md")
35669
36063
  ];
35670
36064
  for (const candidate of candidates) {
35671
36065
  try {
@@ -35673,12 +36067,12 @@ async function handleCloseCommand(directory, args) {
35673
36067
  swarmPlanFilesRemoved++;
35674
36068
  } catch (err) {
35675
36069
  if (err?.code !== "ENOENT") {
35676
- warnings.push(`Failed to remove ${path13.basename(candidate)}: ${err instanceof Error ? err.message : String(err)}`);
36070
+ warnings.push(`Failed to remove ${path14.basename(candidate)}: ${err instanceof Error ? err.message : String(err)}`);
35677
36071
  }
35678
36072
  }
35679
36073
  }
35680
36074
  clearAllScopes(directory);
35681
- const contextPath = path13.join(swarmDir, "context.md");
36075
+ const contextPath = path14.join(swarmDir, "context.md");
35682
36076
  const contextContent = [
35683
36077
  "# Context",
35684
36078
  "",
@@ -35847,14 +36241,14 @@ var init_close = __esm(() => {
35847
36241
 
35848
36242
  // src/commands/config.ts
35849
36243
  import * as os4 from "os";
35850
- import * as path14 from "path";
36244
+ import * as path15 from "path";
35851
36245
  function getUserConfigDir2() {
35852
- return process.env.XDG_CONFIG_HOME || path14.join(os4.homedir(), ".config");
36246
+ return process.env.XDG_CONFIG_HOME || path15.join(os4.homedir(), ".config");
35853
36247
  }
35854
36248
  async function handleConfigCommand(directory, _args) {
35855
36249
  const config3 = loadPluginConfig(directory);
35856
- const userConfigPath = path14.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
35857
- const projectConfigPath = path14.join(directory, ".opencode", "opencode-swarm.json");
36250
+ const userConfigPath = path15.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
36251
+ const projectConfigPath = path15.join(directory, ".opencode", "opencode-swarm.json");
35858
36252
  const lines = [
35859
36253
  "## Swarm Configuration",
35860
36254
  "",
@@ -36019,13 +36413,14 @@ var init_curator = __esm(() => {
36019
36413
  init_event_bus();
36020
36414
  init_manager();
36021
36415
  init_bun_compat();
36416
+ init_logger();
36022
36417
  init_knowledge_store();
36023
36418
  init_knowledge_validator();
36024
36419
  init_utils2();
36025
36420
  });
36026
36421
 
36027
36422
  // src/hooks/hive-promoter.ts
36028
- import path15 from "path";
36423
+ import path16 from "path";
36029
36424
  function isAlreadyInHive(entry, hiveEntries, threshold) {
36030
36425
  return findNearDuplicate(entry.lesson, hiveEntries, threshold) !== undefined;
36031
36426
  }
@@ -36204,7 +36599,7 @@ async function promoteToHive(directory, lesson, category) {
36204
36599
  schema_version: 1,
36205
36600
  created_at: new Date().toISOString(),
36206
36601
  updated_at: new Date().toISOString(),
36207
- source_project: path15.basename(directory) || "unknown",
36602
+ source_project: path16.basename(directory) || "unknown",
36208
36603
  encounter_score: 1
36209
36604
  };
36210
36605
  await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
@@ -36295,8 +36690,8 @@ var init_curate = __esm(() => {
36295
36690
  // src/tools/co-change-analyzer.ts
36296
36691
  import * as child_process3 from "child_process";
36297
36692
  import { randomUUID } from "crypto";
36298
- import { readdir, readFile as readFile4, stat as stat2 } from "fs/promises";
36299
- import * as path16 from "path";
36693
+ import { readdir, readFile as readFile5, stat as stat2 } from "fs/promises";
36694
+ import * as path17 from "path";
36300
36695
  import { promisify } from "util";
36301
36696
  function getExecFileAsync() {
36302
36697
  return promisify(child_process3.execFile);
@@ -36398,7 +36793,7 @@ async function scanSourceFiles(dir) {
36398
36793
  try {
36399
36794
  const entries = await readdir(dir, { withFileTypes: true });
36400
36795
  for (const entry of entries) {
36401
- const fullPath = path16.join(dir, entry.name);
36796
+ const fullPath = path17.join(dir, entry.name);
36402
36797
  if (entry.isDirectory()) {
36403
36798
  if (skipDirs.has(entry.name)) {
36404
36799
  continue;
@@ -36406,7 +36801,7 @@ async function scanSourceFiles(dir) {
36406
36801
  const subFiles = await scanSourceFiles(fullPath);
36407
36802
  results.push(...subFiles);
36408
36803
  } else if (entry.isFile()) {
36409
- const ext = path16.extname(entry.name);
36804
+ const ext = path17.extname(entry.name);
36410
36805
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
36411
36806
  results.push(fullPath);
36412
36807
  }
@@ -36420,7 +36815,7 @@ async function getStaticEdges(directory) {
36420
36815
  const sourceFiles = await scanSourceFiles(directory);
36421
36816
  for (const sourceFile of sourceFiles) {
36422
36817
  try {
36423
- const content = await readFile4(sourceFile, "utf-8");
36818
+ const content = await readFile5(sourceFile, "utf-8");
36424
36819
  const importRegex = /(?:import|require)\s*(?:\(?\s*['"`]|.*?from\s+['"`])([^'"`]+)['"`]/g;
36425
36820
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
36426
36821
  const importPath = match[1].trim();
@@ -36428,8 +36823,8 @@ async function getStaticEdges(directory) {
36428
36823
  continue;
36429
36824
  }
36430
36825
  try {
36431
- const sourceDir = path16.dirname(sourceFile);
36432
- const resolvedPath = path16.resolve(sourceDir, importPath);
36826
+ const sourceDir = path17.dirname(sourceFile);
36827
+ const resolvedPath = path17.resolve(sourceDir, importPath);
36433
36828
  const extensions = [
36434
36829
  "",
36435
36830
  ".ts",
@@ -36454,8 +36849,8 @@ async function getStaticEdges(directory) {
36454
36849
  if (!targetFile) {
36455
36850
  continue;
36456
36851
  }
36457
- const relSource = path16.relative(directory, sourceFile).replace(/\\/g, "/");
36458
- const relTarget = path16.relative(directory, targetFile).replace(/\\/g, "/");
36852
+ const relSource = path17.relative(directory, sourceFile).replace(/\\/g, "/");
36853
+ const relTarget = path17.relative(directory, targetFile).replace(/\\/g, "/");
36459
36854
  const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
36460
36855
  edges.add(key);
36461
36856
  } catch {}
@@ -36467,7 +36862,7 @@ async function getStaticEdges(directory) {
36467
36862
  function isTestImplementationPair(fileA, fileB) {
36468
36863
  const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
36469
36864
  const getBaseName = (filePath) => {
36470
- const base = path16.basename(filePath);
36865
+ const base = path17.basename(filePath);
36471
36866
  for (const pattern of testPatterns) {
36472
36867
  if (base.endsWith(pattern)) {
36473
36868
  return base.slice(0, -pattern.length);
@@ -36477,16 +36872,16 @@ function isTestImplementationPair(fileA, fileB) {
36477
36872
  };
36478
36873
  const baseA = getBaseName(fileA);
36479
36874
  const baseB = getBaseName(fileB);
36480
- return baseA === baseB && baseA !== path16.basename(fileA) && baseA !== path16.basename(fileB);
36875
+ return baseA === baseB && baseA !== path17.basename(fileA) && baseA !== path17.basename(fileB);
36481
36876
  }
36482
36877
  function hasSharedPrefix(fileA, fileB) {
36483
- const dirA = path16.dirname(fileA);
36484
- const dirB = path16.dirname(fileB);
36878
+ const dirA = path17.dirname(fileA);
36879
+ const dirB = path17.dirname(fileB);
36485
36880
  if (dirA !== dirB) {
36486
36881
  return false;
36487
36882
  }
36488
- const baseA = path16.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
36489
- const baseB = path16.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
36883
+ const baseA = path17.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
36884
+ const baseB = path17.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
36490
36885
  if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
36491
36886
  return true;
36492
36887
  }
@@ -36514,9 +36909,9 @@ async function detectDarkMatter(directory, options) {
36514
36909
  } catch {
36515
36910
  return [];
36516
36911
  }
36517
- const commitMap = await parseGitLog(directory, maxCommitsToAnalyze);
36518
- const matrix = buildCoChangeMatrix(commitMap);
36519
- const staticEdges = await getStaticEdges(directory);
36912
+ const commitMap = await _internals10.parseGitLog(directory, maxCommitsToAnalyze);
36913
+ const matrix = _internals10.buildCoChangeMatrix(commitMap);
36914
+ const staticEdges = await _internals10.getStaticEdges(directory);
36520
36915
  const results = [];
36521
36916
  for (const entry of matrix.values()) {
36522
36917
  const key = `${entry.fileA}::${entry.fileB}`;
@@ -36540,8 +36935,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
36540
36935
  const entries = [];
36541
36936
  const now = new Date().toISOString();
36542
36937
  for (const pair of pairs.slice(0, 10)) {
36543
- const baseA = path16.basename(pair.fileA);
36544
- const baseB = path16.basename(pair.fileB);
36938
+ const baseA = path17.basename(pair.fileA);
36939
+ const baseB = path17.basename(pair.fileB);
36545
36940
  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.`;
36546
36941
  if (lesson.length > 280) {
36547
36942
  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.`;
@@ -36596,7 +36991,7 @@ ${rows}
36596
36991
  These pairs likely share an architectural concern invisible to static analysis.
36597
36992
  Consider adding explicit documentation or extracting the shared concern.`;
36598
36993
  }
36599
- var co_change_analyzer;
36994
+ var co_change_analyzer, _internals10;
36600
36995
  var init_co_change_analyzer = __esm(() => {
36601
36996
  init_zod();
36602
36997
  init_create_tool();
@@ -36628,14 +37023,22 @@ var init_co_change_analyzer = __esm(() => {
36628
37023
  npmiThreshold,
36629
37024
  maxCommitsToAnalyze
36630
37025
  };
36631
- const pairs = await detectDarkMatter(directory, options);
36632
- return formatDarkMatterOutput(pairs);
37026
+ const pairs = await _internals10.detectDarkMatter(directory, options);
37027
+ return _internals10.formatDarkMatterOutput(pairs);
36633
37028
  }
36634
37029
  });
37030
+ _internals10 = {
37031
+ parseGitLog,
37032
+ buildCoChangeMatrix,
37033
+ getStaticEdges,
37034
+ detectDarkMatter,
37035
+ darkMatterToKnowledgeEntries,
37036
+ formatDarkMatterOutput
37037
+ };
36635
37038
  });
36636
37039
 
36637
37040
  // src/commands/dark-matter.ts
36638
- import path17 from "path";
37041
+ import path18 from "path";
36639
37042
  async function handleDarkMatterCommand(directory, args) {
36640
37043
  const options = {};
36641
37044
  for (let i = 0;i < args.length; i++) {
@@ -36657,7 +37060,7 @@ async function handleDarkMatterCommand(directory, args) {
36657
37060
  const output = formatDarkMatterOutput(pairs);
36658
37061
  if (pairs.length > 0) {
36659
37062
  try {
36660
- const projectName = path17.basename(path17.resolve(directory));
37063
+ const projectName = path18.basename(path18.resolve(directory));
36661
37064
  const entries = darkMatterToKnowledgeEntries(pairs, projectName);
36662
37065
  if (entries.length > 0) {
36663
37066
  const knowledgePath = resolveSwarmKnowledgePath(directory);
@@ -36682,67 +37085,67 @@ var init_dark_matter = __esm(() => {
36682
37085
 
36683
37086
  // src/config/cache-paths.ts
36684
37087
  import * as os5 from "os";
36685
- import * as path18 from "path";
37088
+ import * as path19 from "path";
36686
37089
  function getPluginConfigDir() {
36687
- return path18.join(process.env.XDG_CONFIG_HOME || path18.join(os5.homedir(), ".config"), "opencode");
37090
+ return path19.join(process.env.XDG_CONFIG_HOME || path19.join(os5.homedir(), ".config"), "opencode");
36688
37091
  }
36689
37092
  function getPluginCachePaths() {
36690
- const cacheBase = process.env.XDG_CACHE_HOME || path18.join(os5.homedir(), ".cache");
37093
+ const cacheBase = process.env.XDG_CACHE_HOME || path19.join(os5.homedir(), ".cache");
36691
37094
  const configDir = getPluginConfigDir();
36692
37095
  const paths = [
36693
- path18.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
36694
- path18.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
36695
- path18.join(configDir, "node_modules", "opencode-swarm")
37096
+ path19.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
37097
+ path19.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
37098
+ path19.join(configDir, "node_modules", "opencode-swarm")
36696
37099
  ];
36697
37100
  if (process.platform === "darwin") {
36698
- const libCaches = path18.join(os5.homedir(), "Library", "Caches");
36699
- paths.push(path18.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path18.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
37101
+ const libCaches = path19.join(os5.homedir(), "Library", "Caches");
37102
+ paths.push(path19.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path19.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
36700
37103
  }
36701
37104
  if (process.platform === "win32") {
36702
- const localAppData = process.env.LOCALAPPDATA || path18.join(os5.homedir(), "AppData", "Local");
36703
- const appData = process.env.APPDATA || path18.join(os5.homedir(), "AppData", "Roaming");
36704
- paths.push(path18.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path18.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path18.join(appData, "opencode", "node_modules", "opencode-swarm"));
37105
+ const localAppData = process.env.LOCALAPPDATA || path19.join(os5.homedir(), "AppData", "Local");
37106
+ const appData = process.env.APPDATA || path19.join(os5.homedir(), "AppData", "Roaming");
37107
+ paths.push(path19.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path19.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path19.join(appData, "opencode", "node_modules", "opencode-swarm"));
36705
37108
  }
36706
37109
  return paths;
36707
37110
  }
36708
37111
  function getPluginLockFilePaths() {
36709
- const cacheBase = process.env.XDG_CACHE_HOME || path18.join(os5.homedir(), ".cache");
37112
+ const cacheBase = process.env.XDG_CACHE_HOME || path19.join(os5.homedir(), ".cache");
36710
37113
  const configDir = getPluginConfigDir();
36711
37114
  const paths = [
36712
- path18.join(cacheBase, "opencode", "bun.lock"),
36713
- path18.join(cacheBase, "opencode", "bun.lockb"),
36714
- path18.join(configDir, "package-lock.json")
37115
+ path19.join(cacheBase, "opencode", "bun.lock"),
37116
+ path19.join(cacheBase, "opencode", "bun.lockb"),
37117
+ path19.join(configDir, "package-lock.json")
36715
37118
  ];
36716
37119
  if (process.platform === "darwin") {
36717
- const libCaches = path18.join(os5.homedir(), "Library", "Caches");
36718
- paths.push(path18.join(libCaches, "opencode", "bun.lock"), path18.join(libCaches, "opencode", "bun.lockb"));
37120
+ const libCaches = path19.join(os5.homedir(), "Library", "Caches");
37121
+ paths.push(path19.join(libCaches, "opencode", "bun.lock"), path19.join(libCaches, "opencode", "bun.lockb"));
36719
37122
  }
36720
37123
  if (process.platform === "win32") {
36721
- const localAppData = process.env.LOCALAPPDATA || path18.join(os5.homedir(), "AppData", "Local");
36722
- paths.push(path18.join(localAppData, "opencode", "bun.lock"), path18.join(localAppData, "opencode", "bun.lockb"));
37124
+ const localAppData = process.env.LOCALAPPDATA || path19.join(os5.homedir(), "AppData", "Local");
37125
+ paths.push(path19.join(localAppData, "opencode", "bun.lock"), path19.join(localAppData, "opencode", "bun.lockb"));
36723
37126
  }
36724
37127
  return paths;
36725
37128
  }
36726
37129
  var init_cache_paths = () => {};
36727
37130
 
36728
37131
  // src/services/version-check.ts
36729
- import { existsSync as existsSync8, mkdirSync as mkdirSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
37132
+ import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
36730
37133
  import { homedir as homedir5 } from "os";
36731
- import { join as join16 } from "path";
37134
+ import { join as join17 } from "path";
36732
37135
  function cacheDir() {
36733
37136
  const xdg = process.env.XDG_CACHE_HOME;
36734
- const base = xdg && xdg.length > 0 ? xdg : join16(homedir5(), ".cache");
36735
- return join16(base, "opencode-swarm");
37137
+ const base = xdg && xdg.length > 0 ? xdg : join17(homedir5(), ".cache");
37138
+ return join17(base, "opencode-swarm");
36736
37139
  }
36737
37140
  function cacheFile() {
36738
- return join16(cacheDir(), "version-check.json");
37141
+ return join17(cacheDir(), "version-check.json");
36739
37142
  }
36740
37143
  function readVersionCache() {
36741
37144
  try {
36742
- const path19 = cacheFile();
36743
- if (!existsSync8(path19))
37145
+ const path20 = cacheFile();
37146
+ if (!existsSync9(path20))
36744
37147
  return null;
36745
- const raw = readFileSync5(path19, "utf-8");
37148
+ const raw = readFileSync5(path20, "utf-8");
36746
37149
  const parsed = JSON.parse(raw);
36747
37150
  if (typeof parsed?.checkedAt !== "number")
36748
37151
  return null;
@@ -36781,8 +37184,8 @@ var init_version_check = __esm(() => {
36781
37184
 
36782
37185
  // src/services/diagnose-service.ts
36783
37186
  import * as child_process4 from "child_process";
36784
- import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync6 } from "fs";
36785
- import path19 from "path";
37187
+ import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync6 } from "fs";
37188
+ import path20 from "path";
36786
37189
  import { fileURLToPath } from "url";
36787
37190
  function validateTaskDag(plan) {
36788
37191
  const allTaskIds = new Set;
@@ -37015,7 +37418,7 @@ async function checkConfigBackups(directory) {
37015
37418
  }
37016
37419
  async function checkGitRepository(directory) {
37017
37420
  try {
37018
- if (!existsSync9(directory) || !statSync6(directory).isDirectory()) {
37421
+ if (!existsSync10(directory) || !statSync6(directory).isDirectory()) {
37019
37422
  return {
37020
37423
  name: "Git Repository",
37021
37424
  status: "\u274C",
@@ -37079,8 +37482,8 @@ async function checkSpecStaleness(directory, plan) {
37079
37482
  };
37080
37483
  }
37081
37484
  async function checkConfigParseability(directory) {
37082
- const configPath = path19.join(directory, ".opencode/opencode-swarm.json");
37083
- if (!existsSync9(configPath)) {
37485
+ const configPath = path20.join(directory, ".opencode/opencode-swarm.json");
37486
+ if (!existsSync10(configPath)) {
37084
37487
  return {
37085
37488
  name: "Config Parseability",
37086
37489
  status: "\u2705",
@@ -37108,7 +37511,7 @@ function resolveGrammarDir(thisDir) {
37108
37511
  const normalized = thisDir.replace(/\\/g, "/");
37109
37512
  const isSource = normalized.endsWith("/src/services");
37110
37513
  const isCliBundle = normalized.endsWith("/cli");
37111
- return isSource || isCliBundle ? path19.join(thisDir, "..", "lang", "grammars") : path19.join(thisDir, "lang", "grammars");
37514
+ return isSource || isCliBundle ? path20.join(thisDir, "..", "lang", "grammars") : path20.join(thisDir, "lang", "grammars");
37112
37515
  }
37113
37516
  async function checkGrammarWasmFiles() {
37114
37517
  const grammarFiles = [
@@ -37132,14 +37535,14 @@ async function checkGrammarWasmFiles() {
37132
37535
  "tree-sitter-ini.wasm",
37133
37536
  "tree-sitter-regex.wasm"
37134
37537
  ];
37135
- const thisDir = path19.dirname(fileURLToPath(import.meta.url));
37538
+ const thisDir = path20.dirname(fileURLToPath(import.meta.url));
37136
37539
  const grammarDir = resolveGrammarDir(thisDir);
37137
37540
  const missing = [];
37138
- if (!existsSync9(path19.join(grammarDir, "tree-sitter.wasm"))) {
37541
+ if (!existsSync10(path20.join(grammarDir, "tree-sitter.wasm"))) {
37139
37542
  missing.push("tree-sitter.wasm (core runtime)");
37140
37543
  }
37141
37544
  for (const file3 of grammarFiles) {
37142
- if (!existsSync9(path19.join(grammarDir, file3))) {
37545
+ if (!existsSync10(path20.join(grammarDir, file3))) {
37143
37546
  missing.push(file3);
37144
37547
  }
37145
37548
  }
@@ -37157,8 +37560,8 @@ async function checkGrammarWasmFiles() {
37157
37560
  };
37158
37561
  }
37159
37562
  async function checkCheckpointManifest(directory) {
37160
- const manifestPath = path19.join(directory, ".swarm/checkpoints.json");
37161
- if (!existsSync9(manifestPath)) {
37563
+ const manifestPath = path20.join(directory, ".swarm/checkpoints.json");
37564
+ if (!existsSync10(manifestPath)) {
37162
37565
  return {
37163
37566
  name: "Checkpoint Manifest",
37164
37567
  status: "\u2705",
@@ -37209,8 +37612,8 @@ async function checkCheckpointManifest(directory) {
37209
37612
  }
37210
37613
  }
37211
37614
  async function checkEventStreamIntegrity(directory) {
37212
- const eventsPath = path19.join(directory, ".swarm/events.jsonl");
37213
- if (!existsSync9(eventsPath)) {
37615
+ const eventsPath = path20.join(directory, ".swarm/events.jsonl");
37616
+ if (!existsSync10(eventsPath)) {
37214
37617
  return {
37215
37618
  name: "Event Stream",
37216
37619
  status: "\u2705",
@@ -37250,8 +37653,8 @@ async function checkEventStreamIntegrity(directory) {
37250
37653
  }
37251
37654
  }
37252
37655
  async function checkSteeringDirectives(directory) {
37253
- const eventsPath = path19.join(directory, ".swarm/events.jsonl");
37254
- if (!existsSync9(eventsPath)) {
37656
+ const eventsPath = path20.join(directory, ".swarm/events.jsonl");
37657
+ if (!existsSync10(eventsPath)) {
37255
37658
  return {
37256
37659
  name: "Steering Directives",
37257
37660
  status: "\u2705",
@@ -37306,8 +37709,8 @@ async function checkCurator(directory) {
37306
37709
  detail: "Disabled (enable via curator.enabled)"
37307
37710
  };
37308
37711
  }
37309
- const summaryPath = path19.join(directory, ".swarm/curator-summary.json");
37310
- if (!existsSync9(summaryPath)) {
37712
+ const summaryPath = path20.join(directory, ".swarm/curator-summary.json");
37713
+ if (!existsSync10(summaryPath)) {
37311
37714
  return {
37312
37715
  name: "Curator",
37313
37716
  status: "\u2705",
@@ -37472,8 +37875,8 @@ async function getDiagnoseData(directory) {
37472
37875
  checks5.push(await checkSteeringDirectives(directory));
37473
37876
  checks5.push(await checkCurator(directory));
37474
37877
  try {
37475
- const evidenceDir = path19.join(directory, ".swarm", "evidence");
37476
- const snapshotFiles = existsSync9(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
37878
+ const evidenceDir = path20.join(directory, ".swarm", "evidence");
37879
+ const snapshotFiles = existsSync10(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
37477
37880
  if (snapshotFiles.length > 0) {
37478
37881
  const latest = snapshotFiles.sort().pop();
37479
37882
  checks5.push({
@@ -37506,11 +37909,11 @@ async function getDiagnoseData(directory) {
37506
37909
  const cacheRows = [];
37507
37910
  for (const cachePath of cachePaths) {
37508
37911
  try {
37509
- if (!existsSync9(cachePath)) {
37912
+ if (!existsSync10(cachePath)) {
37510
37913
  cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
37511
37914
  continue;
37512
37915
  }
37513
- const pkgJsonPath = path19.join(cachePath, "package.json");
37916
+ const pkgJsonPath = path20.join(cachePath, "package.json");
37514
37917
  try {
37515
37918
  const raw = readFileSync6(pkgJsonPath, "utf-8");
37516
37919
  const parsed = JSON.parse(raw);
@@ -37598,13 +38001,13 @@ __export(exports_config_doctor, {
37598
38001
  import * as crypto3 from "crypto";
37599
38002
  import * as fs8 from "fs";
37600
38003
  import * as os6 from "os";
37601
- import * as path20 from "path";
38004
+ import * as path21 from "path";
37602
38005
  function getUserConfigDir3() {
37603
- return process.env.XDG_CONFIG_HOME || path20.join(os6.homedir(), ".config");
38006
+ return process.env.XDG_CONFIG_HOME || path21.join(os6.homedir(), ".config");
37604
38007
  }
37605
38008
  function getConfigPaths(directory) {
37606
- const userConfigPath = path20.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
37607
- const projectConfigPath = path20.join(directory, ".opencode", "opencode-swarm.json");
38009
+ const userConfigPath = path21.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
38010
+ const projectConfigPath = path21.join(directory, ".opencode", "opencode-swarm.json");
37608
38011
  return { userConfigPath, projectConfigPath };
37609
38012
  }
37610
38013
  function computeHash(content) {
@@ -37629,9 +38032,9 @@ function isValidConfigPath(configPath, directory) {
37629
38032
  const normalizedUser = userConfigPath.replace(/\\/g, "/");
37630
38033
  const normalizedProject = projectConfigPath.replace(/\\/g, "/");
37631
38034
  try {
37632
- const resolvedConfig = path20.resolve(configPath);
37633
- const resolvedUser = path20.resolve(normalizedUser);
37634
- const resolvedProject = path20.resolve(normalizedProject);
38035
+ const resolvedConfig = path21.resolve(configPath);
38036
+ const resolvedUser = path21.resolve(normalizedUser);
38037
+ const resolvedProject = path21.resolve(normalizedProject);
37635
38038
  return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
37636
38039
  } catch {
37637
38040
  return false;
@@ -37671,12 +38074,12 @@ function createConfigBackup(directory) {
37671
38074
  };
37672
38075
  }
37673
38076
  function writeBackupArtifact(directory, backup) {
37674
- const swarmDir = path20.join(directory, ".swarm");
38077
+ const swarmDir = path21.join(directory, ".swarm");
37675
38078
  if (!fs8.existsSync(swarmDir)) {
37676
38079
  fs8.mkdirSync(swarmDir, { recursive: true });
37677
38080
  }
37678
38081
  const backupFilename = `config-backup-${backup.createdAt}.json`;
37679
- const backupPath = path20.join(swarmDir, backupFilename);
38082
+ const backupPath = path21.join(swarmDir, backupFilename);
37680
38083
  const artifact = {
37681
38084
  createdAt: backup.createdAt,
37682
38085
  configPath: backup.configPath,
@@ -37706,7 +38109,7 @@ function restoreFromBackup(backupPath, directory) {
37706
38109
  return null;
37707
38110
  }
37708
38111
  const targetPath = artifact.configPath;
37709
- const targetDir = path20.dirname(targetPath);
38112
+ const targetDir = path21.dirname(targetPath);
37710
38113
  if (!fs8.existsSync(targetDir)) {
37711
38114
  fs8.mkdirSync(targetDir, { recursive: true });
37712
38115
  }
@@ -37737,9 +38140,9 @@ function readConfigFromFile(directory) {
37737
38140
  return null;
37738
38141
  }
37739
38142
  }
37740
- function validateConfigKey(path21, value, _config) {
38143
+ function validateConfigKey(path22, value, _config) {
37741
38144
  const findings = [];
37742
- switch (path21) {
38145
+ switch (path22) {
37743
38146
  case "agents": {
37744
38147
  if (value !== undefined) {
37745
38148
  findings.push({
@@ -37986,27 +38389,27 @@ function validateConfigKey(path21, value, _config) {
37986
38389
  }
37987
38390
  return findings;
37988
38391
  }
37989
- function walkConfigAndValidate(obj, path21, config3, findings) {
38392
+ function walkConfigAndValidate(obj, path22, config3, findings) {
37990
38393
  if (obj === null || obj === undefined) {
37991
38394
  return;
37992
38395
  }
37993
- if (path21 && typeof obj === "object" && !Array.isArray(obj)) {
37994
- const keyFindings = validateConfigKey(path21, obj, config3);
38396
+ if (path22 && typeof obj === "object" && !Array.isArray(obj)) {
38397
+ const keyFindings = validateConfigKey(path22, obj, config3);
37995
38398
  findings.push(...keyFindings);
37996
38399
  }
37997
38400
  if (typeof obj !== "object") {
37998
- const keyFindings = validateConfigKey(path21, obj, config3);
38401
+ const keyFindings = validateConfigKey(path22, obj, config3);
37999
38402
  findings.push(...keyFindings);
38000
38403
  return;
38001
38404
  }
38002
38405
  if (Array.isArray(obj)) {
38003
38406
  obj.forEach((item, index) => {
38004
- walkConfigAndValidate(item, `${path21}[${index}]`, config3, findings);
38407
+ walkConfigAndValidate(item, `${path22}[${index}]`, config3, findings);
38005
38408
  });
38006
38409
  return;
38007
38410
  }
38008
38411
  for (const [key, value] of Object.entries(obj)) {
38009
- const newPath = path21 ? `${path21}.${key}` : key;
38412
+ const newPath = path22 ? `${path22}.${key}` : key;
38010
38413
  walkConfigAndValidate(value, newPath, config3, findings);
38011
38414
  }
38012
38415
  }
@@ -38126,7 +38529,7 @@ function applySafeAutoFixes(directory, result) {
38126
38529
  }
38127
38530
  }
38128
38531
  if (appliedFixes.length > 0) {
38129
- const configDir = path20.dirname(configPath);
38532
+ const configDir = path21.dirname(configPath);
38130
38533
  if (!fs8.existsSync(configDir)) {
38131
38534
  fs8.mkdirSync(configDir, { recursive: true });
38132
38535
  }
@@ -38136,12 +38539,12 @@ function applySafeAutoFixes(directory, result) {
38136
38539
  return { appliedFixes, updatedConfigPath };
38137
38540
  }
38138
38541
  function writeDoctorArtifact(directory, result) {
38139
- const swarmDir = path20.join(directory, ".swarm");
38542
+ const swarmDir = path21.join(directory, ".swarm");
38140
38543
  if (!fs8.existsSync(swarmDir)) {
38141
38544
  fs8.mkdirSync(swarmDir, { recursive: true });
38142
38545
  }
38143
38546
  const artifactFilename = "config-doctor.json";
38144
- const artifactPath = path20.join(swarmDir, artifactFilename);
38547
+ const artifactPath = path21.join(swarmDir, artifactFilename);
38145
38548
  const guiOutput = {
38146
38549
  timestamp: result.timestamp,
38147
38550
  summary: result.summary,
@@ -39188,7 +39591,7 @@ var init_profiles = __esm(() => {
39188
39591
 
39189
39592
  // src/lang/detector.ts
39190
39593
  import { access as access3, readdir as readdir2 } from "fs/promises";
39191
- import { extname as extname2, join as join18 } from "path";
39594
+ import { extname as extname2, join as join19 } from "path";
39192
39595
  async function detectProjectLanguages(projectDir) {
39193
39596
  const detected = new Set;
39194
39597
  async function scanDir(dir) {
@@ -39204,7 +39607,7 @@ async function detectProjectLanguages(projectDir) {
39204
39607
  if (detectFile.includes("*") || detectFile.includes("?"))
39205
39608
  continue;
39206
39609
  try {
39207
- await access3(join18(dir, detectFile));
39610
+ await access3(join19(dir, detectFile));
39208
39611
  detected.add(profile.id);
39209
39612
  break;
39210
39613
  } catch {}
@@ -39225,7 +39628,7 @@ async function detectProjectLanguages(projectDir) {
39225
39628
  const topEntries = await readdir2(projectDir, { withFileTypes: true });
39226
39629
  for (const entry of topEntries) {
39227
39630
  if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
39228
- await scanDir(join18(projectDir, entry.name));
39631
+ await scanDir(join19(projectDir, entry.name));
39229
39632
  }
39230
39633
  }
39231
39634
  } catch {}
@@ -39244,7 +39647,7 @@ var init_detector = __esm(() => {
39244
39647
 
39245
39648
  // src/build/discovery.ts
39246
39649
  import * as fs9 from "fs";
39247
- import * as path21 from "path";
39650
+ import * as path22 from "path";
39248
39651
  function isCommandAvailable(command) {
39249
39652
  if (toolchainCache.has(command)) {
39250
39653
  return toolchainCache.get(command);
@@ -39276,11 +39679,11 @@ function findBuildFiles(workingDir, patterns) {
39276
39679
  const regex = simpleGlobToRegex(pattern);
39277
39680
  const matches = files.filter((f) => regex.test(f));
39278
39681
  if (matches.length > 0) {
39279
- return path21.join(dir, matches[0]);
39682
+ return path22.join(dir, matches[0]);
39280
39683
  }
39281
39684
  } catch {}
39282
39685
  } else {
39283
- const filePath = path21.join(workingDir, pattern);
39686
+ const filePath = path22.join(workingDir, pattern);
39284
39687
  if (fs9.existsSync(filePath)) {
39285
39688
  return filePath;
39286
39689
  }
@@ -39289,7 +39692,7 @@ function findBuildFiles(workingDir, patterns) {
39289
39692
  return null;
39290
39693
  }
39291
39694
  function getRepoDefinedScripts(workingDir, scripts) {
39292
- const packageJsonPath = path21.join(workingDir, "package.json");
39695
+ const packageJsonPath = path22.join(workingDir, "package.json");
39293
39696
  if (!fs9.existsSync(packageJsonPath)) {
39294
39697
  return [];
39295
39698
  }
@@ -39330,7 +39733,7 @@ function findAllBuildFiles(workingDir) {
39330
39733
  const regex = simpleGlobToRegex(pattern);
39331
39734
  findFilesRecursive(workingDir, regex, allBuildFiles);
39332
39735
  } else {
39333
- const filePath = path21.join(workingDir, pattern);
39736
+ const filePath = path22.join(workingDir, pattern);
39334
39737
  if (fs9.existsSync(filePath)) {
39335
39738
  allBuildFiles.add(filePath);
39336
39739
  }
@@ -39343,7 +39746,7 @@ function findFilesRecursive(dir, regex, results) {
39343
39746
  try {
39344
39747
  const entries = fs9.readdirSync(dir, { withFileTypes: true });
39345
39748
  for (const entry of entries) {
39346
- const fullPath = path21.join(dir, entry.name);
39749
+ const fullPath = path22.join(dir, entry.name);
39347
39750
  if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
39348
39751
  findFilesRecursive(fullPath, regex, results);
39349
39752
  } else if (entry.isFile() && regex.test(entry.name)) {
@@ -39366,7 +39769,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
39366
39769
  let foundCommand = false;
39367
39770
  for (const cmd of sortedCommands) {
39368
39771
  if (cmd.detectFile) {
39369
- const detectFilePath = path21.join(workingDir, cmd.detectFile);
39772
+ const detectFilePath = path22.join(workingDir, cmd.detectFile);
39370
39773
  if (!fs9.existsSync(detectFilePath)) {
39371
39774
  continue;
39372
39775
  }
@@ -39399,7 +39802,7 @@ async function discoverBuildCommands(workingDir, options) {
39399
39802
  const scope = options?.scope ?? "all";
39400
39803
  const changedFiles = options?.changedFiles ?? [];
39401
39804
  const _filesToCheck = filterByScope(workingDir, scope, changedFiles);
39402
- const profileResult = await discoverBuildCommandsFromProfiles(workingDir);
39805
+ const profileResult = await _internals11.discoverBuildCommandsFromProfiles(workingDir);
39403
39806
  const profileCommands = profileResult.commands;
39404
39807
  const profileSkipped = profileResult.skipped;
39405
39808
  const coveredEcosystems = new Set;
@@ -39456,7 +39859,13 @@ async function discoverBuildCommands(workingDir, options) {
39456
39859
  commands.sort((a, b) => a.priority - b.priority);
39457
39860
  return { commands, skipped };
39458
39861
  }
39459
- var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, build_discovery;
39862
+ function clearToolchainCache() {
39863
+ toolchainCache.clear();
39864
+ }
39865
+ function getEcosystems() {
39866
+ return ECOSYSTEMS.map((e) => e.ecosystem);
39867
+ }
39868
+ var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, _internals11, build_discovery;
39460
39869
  var init_discovery = __esm(() => {
39461
39870
  init_dist();
39462
39871
  init_detector();
@@ -39574,6 +39983,13 @@ var init_discovery = __esm(() => {
39574
39983
  php: ["php-composer"]
39575
39984
  };
39576
39985
  toolchainCache = new Map;
39986
+ _internals11 = {
39987
+ isCommandAvailable,
39988
+ discoverBuildCommandsFromProfiles,
39989
+ discoverBuildCommands,
39990
+ clearToolchainCache,
39991
+ getEcosystems
39992
+ };
39577
39993
  build_discovery = tool({
39578
39994
  description: "Discover build commands for various ecosystems in a project directory",
39579
39995
  args: {
@@ -39593,7 +40009,7 @@ var init_discovery = __esm(() => {
39593
40009
 
39594
40010
  // src/services/tool-doctor.ts
39595
40011
  import * as fs10 from "fs";
39596
- import * as path22 from "path";
40012
+ import * as path23 from "path";
39597
40013
  function extractRegisteredToolKeys(indexPath) {
39598
40014
  const registeredKeys = new Set;
39599
40015
  try {
@@ -39648,8 +40064,8 @@ function checkBinaryReadiness() {
39648
40064
  }
39649
40065
  function runToolDoctor(_directory, pluginRoot) {
39650
40066
  const findings = [];
39651
- const resolvedPluginRoot = pluginRoot ?? path22.resolve(import.meta.dir, "..", "..");
39652
- const indexPath = path22.join(resolvedPluginRoot, "src", "index.ts");
40067
+ const resolvedPluginRoot = pluginRoot ?? path23.resolve(import.meta.dir, "..", "..");
40068
+ const indexPath = path23.join(resolvedPluginRoot, "src", "index.ts");
39653
40069
  if (!fs10.existsSync(indexPath)) {
39654
40070
  return {
39655
40071
  findings: [
@@ -39819,6 +40235,7 @@ var exports_evidence_summary_service = {};
39819
40235
  __export(exports_evidence_summary_service, {
39820
40236
  isAutoSummaryEnabled: () => isAutoSummaryEnabled,
39821
40237
  buildEvidenceSummary: () => buildEvidenceSummary,
40238
+ _internals: () => _internals12,
39822
40239
  REQUIRED_EVIDENCE_TYPES: () => REQUIRED_EVIDENCE_TYPES,
39823
40240
  EVIDENCE_SUMMARY_VERSION: () => EVIDENCE_SUMMARY_VERSION
39824
40241
  });
@@ -39856,14 +40273,14 @@ function getTaskStatus(task, bundle) {
39856
40273
  if (task?.status) {
39857
40274
  return task.status;
39858
40275
  }
39859
- const entries = normalizeBundleEntries(bundle);
40276
+ const entries = _internals12.normalizeBundleEntries(bundle);
39860
40277
  if (entries.length > 0) {
39861
40278
  return "completed";
39862
40279
  }
39863
40280
  return "pending";
39864
40281
  }
39865
40282
  function isEvidenceComplete(bundle) {
39866
- const entries = normalizeBundleEntries(bundle);
40283
+ const entries = _internals12.normalizeBundleEntries(bundle);
39867
40284
  if (entries.length === 0) {
39868
40285
  return {
39869
40286
  isComplete: false,
@@ -39899,10 +40316,10 @@ async function buildTaskSummary(directory, task, taskId) {
39899
40316
  const result = await loadEvidence(directory, taskId);
39900
40317
  const bundle = result.status === "found" ? result.bundle : null;
39901
40318
  const phase = task?.phase ?? 0;
39902
- const status = getTaskStatus(task, bundle);
39903
- const evidenceCheck = isEvidenceComplete(bundle);
39904
- const blockers = getTaskBlockers(task, evidenceCheck, status);
39905
- const entries = normalizeBundleEntries(bundle);
40319
+ const status = _internals12.getTaskStatus(task, bundle);
40320
+ const evidenceCheck = _internals12.isEvidenceComplete(bundle);
40321
+ const blockers = _internals12.getTaskBlockers(task, evidenceCheck, status);
40322
+ const entries = _internals12.normalizeBundleEntries(bundle);
39906
40323
  const hasReview = entries.some((e) => e.type === "review");
39907
40324
  const hasTest = entries.some((e) => e.type === "test");
39908
40325
  const hasApproval = entries.some((e) => e.type === "approval");
@@ -39931,12 +40348,12 @@ async function buildPhaseSummary(directory, phase) {
39931
40348
  const taskSummaries = [];
39932
40349
  const _taskMap = new Map(phase.tasks.map((t) => [t.id, t]));
39933
40350
  for (const task of phase.tasks) {
39934
- const summary = await buildTaskSummary(directory, task, task.id);
40351
+ const summary = await _internals12.buildTaskSummary(directory, task, task.id);
39935
40352
  taskSummaries.push(summary);
39936
40353
  }
39937
40354
  const extraTaskIds = taskIds.filter((id) => !phaseTaskIds.has(id));
39938
40355
  for (const taskId of extraTaskIds) {
39939
- const summary = await buildTaskSummary(directory, undefined, taskId);
40356
+ const summary = await _internals12.buildTaskSummary(directory, undefined, taskId);
39940
40357
  if (summary.phase === phase.id) {
39941
40358
  taskSummaries.push(summary);
39942
40359
  }
@@ -40037,7 +40454,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
40037
40454
  let totalTasks = 0;
40038
40455
  let completedTasks = 0;
40039
40456
  for (const phase of phasesToProcess) {
40040
- const summary = await buildPhaseSummary(directory, phase);
40457
+ const summary = await _internals12.buildPhaseSummary(directory, phase);
40041
40458
  phaseSummaries.push(summary);
40042
40459
  totalTasks += summary.totalTasks;
40043
40460
  completedTasks += summary.completedTasks;
@@ -40059,7 +40476,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
40059
40476
  overallBlockers,
40060
40477
  summaryText: ""
40061
40478
  };
40062
- artifact.summaryText = generateSummaryText(artifact);
40479
+ artifact.summaryText = _internals12.generateSummaryText(artifact);
40063
40480
  log("[EvidenceSummary] Summary built", {
40064
40481
  phases: phaseSummaries.length,
40065
40482
  totalTasks,
@@ -40078,7 +40495,7 @@ function isAutoSummaryEnabled(automationConfig) {
40078
40495
  }
40079
40496
  return automationConfig.capabilities?.evidence_auto_summaries === true;
40080
40497
  }
40081
- var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0";
40498
+ var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0", _internals12;
40082
40499
  var init_evidence_summary_service = __esm(() => {
40083
40500
  init_manager2();
40084
40501
  init_manager();
@@ -40092,6 +40509,17 @@ var init_evidence_summary_service = __esm(() => {
40092
40509
  "retrospective"
40093
40510
  ]);
40094
40511
  REQUIRED_EVIDENCE_TYPES = ["review", "test"];
40512
+ _internals12 = {
40513
+ buildEvidenceSummary,
40514
+ isAutoSummaryEnabled,
40515
+ normalizeBundleEntries,
40516
+ getTaskStatus,
40517
+ isEvidenceComplete,
40518
+ getTaskBlockers,
40519
+ buildTaskSummary,
40520
+ buildPhaseSummary,
40521
+ generateSummaryText
40522
+ };
40095
40523
  });
40096
40524
 
40097
40525
  // src/services/evidence-service.ts
@@ -40391,7 +40819,7 @@ function extractCurrentPhaseFromPlan2(plan) {
40391
40819
  if (!plan) {
40392
40820
  return { currentPhase: null, currentTask: null, incompleteTasks: [] };
40393
40821
  }
40394
- if (!validatePlanPhases(plan)) {
40822
+ if (!_internals13.validatePlanPhases(plan)) {
40395
40823
  return { currentPhase: null, currentTask: null, incompleteTasks: [] };
40396
40824
  }
40397
40825
  let currentPhase = null;
@@ -40533,9 +40961,9 @@ function extractPhaseMetrics(content) {
40533
40961
  async function getHandoffData(directory) {
40534
40962
  const now = new Date().toISOString();
40535
40963
  const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
40536
- const sessionState = parseSessionState(sessionContent);
40964
+ const sessionState = _internals13.parseSessionState(sessionContent);
40537
40965
  const plan = await loadPlanJsonOnly(directory);
40538
- const planInfo = extractCurrentPhaseFromPlan2(plan);
40966
+ const planInfo = _internals13.extractCurrentPhaseFromPlan(plan);
40539
40967
  if (!plan) {
40540
40968
  const planMdContent = await readSwarmFileAsync(directory, "plan.md");
40541
40969
  if (planMdContent) {
@@ -40554,8 +40982,8 @@ async function getHandoffData(directory) {
40554
40982
  }
40555
40983
  }
40556
40984
  const contextContent = await readSwarmFileAsync(directory, "context.md");
40557
- const recentDecisions = extractDecisions(contextContent);
40558
- const rawPhaseMetrics = extractPhaseMetrics(contextContent);
40985
+ const recentDecisions = _internals13.extractDecisions(contextContent);
40986
+ const rawPhaseMetrics = _internals13.extractPhaseMetrics(contextContent);
40559
40987
  const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
40560
40988
  let delegationState = null;
40561
40989
  if (sessionState?.delegationState) {
@@ -40719,12 +41147,24 @@ ${lines.join(`
40719
41147
  `)}
40720
41148
  \`\`\``;
40721
41149
  }
40722
- var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20;
41150
+ var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20, _internals13;
40723
41151
  var init_handoff_service = __esm(() => {
40724
41152
  init_utils2();
40725
41153
  init_manager();
40726
41154
  init_utils();
40727
41155
  RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
41156
+ _internals13 = {
41157
+ getHandoffData,
41158
+ formatHandoffMarkdown,
41159
+ formatContinuationPrompt,
41160
+ escapeHtml,
41161
+ sanitizeString,
41162
+ validatePlanPhases,
41163
+ extractCurrentPhaseFromPlan: extractCurrentPhaseFromPlan2,
41164
+ parseSessionState,
41165
+ extractDecisions,
41166
+ extractPhaseMetrics
41167
+ };
40728
41168
  });
40729
41169
 
40730
41170
  // src/commands/handoff.ts
@@ -41116,14 +41556,23 @@ var init_issue = __esm(() => {
41116
41556
 
41117
41557
  // src/hooks/knowledge-migrator.ts
41118
41558
  import { randomUUID as randomUUID2 } from "crypto";
41119
- import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
41120
- import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
41121
- import * as path23 from "path";
41559
+ import { existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
41560
+ import { mkdir as mkdir5, readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
41561
+ import * as path24 from "path";
41562
+ async function migrateKnowledgeToExternal(_directory, _config) {
41563
+ return {
41564
+ migrated: false,
41565
+ entriesMigrated: 0,
41566
+ entriesDropped: 0,
41567
+ entriesTotal: 0,
41568
+ skippedReason: "no-context-file"
41569
+ };
41570
+ }
41122
41571
  async function migrateContextToKnowledge(directory, config3) {
41123
- const sentinelPath = path23.join(directory, ".swarm", ".knowledge-migrated");
41124
- const contextPath = path23.join(directory, ".swarm", "context.md");
41572
+ const sentinelPath = path24.join(directory, ".swarm", ".knowledge-migrated");
41573
+ const contextPath = path24.join(directory, ".swarm", "context.md");
41125
41574
  const knowledgePath = resolveSwarmKnowledgePath(directory);
41126
- if (existsSync13(sentinelPath)) {
41575
+ if (existsSync14(sentinelPath)) {
41127
41576
  return {
41128
41577
  migrated: false,
41129
41578
  entriesMigrated: 0,
@@ -41132,7 +41581,7 @@ async function migrateContextToKnowledge(directory, config3) {
41132
41581
  skippedReason: "sentinel-exists"
41133
41582
  };
41134
41583
  }
41135
- if (!existsSync13(contextPath)) {
41584
+ if (!existsSync14(contextPath)) {
41136
41585
  return {
41137
41586
  migrated: false,
41138
41587
  entriesMigrated: 0,
@@ -41141,7 +41590,7 @@ async function migrateContextToKnowledge(directory, config3) {
41141
41590
  skippedReason: "no-context-file"
41142
41591
  };
41143
41592
  }
41144
- const contextContent = await readFile5(contextPath, "utf-8");
41593
+ const contextContent = await readFile6(contextPath, "utf-8");
41145
41594
  if (contextContent.trim().length === 0) {
41146
41595
  return {
41147
41596
  migrated: false,
@@ -41151,9 +41600,9 @@ async function migrateContextToKnowledge(directory, config3) {
41151
41600
  skippedReason: "empty-context"
41152
41601
  };
41153
41602
  }
41154
- const rawEntries = parseContextMd(contextContent);
41603
+ const rawEntries = _internals14.parseContextMd(contextContent);
41155
41604
  if (rawEntries.length === 0) {
41156
- await writeSentinel(sentinelPath, 0, 0);
41605
+ await _internals14.writeSentinel(sentinelPath, 0, 0);
41157
41606
  return {
41158
41607
  migrated: true,
41159
41608
  entriesMigrated: 0,
@@ -41164,10 +41613,10 @@ async function migrateContextToKnowledge(directory, config3) {
41164
41613
  const existing = await readKnowledge(knowledgePath);
41165
41614
  let migrated = 0;
41166
41615
  let dropped = 0;
41167
- const projectName = inferProjectName(directory);
41616
+ const projectName = _internals14.inferProjectName(directory);
41168
41617
  for (const raw of rawEntries) {
41169
41618
  if (config3.validation_enabled !== false) {
41170
- const category = raw.categoryHint ?? inferCategoryFromText(raw.text);
41619
+ const category = raw.categoryHint ?? _internals14.inferCategoryFromText(raw.text);
41171
41620
  const result = validateLesson(raw.text, existing.map((e) => e.lesson), {
41172
41621
  category,
41173
41622
  scope: "global",
@@ -41187,8 +41636,8 @@ async function migrateContextToKnowledge(directory, config3) {
41187
41636
  const entry = {
41188
41637
  id: randomUUID2(),
41189
41638
  tier: "swarm",
41190
- lesson: truncateLesson(raw.text),
41191
- category: raw.categoryHint ?? inferCategoryFromText(raw.text),
41639
+ lesson: _internals14.truncateLesson(raw.text),
41640
+ category: raw.categoryHint ?? _internals14.inferCategoryFromText(raw.text),
41192
41641
  tags: [...inferredTags, `migration:${raw.sourceSection}`],
41193
41642
  scope: "global",
41194
41643
  confidence: 0.3,
@@ -41211,7 +41660,7 @@ async function migrateContextToKnowledge(directory, config3) {
41211
41660
  if (migrated > 0) {
41212
41661
  await rewriteKnowledge(knowledgePath, existing);
41213
41662
  }
41214
- await writeSentinel(sentinelPath, migrated, dropped);
41663
+ await _internals14.writeSentinel(sentinelPath, migrated, dropped);
41215
41664
  log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`);
41216
41665
  return {
41217
41666
  migrated: true,
@@ -41221,7 +41670,7 @@ async function migrateContextToKnowledge(directory, config3) {
41221
41670
  };
41222
41671
  }
41223
41672
  function parseContextMd(content) {
41224
- const sections = splitIntoSections(content);
41673
+ const sections = _internals14.splitIntoSections(content);
41225
41674
  const entries = [];
41226
41675
  const seen = new Set;
41227
41676
  const sectionPatterns = [
@@ -41237,7 +41686,7 @@ function parseContextMd(content) {
41237
41686
  const match = sectionPatterns.find((sp) => sp.pattern.test(section.heading));
41238
41687
  if (!match)
41239
41688
  continue;
41240
- const bullets = extractBullets(section.body);
41689
+ const bullets = _internals14.extractBullets(section.body);
41241
41690
  for (const bullet of bullets) {
41242
41691
  if (bullet.length < 15)
41243
41692
  continue;
@@ -41246,9 +41695,9 @@ function parseContextMd(content) {
41246
41695
  continue;
41247
41696
  seen.add(normalized);
41248
41697
  entries.push({
41249
- text: truncateLesson(bullet),
41698
+ text: _internals14.truncateLesson(bullet),
41250
41699
  sourceSection: match.sourceSection,
41251
- categoryHint: inferCategoryFromText(bullet)
41700
+ categoryHint: _internals14.inferCategoryFromText(bullet)
41252
41701
  });
41253
41702
  }
41254
41703
  }
@@ -41317,8 +41766,8 @@ function truncateLesson(text) {
41317
41766
  return `${text.slice(0, 277)}...`;
41318
41767
  }
41319
41768
  function inferProjectName(directory) {
41320
- const packageJsonPath = path23.join(directory, "package.json");
41321
- if (existsSync13(packageJsonPath)) {
41769
+ const packageJsonPath = path24.join(directory, "package.json");
41770
+ if (existsSync14(packageJsonPath)) {
41322
41771
  try {
41323
41772
  const pkg = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
41324
41773
  if (pkg.name && typeof pkg.name === "string") {
@@ -41326,7 +41775,7 @@ function inferProjectName(directory) {
41326
41775
  }
41327
41776
  } catch {}
41328
41777
  }
41329
- return path23.basename(directory);
41778
+ return path24.basename(directory);
41330
41779
  }
41331
41780
  async function writeSentinel(sentinelPath, migrated, dropped) {
41332
41781
  const sentinel = {
@@ -41338,16 +41787,29 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
41338
41787
  schema_version: 1,
41339
41788
  migration_tool: "knowledge-migrator.ts"
41340
41789
  };
41341
- await mkdir4(path23.dirname(sentinelPath), { recursive: true });
41342
- await writeFile5(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
41790
+ await mkdir5(path24.dirname(sentinelPath), { recursive: true });
41791
+ await writeFile6(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
41343
41792
  }
41793
+ var _internals14;
41344
41794
  var init_knowledge_migrator = __esm(() => {
41795
+ init_logger();
41345
41796
  init_knowledge_store();
41346
41797
  init_knowledge_validator();
41798
+ _internals14 = {
41799
+ migrateContextToKnowledge,
41800
+ migrateKnowledgeToExternal,
41801
+ parseContextMd,
41802
+ splitIntoSections,
41803
+ extractBullets,
41804
+ inferCategoryFromText,
41805
+ truncateLesson,
41806
+ inferProjectName,
41807
+ writeSentinel
41808
+ };
41347
41809
  });
41348
41810
 
41349
41811
  // src/commands/knowledge.ts
41350
- import { join as join22 } from "path";
41812
+ import { join as join23 } from "path";
41351
41813
  function resolveEntryByPrefix(entries, inputId) {
41352
41814
  const exact = entries.find((e) => e.id === inputId);
41353
41815
  if (exact)
@@ -41398,7 +41860,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
41398
41860
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
41399
41861
  }
41400
41862
  try {
41401
- const quarantinePath = join22(directory, ".swarm", "knowledge-quarantined.jsonl");
41863
+ const quarantinePath = join23(directory, ".swarm", "knowledge-quarantined.jsonl");
41402
41864
  const entries = await readKnowledge(quarantinePath);
41403
41865
  const resolved = resolveEntryByPrefix(entries, inputId);
41404
41866
  if ("error" in resolved) {
@@ -41847,7 +42309,7 @@ var init_path_security = () => {};
41847
42309
 
41848
42310
  // src/tools/lint.ts
41849
42311
  import * as fs11 from "fs";
41850
- import * as path24 from "path";
42312
+ import * as path25 from "path";
41851
42313
  function validateArgs(args) {
41852
42314
  if (typeof args !== "object" || args === null)
41853
42315
  return false;
@@ -41858,9 +42320,9 @@ function validateArgs(args) {
41858
42320
  }
41859
42321
  function getLinterCommand(linter, mode, projectDir) {
41860
42322
  const isWindows = process.platform === "win32";
41861
- const binDir = path24.join(projectDir, "node_modules", ".bin");
41862
- const biomeBin = isWindows ? path24.join(binDir, "biome.EXE") : path24.join(binDir, "biome");
41863
- const eslintBin = isWindows ? path24.join(binDir, "eslint.cmd") : path24.join(binDir, "eslint");
42323
+ const binDir = path25.join(projectDir, "node_modules", ".bin");
42324
+ const biomeBin = isWindows ? path25.join(binDir, "biome.EXE") : path25.join(binDir, "biome");
42325
+ const eslintBin = isWindows ? path25.join(binDir, "eslint.cmd") : path25.join(binDir, "eslint");
41864
42326
  switch (linter) {
41865
42327
  case "biome":
41866
42328
  if (mode === "fix") {
@@ -41876,7 +42338,7 @@ function getLinterCommand(linter, mode, projectDir) {
41876
42338
  }
41877
42339
  function getAdditionalLinterCommand(linter, mode, cwd) {
41878
42340
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
41879
- const gradlew = fs11.existsSync(path24.join(cwd, gradlewName)) ? path24.join(cwd, gradlewName) : null;
42341
+ const gradlew = fs11.existsSync(path25.join(cwd, gradlewName)) ? path25.join(cwd, gradlewName) : null;
41880
42342
  switch (linter) {
41881
42343
  case "ruff":
41882
42344
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -41910,10 +42372,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
41910
42372
  }
41911
42373
  }
41912
42374
  function detectRuff(cwd) {
41913
- if (fs11.existsSync(path24.join(cwd, "ruff.toml")))
42375
+ if (fs11.existsSync(path25.join(cwd, "ruff.toml")))
41914
42376
  return isCommandAvailable("ruff");
41915
42377
  try {
41916
- const pyproject = path24.join(cwd, "pyproject.toml");
42378
+ const pyproject = path25.join(cwd, "pyproject.toml");
41917
42379
  if (fs11.existsSync(pyproject)) {
41918
42380
  const content = fs11.readFileSync(pyproject, "utf-8");
41919
42381
  if (content.includes("[tool.ruff]"))
@@ -41923,19 +42385,19 @@ function detectRuff(cwd) {
41923
42385
  return false;
41924
42386
  }
41925
42387
  function detectClippy(cwd) {
41926
- return fs11.existsSync(path24.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
42388
+ return fs11.existsSync(path25.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
41927
42389
  }
41928
42390
  function detectGolangciLint(cwd) {
41929
- return fs11.existsSync(path24.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
42391
+ return fs11.existsSync(path25.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
41930
42392
  }
41931
42393
  function detectCheckstyle(cwd) {
41932
- const hasMaven = fs11.existsSync(path24.join(cwd, "pom.xml"));
41933
- const hasGradle = fs11.existsSync(path24.join(cwd, "build.gradle")) || fs11.existsSync(path24.join(cwd, "build.gradle.kts"));
41934
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs11.existsSync(path24.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
42394
+ const hasMaven = fs11.existsSync(path25.join(cwd, "pom.xml"));
42395
+ const hasGradle = fs11.existsSync(path25.join(cwd, "build.gradle")) || fs11.existsSync(path25.join(cwd, "build.gradle.kts"));
42396
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs11.existsSync(path25.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
41935
42397
  return (hasMaven || hasGradle) && hasBinary;
41936
42398
  }
41937
42399
  function detectKtlint(cwd) {
41938
- const hasKotlin = fs11.existsSync(path24.join(cwd, "build.gradle.kts")) || fs11.existsSync(path24.join(cwd, "build.gradle")) || (() => {
42400
+ const hasKotlin = fs11.existsSync(path25.join(cwd, "build.gradle.kts")) || fs11.existsSync(path25.join(cwd, "build.gradle")) || (() => {
41939
42401
  try {
41940
42402
  return fs11.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
41941
42403
  } catch {
@@ -41954,11 +42416,11 @@ function detectDotnetFormat(cwd) {
41954
42416
  }
41955
42417
  }
41956
42418
  function detectCppcheck(cwd) {
41957
- if (fs11.existsSync(path24.join(cwd, "CMakeLists.txt"))) {
42419
+ if (fs11.existsSync(path25.join(cwd, "CMakeLists.txt"))) {
41958
42420
  return isCommandAvailable("cppcheck");
41959
42421
  }
41960
42422
  try {
41961
- const dirsToCheck = [cwd, path24.join(cwd, "src")];
42423
+ const dirsToCheck = [cwd, path25.join(cwd, "src")];
41962
42424
  const hasCpp = dirsToCheck.some((dir) => {
41963
42425
  try {
41964
42426
  return fs11.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
@@ -41972,13 +42434,13 @@ function detectCppcheck(cwd) {
41972
42434
  }
41973
42435
  }
41974
42436
  function detectSwiftlint(cwd) {
41975
- return fs11.existsSync(path24.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
42437
+ return fs11.existsSync(path25.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
41976
42438
  }
41977
42439
  function detectDartAnalyze(cwd) {
41978
- return fs11.existsSync(path24.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
42440
+ return fs11.existsSync(path25.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
41979
42441
  }
41980
42442
  function detectRubocop(cwd) {
41981
- return (fs11.existsSync(path24.join(cwd, "Gemfile")) || fs11.existsSync(path24.join(cwd, "gems.rb")) || fs11.existsSync(path24.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
42443
+ return (fs11.existsSync(path25.join(cwd, "Gemfile")) || fs11.existsSync(path25.join(cwd, "gems.rb")) || fs11.existsSync(path25.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
41982
42444
  }
41983
42445
  function detectAdditionalLinter(cwd) {
41984
42446
  if (detectRuff(cwd))
@@ -42006,10 +42468,10 @@ function detectAdditionalLinter(cwd) {
42006
42468
  function findBinInAncestors(startDir, binName) {
42007
42469
  let dir = startDir;
42008
42470
  while (true) {
42009
- const candidate = path24.join(dir, "node_modules", ".bin", binName);
42471
+ const candidate = path25.join(dir, "node_modules", ".bin", binName);
42010
42472
  if (fs11.existsSync(candidate))
42011
42473
  return candidate;
42012
- const parent = path24.dirname(dir);
42474
+ const parent = path25.dirname(dir);
42013
42475
  if (parent === dir)
42014
42476
  break;
42015
42477
  dir = parent;
@@ -42018,10 +42480,10 @@ function findBinInAncestors(startDir, binName) {
42018
42480
  }
42019
42481
  function findBinInEnvPath(binName) {
42020
42482
  const searchPath = process.env.PATH ?? "";
42021
- for (const dir of searchPath.split(path24.delimiter)) {
42483
+ for (const dir of searchPath.split(path25.delimiter)) {
42022
42484
  if (!dir)
42023
42485
  continue;
42024
- const candidate = path24.join(dir, binName);
42486
+ const candidate = path25.join(dir, binName);
42025
42487
  if (fs11.existsSync(candidate))
42026
42488
  return candidate;
42027
42489
  }
@@ -42034,13 +42496,13 @@ async function detectAvailableLinter(directory) {
42034
42496
  return null;
42035
42497
  const projectDir = directory;
42036
42498
  const isWindows = process.platform === "win32";
42037
- const biomeBin = isWindows ? path24.join(projectDir, "node_modules", ".bin", "biome.EXE") : path24.join(projectDir, "node_modules", ".bin", "biome");
42038
- const eslintBin = isWindows ? path24.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path24.join(projectDir, "node_modules", ".bin", "eslint");
42499
+ const biomeBin = isWindows ? path25.join(projectDir, "node_modules", ".bin", "biome.EXE") : path25.join(projectDir, "node_modules", ".bin", "biome");
42500
+ const eslintBin = isWindows ? path25.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path25.join(projectDir, "node_modules", ".bin", "eslint");
42039
42501
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
42040
42502
  if (localResult)
42041
42503
  return localResult;
42042
- const biomeAncestor = findBinInAncestors(path24.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
42043
- const eslintAncestor = findBinInAncestors(path24.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
42504
+ const biomeAncestor = findBinInAncestors(path25.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
42505
+ const eslintAncestor = findBinInAncestors(path25.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
42044
42506
  if (biomeAncestor || eslintAncestor) {
42045
42507
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
42046
42508
  }
@@ -42199,7 +42661,7 @@ async function runAdditionalLint(linter, mode, cwd) {
42199
42661
  };
42200
42662
  }
42201
42663
  }
42202
- var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint;
42664
+ var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint, _internals15;
42203
42665
  var init_lint = __esm(() => {
42204
42666
  init_zod();
42205
42667
  init_discovery();
@@ -42231,15 +42693,15 @@ var init_lint = __esm(() => {
42231
42693
  }
42232
42694
  const { mode } = args;
42233
42695
  const cwd = directory;
42234
- const linter = await detectAvailableLinter(directory);
42696
+ const linter = await _internals15.detectAvailableLinter(directory);
42235
42697
  if (linter) {
42236
- const result = await runLint(linter, mode, directory);
42698
+ const result = await _internals15.runLint(linter, mode, directory);
42237
42699
  return JSON.stringify(result, null, 2);
42238
42700
  }
42239
- const additionalLinter = detectAdditionalLinter(cwd);
42701
+ const additionalLinter = _internals15.detectAdditionalLinter(cwd);
42240
42702
  if (additionalLinter) {
42241
42703
  warn(`[lint] Using ${additionalLinter} linter for this project`);
42242
- const result = await runAdditionalLint(additionalLinter, mode, cwd);
42704
+ const result = await _internals15.runAdditionalLint(additionalLinter, mode, cwd);
42243
42705
  return JSON.stringify(result, null, 2);
42244
42706
  }
42245
42707
  const errorResult = {
@@ -42253,11 +42715,17 @@ For Rust: rustup component add clippy`
42253
42715
  return JSON.stringify(errorResult, null, 2);
42254
42716
  }
42255
42717
  });
42718
+ _internals15 = {
42719
+ detectAvailableLinter,
42720
+ runLint,
42721
+ detectAdditionalLinter,
42722
+ runAdditionalLint
42723
+ };
42256
42724
  });
42257
42725
 
42258
42726
  // src/tools/secretscan.ts
42259
42727
  import * as fs12 from "fs";
42260
- import * as path25 from "path";
42728
+ import * as path26 from "path";
42261
42729
  function calculateShannonEntropy(str) {
42262
42730
  if (str.length === 0)
42263
42731
  return 0;
@@ -42305,7 +42773,7 @@ function isGlobOrPathPattern(pattern) {
42305
42773
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
42306
42774
  }
42307
42775
  function loadSecretScanIgnore(scanDir) {
42308
- const ignorePath = path25.join(scanDir, ".secretscanignore");
42776
+ const ignorePath = path26.join(scanDir, ".secretscanignore");
42309
42777
  try {
42310
42778
  if (!fs12.existsSync(ignorePath))
42311
42779
  return [];
@@ -42328,7 +42796,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
42328
42796
  if (exactNames.has(entry))
42329
42797
  return true;
42330
42798
  for (const pattern of globPatterns) {
42331
- if (path25.matchesGlob(relPath, pattern))
42799
+ if (path26.matchesGlob(relPath, pattern))
42332
42800
  return true;
42333
42801
  }
42334
42802
  return false;
@@ -42349,7 +42817,7 @@ function validateDirectoryInput(dir) {
42349
42817
  return null;
42350
42818
  }
42351
42819
  function isBinaryFile(filePath, buffer) {
42352
- const ext = path25.extname(filePath).toLowerCase();
42820
+ const ext = path26.extname(filePath).toLowerCase();
42353
42821
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
42354
42822
  return true;
42355
42823
  }
@@ -42485,9 +42953,9 @@ function isSymlinkLoop(realPath, visited) {
42485
42953
  return false;
42486
42954
  }
42487
42955
  function isPathWithinScope(realPath, scanDir) {
42488
- const resolvedScanDir = path25.resolve(scanDir);
42489
- const resolvedRealPath = path25.resolve(realPath);
42490
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path25.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
42956
+ const resolvedScanDir = path26.resolve(scanDir);
42957
+ const resolvedRealPath = path26.resolve(realPath);
42958
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path26.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
42491
42959
  }
42492
42960
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
42493
42961
  skippedDirs: 0,
@@ -42513,8 +42981,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
42513
42981
  return a.localeCompare(b);
42514
42982
  });
42515
42983
  for (const entry of entries) {
42516
- const fullPath = path25.join(dir, entry);
42517
- const relPath = path25.relative(scanDir, fullPath).replace(/\\/g, "/");
42984
+ const fullPath = path26.join(dir, entry);
42985
+ const relPath = path26.relative(scanDir, fullPath).replace(/\\/g, "/");
42518
42986
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
42519
42987
  stats.skippedDirs++;
42520
42988
  continue;
@@ -42549,7 +43017,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
42549
43017
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
42550
43018
  files.push(...subFiles);
42551
43019
  } else if (lstat.isFile()) {
42552
- const ext = path25.extname(fullPath).toLowerCase();
43020
+ const ext = path26.extname(fullPath).toLowerCase();
42553
43021
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
42554
43022
  files.push(fullPath);
42555
43023
  } else {
@@ -42561,7 +43029,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
42561
43029
  }
42562
43030
  async function runSecretscan(directory) {
42563
43031
  try {
42564
- const result = await secretscan.execute({ directory }, {});
43032
+ const result = await _internals16.secretscan.execute({ directory }, {});
42565
43033
  const jsonStr = typeof result === "string" ? result : result.output;
42566
43034
  return JSON.parse(jsonStr);
42567
43035
  } catch (e) {
@@ -42576,7 +43044,7 @@ async function runSecretscan(directory) {
42576
43044
  return errorResult;
42577
43045
  }
42578
43046
  }
42579
- var MAX_FILE_PATH_LENGTH = 500, MAX_FILE_SIZE_BYTES, MAX_FILES_SCANNED = 1000, MAX_FINDINGS = 100, MAX_OUTPUT_BYTES2 = 512000, MAX_LINE_LENGTH = 1e4, MAX_CONTENT_BYTES, BINARY_SIGNATURES, BINARY_PREFIX_BYTES = 4, BINARY_NULL_CHECK_BYTES = 8192, BINARY_NULL_THRESHOLD = 0.1, DEFAULT_EXCLUDE_DIRS, DEFAULT_EXCLUDE_EXTENSIONS, SECRET_PATTERNS, O_NOFOLLOW, secretscan;
43047
+ var MAX_FILE_PATH_LENGTH = 500, MAX_FILE_SIZE_BYTES, MAX_FILES_SCANNED = 1000, MAX_FINDINGS = 100, MAX_OUTPUT_BYTES2 = 512000, MAX_LINE_LENGTH = 1e4, MAX_CONTENT_BYTES, BINARY_SIGNATURES, BINARY_PREFIX_BYTES = 4, BINARY_NULL_CHECK_BYTES = 8192, BINARY_NULL_THRESHOLD = 0.1, DEFAULT_EXCLUDE_DIRS, DEFAULT_EXCLUDE_EXTENSIONS, SECRET_PATTERNS, O_NOFOLLOW, secretscan, _internals16;
42580
43048
  var init_secretscan = __esm(() => {
42581
43049
  init_zod();
42582
43050
  init_path_security();
@@ -42809,7 +43277,7 @@ var init_secretscan = __esm(() => {
42809
43277
  }
42810
43278
  }
42811
43279
  try {
42812
- const _scanDirRaw = path25.resolve(directory);
43280
+ const _scanDirRaw = path26.resolve(directory);
42813
43281
  const scanDir = (() => {
42814
43282
  try {
42815
43283
  return fs12.realpathSync(_scanDirRaw);
@@ -42948,11 +43416,15 @@ var init_secretscan = __esm(() => {
42948
43416
  }
42949
43417
  }
42950
43418
  });
43419
+ _internals16 = {
43420
+ secretscan,
43421
+ runSecretscan
43422
+ };
42951
43423
  });
42952
43424
 
42953
43425
  // src/test-impact/analyzer.ts
42954
43426
  import fs13 from "fs";
42955
- import path26 from "path";
43427
+ import path27 from "path";
42956
43428
  function normalizePath(p) {
42957
43429
  return p.replace(/\\/g, "/");
42958
43430
  }
@@ -42973,8 +43445,8 @@ function resolveRelativeImport(fromDir, importPath) {
42973
43445
  if (!importPath.startsWith(".")) {
42974
43446
  return null;
42975
43447
  }
42976
- const resolved = path26.resolve(fromDir, importPath);
42977
- if (path26.extname(resolved)) {
43448
+ const resolved = path27.resolve(fromDir, importPath);
43449
+ if (path27.extname(resolved)) {
42978
43450
  if (fs13.existsSync(resolved) && fs13.statSync(resolved).isFile()) {
42979
43451
  return normalizePath(resolved);
42980
43452
  }
@@ -43019,12 +43491,12 @@ function findTestFilesSync(cwd) {
43019
43491
  for (const entry of entries) {
43020
43492
  if (entry.isDirectory()) {
43021
43493
  if (!skipDirs.has(entry.name)) {
43022
- walk(path26.join(dir, entry.name), visitedInodes);
43494
+ walk(path27.join(dir, entry.name), visitedInodes);
43023
43495
  }
43024
43496
  } else if (entry.isFile()) {
43025
43497
  const name = entry.name;
43026
43498
  if (/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name)) {
43027
- testFiles.push(normalizePath(path26.join(dir, entry.name)));
43499
+ testFiles.push(normalizePath(path27.join(dir, entry.name)));
43028
43500
  }
43029
43501
  }
43030
43502
  }
@@ -43062,7 +43534,7 @@ async function buildImpactMapInternal(cwd) {
43062
43534
  continue;
43063
43535
  }
43064
43536
  const imports = extractImports(content);
43065
- const testDir = path26.dirname(testFile);
43537
+ const testDir = path27.dirname(testFile);
43066
43538
  for (const importPath of imports) {
43067
43539
  const resolvedSource = resolveRelativeImport(testDir, importPath);
43068
43540
  if (resolvedSource === null) {
@@ -43079,28 +43551,28 @@ async function buildImpactMapInternal(cwd) {
43079
43551
  return impactMap;
43080
43552
  }
43081
43553
  async function buildImpactMap(cwd) {
43082
- const impactMap = await buildImpactMapInternal(cwd);
43083
- await saveImpactMap(cwd, impactMap);
43554
+ const impactMap = await _internals17.buildImpactMapInternal(cwd);
43555
+ await _internals17.saveImpactMap(cwd, impactMap);
43084
43556
  return impactMap;
43085
43557
  }
43086
43558
  async function loadImpactMap(cwd) {
43087
- const cachePath = path26.join(cwd, ".swarm", "cache", "impact-map.json");
43559
+ const cachePath = path27.join(cwd, ".swarm", "cache", "impact-map.json");
43088
43560
  if (fs13.existsSync(cachePath)) {
43089
43561
  try {
43090
43562
  const content = fs13.readFileSync(cachePath, "utf-8");
43091
43563
  const data = JSON.parse(content);
43092
43564
  const map3 = data.map;
43093
43565
  const generatedAt = new Date(data.generatedAt).getTime();
43094
- if (!isCacheStale(map3, generatedAt)) {
43566
+ if (!_internals17.isCacheStale(map3, generatedAt)) {
43095
43567
  return map3;
43096
43568
  }
43097
43569
  } catch {}
43098
43570
  }
43099
- return buildImpactMap(cwd);
43571
+ return _internals17.buildImpactMap(cwd);
43100
43572
  }
43101
43573
  async function saveImpactMap(cwd, impactMap) {
43102
- const cacheDir2 = path26.join(cwd, ".swarm", "cache");
43103
- const cachePath = path26.join(cacheDir2, "impact-map.json");
43574
+ const cacheDir2 = path27.join(cwd, ".swarm", "cache");
43575
+ const cachePath = path27.join(cacheDir2, "impact-map.json");
43104
43576
  if (!fs13.existsSync(cacheDir2)) {
43105
43577
  fs13.mkdirSync(cacheDir2, { recursive: true });
43106
43578
  }
@@ -43122,11 +43594,11 @@ async function analyzeImpact(changedFiles, cwd) {
43122
43594
  };
43123
43595
  }
43124
43596
  const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !f.includes("\x00"));
43125
- const impactMap = await loadImpactMap(cwd);
43597
+ const impactMap = await _internals17.loadImpactMap(cwd);
43126
43598
  const impactedTestsSet = new Set;
43127
43599
  const untestedFiles = [];
43128
43600
  for (const changedFile of validFiles) {
43129
- const normalizedChanged = normalizePath(path26.resolve(changedFile));
43601
+ const normalizedChanged = normalizePath(path27.resolve(changedFile));
43130
43602
  const tests = impactMap[normalizedChanged];
43131
43603
  if (tests && tests.length > 0) {
43132
43604
  for (const test of tests) {
@@ -43163,12 +43635,24 @@ async function analyzeImpact(changedFiles, cwd) {
43163
43635
  impactMap
43164
43636
  };
43165
43637
  }
43166
- var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, EXTENSIONS_TO_TRY;
43638
+ var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, EXTENSIONS_TO_TRY, _internals17;
43167
43639
  var init_analyzer = __esm(() => {
43168
43640
  IMPORT_REGEX_ES = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
43169
43641
  IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
43170
43642
  IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
43171
43643
  EXTENSIONS_TO_TRY = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
43644
+ _internals17 = {
43645
+ normalizePath,
43646
+ isCacheStale,
43647
+ resolveRelativeImport,
43648
+ findTestFilesSync,
43649
+ extractImports,
43650
+ buildImpactMapInternal,
43651
+ buildImpactMap,
43652
+ loadImpactMap,
43653
+ saveImpactMap,
43654
+ analyzeImpact
43655
+ };
43172
43656
  });
43173
43657
 
43174
43658
  // src/test-impact/failure-classifier.ts
@@ -43378,9 +43862,9 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
43378
43862
 
43379
43863
  // src/test-impact/history-store.ts
43380
43864
  import fs14 from "fs";
43381
- import path27 from "path";
43865
+ import path28 from "path";
43382
43866
  function getHistoryPath(workingDir) {
43383
- return path27.join(workingDir || process.cwd(), ".swarm", "cache", "test-history.jsonl");
43867
+ return path28.join(workingDir || process.cwd(), ".swarm", "cache", "test-history.jsonl");
43384
43868
  }
43385
43869
  function sanitizeErrorMessage(errorMessage) {
43386
43870
  if (errorMessage === undefined) {
@@ -43435,7 +43919,7 @@ function appendTestRun(record3, workingDir) {
43435
43919
  changedFiles: sanitizeChangedFiles(record3.changedFiles || [])
43436
43920
  };
43437
43921
  const historyPath = getHistoryPath(workingDir);
43438
- const historyDir = path27.dirname(historyPath);
43922
+ const historyDir = path28.dirname(historyPath);
43439
43923
  if (!fs14.existsSync(historyDir)) {
43440
43924
  fs14.mkdirSync(historyDir, { recursive: true });
43441
43925
  }
@@ -43517,7 +44001,7 @@ var init_history_store = __esm(() => {
43517
44001
 
43518
44002
  // src/tools/resolve-working-directory.ts
43519
44003
  import * as fs15 from "fs";
43520
- import * as path28 from "path";
44004
+ import * as path29 from "path";
43521
44005
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
43522
44006
  if (workingDirectory == null || workingDirectory === "") {
43523
44007
  return { success: true, directory: fallbackDirectory };
@@ -43537,15 +44021,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
43537
44021
  };
43538
44022
  }
43539
44023
  }
43540
- const normalizedDir = path28.normalize(workingDirectory);
43541
- const pathParts = normalizedDir.split(path28.sep);
44024
+ const normalizedDir = path29.normalize(workingDirectory);
44025
+ const pathParts = normalizedDir.split(path29.sep);
43542
44026
  if (pathParts.includes("..")) {
43543
44027
  return {
43544
44028
  success: false,
43545
44029
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
43546
44030
  };
43547
44031
  }
43548
- const resolvedDir = path28.resolve(normalizedDir);
44032
+ const resolvedDir = path29.resolve(normalizedDir);
43549
44033
  let statResult;
43550
44034
  try {
43551
44035
  statResult = fs15.statSync(resolvedDir);
@@ -43561,7 +44045,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
43561
44045
  message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
43562
44046
  };
43563
44047
  }
43564
- const resolvedFallback = path28.resolve(fallbackDirectory);
44048
+ const resolvedFallback = path29.resolve(fallbackDirectory);
43565
44049
  let fallbackExists = false;
43566
44050
  try {
43567
44051
  fs15.statSync(resolvedFallback);
@@ -43571,7 +44055,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
43571
44055
  }
43572
44056
  if (workingDirectory != null && workingDirectory !== "") {
43573
44057
  if (fallbackExists) {
43574
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path28.sep);
44058
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path29.sep);
43575
44059
  if (isSubdirectory) {
43576
44060
  return {
43577
44061
  success: false,
@@ -43593,7 +44077,7 @@ var init_resolve_working_directory = () => {};
43593
44077
 
43594
44078
  // src/tools/test-runner.ts
43595
44079
  import * as fs16 from "fs";
43596
- import * as path29 from "path";
44080
+ import * as path30 from "path";
43597
44081
  function isAbsolutePath(str) {
43598
44082
  if (str.startsWith("/"))
43599
44083
  return true;
@@ -43658,14 +44142,14 @@ function hasDevDependency(devDeps, ...patterns) {
43658
44142
  return hasPackageJsonDependency(devDeps, ...patterns);
43659
44143
  }
43660
44144
  function detectGoTest(cwd) {
43661
- return fs16.existsSync(path29.join(cwd, "go.mod")) && isCommandAvailable("go");
44145
+ return fs16.existsSync(path30.join(cwd, "go.mod")) && isCommandAvailable("go");
43662
44146
  }
43663
44147
  function detectJavaMaven(cwd) {
43664
- return fs16.existsSync(path29.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
44148
+ return fs16.existsSync(path30.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
43665
44149
  }
43666
44150
  function detectGradle(cwd) {
43667
- const hasBuildFile = fs16.existsSync(path29.join(cwd, "build.gradle")) || fs16.existsSync(path29.join(cwd, "build.gradle.kts"));
43668
- const hasGradlew = fs16.existsSync(path29.join(cwd, "gradlew")) || fs16.existsSync(path29.join(cwd, "gradlew.bat"));
44151
+ const hasBuildFile = fs16.existsSync(path30.join(cwd, "build.gradle")) || fs16.existsSync(path30.join(cwd, "build.gradle.kts"));
44152
+ const hasGradlew = fs16.existsSync(path30.join(cwd, "gradlew")) || fs16.existsSync(path30.join(cwd, "gradlew.bat"));
43669
44153
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
43670
44154
  }
43671
44155
  function detectDotnetTest(cwd) {
@@ -43678,30 +44162,30 @@ function detectDotnetTest(cwd) {
43678
44162
  }
43679
44163
  }
43680
44164
  function detectCTest(cwd) {
43681
- const hasSource = fs16.existsSync(path29.join(cwd, "CMakeLists.txt"));
43682
- const hasBuildCache = fs16.existsSync(path29.join(cwd, "CMakeCache.txt")) || fs16.existsSync(path29.join(cwd, "build", "CMakeCache.txt"));
44165
+ const hasSource = fs16.existsSync(path30.join(cwd, "CMakeLists.txt"));
44166
+ const hasBuildCache = fs16.existsSync(path30.join(cwd, "CMakeCache.txt")) || fs16.existsSync(path30.join(cwd, "build", "CMakeCache.txt"));
43683
44167
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
43684
44168
  }
43685
44169
  function detectSwiftTest(cwd) {
43686
- return fs16.existsSync(path29.join(cwd, "Package.swift")) && isCommandAvailable("swift");
44170
+ return fs16.existsSync(path30.join(cwd, "Package.swift")) && isCommandAvailable("swift");
43687
44171
  }
43688
44172
  function detectDartTest(cwd) {
43689
- return fs16.existsSync(path29.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
44173
+ return fs16.existsSync(path30.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
43690
44174
  }
43691
44175
  function detectRSpec(cwd) {
43692
- const hasRSpecFile = fs16.existsSync(path29.join(cwd, ".rspec"));
43693
- const hasGemfile = fs16.existsSync(path29.join(cwd, "Gemfile"));
43694
- const hasSpecDir = fs16.existsSync(path29.join(cwd, "spec"));
44176
+ const hasRSpecFile = fs16.existsSync(path30.join(cwd, ".rspec"));
44177
+ const hasGemfile = fs16.existsSync(path30.join(cwd, "Gemfile"));
44178
+ const hasSpecDir = fs16.existsSync(path30.join(cwd, "spec"));
43695
44179
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
43696
44180
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
43697
44181
  }
43698
44182
  function detectMinitest(cwd) {
43699
- return fs16.existsSync(path29.join(cwd, "test")) && (fs16.existsSync(path29.join(cwd, "Gemfile")) || fs16.existsSync(path29.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
44183
+ return fs16.existsSync(path30.join(cwd, "test")) && (fs16.existsSync(path30.join(cwd, "Gemfile")) || fs16.existsSync(path30.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
43700
44184
  }
43701
44185
  async function detectTestFramework(cwd) {
43702
44186
  const baseDir = cwd;
43703
44187
  try {
43704
- const packageJsonPath = path29.join(baseDir, "package.json");
44188
+ const packageJsonPath = path30.join(baseDir, "package.json");
43705
44189
  if (fs16.existsSync(packageJsonPath)) {
43706
44190
  const content = fs16.readFileSync(packageJsonPath, "utf-8");
43707
44191
  const pkg = JSON.parse(content);
@@ -43722,16 +44206,16 @@ async function detectTestFramework(cwd) {
43722
44206
  return "jest";
43723
44207
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
43724
44208
  return "mocha";
43725
- if (fs16.existsSync(path29.join(baseDir, "bun.lockb")) || fs16.existsSync(path29.join(baseDir, "bun.lock"))) {
44209
+ if (fs16.existsSync(path30.join(baseDir, "bun.lockb")) || fs16.existsSync(path30.join(baseDir, "bun.lock"))) {
43726
44210
  if (scripts.test?.includes("bun"))
43727
44211
  return "bun";
43728
44212
  }
43729
44213
  }
43730
44214
  } catch {}
43731
44215
  try {
43732
- const pyprojectTomlPath = path29.join(baseDir, "pyproject.toml");
43733
- const setupCfgPath = path29.join(baseDir, "setup.cfg");
43734
- const requirementsTxtPath = path29.join(baseDir, "requirements.txt");
44216
+ const pyprojectTomlPath = path30.join(baseDir, "pyproject.toml");
44217
+ const setupCfgPath = path30.join(baseDir, "setup.cfg");
44218
+ const requirementsTxtPath = path30.join(baseDir, "requirements.txt");
43735
44219
  if (fs16.existsSync(pyprojectTomlPath)) {
43736
44220
  const content = fs16.readFileSync(pyprojectTomlPath, "utf-8");
43737
44221
  if (content.includes("[tool.pytest"))
@@ -43751,7 +44235,7 @@ async function detectTestFramework(cwd) {
43751
44235
  }
43752
44236
  } catch {}
43753
44237
  try {
43754
- const cargoTomlPath = path29.join(baseDir, "Cargo.toml");
44238
+ const cargoTomlPath = path30.join(baseDir, "Cargo.toml");
43755
44239
  if (fs16.existsSync(cargoTomlPath)) {
43756
44240
  const content = fs16.readFileSync(cargoTomlPath, "utf-8");
43757
44241
  if (content.includes("[dev-dependencies]")) {
@@ -43762,9 +44246,9 @@ async function detectTestFramework(cwd) {
43762
44246
  }
43763
44247
  } catch {}
43764
44248
  try {
43765
- const pesterConfigPath = path29.join(baseDir, "pester.config.ps1");
43766
- const pesterConfigJsonPath = path29.join(baseDir, "pester.config.ps1.json");
43767
- const pesterPs1Path = path29.join(baseDir, "tests.ps1");
44249
+ const pesterConfigPath = path30.join(baseDir, "pester.config.ps1");
44250
+ const pesterConfigJsonPath = path30.join(baseDir, "pester.config.ps1.json");
44251
+ const pesterPs1Path = path30.join(baseDir, "tests.ps1");
43768
44252
  if (fs16.existsSync(pesterConfigPath) || fs16.existsSync(pesterConfigJsonPath) || fs16.existsSync(pesterPs1Path)) {
43769
44253
  return "pester";
43770
44254
  }
@@ -43793,12 +44277,12 @@ function isTestDirectoryPath(normalizedPath) {
43793
44277
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
43794
44278
  }
43795
44279
  function resolveWorkspacePath(file3, workingDir) {
43796
- return path29.isAbsolute(file3) ? path29.resolve(file3) : path29.resolve(workingDir, file3);
44280
+ return path30.isAbsolute(file3) ? path30.resolve(file3) : path30.resolve(workingDir, file3);
43797
44281
  }
43798
44282
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
43799
44283
  if (!preferRelative)
43800
44284
  return absolutePath;
43801
- return path29.relative(workingDir, absolutePath);
44285
+ return path30.relative(workingDir, absolutePath);
43802
44286
  }
43803
44287
  function dedupePush(target, value) {
43804
44288
  if (!target.includes(value)) {
@@ -43835,18 +44319,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
43835
44319
  }
43836
44320
  }
43837
44321
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
43838
- const relativeDir = path29.dirname(relativePath);
44322
+ const relativeDir = path30.dirname(relativePath);
43839
44323
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
43840
44324
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
43841
- const rootDir = path29.join(workingDir, dirName);
43842
- return nestedRelativeDir ? [rootDir, path29.join(rootDir, nestedRelativeDir)] : [rootDir];
44325
+ const rootDir = path30.join(workingDir, dirName);
44326
+ return nestedRelativeDir ? [rootDir, path30.join(rootDir, nestedRelativeDir)] : [rootDir];
43843
44327
  });
43844
44328
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
43845
44329
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
43846
- directories.push(path29.join(workingDir, "src/test/java", path29.dirname(normalizedRelativePath.slice("src/main/java/".length))));
44330
+ directories.push(path30.join(workingDir, "src/test/java", path30.dirname(normalizedRelativePath.slice("src/main/java/".length))));
43847
44331
  }
43848
44332
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
43849
- directories.push(path29.join(workingDir, "src/test/kotlin", path29.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
44333
+ directories.push(path30.join(workingDir, "src/test/kotlin", path30.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
43850
44334
  }
43851
44335
  return [...new Set(directories)];
43852
44336
  }
@@ -43874,23 +44358,23 @@ function isLanguageSpecificTestFile(basename5) {
43874
44358
  }
43875
44359
  function isConventionTestFilePath(filePath) {
43876
44360
  const normalizedPath = filePath.replace(/\\/g, "/");
43877
- const basename5 = path29.basename(filePath);
44361
+ const basename5 = path30.basename(filePath);
43878
44362
  return hasCompoundTestExtension(basename5) || basename5.includes(".spec.") || basename5.includes(".test.") || isLanguageSpecificTestFile(basename5) || isTestDirectoryPath(normalizedPath);
43879
44363
  }
43880
44364
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
43881
44365
  const testFiles = [];
43882
44366
  for (const file3 of sourceFiles) {
43883
44367
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
43884
- const relativeFile = path29.relative(workingDir, absoluteFile);
43885
- const basename5 = path29.basename(absoluteFile);
43886
- const dirname12 = path29.dirname(absoluteFile);
43887
- const preferRelativeOutput = !path29.isAbsolute(file3);
44368
+ const relativeFile = path30.relative(workingDir, absoluteFile);
44369
+ const basename5 = path30.basename(absoluteFile);
44370
+ const dirname13 = path30.dirname(absoluteFile);
44371
+ const preferRelativeOutput = !path30.isAbsolute(file3);
43888
44372
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
43889
44373
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
43890
44374
  continue;
43891
44375
  }
43892
44376
  const nameWithoutExt = basename5.replace(/\.[^.]+$/, "");
43893
- const ext = path29.extname(basename5);
44377
+ const ext = path30.extname(basename5);
43894
44378
  const genericTestNames = [
43895
44379
  `${nameWithoutExt}.spec${ext}`,
43896
44380
  `${nameWithoutExt}.test${ext}`
@@ -43899,7 +44383,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
43899
44383
  const colocatedCandidates = [
43900
44384
  ...genericTestNames,
43901
44385
  ...languageSpecificTestNames
43902
- ].map((candidateName) => path29.join(dirname12, candidateName));
44386
+ ].map((candidateName) => path30.join(dirname13, candidateName));
43903
44387
  const testDirectoryNames = [
43904
44388
  basename5,
43905
44389
  ...genericTestNames,
@@ -43908,8 +44392,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
43908
44392
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
43909
44393
  const possibleTestFiles = [
43910
44394
  ...colocatedCandidates,
43911
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path29.join(dirname12, dirName, candidateName))),
43912
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path29.join(candidateDir, candidateName)))
44395
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path30.join(dirname13, dirName, candidateName))),
44396
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path30.join(candidateDir, candidateName)))
43913
44397
  ];
43914
44398
  for (const testFile of possibleTestFiles) {
43915
44399
  if (fs16.existsSync(testFile)) {
@@ -43930,7 +44414,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
43930
44414
  try {
43931
44415
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
43932
44416
  const content = fs16.readFileSync(absoluteTestFile, "utf-8");
43933
- const testDir = path29.dirname(absoluteTestFile);
44417
+ const testDir = path30.dirname(absoluteTestFile);
43934
44418
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
43935
44419
  let match;
43936
44420
  match = importRegex.exec(content);
@@ -43938,8 +44422,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
43938
44422
  const importPath = match[1];
43939
44423
  let resolvedImport;
43940
44424
  if (importPath.startsWith(".")) {
43941
- resolvedImport = path29.resolve(testDir, importPath);
43942
- const existingExt = path29.extname(resolvedImport);
44425
+ resolvedImport = path30.resolve(testDir, importPath);
44426
+ const existingExt = path30.extname(resolvedImport);
43943
44427
  if (!existingExt) {
43944
44428
  for (const extToTry of [
43945
44429
  ".ts",
@@ -43959,12 +44443,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
43959
44443
  } else {
43960
44444
  continue;
43961
44445
  }
43962
- const importBasename = path29.basename(resolvedImport, path29.extname(resolvedImport));
43963
- const importDir = path29.dirname(resolvedImport);
44446
+ const importBasename = path30.basename(resolvedImport, path30.extname(resolvedImport));
44447
+ const importDir = path30.dirname(resolvedImport);
43964
44448
  for (const sourceFile of absoluteSourceFiles) {
43965
- const sourceDir = path29.dirname(sourceFile);
43966
- const sourceBasename = path29.basename(sourceFile, path29.extname(sourceFile));
43967
- const isRelatedDir = importDir === sourceDir || importDir === path29.join(sourceDir, "__tests__") || importDir === path29.join(sourceDir, "tests") || importDir === path29.join(sourceDir, "test") || importDir === path29.join(sourceDir, "spec");
44449
+ const sourceDir = path30.dirname(sourceFile);
44450
+ const sourceBasename = path30.basename(sourceFile, path30.extname(sourceFile));
44451
+ const isRelatedDir = importDir === sourceDir || importDir === path30.join(sourceDir, "__tests__") || importDir === path30.join(sourceDir, "tests") || importDir === path30.join(sourceDir, "test") || importDir === path30.join(sourceDir, "spec");
43968
44452
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
43969
44453
  dedupePush(testFiles, testFile);
43970
44454
  break;
@@ -43977,8 +44461,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
43977
44461
  while (match !== null) {
43978
44462
  const importPath = match[1];
43979
44463
  if (importPath.startsWith(".")) {
43980
- let resolvedImport = path29.resolve(testDir, importPath);
43981
- const existingExt = path29.extname(resolvedImport);
44464
+ let resolvedImport = path30.resolve(testDir, importPath);
44465
+ const existingExt = path30.extname(resolvedImport);
43982
44466
  if (!existingExt) {
43983
44467
  for (const extToTry of [
43984
44468
  ".ts",
@@ -43995,12 +44479,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
43995
44479
  }
43996
44480
  }
43997
44481
  }
43998
- const importDir = path29.dirname(resolvedImport);
43999
- const importBasename = path29.basename(resolvedImport, path29.extname(resolvedImport));
44482
+ const importDir = path30.dirname(resolvedImport);
44483
+ const importBasename = path30.basename(resolvedImport, path30.extname(resolvedImport));
44000
44484
  for (const sourceFile of absoluteSourceFiles) {
44001
- const sourceDir = path29.dirname(sourceFile);
44002
- const sourceBasename = path29.basename(sourceFile, path29.extname(sourceFile));
44003
- const isRelatedDir = importDir === sourceDir || importDir === path29.join(sourceDir, "__tests__") || importDir === path29.join(sourceDir, "tests") || importDir === path29.join(sourceDir, "test") || importDir === path29.join(sourceDir, "spec");
44485
+ const sourceDir = path30.dirname(sourceFile);
44486
+ const sourceBasename = path30.basename(sourceFile, path30.extname(sourceFile));
44487
+ const isRelatedDir = importDir === sourceDir || importDir === path30.join(sourceDir, "__tests__") || importDir === path30.join(sourceDir, "tests") || importDir === path30.join(sourceDir, "test") || importDir === path30.join(sourceDir, "spec");
44004
44488
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
44005
44489
  dedupePush(testFiles, testFile);
44006
44490
  break;
@@ -44103,8 +44587,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
44103
44587
  return ["mvn", "test"];
44104
44588
  case "gradle": {
44105
44589
  const isWindows = process.platform === "win32";
44106
- const hasGradlewBat = fs16.existsSync(path29.join(baseDir, "gradlew.bat"));
44107
- const hasGradlew = fs16.existsSync(path29.join(baseDir, "gradlew"));
44590
+ const hasGradlewBat = fs16.existsSync(path30.join(baseDir, "gradlew.bat"));
44591
+ const hasGradlew = fs16.existsSync(path30.join(baseDir, "gradlew"));
44108
44592
  if (hasGradlewBat && isWindows)
44109
44593
  return ["gradlew.bat", "test"];
44110
44594
  if (hasGradlew)
@@ -44121,7 +44605,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir) {
44121
44605
  "cmake-build-release",
44122
44606
  "out"
44123
44607
  ];
44124
- const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path29.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
44608
+ const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path30.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
44125
44609
  return ["ctest", "--test-dir", actualBuildDir];
44126
44610
  }
44127
44611
  case "swift-test":
@@ -44774,7 +45258,7 @@ var init_test_runner = __esm(() => {
44774
45258
  const sourceFiles = args.files.filter((file3) => {
44775
45259
  if (directTestFiles.includes(file3))
44776
45260
  return false;
44777
- const ext = path29.extname(file3).toLowerCase();
45261
+ const ext = path30.extname(file3).toLowerCase();
44778
45262
  return SOURCE_EXTENSIONS.has(ext);
44779
45263
  });
44780
45264
  const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
@@ -44809,7 +45293,7 @@ var init_test_runner = __esm(() => {
44809
45293
  if (isConventionTestFilePath(f)) {
44810
45294
  return false;
44811
45295
  }
44812
- const ext = path29.extname(f).toLowerCase();
45296
+ const ext = path30.extname(f).toLowerCase();
44813
45297
  return SOURCE_EXTENSIONS.has(ext);
44814
45298
  });
44815
45299
  if (sourceFiles.length === 0) {
@@ -44836,7 +45320,7 @@ var init_test_runner = __esm(() => {
44836
45320
  if (isConventionTestFilePath(f)) {
44837
45321
  return false;
44838
45322
  }
44839
- const ext = path29.extname(f).toLowerCase();
45323
+ const ext = path30.extname(f).toLowerCase();
44840
45324
  return SOURCE_EXTENSIONS.has(ext);
44841
45325
  });
44842
45326
  if (sourceFiles.length === 0) {
@@ -44854,8 +45338,8 @@ var init_test_runner = __esm(() => {
44854
45338
  const impactResult = await analyzeImpact(sourceFiles, workingDir);
44855
45339
  if (impactResult.impactedTests.length > 0) {
44856
45340
  testFiles = impactResult.impactedTests.map((absPath) => {
44857
- const relativePath = path29.relative(workingDir, absPath);
44858
- return path29.isAbsolute(relativePath) ? absPath : relativePath;
45341
+ const relativePath = path30.relative(workingDir, absPath);
45342
+ return path30.isAbsolute(relativePath) ? absPath : relativePath;
44859
45343
  });
44860
45344
  } else {
44861
45345
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -44931,7 +45415,7 @@ var init_test_runner = __esm(() => {
44931
45415
 
44932
45416
  // src/services/preflight-service.ts
44933
45417
  import * as fs17 from "fs";
44934
- import * as path30 from "path";
45418
+ import * as path31 from "path";
44935
45419
  function validateDirectoryPath(dir) {
44936
45420
  if (!dir || typeof dir !== "string") {
44937
45421
  throw new Error("Directory path is required");
@@ -44939,8 +45423,8 @@ function validateDirectoryPath(dir) {
44939
45423
  if (dir.includes("..")) {
44940
45424
  throw new Error("Directory path must not contain path traversal sequences");
44941
45425
  }
44942
- const normalized = path30.normalize(dir);
44943
- const absolutePath = path30.isAbsolute(normalized) ? normalized : path30.resolve(normalized);
45426
+ const normalized = path31.normalize(dir);
45427
+ const absolutePath = path31.isAbsolute(normalized) ? normalized : path31.resolve(normalized);
44944
45428
  return absolutePath;
44945
45429
  }
44946
45430
  function validateTimeout(timeoutMs, defaultValue) {
@@ -44963,7 +45447,7 @@ function validateTimeout(timeoutMs, defaultValue) {
44963
45447
  }
44964
45448
  function getPackageVersion(dir) {
44965
45449
  try {
44966
- const packagePath = path30.join(dir, "package.json");
45450
+ const packagePath = path31.join(dir, "package.json");
44967
45451
  if (fs17.existsSync(packagePath)) {
44968
45452
  const content = fs17.readFileSync(packagePath, "utf-8");
44969
45453
  const pkg = JSON.parse(content);
@@ -44974,7 +45458,7 @@ function getPackageVersion(dir) {
44974
45458
  }
44975
45459
  function getChangelogVersion(dir) {
44976
45460
  try {
44977
- const changelogPath = path30.join(dir, "CHANGELOG.md");
45461
+ const changelogPath = path31.join(dir, "CHANGELOG.md");
44978
45462
  if (fs17.existsSync(changelogPath)) {
44979
45463
  const content = fs17.readFileSync(changelogPath, "utf-8");
44980
45464
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
@@ -44988,7 +45472,7 @@ function getChangelogVersion(dir) {
44988
45472
  function getVersionFileVersion(dir) {
44989
45473
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
44990
45474
  for (const file3 of possibleFiles) {
44991
- const filePath = path30.join(dir, file3);
45475
+ const filePath = path31.join(dir, file3);
44992
45476
  if (fs17.existsSync(filePath)) {
44993
45477
  try {
44994
45478
  const content = fs17.readFileSync(filePath, "utf-8").trim();
@@ -45004,9 +45488,9 @@ function getVersionFileVersion(dir) {
45004
45488
  async function runVersionCheck(dir, _timeoutMs) {
45005
45489
  const startTime = Date.now();
45006
45490
  try {
45007
- const packageVersion = getPackageVersion(dir);
45008
- const changelogVersion = getChangelogVersion(dir);
45009
- const versionFileVersion = getVersionFileVersion(dir);
45491
+ const packageVersion = _internals18.getPackageVersion(dir);
45492
+ const changelogVersion = _internals18.getChangelogVersion(dir);
45493
+ const versionFileVersion = _internals18.getVersionFileVersion(dir);
45010
45494
  const versions3 = [];
45011
45495
  if (packageVersion)
45012
45496
  versions3.push(`package.json: ${packageVersion}`);
@@ -45315,7 +45799,7 @@ async function runEvidenceCheck(dir) {
45315
45799
  async function runRequirementCoverageCheck(dir, currentPhase) {
45316
45800
  const startTime = Date.now();
45317
45801
  try {
45318
- const specPath = path30.join(dir, ".swarm", "spec.md");
45802
+ const specPath = path31.join(dir, ".swarm", "spec.md");
45319
45803
  if (!fs17.existsSync(specPath)) {
45320
45804
  return {
45321
45805
  type: "req_coverage",
@@ -45356,7 +45840,7 @@ async function runPreflight(dir, phase, config3) {
45356
45840
  const reportId = `preflight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
45357
45841
  let validatedDir;
45358
45842
  try {
45359
- validatedDir = validateDirectoryPath(dir);
45843
+ validatedDir = _internals18.validateDirectoryPath(dir);
45360
45844
  } catch (error93) {
45361
45845
  return {
45362
45846
  id: reportId,
@@ -45376,7 +45860,7 @@ async function runPreflight(dir, phase, config3) {
45376
45860
  }
45377
45861
  let validatedTimeout;
45378
45862
  try {
45379
- validatedTimeout = validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
45863
+ validatedTimeout = _internals18.validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
45380
45864
  } catch (error93) {
45381
45865
  return {
45382
45866
  id: reportId,
@@ -45417,12 +45901,12 @@ async function runPreflight(dir, phase, config3) {
45417
45901
  });
45418
45902
  const checks5 = [];
45419
45903
  log("[Preflight] Running lint check...");
45420
- const lintResult = await runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
45904
+ const lintResult = await _internals18.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
45421
45905
  checks5.push(lintResult);
45422
45906
  log(`[Preflight] Lint check: ${lintResult.status} ${lintResult.message}`);
45423
45907
  if (!cfg.skipTests) {
45424
45908
  log("[Preflight] Running tests check...");
45425
- const testsResult = await runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
45909
+ const testsResult = await _internals18.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
45426
45910
  checks5.push(testsResult);
45427
45911
  log(`[Preflight] Tests check: ${testsResult.status} ${testsResult.message}`);
45428
45912
  } else {
@@ -45434,7 +45918,7 @@ async function runPreflight(dir, phase, config3) {
45434
45918
  }
45435
45919
  if (!cfg.skipSecrets) {
45436
45920
  log("[Preflight] Running secrets check...");
45437
- const secretsResult = await runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
45921
+ const secretsResult = await _internals18.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
45438
45922
  checks5.push(secretsResult);
45439
45923
  log(`[Preflight] Secrets check: ${secretsResult.status} ${secretsResult.message}`);
45440
45924
  } else {
@@ -45446,7 +45930,7 @@ async function runPreflight(dir, phase, config3) {
45446
45930
  }
45447
45931
  if (!cfg.skipEvidence) {
45448
45932
  log("[Preflight] Running evidence check...");
45449
- const evidenceResult = await runEvidenceCheck(validatedDir);
45933
+ const evidenceResult = await _internals18.runEvidenceCheck(validatedDir);
45450
45934
  checks5.push(evidenceResult);
45451
45935
  log(`[Preflight] Evidence check: ${evidenceResult.status} ${evidenceResult.message}`);
45452
45936
  } else {
@@ -45457,12 +45941,12 @@ async function runPreflight(dir, phase, config3) {
45457
45941
  });
45458
45942
  }
45459
45943
  log("[Preflight] Running requirement coverage check...");
45460
- const reqCoverageResult = await runRequirementCoverageCheck(validatedDir, phase);
45944
+ const reqCoverageResult = await _internals18.runRequirementCoverageCheck(validatedDir, phase);
45461
45945
  checks5.push(reqCoverageResult);
45462
45946
  log(`[Preflight] Requirement coverage check: ${reqCoverageResult.status} ${reqCoverageResult.message}`);
45463
45947
  if (!cfg.skipVersion) {
45464
45948
  log("[Preflight] Running version check...");
45465
- const versionResult = await runVersionCheck(validatedDir, cfg.checkTimeoutMs);
45949
+ const versionResult = await _internals18.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
45466
45950
  checks5.push(versionResult);
45467
45951
  log(`[Preflight] Version check: ${versionResult.status} ${versionResult.message}`);
45468
45952
  } else {
@@ -45525,10 +46009,10 @@ function formatPreflightMarkdown(report) {
45525
46009
  async function handlePreflightCommand(directory, _args) {
45526
46010
  const plan = await loadPlan(directory);
45527
46011
  const phase = plan?.current_phase ?? 1;
45528
- const report = await runPreflight(directory, phase);
45529
- return formatPreflightMarkdown(report);
46012
+ const report = await _internals18.runPreflight(directory, phase);
46013
+ return _internals18.formatPreflightMarkdown(report);
45530
46014
  }
45531
- var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG;
46015
+ var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG, _internals18;
45532
46016
  var init_preflight_service = __esm(() => {
45533
46017
  init_manager2();
45534
46018
  init_manager();
@@ -45545,6 +46029,22 @@ var init_preflight_service = __esm(() => {
45545
46029
  testScope: "convention",
45546
46030
  linter: "biome"
45547
46031
  };
46032
+ _internals18 = {
46033
+ runPreflight,
46034
+ formatPreflightMarkdown,
46035
+ handlePreflightCommand,
46036
+ validateDirectoryPath,
46037
+ validateTimeout,
46038
+ getPackageVersion,
46039
+ getChangelogVersion,
46040
+ getVersionFileVersion,
46041
+ runVersionCheck,
46042
+ runLintCheck,
46043
+ runTestsCheck,
46044
+ runSecretsCheck,
46045
+ runEvidenceCheck,
46046
+ runRequirementCoverageCheck
46047
+ };
45548
46048
  });
45549
46049
 
45550
46050
  // src/commands/preflight.ts
@@ -46418,7 +46918,7 @@ var init_manager3 = __esm(() => {
46418
46918
 
46419
46919
  // src/commands/reset.ts
46420
46920
  import * as fs18 from "fs";
46421
- import * as path31 from "path";
46921
+ import * as path32 from "path";
46422
46922
  async function handleResetCommand(directory, args) {
46423
46923
  const hasConfirm = args.includes("--confirm");
46424
46924
  if (!hasConfirm) {
@@ -46458,7 +46958,7 @@ async function handleResetCommand(directory, args) {
46458
46958
  }
46459
46959
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
46460
46960
  try {
46461
- const rootPath = path31.join(directory, filename);
46961
+ const rootPath = path32.join(directory, filename);
46462
46962
  if (fs18.existsSync(rootPath)) {
46463
46963
  fs18.unlinkSync(rootPath);
46464
46964
  results.push(`- \u2705 Deleted ${filename} (root)`);
@@ -46498,7 +46998,7 @@ var init_reset = __esm(() => {
46498
46998
 
46499
46999
  // src/commands/reset-session.ts
46500
47000
  import * as fs19 from "fs";
46501
- import * as path32 from "path";
47001
+ import * as path33 from "path";
46502
47002
  async function handleResetSessionCommand(directory, _args) {
46503
47003
  const results = [];
46504
47004
  try {
@@ -46513,13 +47013,13 @@ async function handleResetSessionCommand(directory, _args) {
46513
47013
  results.push("\u274C Failed to delete state.json");
46514
47014
  }
46515
47015
  try {
46516
- const sessionDir = path32.dirname(validateSwarmPath(directory, "session/state.json"));
47016
+ const sessionDir = path33.dirname(validateSwarmPath(directory, "session/state.json"));
46517
47017
  if (fs19.existsSync(sessionDir)) {
46518
47018
  const files = fs19.readdirSync(sessionDir);
46519
47019
  const otherFiles = files.filter((f) => f !== "state.json");
46520
47020
  let deletedCount = 0;
46521
47021
  for (const file3 of otherFiles) {
46522
- const filePath = path32.join(sessionDir, file3);
47022
+ const filePath = path33.join(sessionDir, file3);
46523
47023
  if (fs19.lstatSync(filePath).isFile()) {
46524
47024
  fs19.unlinkSync(filePath);
46525
47025
  deletedCount++;
@@ -46551,7 +47051,7 @@ var init_reset_session = __esm(() => {
46551
47051
  });
46552
47052
 
46553
47053
  // src/summaries/manager.ts
46554
- import * as path33 from "path";
47054
+ import * as path34 from "path";
46555
47055
  function sanitizeSummaryId(id) {
46556
47056
  if (!id || id.length === 0) {
46557
47057
  throw new Error("Invalid summary ID: empty string");
@@ -46574,7 +47074,7 @@ function sanitizeSummaryId(id) {
46574
47074
  }
46575
47075
  async function loadFullOutput(directory, id) {
46576
47076
  const sanitizedId = sanitizeSummaryId(id);
46577
- const relativePath = path33.join("summaries", `${sanitizedId}.json`);
47077
+ const relativePath = path34.join("summaries", `${sanitizedId}.json`);
46578
47078
  validateSwarmPath(directory, relativePath);
46579
47079
  const content = await readSwarmFileAsync(directory, relativePath);
46580
47080
  if (content === null) {
@@ -46637,7 +47137,7 @@ var init_retrieve = __esm(() => {
46637
47137
 
46638
47138
  // src/commands/rollback.ts
46639
47139
  import * as fs20 from "fs";
46640
- import * as path34 from "path";
47140
+ import * as path35 from "path";
46641
47141
  async function handleRollbackCommand(directory, args) {
46642
47142
  const phaseArg = args[0];
46643
47143
  if (!phaseArg) {
@@ -46702,8 +47202,8 @@ async function handleRollbackCommand(directory, args) {
46702
47202
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
46703
47203
  continue;
46704
47204
  }
46705
- const src = path34.join(checkpointDir, file3);
46706
- const dest = path34.join(swarmDir, file3);
47205
+ const src = path35.join(checkpointDir, file3);
47206
+ const dest = path35.join(swarmDir, file3);
46707
47207
  try {
46708
47208
  fs20.cpSync(src, dest, { recursive: true, force: true });
46709
47209
  successes.push(file3);
@@ -46722,12 +47222,12 @@ async function handleRollbackCommand(directory, args) {
46722
47222
  ].join(`
46723
47223
  `);
46724
47224
  }
46725
- const existingLedgerPath = path34.join(swarmDir, "plan-ledger.jsonl");
47225
+ const existingLedgerPath = path35.join(swarmDir, "plan-ledger.jsonl");
46726
47226
  if (fs20.existsSync(existingLedgerPath)) {
46727
47227
  fs20.unlinkSync(existingLedgerPath);
46728
47228
  }
46729
47229
  try {
46730
- const planJsonPath = path34.join(swarmDir, "plan.json");
47230
+ const planJsonPath = path35.join(swarmDir, "plan.json");
46731
47231
  if (fs20.existsSync(planJsonPath)) {
46732
47232
  const planRaw = fs20.readFileSync(planJsonPath, "utf-8");
46733
47233
  const plan = PlanSchema.parse(JSON.parse(planRaw));
@@ -46805,9 +47305,9 @@ async function handleSimulateCommand(directory, args) {
46805
47305
  const report = reportLines.filter(Boolean).join(`
46806
47306
  `);
46807
47307
  const fs21 = await import("fs/promises");
46808
- const path35 = await import("path");
46809
- const reportPath = path35.join(directory, ".swarm", "simulate-report.md");
46810
- await fs21.mkdir(path35.dirname(reportPath), { recursive: true });
47308
+ const path36 = await import("path");
47309
+ const reportPath = path36.join(directory, ".swarm", "simulate-report.md");
47310
+ await fs21.mkdir(path36.dirname(reportPath), { recursive: true });
46811
47311
  await fs21.writeFile(reportPath, report, "utf-8");
46812
47312
  return `${darkMatterPairs.length} hidden coupling pairs detected`;
46813
47313
  }
@@ -46982,6 +47482,7 @@ async function handleStatusCommand(directory, agents) {
46982
47482
  return formatStatusMarkdown(statusData);
46983
47483
  }
46984
47484
  var init_status_service = __esm(() => {
47485
+ init_extractors();
46985
47486
  init_utils2();
46986
47487
  init_manager();
46987
47488
  init_state();
@@ -47161,7 +47662,7 @@ __export(exports_commands, {
47161
47662
  COMMAND_REGISTRY: () => COMMAND_REGISTRY
47162
47663
  });
47163
47664
  import fs21 from "fs";
47164
- import path35 from "path";
47665
+ import path36 from "path";
47165
47666
  function buildHelpText() {
47166
47667
  const lines = ["## Swarm Commands", ""];
47167
47668
  const CATEGORIES = [
@@ -47270,9 +47771,9 @@ function createSwarmCommandHandler(directory, agents) {
47270
47771
  return;
47271
47772
  }
47272
47773
  let isFirstRun = false;
47273
- const sentinelPath = path35.join(directory, ".swarm", ".first-run-complete");
47774
+ const sentinelPath = path36.join(directory, ".swarm", ".first-run-complete");
47274
47775
  try {
47275
- const swarmDir = path35.join(directory, ".swarm");
47776
+ const swarmDir = path36.join(directory, ".swarm");
47276
47777
  fs21.mkdirSync(swarmDir, { recursive: true });
47277
47778
  fs21.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
47278
47779
  `, { flag: "wx" });
@@ -47387,7 +47888,7 @@ function findSimilarCommands(query) {
47387
47888
  return cmd.toLowerCase().includes(q) || q.includes(cmd.toLowerCase());
47388
47889
  }).map((cmd) => ({
47389
47890
  cmd,
47390
- score: cmd.length < q.length ? q.length - cmd.length : levenshteinDistance(q, cmd)
47891
+ score: cmd.length < q.length ? q.length - cmd.length : _internals19.levenshteinDistance(q, cmd)
47391
47892
  }));
47392
47893
  scored.sort((a, b) => a.score - b.score);
47393
47894
  return scored.slice(0, 3).map((s) => s.cmd);
@@ -47417,11 +47918,11 @@ async function handleHelpCommand(ctx) {
47417
47918
  return buildHelpText2();
47418
47919
  }
47419
47920
  const tokens = targetCommand.split(/\s+/);
47420
- const resolved = resolveCommand(tokens);
47921
+ const resolved = _internals19.resolveCommand(tokens);
47421
47922
  if (resolved) {
47422
- return buildDetailedHelp(resolved.key, resolved.entry);
47923
+ return _internals19.buildDetailedHelp(resolved.key, resolved.entry);
47423
47924
  }
47424
- const similar = findSimilarCommands(targetCommand);
47925
+ const similar = _internals19.findSimilarCommands(targetCommand);
47425
47926
  const { buildHelpText: fullHelp } = await Promise.resolve().then(() => (init_commands(), exports_commands));
47426
47927
  if (similar.length > 0) {
47427
47928
  return `Command '/swarm ${targetCommand}' not found.
@@ -47457,24 +47958,24 @@ function validateAliases() {
47457
47958
  }
47458
47959
  aliasTargets.get(target).push(name);
47459
47960
  const visited = new Set;
47460
- const path36 = [];
47961
+ const path37 = [];
47461
47962
  let current = target;
47462
47963
  while (current) {
47463
47964
  const currentEntry = COMMAND_REGISTRY[current];
47464
47965
  if (!currentEntry)
47465
47966
  break;
47466
47967
  if (visited.has(current)) {
47467
- const cycleStart = path36.indexOf(current);
47968
+ const cycleStart = path37.indexOf(current);
47468
47969
  const fullChain = [
47469
47970
  name,
47470
- ...path36.slice(0, cycleStart > 0 ? cycleStart : path36.length),
47971
+ ...path37.slice(0, cycleStart > 0 ? cycleStart : path37.length),
47471
47972
  current
47472
47973
  ].join(" \u2192 ");
47473
47974
  errors5.push(`Circular alias detected: ${fullChain}`);
47474
47975
  break;
47475
47976
  }
47476
47977
  visited.add(current);
47477
- path36.push(current);
47978
+ path37.push(current);
47478
47979
  current = currentEntry.aliasOf || "";
47479
47980
  }
47480
47981
  }
@@ -47515,7 +48016,7 @@ function resolveCommand(tokens) {
47515
48016
  }
47516
48017
  return null;
47517
48018
  }
47518
- var COMMAND_REGISTRY, VALID_COMMANDS, validation;
48019
+ var COMMAND_REGISTRY, VALID_COMMANDS, _internals19, validation;
47519
48020
  var init_registry = __esm(() => {
47520
48021
  init_acknowledge_spec_drift();
47521
48022
  init_agents();
@@ -47576,7 +48077,7 @@ var init_registry = __esm(() => {
47576
48077
  clashesWithNativeCcCommand: "/agents"
47577
48078
  },
47578
48079
  help: {
47579
- handler: (ctx) => handleHelpCommand(ctx),
48080
+ handler: (ctx) => _internals19.handleHelpCommand(ctx),
47580
48081
  description: "Show help for swarm commands",
47581
48082
  category: "core",
47582
48083
  args: "[command]",
@@ -47906,7 +48407,15 @@ var init_registry = __esm(() => {
47906
48407
  }
47907
48408
  };
47908
48409
  VALID_COMMANDS = Object.keys(COMMAND_REGISTRY);
47909
- validation = validateAliases();
48410
+ _internals19 = {
48411
+ handleHelpCommand,
48412
+ validateAliases,
48413
+ resolveCommand,
48414
+ levenshteinDistance,
48415
+ findSimilarCommands,
48416
+ buildDetailedHelp
48417
+ };
48418
+ validation = _internals19.validateAliases();
47910
48419
  if (!validation.valid) {
47911
48420
  throw new Error(`COMMAND_REGISTRY alias validation failed:
47912
48421
  ${validation.errors.join(`
@@ -47926,53 +48435,53 @@ init_cache_paths();
47926
48435
  init_constants();
47927
48436
  import * as fs22 from "fs";
47928
48437
  import * as os7 from "os";
47929
- import * as path36 from "path";
48438
+ import * as path37 from "path";
47930
48439
  var { version: version4 } = package_default;
47931
48440
  var CONFIG_DIR = getPluginConfigDir();
47932
- var OPENCODE_CONFIG_PATH = path36.join(CONFIG_DIR, "opencode.json");
47933
- var PLUGIN_CONFIG_PATH = path36.join(CONFIG_DIR, "opencode-swarm.json");
47934
- var PROMPTS_DIR = path36.join(CONFIG_DIR, "opencode-swarm");
48441
+ var OPENCODE_CONFIG_PATH = path37.join(CONFIG_DIR, "opencode.json");
48442
+ var PLUGIN_CONFIG_PATH = path37.join(CONFIG_DIR, "opencode-swarm.json");
48443
+ var PROMPTS_DIR = path37.join(CONFIG_DIR, "opencode-swarm");
47935
48444
  var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
47936
48445
  var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
47937
48446
  function isSafeCachePath(p) {
47938
- const resolved = path36.resolve(p);
47939
- const home = path36.resolve(os7.homedir());
48447
+ const resolved = path37.resolve(p);
48448
+ const home = path37.resolve(os7.homedir());
47940
48449
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
47941
48450
  return false;
47942
48451
  }
47943
- const segments = resolved.split(path36.sep).filter((s) => s.length > 0);
48452
+ const segments = resolved.split(path37.sep).filter((s) => s.length > 0);
47944
48453
  if (segments.length < 4) {
47945
48454
  return false;
47946
48455
  }
47947
- const leaf = path36.basename(resolved);
48456
+ const leaf = path37.basename(resolved);
47948
48457
  if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
47949
48458
  return false;
47950
48459
  }
47951
- const parent = path36.basename(path36.dirname(resolved));
48460
+ const parent = path37.basename(path37.dirname(resolved));
47952
48461
  if (parent !== "packages" && parent !== "node_modules") {
47953
48462
  return false;
47954
48463
  }
47955
- const grandparent = path36.basename(path36.dirname(path36.dirname(resolved)));
48464
+ const grandparent = path37.basename(path37.dirname(path37.dirname(resolved)));
47956
48465
  if (grandparent !== "opencode") {
47957
48466
  return false;
47958
48467
  }
47959
48468
  return true;
47960
48469
  }
47961
48470
  function isSafeLockFilePath(p) {
47962
- const resolved = path36.resolve(p);
47963
- const home = path36.resolve(os7.homedir());
48471
+ const resolved = path37.resolve(p);
48472
+ const home = path37.resolve(os7.homedir());
47964
48473
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
47965
48474
  return false;
47966
48475
  }
47967
- const segments = resolved.split(path36.sep).filter((s) => s.length > 0);
48476
+ const segments = resolved.split(path37.sep).filter((s) => s.length > 0);
47968
48477
  if (segments.length < 4) {
47969
48478
  return false;
47970
48479
  }
47971
- const leaf = path36.basename(resolved);
48480
+ const leaf = path37.basename(resolved);
47972
48481
  if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
47973
48482
  return false;
47974
48483
  }
47975
- const parent = path36.basename(path36.dirname(resolved));
48484
+ const parent = path37.basename(path37.dirname(resolved));
47976
48485
  if (parent !== "opencode") {
47977
48486
  return false;
47978
48487
  }
@@ -47998,8 +48507,8 @@ function saveJson(filepath, data) {
47998
48507
  }
47999
48508
  function writeProjectConfigIfMissing(cwd) {
48000
48509
  try {
48001
- const opencodeDir = path36.join(cwd, ".opencode");
48002
- const projectConfigPath = path36.join(opencodeDir, "opencode-swarm.json");
48510
+ const opencodeDir = path37.join(cwd, ".opencode");
48511
+ const projectConfigPath = path37.join(opencodeDir, "opencode-swarm.json");
48003
48512
  if (fs22.existsSync(projectConfigPath)) {
48004
48513
  return;
48005
48514
  }
@@ -48020,7 +48529,7 @@ async function install() {
48020
48529
  `);
48021
48530
  ensureDir(CONFIG_DIR);
48022
48531
  ensureDir(PROMPTS_DIR);
48023
- const LEGACY_CONFIG_PATH = path36.join(CONFIG_DIR, "config.json");
48532
+ const LEGACY_CONFIG_PATH = path37.join(CONFIG_DIR, "config.json");
48024
48533
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
48025
48534
  if (!opencodeConfig) {
48026
48535
  const legacyConfig = loadJson(LEGACY_CONFIG_PATH);