opencode-swarm 7.33.0 → 7.33.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -34,7 +34,7 @@ var package_default;
34
34
  var init_package = __esm(() => {
35
35
  package_default = {
36
36
  name: "opencode-swarm",
37
- version: "7.33.0",
37
+ version: "7.33.2",
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",
@@ -14580,9 +14580,138 @@ function emit(event, data) {
14580
14580
  }
14581
14581
  } catch {}
14582
14582
  }
14583
- var _writeStream = null, _listeners, _disabled = false;
14583
+ var _writeStream = null, _listeners, _disabled = false, telemetry, _internals2;
14584
14584
  var init_telemetry = __esm(() => {
14585
14585
  _listeners = [];
14586
+ telemetry = {
14587
+ sessionStarted(sessionId, agentName) {
14588
+ _internals2.emit("session_started", { sessionId, agentName });
14589
+ },
14590
+ sessionEnded(sessionId, reason) {
14591
+ _internals2.emit("session_ended", { sessionId, reason });
14592
+ },
14593
+ agentActivated(sessionId, agentName, oldName) {
14594
+ _internals2.emit("agent_activated", { sessionId, agentName, oldName });
14595
+ },
14596
+ delegationBegin(sessionId, agentName, taskId) {
14597
+ _internals2.emit("delegation_begin", { sessionId, agentName, taskId });
14598
+ },
14599
+ delegationEnd(sessionId, agentName, taskId, result) {
14600
+ _internals2.emit("delegation_end", { sessionId, agentName, taskId, result });
14601
+ },
14602
+ taskStateChanged(sessionId, taskId, newState, oldState) {
14603
+ _internals2.emit("task_state_changed", {
14604
+ sessionId,
14605
+ taskId,
14606
+ newState,
14607
+ oldState
14608
+ });
14609
+ },
14610
+ gatePassed(sessionId, gate, taskId) {
14611
+ _internals2.emit("gate_passed", { sessionId, gate, taskId });
14612
+ },
14613
+ gateParseError(taskId, error49) {
14614
+ _internals2.emit("gate_parse_error", {
14615
+ taskId,
14616
+ errorName: error49.name,
14617
+ errorMessage: error49.message.slice(0, 200)
14618
+ });
14619
+ },
14620
+ gateFailed(sessionId, gate, taskId, reason) {
14621
+ _internals2.emit("gate_failed", { sessionId, gate, taskId, reason });
14622
+ },
14623
+ phaseChanged(sessionId, oldPhase, newPhase) {
14624
+ _internals2.emit("phase_changed", { sessionId, oldPhase, newPhase });
14625
+ },
14626
+ budgetUpdated(sessionId, budgetPct, agentName) {
14627
+ _internals2.emit("budget_updated", { sessionId, budgetPct, agentName });
14628
+ },
14629
+ modelFallback(sessionId, agentName, fromModel, toModel, reason) {
14630
+ _internals2.emit("model_fallback", {
14631
+ sessionId,
14632
+ agentName,
14633
+ fromModel,
14634
+ toModel,
14635
+ reason
14636
+ });
14637
+ },
14638
+ hardLimitHit(sessionId, agentName, limitType, value) {
14639
+ _internals2.emit("hard_limit_hit", {
14640
+ sessionId,
14641
+ agentName,
14642
+ limitType,
14643
+ value
14644
+ });
14645
+ },
14646
+ revisionLimitHit(sessionId, agentName) {
14647
+ _internals2.emit("revision_limit_hit", { sessionId, agentName });
14648
+ },
14649
+ loopDetected(sessionId, agentName, loopType) {
14650
+ _internals2.emit("loop_detected", { sessionId, agentName, loopType });
14651
+ },
14652
+ scopeViolation(sessionId, agentName, file2, reason) {
14653
+ _internals2.emit("scope_violation", { sessionId, agentName, file: file2, reason });
14654
+ },
14655
+ qaSkipViolation(sessionId, agentName, skipCount) {
14656
+ _internals2.emit("qa_skip_violation", { sessionId, agentName, skipCount });
14657
+ },
14658
+ heartbeat(sessionId) {
14659
+ _internals2.emit("heartbeat", { sessionId });
14660
+ },
14661
+ turboModeChanged(sessionId, enabled, agentName) {
14662
+ _internals2.emit("turbo_mode_changed", { sessionId, enabled, agentName });
14663
+ },
14664
+ autoOversightEscalation(sessionId, reason, interactionCount, deadlockCount, phase) {
14665
+ _internals2.emit("auto_oversight_escalation", {
14666
+ sessionId,
14667
+ reason,
14668
+ interactionCount,
14669
+ deadlockCount,
14670
+ phase
14671
+ });
14672
+ },
14673
+ environmentDetected(sessionId, hostOS, shellFamily, executionMode) {
14674
+ _internals2.emit("environment_detected", {
14675
+ sessionId,
14676
+ hostOS,
14677
+ shellFamily,
14678
+ executionMode
14679
+ });
14680
+ },
14681
+ prmPatternDetected(sessionId, pattern, severity, category, stepRange) {
14682
+ _internals2.emit("prm_pattern_detected", {
14683
+ sessionId,
14684
+ pattern,
14685
+ severity,
14686
+ category,
14687
+ stepRange
14688
+ });
14689
+ },
14690
+ prmCourseCorrectionInjected(sessionId, pattern, level) {
14691
+ _internals2.emit("prm_course_correction_injected", {
14692
+ sessionId,
14693
+ pattern,
14694
+ level
14695
+ });
14696
+ },
14697
+ prmEscalationTriggered(sessionId, pattern, level, occurrenceCount) {
14698
+ _internals2.emit("prm_escalation_triggered", {
14699
+ sessionId,
14700
+ pattern,
14701
+ level,
14702
+ occurrenceCount
14703
+ });
14704
+ },
14705
+ prmHardStop(sessionId, pattern, level, occurrenceCount) {
14706
+ _internals2.emit("prm_hard_stop", {
14707
+ sessionId,
14708
+ pattern,
14709
+ level,
14710
+ occurrenceCount
14711
+ });
14712
+ }
14713
+ };
14714
+ _internals2 = { telemetry, emit };
14586
14715
  });
14587
14716
 
14588
14717
  // src/utils/spec-hash.ts
@@ -14603,7 +14732,7 @@ async function computeSpecHash(directory) {
14603
14732
  return hash2;
14604
14733
  }
14605
14734
  async function isSpecStale(directory, plan) {
14606
- const currentHash = await _internals2.computeSpecHash(directory);
14735
+ const currentHash = await _internals3.computeSpecHash(directory);
14607
14736
  if (!plan.specHash) {
14608
14737
  return { stale: false };
14609
14738
  }
@@ -14623,9 +14752,9 @@ async function isSpecStale(directory, plan) {
14623
14752
  }
14624
14753
  return { stale: false };
14625
14754
  }
14626
- var _internals2;
14755
+ var _internals3;
14627
14756
  var init_spec_hash = __esm(() => {
14628
- _internals2 = {
14757
+ _internals3 = {
14629
14758
  computeSpecHash,
14630
14759
  isSpecStale
14631
14760
  };
@@ -14815,6 +14944,32 @@ async function appendLedgerEvent(directory, eventInput, options) {
14815
14944
  fs.renameSync(tempPath, ledgerPath);
14816
14945
  return event;
14817
14946
  }
14947
+ async function takeSnapshotWithRetry(directory, plan, options) {
14948
+ const MAX_RETRIES = 3;
14949
+ const TOTAL_ATTEMPTS = 1 + MAX_RETRIES;
14950
+ const telemetrySource = options?.source ?? "save_plan_tool";
14951
+ const snapshotOptions = { planHashAfter: options?.planHashAfter };
14952
+ let lastError;
14953
+ for (let attempt = 1;attempt <= TOTAL_ATTEMPTS; attempt++) {
14954
+ try {
14955
+ await takeSnapshotEvent(directory, plan, snapshotOptions);
14956
+ return;
14957
+ } catch (err) {
14958
+ lastError = err instanceof Error ? err : new Error(String(err));
14959
+ if (attempt < TOTAL_ATTEMPTS) {
14960
+ await new Promise((r) => setTimeout(r, 10 * 2 ** (attempt - 1)));
14961
+ }
14962
+ }
14963
+ }
14964
+ console.warn(`[takeSnapshotWithRetry] Snapshot failed after ${MAX_RETRIES} retries (${TOTAL_ATTEMPTS} attempts): ${lastError.message}`);
14965
+ try {
14966
+ emit("snapshot_failed", {
14967
+ error: lastError.message,
14968
+ retries: MAX_RETRIES,
14969
+ source: telemetrySource
14970
+ });
14971
+ } catch {}
14972
+ }
14818
14973
  async function takeSnapshotEvent(directory, plan, options) {
14819
14974
  const payloadHash = computePlanHash(plan);
14820
14975
  const snapshotPayload = {
@@ -15048,6 +15203,7 @@ async function loadLastApprovedPlan(directory, expectedPlanId) {
15048
15203
  var LEDGER_SCHEMA_VERSION = "1.1.0", LEDGER_FILENAME = "plan-ledger.jsonl", PLAN_JSON_FILENAME = "plan.json", LedgerStaleWriterError;
15049
15204
  var init_ledger = __esm(() => {
15050
15205
  init_plan_schema();
15206
+ init_telemetry();
15051
15207
  LedgerStaleWriterError = class LedgerStaleWriterError extends Error {
15052
15208
  constructor(message) {
15053
15209
  super(message);
@@ -15219,7 +15375,7 @@ async function loadPlan(directory) {
15219
15375
  const inSync = await isPlanMdInSync(directory, validated);
15220
15376
  if (!inSync) {
15221
15377
  try {
15222
- await _internals3.regeneratePlanMarkdown(directory, validated);
15378
+ await _internals4.regeneratePlanMarkdown(directory, validated);
15223
15379
  } catch (regenError) {
15224
15380
  warn(`Failed to regenerate plan.md: ${regenError instanceof Error ? regenError.message : String(regenError)}. Proceeding with plan.json only.`);
15225
15381
  }
@@ -15241,7 +15397,9 @@ async function loadPlan(directory) {
15241
15397
  try {
15242
15398
  const rebuilt = await replayFromLedger(directory);
15243
15399
  if (rebuilt) {
15244
- await rebuildPlan(directory, rebuilt);
15400
+ await rebuildPlan(directory, rebuilt, {
15401
+ reason: "ledger_hash_mismatch_recovery"
15402
+ });
15245
15403
  warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at .swarm/SWARM_PLAN.md if it exists.");
15246
15404
  return rebuilt;
15247
15405
  }
@@ -15249,7 +15407,9 @@ async function loadPlan(directory) {
15249
15407
  try {
15250
15408
  const approved = await loadLastApprovedPlan(directory, currentPlanId);
15251
15409
  if (approved) {
15252
- await rebuildPlan(directory, approved.plan);
15410
+ await rebuildPlan(directory, approved.plan, {
15411
+ reason: "approved_snapshot_fallback"
15412
+ });
15253
15413
  try {
15254
15414
  await takeSnapshotEvent(directory, approved.plan, {
15255
15415
  source: "recovery_from_approved_snapshot",
@@ -15326,7 +15486,9 @@ async function loadPlan(directory) {
15326
15486
  } else if (catchFirstEvent !== null && rawPlanId !== null) {
15327
15487
  const rebuilt = await replayFromLedger(directory);
15328
15488
  if (rebuilt) {
15329
- await rebuildPlan(directory, rebuilt);
15489
+ await rebuildPlan(directory, rebuilt, {
15490
+ reason: "validation_failure_recovery"
15491
+ });
15330
15492
  warn("[loadPlan] Rebuilt plan from ledger after validation failure. Projection was stale.");
15331
15493
  return rebuilt;
15332
15494
  }
@@ -15358,7 +15520,7 @@ async function loadPlan(directory) {
15358
15520
  const existingMutex = recoveryMutexes.get(resolvedDir);
15359
15521
  if (existingMutex) {
15360
15522
  await existingMutex;
15361
- const postRecoveryPlan = await _internals3.loadPlanJsonOnly(directory);
15523
+ const postRecoveryPlan = await _internals4.loadPlanJsonOnly(directory);
15362
15524
  if (postRecoveryPlan)
15363
15525
  return postRecoveryPlan;
15364
15526
  }
@@ -15418,7 +15580,7 @@ async function loadPlan(directory) {
15418
15580
  return null;
15419
15581
  }
15420
15582
  async function savePlanWithAutoAcknowledgedRemovals(directory, plan, source, reason, options) {
15421
- const existing = await _internals3.loadPlanJsonOnly(directory);
15583
+ const existing = await _internals4.loadPlanJsonOnly(directory);
15422
15584
  const newIds = new Set;
15423
15585
  for (const phase of plan.phases) {
15424
15586
  for (const task of phase.tasks)
@@ -15446,7 +15608,7 @@ async function savePlan(directory, plan, options) {
15446
15608
  const validated = PlanSchema.parse(plan);
15447
15609
  if (options?.preserveCompletedStatuses !== false) {
15448
15610
  try {
15449
- const currentPlan2 = await _internals3.loadPlanJsonOnly(directory);
15611
+ const currentPlan2 = await _internals4.loadPlanJsonOnly(directory);
15450
15612
  if (currentPlan2) {
15451
15613
  const completedTaskIds = new Set;
15452
15614
  for (const phase of currentPlan2.phases) {
@@ -15479,7 +15641,7 @@ async function savePlan(directory, plan, options) {
15479
15641
  phase.status = "pending";
15480
15642
  }
15481
15643
  }
15482
- const currentPlan = await _internals3.loadPlanJsonOnly(directory);
15644
+ const currentPlan = await _internals4.loadPlanJsonOnly(directory);
15483
15645
  const planId = derivePlanId(validated);
15484
15646
  const planHashForInit = computePlanHash(validated);
15485
15647
  if (!await ledgerExists(directory)) {
@@ -15624,7 +15786,7 @@ async function savePlan(directory, plan, options) {
15624
15786
  expectedHash: currentHash,
15625
15787
  planHashAfter: hashAfter,
15626
15788
  verifyValid: async () => {
15627
- const onDisk = await _internals3.loadPlanJsonOnly(directory);
15789
+ const onDisk = await _internals4.loadPlanJsonOnly(directory);
15628
15790
  if (!onDisk)
15629
15791
  return true;
15630
15792
  for (const p of onDisk.phases) {
@@ -15662,7 +15824,7 @@ async function savePlan(directory, plan, options) {
15662
15824
  expectedHash: currentHash,
15663
15825
  planHashAfter: hashAfter,
15664
15826
  verifyValid: async () => {
15665
- const onDisk = await _internals3.loadPlanJsonOnly(directory);
15827
+ const onDisk = await _internals4.loadPlanJsonOnly(directory);
15666
15828
  if (!onDisk)
15667
15829
  return true;
15668
15830
  for (const p of onDisk.phases) {
@@ -15687,12 +15849,9 @@ async function savePlan(directory, plan, options) {
15687
15849
  const SNAPSHOT_INTERVAL = 50;
15688
15850
  const latestSeq = await getLatestLedgerSeq(directory);
15689
15851
  if (latestSeq > 0 && latestSeq % SNAPSHOT_INTERVAL === 0) {
15690
- await takeSnapshotEvent(directory, validated, {
15691
- planHashAfter: hashAfter
15692
- }).catch((err) => {
15693
- if (process.env.DEBUG_SWARM) {
15694
- warn(`[savePlan] Periodic snapshot write failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
15695
- }
15852
+ await takeSnapshotWithRetry(directory, validated, {
15853
+ planHashAfter: hashAfter,
15854
+ source: "savePlan_manager"
15696
15855
  });
15697
15856
  }
15698
15857
  const swarmDir = path4.resolve(directory, ".swarm");
@@ -15706,6 +15865,17 @@ async function savePlan(directory, plan, options) {
15706
15865
  unlinkSync(tempPath);
15707
15866
  } catch {}
15708
15867
  }
15868
+ try {
15869
+ const markerPath = path4.join(swarmDir, ".plan-write-marker");
15870
+ const inProgressMarker = JSON.stringify({
15871
+ source: "plan_manager",
15872
+ timestamp: new Date().toISOString(),
15873
+ phases_count: validated.phases.length,
15874
+ tasks_count: validated.phases.reduce((sum, p) => sum + p.tasks.length, 0),
15875
+ in_progress: true
15876
+ });
15877
+ await bunWrite(markerPath, inProgressMarker);
15878
+ } catch {}
15709
15879
  try {
15710
15880
  const contentHash = computePlanContentHash(validated);
15711
15881
  const markdown = derivePlanMarkdown(validated);
@@ -15739,41 +15909,146 @@ ${markdown}`;
15739
15909
  source: "plan_manager",
15740
15910
  timestamp: new Date().toISOString(),
15741
15911
  phases_count: validated.phases.length,
15742
- tasks_count: tasksCount
15912
+ tasks_count: tasksCount,
15913
+ in_progress: false
15743
15914
  });
15744
15915
  await bunWrite(markerPath, marker);
15745
15916
  } catch {}
15746
15917
  }
15747
- async function rebuildPlan(directory, plan) {
15918
+ async function rebuildPlan(directory, plan, options) {
15748
15919
  const targetPlan = plan ?? await replayFromLedger(directory);
15749
15920
  if (!targetPlan)
15750
15921
  return null;
15751
15922
  const swarmDir = path4.join(directory, ".swarm");
15752
15923
  const planPath = path4.join(swarmDir, "plan.json");
15753
15924
  const mdPath = path4.join(swarmDir, "plan.md");
15754
- const tempPlanPath = path4.join(swarmDir, `plan.json.rebuild.${Date.now()}`);
15925
+ const tempPlanPath = path4.join(swarmDir, `plan.json.rebuild.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15755
15926
  await bunWrite(tempPlanPath, JSON.stringify(targetPlan, null, 2));
15756
15927
  renameSync2(tempPlanPath, planPath);
15757
- const contentHash = computePlanContentHash(targetPlan);
15758
- const markdown = derivePlanMarkdown(targetPlan);
15759
- const markdownWithHash = `<!-- PLAN_HASH: ${contentHash} -->
15760
- ${markdown}`;
15761
- const tempMdPath = path4.join(swarmDir, `plan.md.rebuild.${Date.now()}`);
15762
- await bunWrite(tempMdPath, markdownWithHash);
15763
- renameSync2(tempMdPath, mdPath);
15764
15928
  try {
15765
15929
  const markerPath = path4.join(swarmDir, ".plan-write-marker");
15766
- const tasksCount = targetPlan.phases.reduce((sum, phase) => sum + phase.tasks.length, 0);
15767
- const marker = JSON.stringify({
15930
+ const inProgressMarker = JSON.stringify({
15768
15931
  source: "plan_manager",
15769
15932
  timestamp: new Date().toISOString(),
15770
15933
  phases_count: targetPlan.phases.length,
15771
- tasks_count: tasksCount
15934
+ tasks_count: targetPlan.phases.reduce((sum, phase) => sum + phase.tasks.length, 0),
15935
+ in_progress: true
15772
15936
  });
15773
- await bunWrite(markerPath, marker);
15937
+ await bunWrite(markerPath, inProgressMarker);
15938
+ } catch {}
15939
+ try {
15940
+ const contentHash = computePlanContentHash(targetPlan);
15941
+ const markdown = derivePlanMarkdown(targetPlan);
15942
+ const markdownWithHash = `<!-- PLAN_HASH: ${contentHash} -->
15943
+ ${markdown}`;
15944
+ const tempMdPath = path4.join(swarmDir, `plan.md.rebuild.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
15945
+ await bunWrite(tempMdPath, markdownWithHash);
15946
+ renameSync2(tempMdPath, mdPath);
15947
+ } finally {
15948
+ try {
15949
+ const markerPath = path4.join(swarmDir, ".plan-write-marker");
15950
+ const tasksCount = targetPlan.phases.reduce((sum, phase) => sum + phase.tasks.length, 0);
15951
+ const marker = JSON.stringify({
15952
+ source: "plan_manager",
15953
+ timestamp: new Date().toISOString(),
15954
+ phases_count: targetPlan.phases.length,
15955
+ tasks_count: tasksCount,
15956
+ in_progress: false
15957
+ });
15958
+ await bunWrite(markerPath, marker);
15959
+ } catch {}
15960
+ }
15961
+ try {
15962
+ const planId = derivePlanId(targetPlan);
15963
+ const planHashAfter = computePlanHash(targetPlan);
15964
+ await appendLedgerEvent(directory, {
15965
+ event_type: "plan_rebuilt",
15966
+ source: "rebuildPlan",
15967
+ plan_id: planId,
15968
+ payload: {
15969
+ reason: options?.reason ?? "ledger_replay_recovery",
15970
+ phases_count: targetPlan.phases.length,
15971
+ tasks_count: targetPlan.phases.reduce((sum, p) => sum + p.tasks.length, 0)
15972
+ }
15973
+ }, { planHashAfter });
15774
15974
  } catch {}
15775
15975
  return targetPlan;
15776
15976
  }
15977
+ async function closePlanTerminalState(directory, plan, options) {
15978
+ const planId = derivePlanId(plan);
15979
+ const validated = PlanSchema.parse(plan);
15980
+ const hashAfter = computePlanHash(validated);
15981
+ for (const taskId of options.closedTaskIds) {
15982
+ let taskPhaseId;
15983
+ for (const phase of validated.phases) {
15984
+ if (phase.tasks.some((t) => t.id === taskId)) {
15985
+ taskPhaseId = phase.id;
15986
+ break;
15987
+ }
15988
+ }
15989
+ const fromStatus = options.originalStatuses?.get(taskId) ?? "in_progress";
15990
+ await appendLedgerEvent(directory, {
15991
+ plan_id: planId,
15992
+ event_type: "task_status_changed",
15993
+ task_id: taskId,
15994
+ phase_id: taskPhaseId,
15995
+ from_status: fromStatus,
15996
+ to_status: "closed",
15997
+ source: "close_terminal"
15998
+ }, { planHashAfter: hashAfter });
15999
+ }
16000
+ for (const phaseId of options.closedPhaseIds) {
16001
+ await appendLedgerEvent(directory, {
16002
+ plan_id: planId,
16003
+ event_type: "phase_completed",
16004
+ phase_id: phaseId,
16005
+ source: "close_terminal"
16006
+ }, { planHashAfter: hashAfter });
16007
+ }
16008
+ await takeSnapshotEvent(directory, validated, {
16009
+ planHashAfter: hashAfter,
16010
+ source: "close_terminal"
16011
+ });
16012
+ const swarmDir = path4.join(directory, ".swarm");
16013
+ const planPath = path4.join(swarmDir, "plan.json");
16014
+ const tempPlanPath = path4.join(swarmDir, `plan.json.close.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
16015
+ await bunWrite(tempPlanPath, JSON.stringify(validated, null, 2));
16016
+ renameSync2(tempPlanPath, planPath);
16017
+ try {
16018
+ const markerPath = path4.join(swarmDir, ".plan-write-marker");
16019
+ const inProgressMarker = JSON.stringify({
16020
+ source: "plan_manager_close",
16021
+ timestamp: new Date().toISOString(),
16022
+ phases_count: validated.phases.length,
16023
+ tasks_count: validated.phases.reduce((sum, phase) => sum + phase.tasks.length, 0),
16024
+ in_progress: true
16025
+ });
16026
+ await bunWrite(markerPath, inProgressMarker);
16027
+ } catch {}
16028
+ try {
16029
+ const mdPath = path4.join(swarmDir, "plan.md");
16030
+ const contentHash = computePlanContentHash(validated);
16031
+ const markdown = derivePlanMarkdown(validated);
16032
+ const markdownWithHash = `<!-- PLAN_HASH: ${contentHash} -->
16033
+ ${markdown}`;
16034
+ const mdTempPath = path4.join(swarmDir, `plan.md.close.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
16035
+ await bunWrite(mdTempPath, markdownWithHash);
16036
+ renameSync2(mdTempPath, mdPath);
16037
+ } finally {
16038
+ try {
16039
+ const markerPath = path4.join(swarmDir, ".plan-write-marker");
16040
+ const tasksCount = validated.phases.reduce((sum, phase) => sum + phase.tasks.length, 0);
16041
+ const marker = JSON.stringify({
16042
+ source: "plan_manager_close",
16043
+ timestamp: new Date().toISOString(),
16044
+ phases_count: validated.phases.length,
16045
+ tasks_count: tasksCount,
16046
+ in_progress: false
16047
+ });
16048
+ await bunWrite(markerPath, marker);
16049
+ } catch {}
16050
+ }
16051
+ }
15777
16052
  function derivePlanMarkdown(plan) {
15778
16053
  const statusMap = {
15779
16054
  pending: "PENDING",
@@ -16042,7 +16317,7 @@ function migrateLegacyPlan(planContent, swarmId) {
16042
16317
  };
16043
16318
  return plan;
16044
16319
  }
16045
- var PlanConcurrentModificationError, PlanTaskRemovalNotAcknowledgedError, startupLedgerCheckedWorkspaces, recoveryMutexes, _internals3, CAS_BACKOFF_START_MS = 5, CAS_BACKOFF_CAP_MS = 250, CAS_BACKOFF_JITTER = 0.25, CAS_MAX_RETRIES = 3;
16320
+ var PlanConcurrentModificationError, PlanTaskRemovalNotAcknowledgedError, startupLedgerCheckedWorkspaces, recoveryMutexes, _internals4, CAS_BACKOFF_START_MS = 5, CAS_BACKOFF_CAP_MS = 250, CAS_BACKOFF_JITTER = 0.25, CAS_MAX_RETRIES = 3;
16046
16321
  var init_manager = __esm(() => {
16047
16322
  init_plan_schema();
16048
16323
  init_utils2();
@@ -16068,7 +16343,7 @@ var init_manager = __esm(() => {
16068
16343
  };
16069
16344
  startupLedgerCheckedWorkspaces = new Set;
16070
16345
  recoveryMutexes = new Map;
16071
- _internals3 = {
16346
+ _internals4 = {
16072
16347
  loadPlan,
16073
16348
  loadPlanJsonOnly,
16074
16349
  regeneratePlanMarkdown
@@ -19763,11 +20038,11 @@ async function tryAcquireLock(directory, filePath, agent, taskId) {
19763
20038
  };
19764
20039
  return { acquired: true, lock };
19765
20040
  }
19766
- var import_proper_lockfile, LOCKS_DIR = ".swarm/locks", LOCK_TIMEOUT_MS, _internals4;
20041
+ var import_proper_lockfile, LOCKS_DIR = ".swarm/locks", LOCK_TIMEOUT_MS, _internals5;
19767
20042
  var init_file_locks = __esm(() => {
19768
20043
  import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
19769
20044
  LOCK_TIMEOUT_MS = 5 * 60 * 1000;
19770
- _internals4 = {
20045
+ _internals5 = {
19771
20046
  tryAcquireLock,
19772
20047
  writeFile: fs3.promises.writeFile
19773
20048
  };
@@ -19867,6 +20142,19 @@ function checkUnsafeChars(taskId) {
19867
20142
  }
19868
20143
  return;
19869
20144
  }
20145
+ function isStrictTaskId(taskId) {
20146
+ if (!taskId)
20147
+ return false;
20148
+ const unsafeMsg = checkUnsafeChars(taskId);
20149
+ if (unsafeMsg)
20150
+ return false;
20151
+ return STRICT_TASK_ID_PATTERN.test(taskId);
20152
+ }
20153
+ function assertStrictTaskId(taskId) {
20154
+ if (!isStrictTaskId(taskId)) {
20155
+ throw new Error(`Invalid taskId: "${taskId}". Must match N.M or N.M.P (e.g. "1.1", "1.2.3").`);
20156
+ }
20157
+ }
19870
20158
  function sanitizeTaskId(taskId) {
19871
20159
  const unsafeMsg = checkUnsafeChars(taskId);
19872
20160
  if (unsafeMsg) {
@@ -19947,7 +20235,7 @@ function validateProjectRoot(directory) {
19947
20235
  }
19948
20236
  }
19949
20237
  async function saveEvidence(directory, taskId, evidence) {
19950
- _internals5.validateProjectRoot(directory);
20238
+ _internals6.validateProjectRoot(directory);
19951
20239
  const sanitizedTaskId = sanitizeTaskId2(taskId);
19952
20240
  const relativePath = path7.join("evidence", sanitizedTaskId, "evidence.json");
19953
20241
  validateSwarmPath(directory, relativePath);
@@ -20048,7 +20336,7 @@ async function loadEvidence(directory, taskId) {
20048
20336
  return { status: "invalid_schema", errors: ["Invalid JSON"] };
20049
20337
  }
20050
20338
  if (isFlatRetrospective(parsed)) {
20051
- const wrappedBundle = _internals5.wrapFlatRetrospective(parsed, sanitizedTaskId);
20339
+ const wrappedBundle = _internals6.wrapFlatRetrospective(parsed, sanitizedTaskId);
20052
20340
  try {
20053
20341
  const validated = EvidenceBundleSchema.parse(wrappedBundle);
20054
20342
  try {
@@ -20144,14 +20432,14 @@ async function checkRequirementCoverage(phase, directory) {
20144
20432
  }
20145
20433
  }
20146
20434
  async function archiveEvidence(directory, maxAgeDays, maxBundles) {
20147
- const taskIds = await _internals5.listEvidenceTaskIds(directory);
20435
+ const taskIds = await _internals6.listEvidenceTaskIds(directory);
20148
20436
  const cutoffDate = new Date;
20149
20437
  cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);
20150
20438
  const cutoffIso = cutoffDate.toISOString();
20151
20439
  const archived = [];
20152
20440
  const remainingBundles = [];
20153
20441
  for (const taskId of taskIds) {
20154
- const result = await _internals5.loadEvidence(directory, taskId);
20442
+ const result = await _internals6.loadEvidence(directory, taskId);
20155
20443
  if (result.status !== "found") {
20156
20444
  continue;
20157
20445
  }
@@ -20179,7 +20467,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles) {
20179
20467
  }
20180
20468
  return archived;
20181
20469
  }
20182
- var VALID_EVIDENCE_TYPES, sanitizeTaskId2, MAX_DEPTH = 20, PROJECT_INDICATORS, LEGACY_TASK_COMPLEXITY_MAP, _internals5;
20470
+ var VALID_EVIDENCE_TYPES, sanitizeTaskId2, MAX_DEPTH = 20, PROJECT_INDICATORS, LEGACY_TASK_COMPLEXITY_MAP, _internals6;
20183
20471
  var init_manager2 = __esm(() => {
20184
20472
  init_zod();
20185
20473
  init_evidence_schema();
@@ -20222,7 +20510,7 @@ var init_manager2 = __esm(() => {
20222
20510
  medium: "moderate",
20223
20511
  high: "complex"
20224
20512
  };
20225
- _internals5 = {
20513
+ _internals6 = {
20226
20514
  wrapFlatRetrospective,
20227
20515
  loadEvidence,
20228
20516
  listEvidenceTaskIds,
@@ -20434,7 +20722,7 @@ function getProfile(directory, planId) {
20434
20722
  return row ? rowToProfile(row) : null;
20435
20723
  }
20436
20724
  function getOrCreateProfile(directory, planId, projectType) {
20437
- const existing = _internals6.getProfile(directory, planId);
20725
+ const existing = _internals7.getProfile(directory, planId);
20438
20726
  if (existing)
20439
20727
  return existing;
20440
20728
  const db = getProjectDb(directory);
@@ -20450,14 +20738,14 @@ function getOrCreateProfile(directory, planId, projectType) {
20450
20738
  throw err;
20451
20739
  }
20452
20740
  }
20453
- const after = _internals6.getProfile(directory, planId);
20741
+ const after = _internals7.getProfile(directory, planId);
20454
20742
  if (!after) {
20455
20743
  throw new Error(`Failed to create or load QA gate profile for plan_id=${planId}`);
20456
20744
  }
20457
20745
  return after;
20458
20746
  }
20459
20747
  function setGates(directory, planId, gates) {
20460
- const current = _internals6.getProfile(directory, planId);
20748
+ const current = _internals7.getProfile(directory, planId);
20461
20749
  if (!current) {
20462
20750
  throw new Error(`No QA gate profile found for plan_id=${planId} \u2014 call getOrCreateProfile first`);
20463
20751
  }
@@ -20481,7 +20769,7 @@ function setGates(directory, planId, gates) {
20481
20769
  JSON.stringify(merged),
20482
20770
  planId
20483
20771
  ]);
20484
- const updated = _internals6.getProfile(directory, planId);
20772
+ const updated = _internals7.getProfile(directory, planId);
20485
20773
  if (!updated) {
20486
20774
  throw new Error(`Failed to re-read QA gate profile after update for plan_id=${planId}`);
20487
20775
  }
@@ -20503,10 +20791,10 @@ function getEffectiveGates(profile, sessionOverrides) {
20503
20791
  }
20504
20792
  return merged;
20505
20793
  }
20506
- var _internals6, DEFAULT_QA_GATES;
20794
+ var _internals7, DEFAULT_QA_GATES;
20507
20795
  var init_qa_gate_profile = __esm(() => {
20508
20796
  init_project_db();
20509
- _internals6 = {
20797
+ _internals7 = {
20510
20798
  getProfile,
20511
20799
  getOrCreateProfile,
20512
20800
  setGates,
@@ -34954,7 +35242,7 @@ function resetToRemoteBranch(cwd, options) {
34954
35242
  const prunedBranches = [];
34955
35243
  try {
34956
35244
  const currentBranch = getCurrentBranch(cwd);
34957
- const defaultRemoteBranch = _internals7.detectDefaultRemoteBranch(cwd);
35245
+ const defaultRemoteBranch = _internals8.detectDefaultRemoteBranch(cwd);
34958
35246
  if (!defaultRemoteBranch) {
34959
35247
  return {
34960
35248
  success: false,
@@ -35136,7 +35424,7 @@ function resetToRemoteBranch(cwd, options) {
35136
35424
  function resetToMainAfterMerge(cwd, options) {
35137
35425
  const warnings = [];
35138
35426
  try {
35139
- const defaultBranch = _internals7.detectDefaultRemoteBranch(cwd);
35427
+ const defaultBranch = _internals8.detectDefaultRemoteBranch(cwd);
35140
35428
  if (!defaultBranch) {
35141
35429
  return {
35142
35430
  success: false,
@@ -35163,7 +35451,7 @@ function resetToMainAfterMerge(cwd, options) {
35163
35451
  }
35164
35452
  if (currentBranch === defaultBranch) {
35165
35453
  try {
35166
- const logOutput = _internals7.gitExec(["log", `${targetBranch}..HEAD`, "--oneline"], cwd);
35454
+ const logOutput = _internals8.gitExec(["log", `${targetBranch}..HEAD`, "--oneline"], cwd);
35167
35455
  if (logOutput.trim().length > 0) {
35168
35456
  return {
35169
35457
  success: false,
@@ -35178,11 +35466,11 @@ function resetToMainAfterMerge(cwd, options) {
35178
35466
  } catch {}
35179
35467
  } else {
35180
35468
  try {
35181
- _internals7.gitExec(["rev-parse", "--abbrev-ref", `${currentBranch}@{upstream}`], cwd);
35469
+ _internals8.gitExec(["rev-parse", "--abbrev-ref", `${currentBranch}@{upstream}`], cwd);
35182
35470
  } catch {
35183
35471
  try {
35184
- const localSha = _internals7.gitExec(["rev-parse", "HEAD"], cwd).trim();
35185
- const remoteSha = _internals7.gitExec(["rev-parse", targetBranch], cwd).trim();
35472
+ const localSha = _internals8.gitExec(["rev-parse", "HEAD"], cwd).trim();
35473
+ const remoteSha = _internals8.gitExec(["rev-parse", targetBranch], cwd).trim();
35186
35474
  if (localSha !== remoteSha) {
35187
35475
  return {
35188
35476
  success: false,
@@ -35208,7 +35496,7 @@ function resetToMainAfterMerge(cwd, options) {
35208
35496
  }
35209
35497
  }
35210
35498
  try {
35211
- _internals7.gitExec(["fetch", "--prune", "origin"], cwd);
35499
+ _internals8.gitExec(["fetch", "--prune", "origin"], cwd);
35212
35500
  } catch (err) {
35213
35501
  return {
35214
35502
  success: false,
@@ -35224,7 +35512,7 @@ function resetToMainAfterMerge(cwd, options) {
35224
35512
  let switchedBranch = false;
35225
35513
  if (currentBranch !== defaultBranch) {
35226
35514
  try {
35227
- _internals7.gitExec(["checkout", defaultBranch], cwd);
35515
+ _internals8.gitExec(["checkout", defaultBranch], cwd);
35228
35516
  switchedBranch = true;
35229
35517
  } catch (err) {
35230
35518
  return {
@@ -35239,7 +35527,7 @@ function resetToMainAfterMerge(cwd, options) {
35239
35527
  }
35240
35528
  }
35241
35529
  try {
35242
- _internals7.gitExec(["reset", "--hard", targetBranch], cwd);
35530
+ _internals8.gitExec(["reset", "--hard", targetBranch], cwd);
35243
35531
  } catch (err) {
35244
35532
  return {
35245
35533
  success: false,
@@ -35260,7 +35548,7 @@ function resetToMainAfterMerge(cwd, options) {
35260
35548
  while (Date.now() < endTime) {}
35261
35549
  }
35262
35550
  try {
35263
- _internals7.gitExec(["checkout", "--", "."], cwd);
35551
+ _internals8.gitExec(["checkout", "--", "."], cwd);
35264
35552
  discardSucceeded = true;
35265
35553
  break;
35266
35554
  } catch {}
@@ -35271,18 +35559,18 @@ function resetToMainAfterMerge(cwd, options) {
35271
35559
  changesDiscarded = discardSucceeded;
35272
35560
  }
35273
35561
  try {
35274
- _internals7.gitExec(["clean", "-fd"], cwd);
35562
+ _internals8.gitExec(["clean", "-fd"], cwd);
35275
35563
  } catch {
35276
35564
  warnings.push("Could not clean untracked files");
35277
35565
  }
35278
35566
  let branchDeleted = false;
35279
35567
  if (switchedBranch && previousBranch !== defaultBranch) {
35280
35568
  try {
35281
- const mergedOutput = _internals7.gitExec(["branch", "--merged", defaultBranch], cwd);
35569
+ const mergedOutput = _internals8.gitExec(["branch", "--merged", defaultBranch], cwd);
35282
35570
  const isMerged = mergedOutput.split(`
35283
35571
  `).some((line) => line.trim() === previousBranch || line.trim() === `* ${previousBranch}`);
35284
35572
  if (isMerged) {
35285
- _internals7.gitExec(["branch", "-d", previousBranch], cwd);
35573
+ _internals8.gitExec(["branch", "-d", previousBranch], cwd);
35286
35574
  branchDeleted = true;
35287
35575
  } else {
35288
35576
  warnings.push(`Branch ${previousBranch} is not merged into ${defaultBranch} \u2014 keeping it`);
@@ -35293,7 +35581,7 @@ function resetToMainAfterMerge(cwd, options) {
35293
35581
  }
35294
35582
  if (options?.pruneBranches) {
35295
35583
  try {
35296
- const mergedOutput = _internals7.gitExec(["branch", "--merged", defaultBranch], cwd);
35584
+ const mergedOutput = _internals8.gitExec(["branch", "--merged", defaultBranch], cwd);
35297
35585
  const mergedLines = mergedOutput.split(`
35298
35586
  `);
35299
35587
  for (const line of mergedLines) {
@@ -35302,7 +35590,7 @@ function resetToMainAfterMerge(cwd, options) {
35302
35590
  continue;
35303
35591
  }
35304
35592
  try {
35305
- _internals7.gitExec(["branch", "-d", trimmedLine], cwd);
35593
+ _internals8.gitExec(["branch", "-d", trimmedLine], cwd);
35306
35594
  } catch {
35307
35595
  warnings.push(`Could not prune branch: ${trimmedLine}`);
35308
35596
  }
@@ -35332,10 +35620,10 @@ function resetToMainAfterMerge(cwd, options) {
35332
35620
  };
35333
35621
  }
35334
35622
  }
35335
- var GIT_TIMEOUT_MS2 = 30000, _internals7;
35623
+ var GIT_TIMEOUT_MS2 = 30000, _internals8;
35336
35624
  var init_branch = __esm(() => {
35337
35625
  init_logger();
35338
- _internals7 = {
35626
+ _internals8 = {
35339
35627
  gitExec: gitExec2,
35340
35628
  detectDefaultRemoteBranch,
35341
35629
  getDefaultBaseBranch,
@@ -36529,7 +36817,7 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
36529
36817
  existingEntries.push(entry);
36530
36818
  }
36531
36819
  await enforceKnowledgeCap(knowledgePath, config3.swarm_max_entries);
36532
- await _internals8.runAutoPromotion(directory, config3);
36820
+ await _internals9.runAutoPromotion(directory, config3);
36533
36821
  return { stored, skipped, rejected };
36534
36822
  }
36535
36823
  async function runAutoPromotion(directory, config3) {
@@ -36610,7 +36898,7 @@ function createKnowledgeCuratorHook(directory, config3) {
36610
36898
  });
36611
36899
  const projectName2 = evidenceData.project_name ?? "unknown";
36612
36900
  const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
36613
- await _internals8.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3);
36901
+ await _internals9.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3);
36614
36902
  return;
36615
36903
  }
36616
36904
  const planContent = await readSwarmFileAsync(directory, "plan.md");
@@ -36632,17 +36920,17 @@ function createKnowledgeCuratorHook(directory, config3) {
36632
36920
  const projectName = projectNameMatch ? projectNameMatch[1].trim() : "unknown";
36633
36921
  const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
36634
36922
  const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
36635
- await _internals8.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3);
36923
+ await _internals9.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3);
36636
36924
  };
36637
36925
  return safeHook(handler);
36638
36926
  }
36639
- var seenRetroSections, _internals8;
36927
+ var seenRetroSections, _internals9;
36640
36928
  var init_knowledge_curator = __esm(() => {
36641
36929
  init_knowledge_store();
36642
36930
  init_knowledge_validator();
36643
36931
  init_utils2();
36644
36932
  seenRetroSections = new Map;
36645
- _internals8 = {
36933
+ _internals9 = {
36646
36934
  isWriteToEvidenceFile,
36647
36935
  curateAndStoreSwarm,
36648
36936
  runAutoPromotion,
@@ -37849,7 +38137,7 @@ async function executeWriteRetro(args, directory) {
37849
38137
  }, null, 2);
37850
38138
  }
37851
38139
  }
37852
- var write_retro, _internals9;
38140
+ var write_retro, _internals10;
37853
38141
  var init_write_retro = __esm(() => {
37854
38142
  init_zod();
37855
38143
  init_evidence_schema();
@@ -37896,13 +38184,13 @@ var init_write_retro = __esm(() => {
37896
38184
  task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
37897
38185
  metadata: args.metadata
37898
38186
  };
37899
- return await _internals9.executeWriteRetro(writeRetroArgs, directory);
38187
+ return await _internals10.executeWriteRetro(writeRetroArgs, directory);
37900
38188
  } catch {
37901
38189
  return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
37902
38190
  }
37903
38191
  }
37904
38192
  });
37905
- _internals9 = {
38193
+ _internals10 = {
37906
38194
  executeWriteRetro,
37907
38195
  write_retro
37908
38196
  };
@@ -38193,6 +38481,12 @@ async function handleCloseCommand(directory, args, options = {}) {
38193
38481
  }
38194
38482
  }
38195
38483
  if (planExists) {
38484
+ const originalStatuses = new Map;
38485
+ for (const phase of planData.phases ?? []) {
38486
+ for (const task of phase.tasks ?? []) {
38487
+ originalStatuses.set(task.id, task.status);
38488
+ }
38489
+ }
38196
38490
  const guaranteeResult = guaranteeAllPlansComplete(planData);
38197
38491
  for (const phaseId of guaranteeResult.closedPhaseIds) {
38198
38492
  if (!closedPhases.includes(phaseId)) {
@@ -38206,11 +38500,15 @@ async function handleCloseCommand(directory, args, options = {}) {
38206
38500
  }
38207
38501
  if (!planAlreadyDone || guaranteeResult.closedPhaseIds.length > 0 || guaranteeResult.closedTaskIds.length > 0) {
38208
38502
  try {
38209
- await fs7.writeFile(planPath, JSON.stringify(planData, null, 2), "utf-8");
38503
+ await closePlanTerminalState(directory, planData, {
38504
+ closedPhaseIds: guaranteeResult.closedPhaseIds,
38505
+ closedTaskIds: guaranteeResult.closedTaskIds,
38506
+ originalStatuses
38507
+ });
38210
38508
  } catch (error93) {
38211
38509
  const msg = error93 instanceof Error ? error93.message : String(error93);
38212
- warnings.push(`Failed to persist terminal plan.json state: ${msg}`);
38213
- console.warn("[close-command] Failed to write plan.json:", error93);
38510
+ warnings.push(`Failed to persist terminal plan state: ${msg}`);
38511
+ console.warn("[close-command] Failed to write terminal plan state:", error93);
38214
38512
  }
38215
38513
  }
38216
38514
  }
@@ -38498,6 +38796,7 @@ var init_close = __esm(() => {
38498
38796
  init_knowledge_curator();
38499
38797
  init_knowledge_store();
38500
38798
  init_utils2();
38799
+ init_manager();
38501
38800
  init_scope_persistence();
38502
38801
  init_skill_improver();
38503
38802
  init_state();
@@ -38724,14 +39023,16 @@ async function parseGitLog(directory, maxCommits) {
38724
39023
  }
38725
39024
  return commitMap;
38726
39025
  }
38727
- function buildCoChangeMatrix(commitMap) {
39026
+ function buildCoChangeMatrix(commitMap, maxFilesPerCommit = 500) {
38728
39027
  const matrix = new Map;
38729
39028
  const fileCommitCount = new Map;
38730
39029
  for (const files of commitMap.values()) {
38731
- const fileArray = Array.from(files).sort();
38732
- for (const file3 of fileArray) {
39030
+ for (const file3 of files) {
38733
39031
  fileCommitCount.set(file3, (fileCommitCount.get(file3) || 0) + 1);
38734
39032
  }
39033
+ if (files.size > maxFilesPerCommit)
39034
+ continue;
39035
+ const fileArray = Array.from(files).sort();
38735
39036
  for (let i = 0;i < fileArray.length; i++) {
38736
39037
  for (let j = i + 1;j < fileArray.length; j++) {
38737
39038
  const fileA = fileArray[i];
@@ -38894,6 +39195,7 @@ async function detectDarkMatter(directory, options) {
38894
39195
  const minCoChanges = options?.minCoChanges ?? 3;
38895
39196
  const npmiThreshold = options?.npmiThreshold ?? 0.5;
38896
39197
  const maxCommitsToAnalyze = options?.maxCommitsToAnalyze ?? 500;
39198
+ const maxFilesPerCommit = options?.maxFilesPerCommit ?? 500;
38897
39199
  try {
38898
39200
  const { stdout } = await getExecFileAsync()("git", ["rev-list", "--count", "HEAD"], {
38899
39201
  cwd: directory,
@@ -38906,9 +39208,9 @@ async function detectDarkMatter(directory, options) {
38906
39208
  } catch {
38907
39209
  return [];
38908
39210
  }
38909
- const commitMap = await _internals10.parseGitLog(directory, maxCommitsToAnalyze);
38910
- const matrix = _internals10.buildCoChangeMatrix(commitMap);
38911
- const staticEdges = await _internals10.getStaticEdges(directory);
39211
+ const commitMap = await _internals11.parseGitLog(directory, maxCommitsToAnalyze);
39212
+ const matrix = _internals11.buildCoChangeMatrix(commitMap, maxFilesPerCommit);
39213
+ const staticEdges = await _internals11.getStaticEdges(directory);
38912
39214
  const results = [];
38913
39215
  for (const entry of matrix.values()) {
38914
39216
  const key = `${entry.fileA}::${entry.fileB}`;
@@ -38988,7 +39290,7 @@ ${rows}
38988
39290
  These pairs likely share an architectural concern invisible to static analysis.
38989
39291
  Consider adding explicit documentation or extracting the shared concern.`;
38990
39292
  }
38991
- var co_change_analyzer, _internals10;
39293
+ var co_change_analyzer, _internals11;
38992
39294
  var init_co_change_analyzer = __esm(() => {
38993
39295
  init_zod();
38994
39296
  init_create_tool();
@@ -39020,11 +39322,11 @@ var init_co_change_analyzer = __esm(() => {
39020
39322
  npmiThreshold,
39021
39323
  maxCommitsToAnalyze
39022
39324
  };
39023
- const pairs = await _internals10.detectDarkMatter(directory, options);
39024
- return _internals10.formatDarkMatterOutput(pairs);
39325
+ const pairs = await _internals11.detectDarkMatter(directory, options);
39326
+ return _internals11.formatDarkMatterOutput(pairs);
39025
39327
  }
39026
39328
  });
39027
- _internals10 = {
39329
+ _internals11 = {
39028
39330
  parseGitLog,
39029
39331
  buildCoChangeMatrix,
39030
39332
  getStaticEdges,
@@ -39055,7 +39357,7 @@ async function handleDarkMatterCommand(directory, args) {
39055
39357
  }
39056
39358
  let pairs;
39057
39359
  try {
39058
- pairs = await _internals10.detectDarkMatter(directory, options);
39360
+ pairs = await _internals11.detectDarkMatter(directory, options);
39059
39361
  } catch (err) {
39060
39362
  const errMsg = err instanceof Error ? err.message : String(err);
39061
39363
  return `## Dark Matter Analysis Failed
@@ -39247,24 +39549,213 @@ function getPluginLockFilePaths() {
39247
39549
  }
39248
39550
  var init_cache_paths = () => {};
39249
39551
 
39552
+ // src/evidence/task-file.ts
39553
+ import * as path21 from "path";
39554
+ function taskEvidenceRelPath(taskId) {
39555
+ return path21.join("evidence", `${taskId}.json`);
39556
+ }
39557
+ function taskEvidencePath(directory, taskId) {
39558
+ return path21.join(directory, ".swarm", taskEvidenceRelPath(taskId));
39559
+ }
39560
+ var init_task_file = __esm(() => {
39561
+ init_bun_compat();
39562
+ init_lock();
39563
+ });
39564
+
39565
+ // src/gate-evidence.ts
39566
+ import { mkdirSync as mkdirSync7, readFileSync as readFileSync6 } from "fs";
39567
+ function isValidTaskId(taskId) {
39568
+ return isStrictTaskId(taskId);
39569
+ }
39570
+ function assertValidTaskId(taskId) {
39571
+ assertStrictTaskId(taskId);
39572
+ }
39573
+ function getEvidencePath(directory, taskId) {
39574
+ assertValidTaskId(taskId);
39575
+ return taskEvidencePath(directory, taskId);
39576
+ }
39577
+ function readExisting(evidencePath, taskId) {
39578
+ try {
39579
+ const raw = readFileSync6(evidencePath, "utf-8");
39580
+ return TaskEvidenceSchema.parse(JSON.parse(raw));
39581
+ } catch (error93) {
39582
+ if (error93.code === "ENOENT")
39583
+ return null;
39584
+ telemetry.gateParseError(taskId, error93);
39585
+ throw error93;
39586
+ }
39587
+ }
39588
+ async function readTaskEvidence(directory, taskId) {
39589
+ try {
39590
+ assertValidTaskId(taskId);
39591
+ return readExisting(getEvidencePath(directory, taskId), taskId);
39592
+ } catch {
39593
+ return null;
39594
+ }
39595
+ }
39596
+ function readTaskEvidenceRaw(directory, taskId) {
39597
+ assertValidTaskId(taskId);
39598
+ const evidencePath = getEvidencePath(directory, taskId);
39599
+ try {
39600
+ const raw = readFileSync6(evidencePath, "utf-8");
39601
+ return TaskEvidenceSchema.parse(JSON.parse(raw));
39602
+ } catch (error93) {
39603
+ if (error93.code === "ENOENT")
39604
+ return null;
39605
+ throw error93;
39606
+ }
39607
+ }
39608
+ var GateEvidenceSchema, TaskEvidenceSchema;
39609
+ var init_gate_evidence = __esm(() => {
39610
+ init_zod();
39611
+ init_task_file();
39612
+ init_telemetry();
39613
+ init_task_id();
39614
+ GateEvidenceSchema = exports_external.object({
39615
+ sessionId: exports_external.string(),
39616
+ timestamp: exports_external.string(),
39617
+ agent: exports_external.string()
39618
+ }).passthrough();
39619
+ TaskEvidenceSchema = exports_external.object({
39620
+ taskId: exports_external.string(),
39621
+ required_gates: exports_external.array(exports_external.string()).default([]),
39622
+ gates: exports_external.record(exports_external.string(), GateEvidenceSchema),
39623
+ turbo: exports_external.boolean().optional()
39624
+ });
39625
+ });
39626
+
39627
+ // src/evidence/gate-bridge.ts
39628
+ async function readDurableGateEvidence(directory, taskId) {
39629
+ try {
39630
+ return await readTaskEvidence(directory, taskId);
39631
+ } catch {
39632
+ return null;
39633
+ }
39634
+ }
39635
+ function getDurableGateEvidenceStatus(evidence) {
39636
+ if (!evidence?.gates || typeof evidence.gates !== "object") {
39637
+ return {
39638
+ isComplete: false,
39639
+ missingGates: [],
39640
+ evidenceExists: evidence != null,
39641
+ invalid: false
39642
+ };
39643
+ }
39644
+ if (!Array.isArray(evidence.required_gates) || evidence.required_gates.length === 0) {
39645
+ return {
39646
+ isComplete: false,
39647
+ missingGates: ["required_gates"],
39648
+ evidenceExists: true,
39649
+ invalid: false
39650
+ };
39651
+ }
39652
+ const missingGates = evidence.required_gates.filter((gate) => evidence.gates[gate] == null);
39653
+ return {
39654
+ isComplete: missingGates.length === 0,
39655
+ missingGates,
39656
+ evidenceExists: true,
39657
+ invalid: false
39658
+ };
39659
+ }
39660
+ async function getDurableGateEvidenceStatusForTask(directory, taskId) {
39661
+ if (!isValidTaskId(taskId)) {
39662
+ return {
39663
+ isComplete: false,
39664
+ missingGates: [],
39665
+ evidenceExists: false,
39666
+ invalid: false
39667
+ };
39668
+ }
39669
+ try {
39670
+ return getDurableGateEvidenceStatus(readTaskEvidenceRaw(directory, taskId));
39671
+ } catch {
39672
+ return {
39673
+ isComplete: false,
39674
+ missingGates: ["invalid_gate_evidence"],
39675
+ evidenceExists: true,
39676
+ invalid: true
39677
+ };
39678
+ }
39679
+ }
39680
+ function gateEvidenceToEntry(taskId, gate, type, evidence) {
39681
+ const gateRecord = evidence.gates[gate];
39682
+ if (!gateRecord) {
39683
+ return null;
39684
+ }
39685
+ const base = {
39686
+ task_id: taskId,
39687
+ timestamp: gateRecord.timestamp,
39688
+ agent: gateRecord.agent || gate,
39689
+ verdict: "pass",
39690
+ summary: `Gate evidence recorded by ${gate}`,
39691
+ metadata: { source: "durable_gate_evidence", gate }
39692
+ };
39693
+ if (type === "review") {
39694
+ return {
39695
+ ...base,
39696
+ type,
39697
+ risk: "low",
39698
+ issues: []
39699
+ };
39700
+ }
39701
+ if (type === "approval") {
39702
+ return {
39703
+ ...base,
39704
+ type
39705
+ };
39706
+ }
39707
+ return {
39708
+ ...base,
39709
+ type,
39710
+ tests_passed: 0,
39711
+ tests_failed: 0,
39712
+ failures: []
39713
+ };
39714
+ }
39715
+ function mergeDurableGateEntriesFromEvidence(taskId, entries, evidence) {
39716
+ if (!evidence?.gates) {
39717
+ return entries;
39718
+ }
39719
+ const merged = [...entries];
39720
+ for (const gate of Object.keys(evidence.gates).sort()) {
39721
+ const type = GATE_EVIDENCE_TYPE_BY_GATE[gate] ?? "approval";
39722
+ if ((type === "review" || type === "test") && merged.some((entry2) => entry2.type === type)) {
39723
+ continue;
39724
+ }
39725
+ const entry = gateEvidenceToEntry(taskId, gate, type, evidence);
39726
+ if (entry) {
39727
+ merged.push(entry);
39728
+ }
39729
+ }
39730
+ return merged;
39731
+ }
39732
+ var GATE_EVIDENCE_TYPE_BY_GATE;
39733
+ var init_gate_bridge = __esm(() => {
39734
+ init_gate_evidence();
39735
+ GATE_EVIDENCE_TYPE_BY_GATE = {
39736
+ reviewer: "review",
39737
+ test_engineer: "test"
39738
+ };
39739
+ });
39740
+
39250
39741
  // src/services/version-check.ts
39251
- import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
39742
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
39252
39743
  import { homedir as homedir5 } from "os";
39253
- import { join as join19 } from "path";
39744
+ import { join as join20 } from "path";
39254
39745
  function cacheDir() {
39255
39746
  const xdg = process.env.XDG_CACHE_HOME;
39256
- const base = xdg && xdg.length > 0 ? xdg : join19(homedir5(), ".cache");
39257
- return join19(base, "opencode-swarm");
39747
+ const base = xdg && xdg.length > 0 ? xdg : join20(homedir5(), ".cache");
39748
+ return join20(base, "opencode-swarm");
39258
39749
  }
39259
39750
  function cacheFile() {
39260
- return join19(cacheDir(), "version-check.json");
39751
+ return join20(cacheDir(), "version-check.json");
39261
39752
  }
39262
39753
  function readVersionCache() {
39263
39754
  try {
39264
- const path21 = cacheFile();
39265
- if (!existsSync11(path21))
39755
+ const path22 = cacheFile();
39756
+ if (!existsSync11(path22))
39266
39757
  return null;
39267
- const raw = readFileSync6(path21, "utf-8");
39758
+ const raw = readFileSync7(path22, "utf-8");
39268
39759
  const parsed = JSON.parse(raw);
39269
39760
  if (typeof parsed?.checkedAt !== "number")
39270
39761
  return null;
@@ -39303,8 +39794,8 @@ var init_version_check = __esm(() => {
39303
39794
 
39304
39795
  // src/services/diagnose-service.ts
39305
39796
  import * as child_process4 from "child_process";
39306
- import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync6 } from "fs";
39307
- import path21 from "path";
39797
+ import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
39798
+ import path22 from "path";
39308
39799
  import { fileURLToPath } from "url";
39309
39800
  function validateTaskDag(plan) {
39310
39801
  const allTaskIds = new Set;
@@ -39336,7 +39827,21 @@ async function checkEvidenceCompleteness(directory, plan) {
39336
39827
  }
39337
39828
  if (completedTaskIds.length > 0) {
39338
39829
  const evidenceTaskIds = new Set(await listEvidenceTaskIds(directory));
39339
- const missingEvidence = completedTaskIds.filter((id) => !evidenceTaskIds.has(id));
39830
+ const missingEvidence = [];
39831
+ for (const id of completedTaskIds) {
39832
+ const gateStatus = await getDurableGateEvidenceStatusForTask(directory, id);
39833
+ if (gateStatus.isComplete) {
39834
+ continue;
39835
+ }
39836
+ if (gateStatus.evidenceExists && gateStatus.missingGates.length > 0) {
39837
+ missingEvidence.push(id);
39838
+ continue;
39839
+ }
39840
+ if (evidenceTaskIds.has(id)) {
39841
+ continue;
39842
+ }
39843
+ missingEvidence.push(id);
39844
+ }
39340
39845
  if (missingEvidence.length === 0) {
39341
39846
  return {
39342
39847
  name: "Evidence",
@@ -39601,7 +40106,7 @@ async function checkSpecStaleness(directory, plan) {
39601
40106
  };
39602
40107
  }
39603
40108
  async function checkConfigParseability(directory) {
39604
- const configPath = path21.join(directory, ".opencode/opencode-swarm.json");
40109
+ const configPath = path22.join(directory, ".opencode/opencode-swarm.json");
39605
40110
  if (!existsSync12(configPath)) {
39606
40111
  return {
39607
40112
  name: "Config Parseability",
@@ -39610,7 +40115,7 @@ async function checkConfigParseability(directory) {
39610
40115
  };
39611
40116
  }
39612
40117
  try {
39613
- const content = readFileSync7(configPath, "utf-8");
40118
+ const content = readFileSync8(configPath, "utf-8");
39614
40119
  JSON.parse(content);
39615
40120
  return {
39616
40121
  name: "Config Parseability",
@@ -39630,7 +40135,7 @@ function resolveGrammarDir(thisDir) {
39630
40135
  const normalized = thisDir.replace(/\\/g, "/");
39631
40136
  const isSource = normalized.endsWith("/src/services");
39632
40137
  const isCliBundle = normalized.endsWith("/cli");
39633
- return isSource || isCliBundle ? path21.join(thisDir, "..", "lang", "grammars") : path21.join(thisDir, "lang", "grammars");
40138
+ return isSource || isCliBundle ? path22.join(thisDir, "..", "lang", "grammars") : path22.join(thisDir, "lang", "grammars");
39634
40139
  }
39635
40140
  async function checkGrammarWasmFiles() {
39636
40141
  const grammarFiles = [
@@ -39654,14 +40159,14 @@ async function checkGrammarWasmFiles() {
39654
40159
  "tree-sitter-ini.wasm",
39655
40160
  "tree-sitter-regex.wasm"
39656
40161
  ];
39657
- const thisDir = path21.dirname(fileURLToPath(import.meta.url));
40162
+ const thisDir = path22.dirname(fileURLToPath(import.meta.url));
39658
40163
  const grammarDir = resolveGrammarDir(thisDir);
39659
40164
  const missing = [];
39660
- if (!existsSync12(path21.join(grammarDir, "tree-sitter.wasm"))) {
40165
+ if (!existsSync12(path22.join(grammarDir, "tree-sitter.wasm"))) {
39661
40166
  missing.push("tree-sitter.wasm (core runtime)");
39662
40167
  }
39663
40168
  for (const file3 of grammarFiles) {
39664
- if (!existsSync12(path21.join(grammarDir, file3))) {
40169
+ if (!existsSync12(path22.join(grammarDir, file3))) {
39665
40170
  missing.push(file3);
39666
40171
  }
39667
40172
  }
@@ -39679,7 +40184,7 @@ async function checkGrammarWasmFiles() {
39679
40184
  };
39680
40185
  }
39681
40186
  async function checkCheckpointManifest(directory) {
39682
- const manifestPath = path21.join(directory, ".swarm/checkpoints.json");
40187
+ const manifestPath = path22.join(directory, ".swarm/checkpoints.json");
39683
40188
  if (!existsSync12(manifestPath)) {
39684
40189
  return {
39685
40190
  name: "Checkpoint Manifest",
@@ -39688,7 +40193,7 @@ async function checkCheckpointManifest(directory) {
39688
40193
  };
39689
40194
  }
39690
40195
  try {
39691
- const content = readFileSync7(manifestPath, "utf-8");
40196
+ const content = readFileSync8(manifestPath, "utf-8");
39692
40197
  const parsed = JSON.parse(content);
39693
40198
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
39694
40199
  return {
@@ -39731,7 +40236,7 @@ async function checkCheckpointManifest(directory) {
39731
40236
  }
39732
40237
  }
39733
40238
  async function checkEventStreamIntegrity(directory) {
39734
- const eventsPath = path21.join(directory, ".swarm/events.jsonl");
40239
+ const eventsPath = path22.join(directory, ".swarm/events.jsonl");
39735
40240
  if (!existsSync12(eventsPath)) {
39736
40241
  return {
39737
40242
  name: "Event Stream",
@@ -39740,7 +40245,7 @@ async function checkEventStreamIntegrity(directory) {
39740
40245
  };
39741
40246
  }
39742
40247
  try {
39743
- const content = readFileSync7(eventsPath, "utf-8");
40248
+ const content = readFileSync8(eventsPath, "utf-8");
39744
40249
  const lines = content.split(`
39745
40250
  `).filter((line) => line.trim() !== "");
39746
40251
  let malformedCount = 0;
@@ -39772,7 +40277,7 @@ async function checkEventStreamIntegrity(directory) {
39772
40277
  }
39773
40278
  }
39774
40279
  async function checkSteeringDirectives(directory) {
39775
- const eventsPath = path21.join(directory, ".swarm/events.jsonl");
40280
+ const eventsPath = path22.join(directory, ".swarm/events.jsonl");
39776
40281
  if (!existsSync12(eventsPath)) {
39777
40282
  return {
39778
40283
  name: "Steering Directives",
@@ -39781,7 +40286,7 @@ async function checkSteeringDirectives(directory) {
39781
40286
  };
39782
40287
  }
39783
40288
  try {
39784
- const content = readFileSync7(eventsPath, "utf-8");
40289
+ const content = readFileSync8(eventsPath, "utf-8");
39785
40290
  const lines = content.split(`
39786
40291
  `).filter((line) => line.trim() !== "");
39787
40292
  const directivesIssued = [];
@@ -39828,7 +40333,7 @@ async function checkCurator(directory) {
39828
40333
  detail: "Disabled (enable via curator.enabled)"
39829
40334
  };
39830
40335
  }
39831
- const summaryPath = path21.join(directory, ".swarm/curator-summary.json");
40336
+ const summaryPath = path22.join(directory, ".swarm/curator-summary.json");
39832
40337
  if (!existsSync12(summaryPath)) {
39833
40338
  return {
39834
40339
  name: "Curator",
@@ -39837,7 +40342,7 @@ async function checkCurator(directory) {
39837
40342
  };
39838
40343
  }
39839
40344
  try {
39840
- const content = readFileSync7(summaryPath, "utf-8");
40345
+ const content = readFileSync8(summaryPath, "utf-8");
39841
40346
  const parsed = JSON.parse(content);
39842
40347
  if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
39843
40348
  return {
@@ -39994,7 +40499,7 @@ async function getDiagnoseData(directory) {
39994
40499
  checks5.push(await checkSteeringDirectives(directory));
39995
40500
  checks5.push(await checkCurator(directory));
39996
40501
  try {
39997
- const evidenceDir = path21.join(directory, ".swarm", "evidence");
40502
+ const evidenceDir = path22.join(directory, ".swarm", "evidence");
39998
40503
  const snapshotFiles = existsSync12(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
39999
40504
  if (snapshotFiles.length > 0) {
40000
40505
  const latest = snapshotFiles.sort().pop();
@@ -40032,9 +40537,9 @@ async function getDiagnoseData(directory) {
40032
40537
  cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
40033
40538
  continue;
40034
40539
  }
40035
- const pkgJsonPath = path21.join(cachePath, "package.json");
40540
+ const pkgJsonPath = path22.join(cachePath, "package.json");
40036
40541
  try {
40037
- const raw = readFileSync7(pkgJsonPath, "utf-8");
40542
+ const raw = readFileSync8(pkgJsonPath, "utf-8");
40038
40543
  const parsed = JSON.parse(raw);
40039
40544
  const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
40040
40545
  cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
@@ -40091,6 +40596,7 @@ var init_diagnose_service = __esm(() => {
40091
40596
  init_package();
40092
40597
  init_cache_paths();
40093
40598
  init_loader();
40599
+ init_gate_bridge();
40094
40600
  init_manager2();
40095
40601
  init_utils2();
40096
40602
  init_manager();
@@ -40122,13 +40628,13 @@ __export(exports_config_doctor, {
40122
40628
  import * as crypto3 from "crypto";
40123
40629
  import * as fs8 from "fs";
40124
40630
  import * as os6 from "os";
40125
- import * as path22 from "path";
40631
+ import * as path23 from "path";
40126
40632
  function getUserConfigDir3() {
40127
- return process.env.XDG_CONFIG_HOME || path22.join(os6.homedir(), ".config");
40633
+ return process.env.XDG_CONFIG_HOME || path23.join(os6.homedir(), ".config");
40128
40634
  }
40129
40635
  function getConfigPaths(directory) {
40130
- const userConfigPath = path22.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
40131
- const projectConfigPath = path22.join(directory, ".opencode", "opencode-swarm.json");
40636
+ const userConfigPath = path23.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
40637
+ const projectConfigPath = path23.join(directory, ".opencode", "opencode-swarm.json");
40132
40638
  return { userConfigPath, projectConfigPath };
40133
40639
  }
40134
40640
  function computeHash(content) {
@@ -40153,9 +40659,9 @@ function isValidConfigPath(configPath, directory) {
40153
40659
  const normalizedUser = userConfigPath.replace(/\\/g, "/");
40154
40660
  const normalizedProject = projectConfigPath.replace(/\\/g, "/");
40155
40661
  try {
40156
- const resolvedConfig = path22.resolve(configPath);
40157
- const resolvedUser = path22.resolve(normalizedUser);
40158
- const resolvedProject = path22.resolve(normalizedProject);
40662
+ const resolvedConfig = path23.resolve(configPath);
40663
+ const resolvedUser = path23.resolve(normalizedUser);
40664
+ const resolvedProject = path23.resolve(normalizedProject);
40159
40665
  return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
40160
40666
  } catch {
40161
40667
  return false;
@@ -40195,12 +40701,12 @@ function createConfigBackup(directory) {
40195
40701
  };
40196
40702
  }
40197
40703
  function writeBackupArtifact(directory, backup) {
40198
- const swarmDir = path22.join(directory, ".swarm");
40704
+ const swarmDir = path23.join(directory, ".swarm");
40199
40705
  if (!fs8.existsSync(swarmDir)) {
40200
40706
  fs8.mkdirSync(swarmDir, { recursive: true });
40201
40707
  }
40202
40708
  const backupFilename = `config-backup-${backup.createdAt}.json`;
40203
- const backupPath = path22.join(swarmDir, backupFilename);
40709
+ const backupPath = path23.join(swarmDir, backupFilename);
40204
40710
  const artifact = {
40205
40711
  createdAt: backup.createdAt,
40206
40712
  configPath: backup.configPath,
@@ -40230,7 +40736,7 @@ function restoreFromBackup(backupPath, directory) {
40230
40736
  return null;
40231
40737
  }
40232
40738
  const targetPath = artifact.configPath;
40233
- const targetDir = path22.dirname(targetPath);
40739
+ const targetDir = path23.dirname(targetPath);
40234
40740
  if (!fs8.existsSync(targetDir)) {
40235
40741
  fs8.mkdirSync(targetDir, { recursive: true });
40236
40742
  }
@@ -40261,9 +40767,9 @@ function readConfigFromFile(directory) {
40261
40767
  return null;
40262
40768
  }
40263
40769
  }
40264
- function validateConfigKey(path23, value, _config) {
40770
+ function validateConfigKey(path24, value, _config) {
40265
40771
  const findings = [];
40266
- switch (path23) {
40772
+ switch (path24) {
40267
40773
  case "agents": {
40268
40774
  if (value !== undefined) {
40269
40775
  findings.push({
@@ -40500,27 +41006,27 @@ function validateConfigKey(path23, value, _config) {
40500
41006
  }
40501
41007
  return findings;
40502
41008
  }
40503
- function walkConfigAndValidate(obj, path23, config3, findings) {
41009
+ function walkConfigAndValidate(obj, path24, config3, findings) {
40504
41010
  if (obj === null || obj === undefined) {
40505
41011
  return;
40506
41012
  }
40507
- if (path23 && typeof obj === "object" && !Array.isArray(obj)) {
40508
- const keyFindings = validateConfigKey(path23, obj, config3);
41013
+ if (path24 && typeof obj === "object" && !Array.isArray(obj)) {
41014
+ const keyFindings = validateConfigKey(path24, obj, config3);
40509
41015
  findings.push(...keyFindings);
40510
41016
  }
40511
41017
  if (typeof obj !== "object") {
40512
- const keyFindings = validateConfigKey(path23, obj, config3);
41018
+ const keyFindings = validateConfigKey(path24, obj, config3);
40513
41019
  findings.push(...keyFindings);
40514
41020
  return;
40515
41021
  }
40516
41022
  if (Array.isArray(obj)) {
40517
41023
  obj.forEach((item, index) => {
40518
- walkConfigAndValidate(item, `${path23}[${index}]`, config3, findings);
41024
+ walkConfigAndValidate(item, `${path24}[${index}]`, config3, findings);
40519
41025
  });
40520
41026
  return;
40521
41027
  }
40522
41028
  for (const [key, value] of Object.entries(obj)) {
40523
- const newPath = path23 ? `${path23}.${key}` : key;
41029
+ const newPath = path24 ? `${path24}.${key}` : key;
40524
41030
  walkConfigAndValidate(value, newPath, config3, findings);
40525
41031
  }
40526
41032
  }
@@ -40640,7 +41146,7 @@ function applySafeAutoFixes(directory, result) {
40640
41146
  }
40641
41147
  }
40642
41148
  if (appliedFixes.length > 0) {
40643
- const configDir = path22.dirname(configPath);
41149
+ const configDir = path23.dirname(configPath);
40644
41150
  if (!fs8.existsSync(configDir)) {
40645
41151
  fs8.mkdirSync(configDir, { recursive: true });
40646
41152
  }
@@ -40650,12 +41156,12 @@ function applySafeAutoFixes(directory, result) {
40650
41156
  return { appliedFixes, updatedConfigPath };
40651
41157
  }
40652
41158
  function writeDoctorArtifact(directory, result) {
40653
- const swarmDir = path22.join(directory, ".swarm");
41159
+ const swarmDir = path23.join(directory, ".swarm");
40654
41160
  if (!fs8.existsSync(swarmDir)) {
40655
41161
  fs8.mkdirSync(swarmDir, { recursive: true });
40656
41162
  }
40657
41163
  const artifactFilename = "config-doctor.json";
40658
- const artifactPath = path22.join(swarmDir, artifactFilename);
41164
+ const artifactPath = path23.join(swarmDir, artifactFilename);
40659
41165
  const guiOutput = {
40660
41166
  timestamp: result.timestamp,
40661
41167
  summary: result.summary,
@@ -40751,17 +41257,17 @@ function detectStraySwarmDirs(projectRoot) {
40751
41257
  if (!entry.isDirectory())
40752
41258
  continue;
40753
41259
  const name = entry.name;
40754
- const fullPath = path22.join(dir, name);
41260
+ const fullPath = path23.join(dir, name);
40755
41261
  if (SKIP_DIRS.has(name))
40756
41262
  continue;
40757
- const gitPath = path22.join(fullPath, ".git");
41263
+ const gitPath = path23.join(fullPath, ".git");
40758
41264
  try {
40759
41265
  const gitStat = fs8.statSync(gitPath);
40760
41266
  if (gitStat.isFile() || gitStat.isDirectory())
40761
41267
  continue;
40762
41268
  } catch {}
40763
41269
  if (name === ".swarm") {
40764
- const parentDir = path22.dirname(fullPath);
41270
+ const parentDir = path23.dirname(fullPath);
40765
41271
  if (parentDir === projectRoot)
40766
41272
  continue;
40767
41273
  let contents = [];
@@ -40771,7 +41277,7 @@ function detectStraySwarmDirs(projectRoot) {
40771
41277
  contents = ["<unreadable>"];
40772
41278
  }
40773
41279
  findings.push({
40774
- path: path22.relative(projectRoot, fullPath).replace(/\\/g, "/"),
41280
+ path: path23.relative(projectRoot, fullPath).replace(/\\/g, "/"),
40775
41281
  absolutePath: fullPath,
40776
41282
  contents: contents.slice(0, MAX_CONTENTS_ENTRIES),
40777
41283
  totalEntries: contents.length
@@ -40789,21 +41295,21 @@ function removeStraySwarmDir(projectRoot, strayPath) {
40789
41295
  let canonicalStray;
40790
41296
  try {
40791
41297
  canonicalRoot = fs8.realpathSync(projectRoot);
40792
- canonicalStray = fs8.realpathSync(path22.isAbsolute(strayPath) ? strayPath : path22.resolve(projectRoot, strayPath));
41298
+ canonicalStray = fs8.realpathSync(path23.isAbsolute(strayPath) ? strayPath : path23.resolve(projectRoot, strayPath));
40793
41299
  } catch (err) {
40794
41300
  return {
40795
41301
  success: false,
40796
41302
  message: `Failed to resolve paths: ${err instanceof Error ? err.message : String(err)}`
40797
41303
  };
40798
41304
  }
40799
- const rootSwarm = path22.join(canonicalRoot, ".swarm");
41305
+ const rootSwarm = path23.join(canonicalRoot, ".swarm");
40800
41306
  if (canonicalStray === rootSwarm || canonicalStray === canonicalRoot) {
40801
41307
  return {
40802
41308
  success: false,
40803
41309
  message: "Refusing to remove root .swarm/ directory"
40804
41310
  };
40805
41311
  }
40806
- if (!canonicalStray.startsWith(canonicalRoot + path22.sep)) {
41312
+ if (!canonicalStray.startsWith(canonicalRoot + path23.sep)) {
40807
41313
  return {
40808
41314
  success: false,
40809
41315
  message: "Path is outside project root \u2014 refusing to remove"
@@ -41892,7 +42398,7 @@ var init_profiles = __esm(() => {
41892
42398
 
41893
42399
  // src/lang/detector.ts
41894
42400
  import { access as access3, readdir as readdir2 } from "fs/promises";
41895
- import { extname as extname2, join as join21 } from "path";
42401
+ import { extname as extname2, join as join22 } from "path";
41896
42402
  async function detectProjectLanguages(projectDir) {
41897
42403
  const detected = new Set;
41898
42404
  async function scanDir(dir) {
@@ -41908,7 +42414,7 @@ async function detectProjectLanguages(projectDir) {
41908
42414
  if (detectFile.includes("*") || detectFile.includes("?"))
41909
42415
  continue;
41910
42416
  try {
41911
- await access3(join21(dir, detectFile));
42417
+ await access3(join22(dir, detectFile));
41912
42418
  detected.add(profile.id);
41913
42419
  break;
41914
42420
  } catch {}
@@ -41929,7 +42435,7 @@ async function detectProjectLanguages(projectDir) {
41929
42435
  const topEntries = await readdir2(projectDir, { withFileTypes: true });
41930
42436
  for (const entry of topEntries) {
41931
42437
  if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
41932
- await scanDir(join21(projectDir, entry.name));
42438
+ await scanDir(join22(projectDir, entry.name));
41933
42439
  }
41934
42440
  }
41935
42441
  } catch {}
@@ -41948,7 +42454,7 @@ var init_detector = __esm(() => {
41948
42454
 
41949
42455
  // src/build/discovery.ts
41950
42456
  import * as fs9 from "fs";
41951
- import * as path23 from "path";
42457
+ import * as path24 from "path";
41952
42458
  function isCommandAvailable(command) {
41953
42459
  if (toolchainCache.has(command)) {
41954
42460
  return toolchainCache.get(command);
@@ -41956,7 +42462,7 @@ function isCommandAvailable(command) {
41956
42462
  const isWindows = process.platform === "win32";
41957
42463
  const cmd = isWindows ? `${command}.exe` : command;
41958
42464
  try {
41959
- const result = _internals11.spawnSyncImpl(isWindows ? ["where", cmd] : ["which", cmd], {
42465
+ const result = _internals12.spawnSyncImpl(isWindows ? ["where", cmd] : ["which", cmd], {
41960
42466
  cwd: process.cwd(),
41961
42467
  stdin: "ignore",
41962
42468
  stdout: "ignore",
@@ -41983,11 +42489,11 @@ function findBuildFiles(workingDir, patterns) {
41983
42489
  const regex = simpleGlobToRegex(pattern);
41984
42490
  const matches = files.filter((f) => regex.test(f));
41985
42491
  if (matches.length > 0) {
41986
- return path23.join(dir, matches[0]);
42492
+ return path24.join(dir, matches[0]);
41987
42493
  }
41988
42494
  } catch {}
41989
42495
  } else {
41990
- const filePath = path23.join(workingDir, pattern);
42496
+ const filePath = path24.join(workingDir, pattern);
41991
42497
  if (fs9.existsSync(filePath)) {
41992
42498
  return filePath;
41993
42499
  }
@@ -41996,7 +42502,7 @@ function findBuildFiles(workingDir, patterns) {
41996
42502
  return null;
41997
42503
  }
41998
42504
  function getRepoDefinedScripts(workingDir, scripts) {
41999
- const packageJsonPath = path23.join(workingDir, "package.json");
42505
+ const packageJsonPath = path24.join(workingDir, "package.json");
42000
42506
  if (!fs9.existsSync(packageJsonPath)) {
42001
42507
  return [];
42002
42508
  }
@@ -42037,7 +42543,7 @@ function findAllBuildFiles(workingDir) {
42037
42543
  const regex = simpleGlobToRegex(pattern);
42038
42544
  findFilesRecursive(workingDir, regex, allBuildFiles);
42039
42545
  } else {
42040
- const filePath = path23.join(workingDir, pattern);
42546
+ const filePath = path24.join(workingDir, pattern);
42041
42547
  if (fs9.existsSync(filePath)) {
42042
42548
  allBuildFiles.add(filePath);
42043
42549
  }
@@ -42050,7 +42556,7 @@ function findFilesRecursive(dir, regex, results) {
42050
42556
  try {
42051
42557
  const entries = fs9.readdirSync(dir, { withFileTypes: true });
42052
42558
  for (const entry of entries) {
42053
- const fullPath = path23.join(dir, entry.name);
42559
+ const fullPath = path24.join(dir, entry.name);
42054
42560
  if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
42055
42561
  findFilesRecursive(fullPath, regex, results);
42056
42562
  } else if (entry.isFile() && regex.test(entry.name)) {
@@ -42073,7 +42579,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
42073
42579
  let foundCommand = false;
42074
42580
  for (const cmd of sortedCommands) {
42075
42581
  if (cmd.detectFile) {
42076
- const detectFilePath = path23.join(workingDir, cmd.detectFile);
42582
+ const detectFilePath = path24.join(workingDir, cmd.detectFile);
42077
42583
  if (!fs9.existsSync(detectFilePath)) {
42078
42584
  continue;
42079
42585
  }
@@ -42106,7 +42612,7 @@ async function discoverBuildCommands(workingDir, options) {
42106
42612
  const scope = options?.scope ?? "all";
42107
42613
  const changedFiles = options?.changedFiles ?? [];
42108
42614
  const _filesToCheck = filterByScope(workingDir, scope, changedFiles);
42109
- const profileResult = await _internals11.discoverBuildCommandsFromProfiles(workingDir);
42615
+ const profileResult = await _internals12.discoverBuildCommandsFromProfiles(workingDir);
42110
42616
  const profileCommands = profileResult.commands;
42111
42617
  const profileSkipped = profileResult.skipped;
42112
42618
  const coveredEcosystems = new Set;
@@ -42169,7 +42675,7 @@ function clearToolchainCache() {
42169
42675
  function getEcosystems() {
42170
42676
  return ECOSYSTEMS.map((e) => e.ecosystem);
42171
42677
  }
42172
- var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, IS_COMMAND_AVAILABLE_TIMEOUT_MS = 3000, _internals11, build_discovery;
42678
+ var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, IS_COMMAND_AVAILABLE_TIMEOUT_MS = 3000, _internals12, build_discovery;
42173
42679
  var init_discovery = __esm(() => {
42174
42680
  init_dist();
42175
42681
  init_detector();
@@ -42287,7 +42793,7 @@ var init_discovery = __esm(() => {
42287
42793
  php: ["php-composer"]
42288
42794
  };
42289
42795
  toolchainCache = new Map;
42290
- _internals11 = {
42796
+ _internals12 = {
42291
42797
  isCommandAvailable,
42292
42798
  discoverBuildCommandsFromProfiles,
42293
42799
  discoverBuildCommands,
@@ -42314,7 +42820,7 @@ var init_discovery = __esm(() => {
42314
42820
 
42315
42821
  // src/services/tool-doctor.ts
42316
42822
  import * as fs10 from "fs";
42317
- import * as path24 from "path";
42823
+ import * as path25 from "path";
42318
42824
  function extractRegisteredToolKeys(indexPath) {
42319
42825
  const registeredKeys = new Set;
42320
42826
  try {
@@ -42369,8 +42875,8 @@ function checkBinaryReadiness() {
42369
42875
  }
42370
42876
  function runToolDoctor(_directory, pluginRoot) {
42371
42877
  const findings = [];
42372
- const resolvedPluginRoot = pluginRoot ?? path24.resolve(import.meta.dir, "..", "..");
42373
- const indexPath = path24.join(resolvedPluginRoot, "src", "index.ts");
42878
+ const resolvedPluginRoot = pluginRoot ?? path25.resolve(import.meta.dir, "..", "..");
42879
+ const indexPath = path25.join(resolvedPluginRoot, "src", "index.ts");
42374
42880
  if (!fs10.existsSync(indexPath)) {
42375
42881
  return {
42376
42882
  findings: [
@@ -42590,7 +43096,7 @@ var exports_evidence_summary_service = {};
42590
43096
  __export(exports_evidence_summary_service, {
42591
43097
  isAutoSummaryEnabled: () => isAutoSummaryEnabled,
42592
43098
  buildEvidenceSummary: () => buildEvidenceSummary,
42593
- _internals: () => _internals12,
43099
+ _internals: () => _internals13,
42594
43100
  REQUIRED_EVIDENCE_TYPES: () => REQUIRED_EVIDENCE_TYPES,
42595
43101
  EVIDENCE_SUMMARY_VERSION: () => EVIDENCE_SUMMARY_VERSION
42596
43102
  });
@@ -42628,14 +43134,13 @@ function getTaskStatus(task, bundle) {
42628
43134
  if (task?.status) {
42629
43135
  return task.status;
42630
43136
  }
42631
- const entries = _internals12.normalizeBundleEntries(bundle);
43137
+ const entries = _internals13.normalizeBundleEntries(bundle);
42632
43138
  if (entries.length > 0) {
42633
43139
  return "completed";
42634
43140
  }
42635
43141
  return "pending";
42636
43142
  }
42637
- function isEvidenceComplete(bundle) {
42638
- const entries = _internals12.normalizeBundleEntries(bundle);
43143
+ function evidenceCompleteFromEntries(entries) {
42639
43144
  if (entries.length === 0) {
42640
43145
  return {
42641
43146
  isComplete: false,
@@ -42654,6 +43159,9 @@ function isEvidenceComplete(bundle) {
42654
43159
  missingEvidence: missing
42655
43160
  };
42656
43161
  }
43162
+ function isEvidenceComplete(bundle) {
43163
+ return evidenceCompleteFromEntries(_internals13.normalizeBundleEntries(bundle));
43164
+ }
42657
43165
  function getTaskBlockers(task, summary, status) {
42658
43166
  const blockers = [];
42659
43167
  if (task?.blocked_reason) {
@@ -42670,11 +43178,19 @@ function getTaskBlockers(task, summary, status) {
42670
43178
  async function buildTaskSummary(directory, task, taskId) {
42671
43179
  const result = await loadEvidence(directory, taskId);
42672
43180
  const bundle = result.status === "found" ? result.bundle : null;
43181
+ const gateEvidence = await readDurableGateEvidence(directory, taskId);
42673
43182
  const phase = task?.phase ?? 0;
42674
- const status = _internals12.getTaskStatus(task, bundle);
42675
- const evidenceCheck = _internals12.isEvidenceComplete(bundle);
42676
- const blockers = _internals12.getTaskBlockers(task, evidenceCheck, status);
42677
- const entries = _internals12.normalizeBundleEntries(bundle);
43183
+ const status = _internals13.getTaskStatus(task, bundle);
43184
+ const entries = mergeDurableGateEntriesFromEvidence(taskId, _internals13.normalizeBundleEntries(bundle), gateEvidence);
43185
+ let evidenceCheck = _internals13.evidenceCompleteFromEntries(entries);
43186
+ if (gateEvidence) {
43187
+ const gateStatus = getDurableGateEvidenceStatus(gateEvidence);
43188
+ evidenceCheck = gateStatus.isComplete ? { isComplete: true, missingEvidence: [] } : {
43189
+ isComplete: false,
43190
+ missingEvidence: gateStatus.missingGates.map((gate) => `gate:${gate}`)
43191
+ };
43192
+ }
43193
+ const blockers = _internals13.getTaskBlockers(task, evidenceCheck, status);
42678
43194
  const hasReview = entries.some((e) => e.type === "review");
42679
43195
  const hasTest = entries.some((e) => e.type === "test");
42680
43196
  const hasApproval = entries.some((e) => e.type === "approval");
@@ -42703,12 +43219,12 @@ async function buildPhaseSummary(directory, phase) {
42703
43219
  const taskSummaries = [];
42704
43220
  const _taskMap = new Map(phase.tasks.map((t) => [t.id, t]));
42705
43221
  for (const task of phase.tasks) {
42706
- const summary = await _internals12.buildTaskSummary(directory, task, task.id);
43222
+ const summary = await _internals13.buildTaskSummary(directory, task, task.id);
42707
43223
  taskSummaries.push(summary);
42708
43224
  }
42709
43225
  const extraTaskIds = taskIds.filter((id) => !phaseTaskIds.has(id));
42710
43226
  for (const taskId of extraTaskIds) {
42711
- const summary = await _internals12.buildTaskSummary(directory, undefined, taskId);
43227
+ const summary = await _internals13.buildTaskSummary(directory, undefined, taskId);
42712
43228
  if (summary.phase === phase.id) {
42713
43229
  taskSummaries.push(summary);
42714
43230
  }
@@ -42809,7 +43325,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
42809
43325
  let totalTasks = 0;
42810
43326
  let completedTasks = 0;
42811
43327
  for (const phase of phasesToProcess) {
42812
- const summary = await _internals12.buildPhaseSummary(directory, phase);
43328
+ const summary = await _internals13.buildPhaseSummary(directory, phase);
42813
43329
  phaseSummaries.push(summary);
42814
43330
  totalTasks += summary.totalTasks;
42815
43331
  completedTasks += summary.completedTasks;
@@ -42831,7 +43347,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
42831
43347
  overallBlockers,
42832
43348
  summaryText: ""
42833
43349
  };
42834
- artifact.summaryText = _internals12.generateSummaryText(artifact);
43350
+ artifact.summaryText = _internals13.generateSummaryText(artifact);
42835
43351
  log("[EvidenceSummary] Summary built", {
42836
43352
  phases: phaseSummaries.length,
42837
43353
  totalTasks,
@@ -42850,8 +43366,9 @@ function isAutoSummaryEnabled(automationConfig) {
42850
43366
  }
42851
43367
  return automationConfig.capabilities?.evidence_auto_summaries === true;
42852
43368
  }
42853
- var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0", _internals12;
43369
+ var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0", _internals13;
42854
43370
  var init_evidence_summary_service = __esm(() => {
43371
+ init_gate_bridge();
42855
43372
  init_manager2();
42856
43373
  init_manager();
42857
43374
  init_utils();
@@ -42864,11 +43381,12 @@ var init_evidence_summary_service = __esm(() => {
42864
43381
  "retrospective"
42865
43382
  ]);
42866
43383
  REQUIRED_EVIDENCE_TYPES = ["review", "test"];
42867
- _internals12 = {
43384
+ _internals13 = {
42868
43385
  buildEvidenceSummary,
42869
43386
  isAutoSummaryEnabled,
42870
43387
  normalizeBundleEntries,
42871
43388
  getTaskStatus,
43389
+ evidenceCompleteFromEntries,
42872
43390
  isEvidenceComplete,
42873
43391
  getTaskBlockers,
42874
43392
  buildTaskSummary,
@@ -42919,7 +43437,7 @@ function getVerdictEmoji(verdict) {
42919
43437
  return getVerdictIcon(verdict);
42920
43438
  }
42921
43439
  async function getTaskEvidenceData(directory, taskId) {
42922
- const result = await _internals13.loadEvidence(directory, taskId);
43440
+ const result = await _internals14.loadEvidence(directory, taskId);
42923
43441
  if (result.status !== "found") {
42924
43442
  return {
42925
43443
  hasEvidence: false,
@@ -42942,13 +43460,13 @@ async function getTaskEvidenceData(directory, taskId) {
42942
43460
  };
42943
43461
  }
42944
43462
  async function getEvidenceListData(directory) {
42945
- const taskIds = await _internals13.listEvidenceTaskIds(directory);
43463
+ const taskIds = await _internals14.listEvidenceTaskIds(directory);
42946
43464
  if (taskIds.length === 0) {
42947
43465
  return { hasEvidence: false, tasks: [] };
42948
43466
  }
42949
43467
  const tasks = [];
42950
43468
  for (const taskId of taskIds) {
42951
- const result = await _internals13.loadEvidence(directory, taskId);
43469
+ const result = await _internals14.loadEvidence(directory, taskId);
42952
43470
  if (result.status === "found") {
42953
43471
  tasks.push({
42954
43472
  taskId,
@@ -43062,10 +43580,10 @@ async function handleEvidenceSummaryCommand(directory) {
43062
43580
  return lines.join(`
43063
43581
  `);
43064
43582
  }
43065
- var _internals13;
43583
+ var _internals14;
43066
43584
  var init_evidence_service = __esm(() => {
43067
43585
  init_manager2();
43068
- _internals13 = {
43586
+ _internals14 = {
43069
43587
  loadEvidence,
43070
43588
  listEvidenceTaskIds
43071
43589
  };
@@ -43116,12 +43634,12 @@ var init_export = __esm(() => {
43116
43634
 
43117
43635
  // src/full-auto/state.ts
43118
43636
  import * as fs11 from "fs";
43119
- import * as path25 from "path";
43637
+ import * as path26 from "path";
43120
43638
  function nowISO() {
43121
43639
  return new Date().toISOString();
43122
43640
  }
43123
43641
  function ensureSwarmDir(directory) {
43124
- const swarmDir = path25.resolve(directory, ".swarm");
43642
+ const swarmDir = path26.resolve(directory, ".swarm");
43125
43643
  if (!fs11.existsSync(swarmDir)) {
43126
43644
  fs11.mkdirSync(swarmDir, { recursive: true });
43127
43645
  }
@@ -43472,7 +43990,7 @@ function extractCurrentPhaseFromPlan2(plan) {
43472
43990
  if (!plan) {
43473
43991
  return { currentPhase: null, currentTask: null, incompleteTasks: [] };
43474
43992
  }
43475
- if (!_internals14.validatePlanPhases(plan)) {
43993
+ if (!_internals15.validatePlanPhases(plan)) {
43476
43994
  return { currentPhase: null, currentTask: null, incompleteTasks: [] };
43477
43995
  }
43478
43996
  let currentPhase = null;
@@ -43614,9 +44132,9 @@ function extractPhaseMetrics(content) {
43614
44132
  async function getHandoffData(directory) {
43615
44133
  const now = new Date().toISOString();
43616
44134
  const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
43617
- const sessionState = _internals14.parseSessionState(sessionContent);
44135
+ const sessionState = _internals15.parseSessionState(sessionContent);
43618
44136
  const plan = await loadPlanJsonOnly(directory);
43619
- const planInfo = _internals14.extractCurrentPhaseFromPlan(plan);
44137
+ const planInfo = _internals15.extractCurrentPhaseFromPlan(plan);
43620
44138
  if (!plan) {
43621
44139
  const planMdContent = await readSwarmFileAsync(directory, "plan.md");
43622
44140
  if (planMdContent) {
@@ -43635,8 +44153,8 @@ async function getHandoffData(directory) {
43635
44153
  }
43636
44154
  }
43637
44155
  const contextContent = await readSwarmFileAsync(directory, "context.md");
43638
- const recentDecisions = _internals14.extractDecisions(contextContent);
43639
- const rawPhaseMetrics = _internals14.extractPhaseMetrics(contextContent);
44156
+ const recentDecisions = _internals15.extractDecisions(contextContent);
44157
+ const rawPhaseMetrics = _internals15.extractPhaseMetrics(contextContent);
43640
44158
  const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
43641
44159
  let delegationState = null;
43642
44160
  if (sessionState?.delegationState) {
@@ -43800,13 +44318,13 @@ ${lines.join(`
43800
44318
  `)}
43801
44319
  \`\`\``;
43802
44320
  }
43803
- var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20, _internals14;
44321
+ var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20, _internals15;
43804
44322
  var init_handoff_service = __esm(() => {
43805
44323
  init_utils2();
43806
44324
  init_manager();
43807
44325
  init_utils();
43808
44326
  RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
43809
- _internals14 = {
44327
+ _internals15 = {
43810
44328
  getHandoffData,
43811
44329
  formatHandoffMarkdown,
43812
44330
  formatContinuationPrompt,
@@ -43821,8 +44339,8 @@ var init_handoff_service = __esm(() => {
43821
44339
  });
43822
44340
 
43823
44341
  // src/session/snapshot-writer.ts
43824
- import { closeSync as closeSync3, fsyncSync as fsyncSync2, mkdirSync as mkdirSync10, openSync as openSync3, renameSync as renameSync6 } from "fs";
43825
- import * as path26 from "path";
44342
+ import { closeSync as closeSync3, fsyncSync as fsyncSync2, mkdirSync as mkdirSync11, openSync as openSync3, renameSync as renameSync6 } from "fs";
44343
+ import * as path27 from "path";
43826
44344
  function serializeAgentSession(s) {
43827
44345
  const gateLog = {};
43828
44346
  const rawGateLog = s.gateLog ?? new Map;
@@ -43919,8 +44437,8 @@ async function writeSnapshot(directory, state) {
43919
44437
  }
43920
44438
  const content = JSON.stringify(snapshot, null, 2);
43921
44439
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
43922
- const dir = path26.dirname(resolvedPath);
43923
- mkdirSync10(dir, { recursive: true });
44440
+ const dir = path27.dirname(resolvedPath);
44441
+ mkdirSync11(dir, { recursive: true });
43924
44442
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
43925
44443
  await bunWrite(tempPath, content);
43926
44444
  try {
@@ -43940,22 +44458,22 @@ async function writeSnapshot(directory, state) {
43940
44458
  }
43941
44459
  function createSnapshotWriterHook(directory) {
43942
44460
  return (_input, _output) => {
43943
- _writeInFlight = _writeInFlight.then(() => _internals15.writeSnapshot(directory, swarmState), () => _internals15.writeSnapshot(directory, swarmState));
44461
+ _writeInFlight = _writeInFlight.then(() => _internals16.writeSnapshot(directory, swarmState), () => _internals16.writeSnapshot(directory, swarmState));
43944
44462
  return _writeInFlight;
43945
44463
  };
43946
44464
  }
43947
44465
  async function flushPendingSnapshot(directory) {
43948
- _writeInFlight = _writeInFlight.then(() => _internals15.writeSnapshot(directory, swarmState), () => _internals15.writeSnapshot(directory, swarmState));
44466
+ _writeInFlight = _writeInFlight.then(() => _internals16.writeSnapshot(directory, swarmState), () => _internals16.writeSnapshot(directory, swarmState));
43949
44467
  await _writeInFlight;
43950
44468
  }
43951
- var _writeInFlight, _internals15;
44469
+ var _writeInFlight, _internals16;
43952
44470
  var init_snapshot_writer = __esm(() => {
43953
44471
  init_utils2();
43954
44472
  init_state();
43955
44473
  init_utils();
43956
44474
  init_bun_compat();
43957
44475
  _writeInFlight = Promise.resolve();
43958
- _internals15 = {
44476
+ _internals16 = {
43959
44477
  writeSnapshot,
43960
44478
  createSnapshotWriterHook,
43961
44479
  flushPendingSnapshot
@@ -44376,9 +44894,9 @@ var init_issue = __esm(() => {
44376
44894
 
44377
44895
  // src/hooks/knowledge-migrator.ts
44378
44896
  import { randomUUID as randomUUID2 } from "crypto";
44379
- import { existsSync as existsSync17, readFileSync as readFileSync12 } from "fs";
44897
+ import { existsSync as existsSync17, readFileSync as readFileSync13 } from "fs";
44380
44898
  import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
44381
- import * as path27 from "path";
44899
+ import * as path28 from "path";
44382
44900
  async function migrateKnowledgeToExternal(_directory, _config) {
44383
44901
  return {
44384
44902
  migrated: false,
@@ -44389,8 +44907,8 @@ async function migrateKnowledgeToExternal(_directory, _config) {
44389
44907
  };
44390
44908
  }
44391
44909
  async function migrateContextToKnowledge(directory, config3) {
44392
- const sentinelPath = path27.join(directory, ".swarm", ".knowledge-migrated");
44393
- const contextPath = path27.join(directory, ".swarm", "context.md");
44910
+ const sentinelPath = path28.join(directory, ".swarm", ".knowledge-migrated");
44911
+ const contextPath = path28.join(directory, ".swarm", "context.md");
44394
44912
  const knowledgePath = resolveSwarmKnowledgePath(directory);
44395
44913
  if (existsSync17(sentinelPath)) {
44396
44914
  return {
@@ -44420,9 +44938,9 @@ async function migrateContextToKnowledge(directory, config3) {
44420
44938
  skippedReason: "empty-context"
44421
44939
  };
44422
44940
  }
44423
- const rawEntries = _internals16.parseContextMd(contextContent);
44941
+ const rawEntries = _internals17.parseContextMd(contextContent);
44424
44942
  if (rawEntries.length === 0) {
44425
- await _internals16.writeSentinel(sentinelPath, 0, 0);
44943
+ await _internals17.writeSentinel(sentinelPath, 0, 0);
44426
44944
  return {
44427
44945
  migrated: true,
44428
44946
  entriesMigrated: 0,
@@ -44433,10 +44951,10 @@ async function migrateContextToKnowledge(directory, config3) {
44433
44951
  const existing = await readKnowledge(knowledgePath);
44434
44952
  let migrated = 0;
44435
44953
  let dropped = 0;
44436
- const projectName = _internals16.inferProjectName(directory);
44954
+ const projectName = _internals17.inferProjectName(directory);
44437
44955
  for (const raw of rawEntries) {
44438
44956
  if (config3.validation_enabled !== false) {
44439
- const category = raw.categoryHint ?? _internals16.inferCategoryFromText(raw.text);
44957
+ const category = raw.categoryHint ?? _internals17.inferCategoryFromText(raw.text);
44440
44958
  const result = validateLesson(raw.text, existing.map((e) => e.lesson), {
44441
44959
  category,
44442
44960
  scope: "global",
@@ -44456,8 +44974,8 @@ async function migrateContextToKnowledge(directory, config3) {
44456
44974
  const entry = {
44457
44975
  id: randomUUID2(),
44458
44976
  tier: "swarm",
44459
- lesson: _internals16.truncateLesson(raw.text),
44460
- category: raw.categoryHint ?? _internals16.inferCategoryFromText(raw.text),
44977
+ lesson: _internals17.truncateLesson(raw.text),
44978
+ category: raw.categoryHint ?? _internals17.inferCategoryFromText(raw.text),
44461
44979
  tags: [...inferredTags, `migration:${raw.sourceSection}`],
44462
44980
  scope: "global",
44463
44981
  confidence: 0.3,
@@ -44480,7 +44998,7 @@ async function migrateContextToKnowledge(directory, config3) {
44480
44998
  if (migrated > 0) {
44481
44999
  await rewriteKnowledge(knowledgePath, existing);
44482
45000
  }
44483
- await _internals16.writeSentinel(sentinelPath, migrated, dropped);
45001
+ await _internals17.writeSentinel(sentinelPath, migrated, dropped);
44484
45002
  log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`);
44485
45003
  return {
44486
45004
  migrated: true,
@@ -44490,7 +45008,7 @@ async function migrateContextToKnowledge(directory, config3) {
44490
45008
  };
44491
45009
  }
44492
45010
  function parseContextMd(content) {
44493
- const sections = _internals16.splitIntoSections(content);
45011
+ const sections = _internals17.splitIntoSections(content);
44494
45012
  const entries = [];
44495
45013
  const seen = new Set;
44496
45014
  const sectionPatterns = [
@@ -44506,7 +45024,7 @@ function parseContextMd(content) {
44506
45024
  const match = sectionPatterns.find((sp) => sp.pattern.test(section.heading));
44507
45025
  if (!match)
44508
45026
  continue;
44509
- const bullets = _internals16.extractBullets(section.body);
45027
+ const bullets = _internals17.extractBullets(section.body);
44510
45028
  for (const bullet of bullets) {
44511
45029
  if (bullet.length < 15)
44512
45030
  continue;
@@ -44515,9 +45033,9 @@ function parseContextMd(content) {
44515
45033
  continue;
44516
45034
  seen.add(normalized);
44517
45035
  entries.push({
44518
- text: _internals16.truncateLesson(bullet),
45036
+ text: _internals17.truncateLesson(bullet),
44519
45037
  sourceSection: match.sourceSection,
44520
- categoryHint: _internals16.inferCategoryFromText(bullet)
45038
+ categoryHint: _internals17.inferCategoryFromText(bullet)
44521
45039
  });
44522
45040
  }
44523
45041
  }
@@ -44586,16 +45104,16 @@ function truncateLesson(text) {
44586
45104
  return `${text.slice(0, 277)}...`;
44587
45105
  }
44588
45106
  function inferProjectName(directory) {
44589
- const packageJsonPath = path27.join(directory, "package.json");
45107
+ const packageJsonPath = path28.join(directory, "package.json");
44590
45108
  if (existsSync17(packageJsonPath)) {
44591
45109
  try {
44592
- const pkg = JSON.parse(readFileSync12(packageJsonPath, "utf-8"));
45110
+ const pkg = JSON.parse(readFileSync13(packageJsonPath, "utf-8"));
44593
45111
  if (pkg.name && typeof pkg.name === "string") {
44594
45112
  return pkg.name;
44595
45113
  }
44596
45114
  } catch {}
44597
45115
  }
44598
- return path27.basename(directory);
45116
+ return path28.basename(directory);
44599
45117
  }
44600
45118
  async function writeSentinel(sentinelPath, migrated, dropped) {
44601
45119
  const sentinel = {
@@ -44607,15 +45125,15 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
44607
45125
  schema_version: 1,
44608
45126
  migration_tool: "knowledge-migrator.ts"
44609
45127
  };
44610
- await mkdir7(path27.dirname(sentinelPath), { recursive: true });
45128
+ await mkdir7(path28.dirname(sentinelPath), { recursive: true });
44611
45129
  await writeFile8(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
44612
45130
  }
44613
- var _internals16;
45131
+ var _internals17;
44614
45132
  var init_knowledge_migrator = __esm(() => {
44615
45133
  init_logger();
44616
45134
  init_knowledge_store();
44617
45135
  init_knowledge_validator();
44618
- _internals16 = {
45136
+ _internals17 = {
44619
45137
  migrateContextToKnowledge,
44620
45138
  migrateKnowledgeToExternal,
44621
45139
  parseContextMd,
@@ -44629,7 +45147,7 @@ var init_knowledge_migrator = __esm(() => {
44629
45147
  });
44630
45148
 
44631
45149
  // src/commands/knowledge.ts
44632
- import { join as join25 } from "path";
45150
+ import { join as join26 } from "path";
44633
45151
  function resolveEntryByPrefix(entries, inputId) {
44634
45152
  const exact = entries.find((e) => e.id === inputId);
44635
45153
  if (exact)
@@ -44680,7 +45198,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
44680
45198
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
44681
45199
  }
44682
45200
  try {
44683
- const quarantinePath = join25(directory, ".swarm", "knowledge-quarantined.jsonl");
45201
+ const quarantinePath = join26(directory, ".swarm", "knowledge-quarantined.jsonl");
44684
45202
  const entries = await readKnowledge(quarantinePath);
44685
45203
  const resolved = resolveEntryByPrefix(entries, inputId);
44686
45204
  if ("error" in resolved) {
@@ -44752,9 +45270,9 @@ var init_knowledge = __esm(() => {
44752
45270
 
44753
45271
  // src/services/plan-service.ts
44754
45272
  async function getPlanData(directory, phaseArg) {
44755
- const plan = await _internals17.loadPlanJsonOnly(directory);
45273
+ const plan = await _internals18.loadPlanJsonOnly(directory);
44756
45274
  if (plan) {
44757
- const fullMarkdown = _internals17.derivePlanMarkdown(plan);
45275
+ const fullMarkdown = _internals18.derivePlanMarkdown(plan);
44758
45276
  if (phaseArg === undefined || phaseArg === null || phaseArg === "") {
44759
45277
  return {
44760
45278
  hasPlan: true,
@@ -44797,7 +45315,7 @@ async function getPlanData(directory, phaseArg) {
44797
45315
  isLegacy: false
44798
45316
  };
44799
45317
  }
44800
- const planContent = await _internals17.readSwarmFileAsync(directory, "plan.md");
45318
+ const planContent = await _internals18.readSwarmFileAsync(directory, "plan.md");
44801
45319
  if (!planContent) {
44802
45320
  return {
44803
45321
  hasPlan: false,
@@ -44893,11 +45411,11 @@ async function handlePlanCommand(directory, args) {
44893
45411
  const planData = await getPlanData(directory, phaseArg);
44894
45412
  return formatPlanMarkdown(planData);
44895
45413
  }
44896
- var _internals17;
45414
+ var _internals18;
44897
45415
  var init_plan_service = __esm(() => {
44898
45416
  init_utils2();
44899
45417
  init_manager();
44900
- _internals17 = {
45418
+ _internals18 = {
44901
45419
  loadPlanJsonOnly,
44902
45420
  derivePlanMarkdown,
44903
45421
  readSwarmFileAsync
@@ -45135,7 +45653,7 @@ var init_path_security = () => {};
45135
45653
 
45136
45654
  // src/tools/lint.ts
45137
45655
  import * as fs12 from "fs";
45138
- import * as path28 from "path";
45656
+ import * as path29 from "path";
45139
45657
  function validateArgs(args) {
45140
45658
  if (typeof args !== "object" || args === null)
45141
45659
  return false;
@@ -45146,9 +45664,9 @@ function validateArgs(args) {
45146
45664
  }
45147
45665
  function getLinterCommand(linter, mode, projectDir) {
45148
45666
  const isWindows = process.platform === "win32";
45149
- const binDir = path28.join(projectDir, "node_modules", ".bin");
45150
- const biomeBin = isWindows ? path28.join(binDir, "biome.EXE") : path28.join(binDir, "biome");
45151
- const eslintBin = isWindows ? path28.join(binDir, "eslint.cmd") : path28.join(binDir, "eslint");
45667
+ const binDir = path29.join(projectDir, "node_modules", ".bin");
45668
+ const biomeBin = isWindows ? path29.join(binDir, "biome.EXE") : path29.join(binDir, "biome");
45669
+ const eslintBin = isWindows ? path29.join(binDir, "eslint.cmd") : path29.join(binDir, "eslint");
45152
45670
  switch (linter) {
45153
45671
  case "biome":
45154
45672
  if (mode === "fix") {
@@ -45164,7 +45682,7 @@ function getLinterCommand(linter, mode, projectDir) {
45164
45682
  }
45165
45683
  function getAdditionalLinterCommand(linter, mode, cwd) {
45166
45684
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
45167
- const gradlew = fs12.existsSync(path28.join(cwd, gradlewName)) ? path28.join(cwd, gradlewName) : null;
45685
+ const gradlew = fs12.existsSync(path29.join(cwd, gradlewName)) ? path29.join(cwd, gradlewName) : null;
45168
45686
  switch (linter) {
45169
45687
  case "ruff":
45170
45688
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -45198,10 +45716,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
45198
45716
  }
45199
45717
  }
45200
45718
  function detectRuff(cwd) {
45201
- if (fs12.existsSync(path28.join(cwd, "ruff.toml")))
45719
+ if (fs12.existsSync(path29.join(cwd, "ruff.toml")))
45202
45720
  return isCommandAvailable("ruff");
45203
45721
  try {
45204
- const pyproject = path28.join(cwd, "pyproject.toml");
45722
+ const pyproject = path29.join(cwd, "pyproject.toml");
45205
45723
  if (fs12.existsSync(pyproject)) {
45206
45724
  const content = fs12.readFileSync(pyproject, "utf-8");
45207
45725
  if (content.includes("[tool.ruff]"))
@@ -45211,19 +45729,19 @@ function detectRuff(cwd) {
45211
45729
  return false;
45212
45730
  }
45213
45731
  function detectClippy(cwd) {
45214
- return fs12.existsSync(path28.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
45732
+ return fs12.existsSync(path29.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
45215
45733
  }
45216
45734
  function detectGolangciLint(cwd) {
45217
- return fs12.existsSync(path28.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
45735
+ return fs12.existsSync(path29.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
45218
45736
  }
45219
45737
  function detectCheckstyle(cwd) {
45220
- const hasMaven = fs12.existsSync(path28.join(cwd, "pom.xml"));
45221
- const hasGradle = fs12.existsSync(path28.join(cwd, "build.gradle")) || fs12.existsSync(path28.join(cwd, "build.gradle.kts"));
45222
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(path28.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
45738
+ const hasMaven = fs12.existsSync(path29.join(cwd, "pom.xml"));
45739
+ const hasGradle = fs12.existsSync(path29.join(cwd, "build.gradle")) || fs12.existsSync(path29.join(cwd, "build.gradle.kts"));
45740
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(path29.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
45223
45741
  return (hasMaven || hasGradle) && hasBinary;
45224
45742
  }
45225
45743
  function detectKtlint(cwd) {
45226
- const hasKotlin = fs12.existsSync(path28.join(cwd, "build.gradle.kts")) || fs12.existsSync(path28.join(cwd, "build.gradle")) || (() => {
45744
+ const hasKotlin = fs12.existsSync(path29.join(cwd, "build.gradle.kts")) || fs12.existsSync(path29.join(cwd, "build.gradle")) || (() => {
45227
45745
  try {
45228
45746
  return fs12.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
45229
45747
  } catch {
@@ -45242,11 +45760,11 @@ function detectDotnetFormat(cwd) {
45242
45760
  }
45243
45761
  }
45244
45762
  function detectCppcheck(cwd) {
45245
- if (fs12.existsSync(path28.join(cwd, "CMakeLists.txt"))) {
45763
+ if (fs12.existsSync(path29.join(cwd, "CMakeLists.txt"))) {
45246
45764
  return isCommandAvailable("cppcheck");
45247
45765
  }
45248
45766
  try {
45249
- const dirsToCheck = [cwd, path28.join(cwd, "src")];
45767
+ const dirsToCheck = [cwd, path29.join(cwd, "src")];
45250
45768
  const hasCpp = dirsToCheck.some((dir) => {
45251
45769
  try {
45252
45770
  return fs12.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
@@ -45260,13 +45778,13 @@ function detectCppcheck(cwd) {
45260
45778
  }
45261
45779
  }
45262
45780
  function detectSwiftlint(cwd) {
45263
- return fs12.existsSync(path28.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
45781
+ return fs12.existsSync(path29.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
45264
45782
  }
45265
45783
  function detectDartAnalyze(cwd) {
45266
- return fs12.existsSync(path28.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
45784
+ return fs12.existsSync(path29.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
45267
45785
  }
45268
45786
  function detectRubocop(cwd) {
45269
- return (fs12.existsSync(path28.join(cwd, "Gemfile")) || fs12.existsSync(path28.join(cwd, "gems.rb")) || fs12.existsSync(path28.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
45787
+ return (fs12.existsSync(path29.join(cwd, "Gemfile")) || fs12.existsSync(path29.join(cwd, "gems.rb")) || fs12.existsSync(path29.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
45270
45788
  }
45271
45789
  function detectAdditionalLinter(cwd) {
45272
45790
  if (detectRuff(cwd))
@@ -45294,10 +45812,10 @@ function detectAdditionalLinter(cwd) {
45294
45812
  function findBinInAncestors(startDir, binName) {
45295
45813
  let dir = startDir;
45296
45814
  while (true) {
45297
- const candidate = path28.join(dir, "node_modules", ".bin", binName);
45815
+ const candidate = path29.join(dir, "node_modules", ".bin", binName);
45298
45816
  if (fs12.existsSync(candidate))
45299
45817
  return candidate;
45300
- const parent = path28.dirname(dir);
45818
+ const parent = path29.dirname(dir);
45301
45819
  if (parent === dir)
45302
45820
  break;
45303
45821
  dir = parent;
@@ -45306,10 +45824,10 @@ function findBinInAncestors(startDir, binName) {
45306
45824
  }
45307
45825
  function findBinInEnvPath(binName) {
45308
45826
  const searchPath = process.env.PATH ?? "";
45309
- for (const dir of searchPath.split(path28.delimiter)) {
45827
+ for (const dir of searchPath.split(path29.delimiter)) {
45310
45828
  if (!dir)
45311
45829
  continue;
45312
- const candidate = path28.join(dir, binName);
45830
+ const candidate = path29.join(dir, binName);
45313
45831
  if (fs12.existsSync(candidate))
45314
45832
  return candidate;
45315
45833
  }
@@ -45322,13 +45840,13 @@ async function detectAvailableLinter(directory) {
45322
45840
  return null;
45323
45841
  const projectDir = directory;
45324
45842
  const isWindows = process.platform === "win32";
45325
- const biomeBin = isWindows ? path28.join(projectDir, "node_modules", ".bin", "biome.EXE") : path28.join(projectDir, "node_modules", ".bin", "biome");
45326
- const eslintBin = isWindows ? path28.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path28.join(projectDir, "node_modules", ".bin", "eslint");
45843
+ const biomeBin = isWindows ? path29.join(projectDir, "node_modules", ".bin", "biome.EXE") : path29.join(projectDir, "node_modules", ".bin", "biome");
45844
+ const eslintBin = isWindows ? path29.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path29.join(projectDir, "node_modules", ".bin", "eslint");
45327
45845
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
45328
45846
  if (localResult)
45329
45847
  return localResult;
45330
- const biomeAncestor = findBinInAncestors(path28.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
45331
- const eslintAncestor = findBinInAncestors(path28.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
45848
+ const biomeAncestor = findBinInAncestors(path29.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
45849
+ const eslintAncestor = findBinInAncestors(path29.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
45332
45850
  if (biomeAncestor || eslintAncestor) {
45333
45851
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
45334
45852
  }
@@ -45487,7 +46005,7 @@ async function runAdditionalLint(linter, mode, cwd) {
45487
46005
  };
45488
46006
  }
45489
46007
  }
45490
- var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint, _internals18;
46008
+ var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint, _internals19;
45491
46009
  var init_lint = __esm(() => {
45492
46010
  init_zod();
45493
46011
  init_discovery();
@@ -45519,15 +46037,15 @@ var init_lint = __esm(() => {
45519
46037
  }
45520
46038
  const { mode } = args;
45521
46039
  const cwd = directory;
45522
- const linter = await _internals18.detectAvailableLinter(directory);
46040
+ const linter = await _internals19.detectAvailableLinter(directory);
45523
46041
  if (linter) {
45524
- const result = await _internals18.runLint(linter, mode, directory);
46042
+ const result = await _internals19.runLint(linter, mode, directory);
45525
46043
  return JSON.stringify(result, null, 2);
45526
46044
  }
45527
- const additionalLinter = _internals18.detectAdditionalLinter(cwd);
46045
+ const additionalLinter = _internals19.detectAdditionalLinter(cwd);
45528
46046
  if (additionalLinter) {
45529
46047
  warn(`[lint] Using ${additionalLinter} linter for this project`);
45530
- const result = await _internals18.runAdditionalLint(additionalLinter, mode, cwd);
46048
+ const result = await _internals19.runAdditionalLint(additionalLinter, mode, cwd);
45531
46049
  return JSON.stringify(result, null, 2);
45532
46050
  }
45533
46051
  const errorResult = {
@@ -45541,7 +46059,7 @@ For Rust: rustup component add clippy`
45541
46059
  return JSON.stringify(errorResult, null, 2);
45542
46060
  }
45543
46061
  });
45544
- _internals18 = {
46062
+ _internals19 = {
45545
46063
  detectAvailableLinter,
45546
46064
  runLint,
45547
46065
  detectAdditionalLinter,
@@ -45551,7 +46069,7 @@ For Rust: rustup component add clippy`
45551
46069
 
45552
46070
  // src/tools/secretscan.ts
45553
46071
  import * as fs13 from "fs";
45554
- import * as path29 from "path";
46072
+ import * as path30 from "path";
45555
46073
  function calculateShannonEntropy(str) {
45556
46074
  if (str.length === 0)
45557
46075
  return 0;
@@ -45599,7 +46117,7 @@ function isGlobOrPathPattern(pattern) {
45599
46117
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
45600
46118
  }
45601
46119
  function loadSecretScanIgnore(scanDir) {
45602
- const ignorePath = path29.join(scanDir, ".secretscanignore");
46120
+ const ignorePath = path30.join(scanDir, ".secretscanignore");
45603
46121
  try {
45604
46122
  if (!fs13.existsSync(ignorePath))
45605
46123
  return [];
@@ -45622,7 +46140,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
45622
46140
  if (exactNames.has(entry))
45623
46141
  return true;
45624
46142
  for (const pattern of globPatterns) {
45625
- if (path29.matchesGlob(relPath, pattern))
46143
+ if (path30.matchesGlob(relPath, pattern))
45626
46144
  return true;
45627
46145
  }
45628
46146
  return false;
@@ -45643,7 +46161,7 @@ function validateDirectoryInput(dir) {
45643
46161
  return null;
45644
46162
  }
45645
46163
  function isBinaryFile(filePath, buffer) {
45646
- const ext = path29.extname(filePath).toLowerCase();
46164
+ const ext = path30.extname(filePath).toLowerCase();
45647
46165
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
45648
46166
  return true;
45649
46167
  }
@@ -45779,9 +46297,9 @@ function isSymlinkLoop(realPath, visited) {
45779
46297
  return false;
45780
46298
  }
45781
46299
  function isPathWithinScope(realPath, scanDir) {
45782
- const resolvedScanDir = path29.resolve(scanDir);
45783
- const resolvedRealPath = path29.resolve(realPath);
45784
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path29.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
46300
+ const resolvedScanDir = path30.resolve(scanDir);
46301
+ const resolvedRealPath = path30.resolve(realPath);
46302
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path30.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
45785
46303
  }
45786
46304
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
45787
46305
  skippedDirs: 0,
@@ -45807,8 +46325,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
45807
46325
  return a.localeCompare(b);
45808
46326
  });
45809
46327
  for (const entry of entries) {
45810
- const fullPath = path29.join(dir, entry);
45811
- const relPath = path29.relative(scanDir, fullPath).replace(/\\/g, "/");
46328
+ const fullPath = path30.join(dir, entry);
46329
+ const relPath = path30.relative(scanDir, fullPath).replace(/\\/g, "/");
45812
46330
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
45813
46331
  stats.skippedDirs++;
45814
46332
  continue;
@@ -45843,7 +46361,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
45843
46361
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
45844
46362
  files.push(...subFiles);
45845
46363
  } else if (lstat.isFile()) {
45846
- const ext = path29.extname(fullPath).toLowerCase();
46364
+ const ext = path30.extname(fullPath).toLowerCase();
45847
46365
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
45848
46366
  files.push(fullPath);
45849
46367
  } else {
@@ -45855,7 +46373,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
45855
46373
  }
45856
46374
  async function runSecretscan(directory) {
45857
46375
  try {
45858
- const result = await _internals19.secretscan.execute({ directory }, {});
46376
+ const result = await _internals20.secretscan.execute({ directory }, {});
45859
46377
  const jsonStr = typeof result === "string" ? result : result.output;
45860
46378
  return JSON.parse(jsonStr);
45861
46379
  } catch (e) {
@@ -45870,7 +46388,7 @@ async function runSecretscan(directory) {
45870
46388
  return errorResult;
45871
46389
  }
45872
46390
  }
45873
- 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, _internals19;
46391
+ 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, _internals20;
45874
46392
  var init_secretscan = __esm(() => {
45875
46393
  init_zod();
45876
46394
  init_path_security();
@@ -46103,7 +46621,7 @@ var init_secretscan = __esm(() => {
46103
46621
  }
46104
46622
  }
46105
46623
  try {
46106
- const _scanDirRaw = path29.resolve(directory);
46624
+ const _scanDirRaw = path30.resolve(directory);
46107
46625
  const scanDir = (() => {
46108
46626
  try {
46109
46627
  return fs13.realpathSync(_scanDirRaw);
@@ -46242,7 +46760,7 @@ var init_secretscan = __esm(() => {
46242
46760
  }
46243
46761
  }
46244
46762
  });
46245
- _internals19 = {
46763
+ _internals20 = {
46246
46764
  secretscan,
46247
46765
  runSecretscan
46248
46766
  };
@@ -46250,7 +46768,7 @@ var init_secretscan = __esm(() => {
46250
46768
 
46251
46769
  // src/lang/default-backend.ts
46252
46770
  import * as fs14 from "fs";
46253
- import * as path30 from "path";
46771
+ import * as path31 from "path";
46254
46772
  function detectFileExists(dir, pattern) {
46255
46773
  if (pattern.includes("*") || pattern.includes("?")) {
46256
46774
  try {
@@ -46262,7 +46780,7 @@ function detectFileExists(dir, pattern) {
46262
46780
  }
46263
46781
  }
46264
46782
  try {
46265
- fs14.accessSync(path30.join(dir, pattern));
46783
+ fs14.accessSync(path31.join(dir, pattern));
46266
46784
  return true;
46267
46785
  } catch {
46268
46786
  return false;
@@ -46390,8 +46908,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
46390
46908
  return ["mvn", "test"];
46391
46909
  case "gradle": {
46392
46910
  const isWindows = process.platform === "win32";
46393
- const hasGradlewBat = fs14.existsSync(path30.join(dir, "gradlew.bat"));
46394
- const hasGradlew = fs14.existsSync(path30.join(dir, "gradlew"));
46911
+ const hasGradlewBat = fs14.existsSync(path31.join(dir, "gradlew.bat"));
46912
+ const hasGradlew = fs14.existsSync(path31.join(dir, "gradlew"));
46395
46913
  if (hasGradlewBat && isWindows)
46396
46914
  return ["gradlew.bat", "test"];
46397
46915
  if (hasGradlew)
@@ -46408,7 +46926,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
46408
46926
  "cmake-build-release",
46409
46927
  "out"
46410
46928
  ];
46411
- const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(path30.join(dir, d, "CMakeCache.txt"))) ?? "build";
46929
+ const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(path31.join(dir, d, "CMakeCache.txt"))) ?? "build";
46412
46930
  return ["ctest", "--test-dir", actualBuildDir];
46413
46931
  }
46414
46932
  case "swift-test":
@@ -46695,17 +47213,17 @@ async function defaultSelectBuildCommand(profile, dir) {
46695
47213
  return null;
46696
47214
  }
46697
47215
  async function defaultTestFilesFor(profile, sourceFile, dir) {
46698
- const ext = path30.extname(sourceFile);
47216
+ const ext = path31.extname(sourceFile);
46699
47217
  if (!profile.extensions.includes(ext))
46700
47218
  return [];
46701
- const base = path30.basename(sourceFile, ext);
46702
- const rel = path30.relative(dir, sourceFile);
46703
- const relDir = path30.dirname(rel);
47219
+ const base = path31.basename(sourceFile, ext);
47220
+ const rel = path31.relative(dir, sourceFile);
47221
+ const relDir = path31.dirname(rel);
46704
47222
  const stripSrc = relDir.replace(/^src(\/|\\)/, "");
46705
47223
  const candidates = new Set;
46706
47224
  for (const tDir of ["tests", "test", "__tests__", "spec"]) {
46707
47225
  for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
46708
- candidates.add(path30.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
47226
+ candidates.add(path31.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
46709
47227
  }
46710
47228
  }
46711
47229
  const existing = [];
@@ -46746,7 +47264,7 @@ var init_default_backend = __esm(() => {
46746
47264
 
46747
47265
  // src/lang/backends/go.ts
46748
47266
  import * as fs15 from "fs";
46749
- import * as path31 from "path";
47267
+ import * as path32 from "path";
46750
47268
  function extractImports(_sourceFile, source) {
46751
47269
  const out = new Set;
46752
47270
  IMPORT_REGEX_SINGLE.lastIndex = 0;
@@ -46772,7 +47290,7 @@ function extractImports(_sourceFile, source) {
46772
47290
  async function selectFramework(dir) {
46773
47291
  let content;
46774
47292
  try {
46775
- content = fs15.readFileSync(path31.join(dir, "go.mod"), "utf-8");
47293
+ content = fs15.readFileSync(path32.join(dir, "go.mod"), "utf-8");
46776
47294
  } catch {
46777
47295
  return null;
46778
47296
  }
@@ -46793,16 +47311,16 @@ async function selectFramework(dir) {
46793
47311
  async function selectEntryPoints(dir) {
46794
47312
  const points = [];
46795
47313
  try {
46796
- fs15.accessSync(path31.join(dir, "main.go"));
47314
+ fs15.accessSync(path32.join(dir, "main.go"));
46797
47315
  points.push("main.go");
46798
47316
  } catch {}
46799
47317
  try {
46800
- const cmdDir = path31.join(dir, "cmd");
47318
+ const cmdDir = path32.join(dir, "cmd");
46801
47319
  const subdirs = fs15.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
46802
47320
  for (const sub of subdirs) {
46803
- const main = path31.join("cmd", sub.name, "main.go");
47321
+ const main = path32.join("cmd", sub.name, "main.go");
46804
47322
  try {
46805
- fs15.accessSync(path31.join(dir, main));
47323
+ fs15.accessSync(path32.join(dir, main));
46806
47324
  points.push(main);
46807
47325
  } catch {}
46808
47326
  }
@@ -46821,19 +47339,19 @@ function buildGoBackend() {
46821
47339
  selectEntryPoints
46822
47340
  };
46823
47341
  }
46824
- var PROFILE_ID = "go", IMPORT_REGEX_SINGLE, IMPORT_REGEX_GROUP, IMPORT_REGEX_GROUP_LINE, _internals20;
47342
+ var PROFILE_ID = "go", IMPORT_REGEX_SINGLE, IMPORT_REGEX_GROUP, IMPORT_REGEX_GROUP_LINE, _internals21;
46825
47343
  var init_go = __esm(() => {
46826
47344
  init_default_backend();
46827
47345
  init_profiles();
46828
47346
  IMPORT_REGEX_SINGLE = /^\s*import\s+(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/gm;
46829
47347
  IMPORT_REGEX_GROUP = /^\s*import\s*\(([\s\S]*?)\)/gm;
46830
47348
  IMPORT_REGEX_GROUP_LINE = /(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/g;
46831
- _internals20 = { extractImports };
47349
+ _internals21 = { extractImports };
46832
47350
  });
46833
47351
 
46834
47352
  // src/lang/backends/python.ts
46835
47353
  import * as fs16 from "fs";
46836
- import * as path32 from "path";
47354
+ import * as path33 from "path";
46837
47355
  function parseImportTargets(rawTargets) {
46838
47356
  const cleaned = rawTargets.replace(/[()]/g, "").split(`
46839
47357
  `).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
@@ -46893,7 +47411,7 @@ async function selectFramework2(dir) {
46893
47411
  ];
46894
47412
  for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
46895
47413
  try {
46896
- const content = fs16.readFileSync(path32.join(dir, candidate), "utf-8");
47414
+ const content = fs16.readFileSync(path33.join(dir, candidate), "utf-8");
46897
47415
  const lower = content.toLowerCase();
46898
47416
  for (const [pkg, name] of candidates) {
46899
47417
  if (lower.includes(pkg)) {
@@ -46907,7 +47425,7 @@ async function selectFramework2(dir) {
46907
47425
  async function selectEntryPoints2(dir) {
46908
47426
  const points = new Set;
46909
47427
  try {
46910
- const content = fs16.readFileSync(path32.join(dir, "pyproject.toml"), "utf-8");
47428
+ const content = fs16.readFileSync(path33.join(dir, "pyproject.toml"), "utf-8");
46911
47429
  const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
46912
47430
  if (scriptsBlock) {
46913
47431
  for (const line of scriptsBlock[0].split(`
@@ -46922,7 +47440,7 @@ async function selectEntryPoints2(dir) {
46922
47440
  } catch {}
46923
47441
  for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
46924
47442
  try {
46925
- fs16.accessSync(path32.join(dir, name));
47443
+ fs16.accessSync(path33.join(dir, name));
46926
47444
  points.add(name);
46927
47445
  } catch {}
46928
47446
  }
@@ -46940,18 +47458,18 @@ function buildPythonBackend() {
46940
47458
  selectEntryPoints: selectEntryPoints2
46941
47459
  };
46942
47460
  }
46943
- var PROFILE_ID2 = "python", IMPORT_REGEX_FROM_WITH_TARGETS, IMPORT_REGEX_IMPORT, _internals21;
47461
+ var PROFILE_ID2 = "python", IMPORT_REGEX_FROM_WITH_TARGETS, IMPORT_REGEX_IMPORT, _internals22;
46944
47462
  var init_python = __esm(() => {
46945
47463
  init_default_backend();
46946
47464
  init_profiles();
46947
47465
  IMPORT_REGEX_FROM_WITH_TARGETS = /^\s*from\s+(\.*[\w.]*)\s+import\s+(\([^)]*\)|[^\n#]+)/gm;
46948
47466
  IMPORT_REGEX_IMPORT = /^\s*import\s+([^\n#]+)/gm;
46949
- _internals21 = { extractImports: extractImports2 };
47467
+ _internals22 = { extractImports: extractImports2 };
46950
47468
  });
46951
47469
 
46952
47470
  // src/test-impact/analyzer.ts
46953
47471
  import fs17 from "fs";
46954
- import path33 from "path";
47472
+ import path34 from "path";
46955
47473
  function normalizePath(p) {
46956
47474
  return p.replace(/\\/g, "/");
46957
47475
  }
@@ -46972,8 +47490,8 @@ function resolveRelativeImport(fromDir, importPath) {
46972
47490
  if (!importPath.startsWith(".")) {
46973
47491
  return null;
46974
47492
  }
46975
- const resolved = path33.resolve(fromDir, importPath);
46976
- if (path33.extname(resolved)) {
47493
+ const resolved = path34.resolve(fromDir, importPath);
47494
+ if (path34.extname(resolved)) {
46977
47495
  if (fs17.existsSync(resolved) && fs17.statSync(resolved).isFile()) {
46978
47496
  return normalizePath(resolved);
46979
47497
  }
@@ -46993,20 +47511,20 @@ function resolvePythonImport(fromDir, module) {
46993
47511
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
46994
47512
  let baseDir = fromDir;
46995
47513
  for (let i = 1;i < leadingDots; i++) {
46996
- baseDir = path33.dirname(baseDir);
47514
+ baseDir = path34.dirname(baseDir);
46997
47515
  }
46998
47516
  const rest = module.slice(leadingDots);
46999
47517
  if (rest.length === 0) {
47000
- const initPath = path33.join(baseDir, "__init__.py");
47518
+ const initPath = path34.join(baseDir, "__init__.py");
47001
47519
  if (fs17.existsSync(initPath) && fs17.statSync(initPath).isFile()) {
47002
47520
  return normalizePath(initPath);
47003
47521
  }
47004
47522
  return null;
47005
47523
  }
47006
- const subpath = rest.replace(/\./g, path33.sep);
47524
+ const subpath = rest.replace(/\./g, path34.sep);
47007
47525
  const candidates = [
47008
- `${path33.join(baseDir, subpath)}.py`,
47009
- path33.join(baseDir, subpath, "__init__.py")
47526
+ `${path34.join(baseDir, subpath)}.py`,
47527
+ path34.join(baseDir, subpath, "__init__.py")
47010
47528
  ];
47011
47529
  for (const c of candidates) {
47012
47530
  if (fs17.existsSync(c) && fs17.statSync(c).isFile())
@@ -47015,7 +47533,7 @@ function resolvePythonImport(fromDir, module) {
47015
47533
  return null;
47016
47534
  }
47017
47535
  function findGoModule(fromDir) {
47018
- const resolved = path33.resolve(fromDir);
47536
+ const resolved = path34.resolve(fromDir);
47019
47537
  let cur = resolved;
47020
47538
  const walked = [];
47021
47539
  for (let i = 0;i < 16; i++) {
@@ -47027,7 +47545,7 @@ function findGoModule(fromDir) {
47027
47545
  }
47028
47546
  walked.push(cur);
47029
47547
  try {
47030
- const goMod = path33.join(cur, "go.mod");
47548
+ const goMod = path34.join(cur, "go.mod");
47031
47549
  const content = fs17.readFileSync(goMod, "utf-8");
47032
47550
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
47033
47551
  if (moduleMatch) {
@@ -47038,10 +47556,10 @@ function findGoModule(fromDir) {
47038
47556
  }
47039
47557
  } catch {}
47040
47558
  try {
47041
- fs17.accessSync(path33.join(cur, ".git"));
47559
+ fs17.accessSync(path34.join(cur, ".git"));
47042
47560
  break;
47043
47561
  } catch {}
47044
- const parent = path33.dirname(cur);
47562
+ const parent = path34.dirname(cur);
47045
47563
  if (parent === cur)
47046
47564
  break;
47047
47565
  cur = parent;
@@ -47053,12 +47571,12 @@ function findGoModule(fromDir) {
47053
47571
  function resolveGoImport(fromDir, importPath) {
47054
47572
  let dir = null;
47055
47573
  if (importPath.startsWith(".")) {
47056
- dir = path33.resolve(fromDir, importPath);
47574
+ dir = path34.resolve(fromDir, importPath);
47057
47575
  } else {
47058
47576
  const mod = findGoModule(fromDir);
47059
47577
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
47060
47578
  const subpath = importPath.slice(mod.modulePath.length);
47061
- dir = path33.join(mod.moduleRoot, subpath);
47579
+ dir = path34.join(mod.moduleRoot, subpath);
47062
47580
  }
47063
47581
  }
47064
47582
  if (dir === null)
@@ -47066,7 +47584,7 @@ function resolveGoImport(fromDir, importPath) {
47066
47584
  if (!fs17.existsSync(dir) || !fs17.statSync(dir).isDirectory())
47067
47585
  return [];
47068
47586
  try {
47069
- return fs17.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path33.join(dir, f)));
47587
+ return fs17.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path34.join(dir, f)));
47070
47588
  } catch {
47071
47589
  return [];
47072
47590
  }
@@ -47105,15 +47623,15 @@ function findTestFilesSync(cwd) {
47105
47623
  for (const entry of entries) {
47106
47624
  if (entry.isDirectory()) {
47107
47625
  if (!skipDirs.has(entry.name)) {
47108
- walk(path33.join(dir, entry.name), visitedInodes);
47626
+ walk(path34.join(dir, entry.name), visitedInodes);
47109
47627
  }
47110
47628
  } else if (entry.isFile()) {
47111
47629
  const name = entry.name;
47112
47630
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
47113
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path33.sep}tests${path33.sep}`) && name.endsWith(".py");
47631
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path34.sep}tests${path34.sep}`) && name.endsWith(".py");
47114
47632
  const isGoTest = /.+_test\.go$/.test(name);
47115
47633
  if (isTsTest || isPyTest || isGoTest) {
47116
- testFiles.push(normalizePath(path33.join(dir, entry.name)));
47634
+ testFiles.push(normalizePath(path34.join(dir, entry.name)));
47117
47635
  }
47118
47636
  }
47119
47637
  }
@@ -47138,8 +47656,8 @@ function extractImports3(content) {
47138
47656
  ];
47139
47657
  }
47140
47658
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
47141
- const ext = path33.extname(testFile).toLowerCase();
47142
- const testDir = path33.dirname(testFile);
47659
+ const ext = path34.extname(testFile).toLowerCase();
47660
+ const testDir = path34.dirname(testFile);
47143
47661
  function addEdge(source) {
47144
47662
  if (!impactMap[source])
47145
47663
  impactMap[source] = [];
@@ -47157,7 +47675,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
47157
47675
  return;
47158
47676
  }
47159
47677
  if (PYTHON_EXTENSIONS.has(ext)) {
47160
- const modules = _internals21.extractImports(testFile, content);
47678
+ const modules = _internals22.extractImports(testFile, content);
47161
47679
  for (const mod of modules) {
47162
47680
  const resolved = resolvePythonImport(testDir, mod);
47163
47681
  if (resolved !== null)
@@ -47166,7 +47684,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
47166
47684
  return;
47167
47685
  }
47168
47686
  if (GO_EXTENSIONS.has(ext)) {
47169
- const imports = _internals20.extractImports(testFile, content);
47687
+ const imports = _internals21.extractImports(testFile, content);
47170
47688
  for (const importPath of imports) {
47171
47689
  const sourceFiles = resolveGoImport(testDir, importPath);
47172
47690
  for (const source of sourceFiles)
@@ -47193,12 +47711,12 @@ async function buildImpactMapInternal(cwd) {
47193
47711
  return impactMap;
47194
47712
  }
47195
47713
  async function buildImpactMap(cwd) {
47196
- const impactMap = await _internals22.buildImpactMapInternal(cwd);
47197
- await _internals22.saveImpactMap(cwd, impactMap);
47714
+ const impactMap = await _internals23.buildImpactMapInternal(cwd);
47715
+ await _internals23.saveImpactMap(cwd, impactMap);
47198
47716
  return impactMap;
47199
47717
  }
47200
47718
  async function loadImpactMap(cwd, options) {
47201
- const cachePath = path33.join(cwd, ".swarm", "cache", "impact-map.json");
47719
+ const cachePath = path34.join(cwd, ".swarm", "cache", "impact-map.json");
47202
47720
  if (fs17.existsSync(cachePath)) {
47203
47721
  try {
47204
47722
  const content = fs17.readFileSync(cachePath, "utf-8");
@@ -47208,7 +47726,7 @@ async function loadImpactMap(cwd, options) {
47208
47726
  const hasValidValues = Object.values(map3).every((v) => Array.isArray(v) && v.every((item) => typeof item === "string"));
47209
47727
  if (hasValidValues) {
47210
47728
  const generatedAt = new Date(data.generatedAt).getTime();
47211
- if (!_internals22.isCacheStale(map3, generatedAt)) {
47729
+ if (!_internals23.isCacheStale(map3, generatedAt)) {
47212
47730
  return map3;
47213
47731
  }
47214
47732
  if (options?.skipRebuild) {
@@ -47228,15 +47746,15 @@ async function loadImpactMap(cwd, options) {
47228
47746
  if (options?.skipRebuild) {
47229
47747
  return {};
47230
47748
  }
47231
- return _internals22.buildImpactMap(cwd);
47749
+ return _internals23.buildImpactMap(cwd);
47232
47750
  }
47233
47751
  async function saveImpactMap(cwd, impactMap) {
47234
- if (!path33.isAbsolute(cwd)) {
47752
+ if (!path34.isAbsolute(cwd)) {
47235
47753
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
47236
47754
  }
47237
- _internals22.validateProjectRoot(cwd);
47238
- const cacheDir2 = path33.join(cwd, ".swarm", "cache");
47239
- const cachePath = path33.join(cacheDir2, "impact-map.json");
47755
+ _internals23.validateProjectRoot(cwd);
47756
+ const cacheDir2 = path34.join(cwd, ".swarm", "cache");
47757
+ const cachePath = path34.join(cacheDir2, "impact-map.json");
47240
47758
  if (!fs17.existsSync(cacheDir2)) {
47241
47759
  fs17.mkdirSync(cacheDir2, { recursive: true });
47242
47760
  }
@@ -47258,7 +47776,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
47258
47776
  };
47259
47777
  }
47260
47778
  const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !f.includes("\x00"));
47261
- const impactMap = await _internals22.loadImpactMap(cwd);
47779
+ const impactMap = await _internals23.loadImpactMap(cwd);
47262
47780
  const impactedTestsSet = new Set;
47263
47781
  const untestedFiles = [];
47264
47782
  let visitedCount = 0;
@@ -47268,7 +47786,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
47268
47786
  budgetExceeded = true;
47269
47787
  break;
47270
47788
  }
47271
- const normalizedChanged = normalizePath(path33.resolve(changedFile));
47789
+ const normalizedChanged = normalizePath(path34.resolve(changedFile));
47272
47790
  const tests = impactMap[normalizedChanged];
47273
47791
  if (tests && tests.length > 0) {
47274
47792
  for (const test of tests) {
@@ -47325,7 +47843,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
47325
47843
  budgetExceeded
47326
47844
  };
47327
47845
  }
47328
- var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, TS_EXTENSIONS, PYTHON_EXTENSIONS, GO_EXTENSIONS, EXTENSIONS_TO_TRY, goModuleCache, _internals22;
47846
+ var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, TS_EXTENSIONS, PYTHON_EXTENSIONS, GO_EXTENSIONS, EXTENSIONS_TO_TRY, goModuleCache, _internals23;
47329
47847
  var init_analyzer = __esm(() => {
47330
47848
  init_manager2();
47331
47849
  init_go();
@@ -47338,7 +47856,7 @@ var init_analyzer = __esm(() => {
47338
47856
  GO_EXTENSIONS = new Set([".go"]);
47339
47857
  EXTENSIONS_TO_TRY = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
47340
47858
  goModuleCache = new Map;
47341
- _internals22 = {
47859
+ _internals23 = {
47342
47860
  validateProjectRoot,
47343
47861
  normalizePath,
47344
47862
  isCacheStale,
@@ -47561,15 +48079,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
47561
48079
 
47562
48080
  // src/test-impact/history-store.ts
47563
48081
  import fs18 from "fs";
47564
- import path34 from "path";
48082
+ import path35 from "path";
47565
48083
  function getHistoryPath(workingDir) {
47566
48084
  if (!workingDir) {
47567
48085
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
47568
48086
  }
47569
- if (!path34.isAbsolute(workingDir)) {
48087
+ if (!path35.isAbsolute(workingDir)) {
47570
48088
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
47571
48089
  }
47572
- return path34.join(workingDir, ".swarm", "cache", "test-history.jsonl");
48090
+ return path35.join(workingDir, ".swarm", "cache", "test-history.jsonl");
47573
48091
  }
47574
48092
  function sanitizeErrorMessage(errorMessage) {
47575
48093
  if (errorMessage === undefined) {
@@ -47656,8 +48174,8 @@ function batchAppendTestRuns(records, workingDir) {
47656
48174
  }
47657
48175
  }
47658
48176
  const historyPath = getHistoryPath(workingDir);
47659
- const historyDir = path34.dirname(historyPath);
47660
- _internals23.validateProjectRoot(workingDir);
48177
+ const historyDir = path35.dirname(historyPath);
48178
+ _internals24.validateProjectRoot(workingDir);
47661
48179
  if (!fs18.existsSync(historyDir)) {
47662
48180
  fs18.mkdirSync(historyDir, { recursive: true });
47663
48181
  }
@@ -47737,7 +48255,7 @@ function getAllHistory(workingDir) {
47737
48255
  records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
47738
48256
  return records;
47739
48257
  }
47740
- var MAX_HISTORY_PER_TEST = 20, MAX_ERROR_LENGTH = 500, MAX_STACK_LENGTH = 200, MAX_CHANGED_FILES = 50, DANGEROUS_PROPERTY_NAMES, _internals23;
48258
+ var MAX_HISTORY_PER_TEST = 20, MAX_ERROR_LENGTH = 500, MAX_STACK_LENGTH = 200, MAX_CHANGED_FILES = 50, DANGEROUS_PROPERTY_NAMES, _internals24;
47741
48259
  var init_history_store = __esm(() => {
47742
48260
  init_manager2();
47743
48261
  DANGEROUS_PROPERTY_NAMES = new Set([
@@ -47745,14 +48263,14 @@ var init_history_store = __esm(() => {
47745
48263
  "constructor",
47746
48264
  "prototype"
47747
48265
  ]);
47748
- _internals23 = {
48266
+ _internals24 = {
47749
48267
  validateProjectRoot
47750
48268
  };
47751
48269
  });
47752
48270
 
47753
48271
  // src/tools/resolve-working-directory.ts
47754
48272
  import * as fs19 from "fs";
47755
- import * as path35 from "path";
48273
+ import * as path36 from "path";
47756
48274
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
47757
48275
  if (workingDirectory == null || workingDirectory === "") {
47758
48276
  return { success: true, directory: fallbackDirectory };
@@ -47772,15 +48290,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
47772
48290
  };
47773
48291
  }
47774
48292
  }
47775
- const normalizedDir = path35.normalize(workingDirectory);
47776
- const pathParts = normalizedDir.split(path35.sep);
48293
+ const normalizedDir = path36.normalize(workingDirectory);
48294
+ const pathParts = normalizedDir.split(path36.sep);
47777
48295
  if (pathParts.includes("..")) {
47778
48296
  return {
47779
48297
  success: false,
47780
48298
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
47781
48299
  };
47782
48300
  }
47783
- const resolvedDir = path35.resolve(normalizedDir);
48301
+ const resolvedDir = path36.resolve(normalizedDir);
47784
48302
  let statResult;
47785
48303
  try {
47786
48304
  statResult = fs19.statSync(resolvedDir);
@@ -47796,7 +48314,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
47796
48314
  message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
47797
48315
  };
47798
48316
  }
47799
- const resolvedFallback = path35.resolve(fallbackDirectory);
48317
+ const resolvedFallback = path36.resolve(fallbackDirectory);
47800
48318
  let fallbackExists = false;
47801
48319
  try {
47802
48320
  fs19.statSync(resolvedFallback);
@@ -47806,7 +48324,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
47806
48324
  }
47807
48325
  if (workingDirectory != null && workingDirectory !== "") {
47808
48326
  if (fallbackExists) {
47809
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path35.sep);
48327
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path36.sep);
47810
48328
  if (isSubdirectory) {
47811
48329
  return {
47812
48330
  success: false,
@@ -47861,17 +48379,17 @@ var init_registry_backend = __esm(() => {
47861
48379
 
47862
48380
  // src/lang/backends/typescript.ts
47863
48381
  import * as fs20 from "fs";
47864
- import * as path36 from "path";
48382
+ import * as path37 from "path";
47865
48383
  function readPackageJsonRaw(dir) {
47866
48384
  try {
47867
- const content = fs20.readFileSync(path36.join(dir, "package.json"), "utf-8");
48385
+ const content = fs20.readFileSync(path37.join(dir, "package.json"), "utf-8");
47868
48386
  return JSON.parse(content);
47869
48387
  } catch {
47870
48388
  return null;
47871
48389
  }
47872
48390
  }
47873
48391
  function readPackageJson(dir) {
47874
- return _internals24.readPackageJsonRaw(dir);
48392
+ return _internals25.readPackageJsonRaw(dir);
47875
48393
  }
47876
48394
  function readPackageJsonTestScript(dir) {
47877
48395
  return readPackageJson(dir)?.scripts?.test ?? null;
@@ -48041,7 +48559,7 @@ function buildTypescriptBackend() {
48041
48559
  selectEntryPoints: selectEntryPoints3
48042
48560
  };
48043
48561
  }
48044
- var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals24;
48562
+ var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals25;
48045
48563
  var init_typescript = __esm(() => {
48046
48564
  init_default_backend();
48047
48565
  init_profiles();
@@ -48050,7 +48568,7 @@ var init_typescript = __esm(() => {
48050
48568
  IMPORT_REGEX_REQUIRE2 = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
48051
48569
  IMPORT_REGEX_DYNAMIC = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
48052
48570
  IMPORT_REGEX_REEXPORT2 = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
48053
- _internals24 = {
48571
+ _internals25 = {
48054
48572
  readPackageJsonRaw,
48055
48573
  readPackageJsonTestScript,
48056
48574
  frameworkFromScriptsTest
@@ -48081,10 +48599,10 @@ __export(exports_dispatch, {
48081
48599
  pickedProfiles: () => pickedProfiles,
48082
48600
  pickBackend: () => pickBackend,
48083
48601
  clearDispatchCache: () => clearDispatchCache,
48084
- _internals: () => _internals25
48602
+ _internals: () => _internals26
48085
48603
  });
48086
48604
  import * as fs21 from "fs";
48087
- import * as path37 from "path";
48605
+ import * as path38 from "path";
48088
48606
  function safeReaddirSet(dir) {
48089
48607
  try {
48090
48608
  return new Set(fs21.readdirSync(dir));
@@ -48101,14 +48619,14 @@ function manifestHash(dir) {
48101
48619
  if (!entries.has(name))
48102
48620
  continue;
48103
48621
  try {
48104
- const stat3 = fs21.statSync(path37.join(dir, name));
48622
+ const stat3 = fs21.statSync(path38.join(dir, name));
48105
48623
  parts.push(`${name}:${stat3.size}:${stat3.mtimeMs}:${stat3.ino}`);
48106
48624
  } catch {}
48107
48625
  }
48108
48626
  return parts.join("|");
48109
48627
  }
48110
48628
  function findManifestRoot(start) {
48111
- const resolved = path37.resolve(start);
48629
+ const resolved = path38.resolve(start);
48112
48630
  const cached3 = manifestRootCache.get(resolved);
48113
48631
  if (cached3 !== undefined)
48114
48632
  return cached3;
@@ -48127,7 +48645,7 @@ function findManifestRoot(start) {
48127
48645
  return cur;
48128
48646
  }
48129
48647
  }
48130
- const parent = path37.dirname(cur);
48648
+ const parent = path38.dirname(cur);
48131
48649
  if (parent === cur)
48132
48650
  break;
48133
48651
  cur = parent;
@@ -48136,7 +48654,7 @@ function findManifestRoot(start) {
48136
48654
  return start;
48137
48655
  }
48138
48656
  function evictIfNeeded() {
48139
- if (cache.size <= _internals25.cacheCapacity)
48657
+ if (cache.size <= _internals26.cacheCapacity)
48140
48658
  return;
48141
48659
  let oldestKey;
48142
48660
  let oldestOrder = Infinity;
@@ -48167,7 +48685,7 @@ async function pickBackend(dir) {
48167
48685
  evictIfNeeded();
48168
48686
  return null;
48169
48687
  }
48170
- const profiles = await _internals25.detectProjectLanguages(root);
48688
+ const profiles = await _internals26.detectProjectLanguages(root);
48171
48689
  if (profiles.length === 0) {
48172
48690
  cache.set(cacheKey, {
48173
48691
  hash: hash3,
@@ -48199,12 +48717,12 @@ function clearDispatchCache() {
48199
48717
  manifestRootCache.clear();
48200
48718
  insertCounter = 0;
48201
48719
  }
48202
- var _internals25, cache, insertCounter = 0, MANIFEST_FILES, _MANIFEST_SET, manifestRootCache;
48720
+ var _internals26, cache, insertCounter = 0, MANIFEST_FILES, _MANIFEST_SET, manifestRootCache;
48203
48721
  var init_dispatch = __esm(() => {
48204
48722
  init_backends();
48205
48723
  init_detector();
48206
48724
  init_registry_backend();
48207
- _internals25 = {
48725
+ _internals26 = {
48208
48726
  detectProjectLanguages,
48209
48727
  cacheCapacity: 64
48210
48728
  };
@@ -48237,13 +48755,13 @@ var init_dispatch = __esm(() => {
48237
48755
 
48238
48756
  // src/tools/test-runner.ts
48239
48757
  import * as fs22 from "fs";
48240
- import * as path38 from "path";
48758
+ import * as path39 from "path";
48241
48759
  async function estimateFanOut(sourceFiles, cwd) {
48242
48760
  try {
48243
48761
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
48244
48762
  const uniqueTestFiles = new Set;
48245
48763
  for (const sourceFile of sourceFiles) {
48246
- const resolvedPath = path38.resolve(cwd, sourceFile);
48764
+ const resolvedPath = path39.resolve(cwd, sourceFile);
48247
48765
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
48248
48766
  const testFiles = impactMap[normalizedPath];
48249
48767
  if (testFiles) {
@@ -48321,14 +48839,14 @@ function hasDevDependency(devDeps, ...patterns) {
48321
48839
  return hasPackageJsonDependency(devDeps, ...patterns);
48322
48840
  }
48323
48841
  function detectGoTest(cwd) {
48324
- return fs22.existsSync(path38.join(cwd, "go.mod")) && isCommandAvailable("go");
48842
+ return fs22.existsSync(path39.join(cwd, "go.mod")) && isCommandAvailable("go");
48325
48843
  }
48326
48844
  function detectJavaMaven(cwd) {
48327
- return fs22.existsSync(path38.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
48845
+ return fs22.existsSync(path39.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
48328
48846
  }
48329
48847
  function detectGradle(cwd) {
48330
- const hasBuildFile = fs22.existsSync(path38.join(cwd, "build.gradle")) || fs22.existsSync(path38.join(cwd, "build.gradle.kts"));
48331
- const hasGradlew = fs22.existsSync(path38.join(cwd, "gradlew")) || fs22.existsSync(path38.join(cwd, "gradlew.bat"));
48848
+ const hasBuildFile = fs22.existsSync(path39.join(cwd, "build.gradle")) || fs22.existsSync(path39.join(cwd, "build.gradle.kts"));
48849
+ const hasGradlew = fs22.existsSync(path39.join(cwd, "gradlew")) || fs22.existsSync(path39.join(cwd, "gradlew.bat"));
48332
48850
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
48333
48851
  }
48334
48852
  function detectDotnetTest(cwd) {
@@ -48341,25 +48859,25 @@ function detectDotnetTest(cwd) {
48341
48859
  }
48342
48860
  }
48343
48861
  function detectCTest(cwd) {
48344
- const hasSource = fs22.existsSync(path38.join(cwd, "CMakeLists.txt"));
48345
- const hasBuildCache = fs22.existsSync(path38.join(cwd, "CMakeCache.txt")) || fs22.existsSync(path38.join(cwd, "build", "CMakeCache.txt"));
48862
+ const hasSource = fs22.existsSync(path39.join(cwd, "CMakeLists.txt"));
48863
+ const hasBuildCache = fs22.existsSync(path39.join(cwd, "CMakeCache.txt")) || fs22.existsSync(path39.join(cwd, "build", "CMakeCache.txt"));
48346
48864
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
48347
48865
  }
48348
48866
  function detectSwiftTest(cwd) {
48349
- return fs22.existsSync(path38.join(cwd, "Package.swift")) && isCommandAvailable("swift");
48867
+ return fs22.existsSync(path39.join(cwd, "Package.swift")) && isCommandAvailable("swift");
48350
48868
  }
48351
48869
  function detectDartTest(cwd) {
48352
- return fs22.existsSync(path38.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
48870
+ return fs22.existsSync(path39.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
48353
48871
  }
48354
48872
  function detectRSpec(cwd) {
48355
- const hasRSpecFile = fs22.existsSync(path38.join(cwd, ".rspec"));
48356
- const hasGemfile = fs22.existsSync(path38.join(cwd, "Gemfile"));
48357
- const hasSpecDir = fs22.existsSync(path38.join(cwd, "spec"));
48873
+ const hasRSpecFile = fs22.existsSync(path39.join(cwd, ".rspec"));
48874
+ const hasGemfile = fs22.existsSync(path39.join(cwd, "Gemfile"));
48875
+ const hasSpecDir = fs22.existsSync(path39.join(cwd, "spec"));
48358
48876
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
48359
48877
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
48360
48878
  }
48361
48879
  function detectMinitest(cwd) {
48362
- return fs22.existsSync(path38.join(cwd, "test")) && (fs22.existsSync(path38.join(cwd, "Gemfile")) || fs22.existsSync(path38.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
48880
+ return fs22.existsSync(path39.join(cwd, "test")) && (fs22.existsSync(path39.join(cwd, "Gemfile")) || fs22.existsSync(path39.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
48363
48881
  }
48364
48882
  async function detectTestFrameworkViaDispatch(cwd) {
48365
48883
  try {
@@ -48421,7 +48939,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
48421
48939
  async function detectTestFramework(cwd) {
48422
48940
  const baseDir = cwd;
48423
48941
  try {
48424
- const packageJsonPath = path38.join(baseDir, "package.json");
48942
+ const packageJsonPath = path39.join(baseDir, "package.json");
48425
48943
  if (fs22.existsSync(packageJsonPath)) {
48426
48944
  const content = fs22.readFileSync(packageJsonPath, "utf-8");
48427
48945
  const pkg = JSON.parse(content);
@@ -48442,16 +48960,16 @@ async function detectTestFramework(cwd) {
48442
48960
  return "jest";
48443
48961
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
48444
48962
  return "mocha";
48445
- if (fs22.existsSync(path38.join(baseDir, "bun.lockb")) || fs22.existsSync(path38.join(baseDir, "bun.lock"))) {
48963
+ if (fs22.existsSync(path39.join(baseDir, "bun.lockb")) || fs22.existsSync(path39.join(baseDir, "bun.lock"))) {
48446
48964
  if (scripts.test?.includes("bun"))
48447
48965
  return "bun";
48448
48966
  }
48449
48967
  }
48450
48968
  } catch {}
48451
48969
  try {
48452
- const pyprojectTomlPath = path38.join(baseDir, "pyproject.toml");
48453
- const setupCfgPath = path38.join(baseDir, "setup.cfg");
48454
- const requirementsTxtPath = path38.join(baseDir, "requirements.txt");
48970
+ const pyprojectTomlPath = path39.join(baseDir, "pyproject.toml");
48971
+ const setupCfgPath = path39.join(baseDir, "setup.cfg");
48972
+ const requirementsTxtPath = path39.join(baseDir, "requirements.txt");
48455
48973
  if (fs22.existsSync(pyprojectTomlPath)) {
48456
48974
  const content = fs22.readFileSync(pyprojectTomlPath, "utf-8");
48457
48975
  if (content.includes("[tool.pytest"))
@@ -48471,7 +48989,7 @@ async function detectTestFramework(cwd) {
48471
48989
  }
48472
48990
  } catch {}
48473
48991
  try {
48474
- const cargoTomlPath = path38.join(baseDir, "Cargo.toml");
48992
+ const cargoTomlPath = path39.join(baseDir, "Cargo.toml");
48475
48993
  if (fs22.existsSync(cargoTomlPath)) {
48476
48994
  const content = fs22.readFileSync(cargoTomlPath, "utf-8");
48477
48995
  if (content.includes("[dev-dependencies]")) {
@@ -48482,9 +49000,9 @@ async function detectTestFramework(cwd) {
48482
49000
  }
48483
49001
  } catch {}
48484
49002
  try {
48485
- const pesterConfigPath = path38.join(baseDir, "pester.config.ps1");
48486
- const pesterConfigJsonPath = path38.join(baseDir, "pester.config.ps1.json");
48487
- const pesterPs1Path = path38.join(baseDir, "tests.ps1");
49003
+ const pesterConfigPath = path39.join(baseDir, "pester.config.ps1");
49004
+ const pesterConfigJsonPath = path39.join(baseDir, "pester.config.ps1.json");
49005
+ const pesterPs1Path = path39.join(baseDir, "tests.ps1");
48488
49006
  if (fs22.existsSync(pesterConfigPath) || fs22.existsSync(pesterConfigJsonPath) || fs22.existsSync(pesterPs1Path)) {
48489
49007
  return "pester";
48490
49008
  }
@@ -48513,12 +49031,12 @@ function isTestDirectoryPath(normalizedPath) {
48513
49031
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
48514
49032
  }
48515
49033
  function resolveWorkspacePath(file3, workingDir) {
48516
- return path38.isAbsolute(file3) ? path38.resolve(file3) : path38.resolve(workingDir, file3);
49034
+ return path39.isAbsolute(file3) ? path39.resolve(file3) : path39.resolve(workingDir, file3);
48517
49035
  }
48518
49036
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
48519
49037
  if (!preferRelative)
48520
49038
  return absolutePath;
48521
- return path38.relative(workingDir, absolutePath);
49039
+ return path39.relative(workingDir, absolutePath);
48522
49040
  }
48523
49041
  function dedupePush(target, value) {
48524
49042
  if (!target.includes(value)) {
@@ -48555,18 +49073,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
48555
49073
  }
48556
49074
  }
48557
49075
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
48558
- const relativeDir = path38.dirname(relativePath);
49076
+ const relativeDir = path39.dirname(relativePath);
48559
49077
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
48560
49078
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
48561
- const rootDir = path38.join(workingDir, dirName);
48562
- return nestedRelativeDir ? [rootDir, path38.join(rootDir, nestedRelativeDir)] : [rootDir];
49079
+ const rootDir = path39.join(workingDir, dirName);
49080
+ return nestedRelativeDir ? [rootDir, path39.join(rootDir, nestedRelativeDir)] : [rootDir];
48563
49081
  });
48564
49082
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
48565
49083
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
48566
- directories.push(path38.join(workingDir, "src/test/java", path38.dirname(normalizedRelativePath.slice("src/main/java/".length))));
49084
+ directories.push(path39.join(workingDir, "src/test/java", path39.dirname(normalizedRelativePath.slice("src/main/java/".length))));
48567
49085
  }
48568
49086
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
48569
- directories.push(path38.join(workingDir, "src/test/kotlin", path38.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
49087
+ directories.push(path39.join(workingDir, "src/test/kotlin", path39.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
48570
49088
  }
48571
49089
  return [...new Set(directories)];
48572
49090
  }
@@ -48594,23 +49112,23 @@ function isLanguageSpecificTestFile(basename6) {
48594
49112
  }
48595
49113
  function isConventionTestFilePath(filePath) {
48596
49114
  const normalizedPath = filePath.replace(/\\/g, "/");
48597
- const basename6 = path38.basename(filePath);
49115
+ const basename6 = path39.basename(filePath);
48598
49116
  return hasCompoundTestExtension(basename6) || basename6.includes(".spec.") || basename6.includes(".test.") || isLanguageSpecificTestFile(basename6) || isTestDirectoryPath(normalizedPath);
48599
49117
  }
48600
49118
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
48601
49119
  const testFiles = [];
48602
49120
  for (const file3 of sourceFiles) {
48603
49121
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
48604
- const relativeFile = path38.relative(workingDir, absoluteFile);
48605
- const basename6 = path38.basename(absoluteFile);
48606
- const dirname17 = path38.dirname(absoluteFile);
48607
- const preferRelativeOutput = !path38.isAbsolute(file3);
49122
+ const relativeFile = path39.relative(workingDir, absoluteFile);
49123
+ const basename6 = path39.basename(absoluteFile);
49124
+ const dirname17 = path39.dirname(absoluteFile);
49125
+ const preferRelativeOutput = !path39.isAbsolute(file3);
48608
49126
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
48609
49127
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
48610
49128
  continue;
48611
49129
  }
48612
49130
  const nameWithoutExt = basename6.replace(/\.[^.]+$/, "");
48613
- const ext = path38.extname(basename6);
49131
+ const ext = path39.extname(basename6);
48614
49132
  const genericTestNames = [
48615
49133
  `${nameWithoutExt}.spec${ext}`,
48616
49134
  `${nameWithoutExt}.test${ext}`
@@ -48619,7 +49137,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
48619
49137
  const colocatedCandidates = [
48620
49138
  ...genericTestNames,
48621
49139
  ...languageSpecificTestNames
48622
- ].map((candidateName) => path38.join(dirname17, candidateName));
49140
+ ].map((candidateName) => path39.join(dirname17, candidateName));
48623
49141
  const testDirectoryNames = [
48624
49142
  basename6,
48625
49143
  ...genericTestNames,
@@ -48628,8 +49146,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
48628
49146
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
48629
49147
  const possibleTestFiles = [
48630
49148
  ...colocatedCandidates,
48631
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path38.join(dirname17, dirName, candidateName))),
48632
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path38.join(candidateDir, candidateName)))
49149
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path39.join(dirname17, dirName, candidateName))),
49150
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path39.join(candidateDir, candidateName)))
48633
49151
  ];
48634
49152
  for (const testFile of possibleTestFiles) {
48635
49153
  if (fs22.existsSync(testFile)) {
@@ -48650,7 +49168,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48650
49168
  try {
48651
49169
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
48652
49170
  const content = fs22.readFileSync(absoluteTestFile, "utf-8");
48653
- const testDir = path38.dirname(absoluteTestFile);
49171
+ const testDir = path39.dirname(absoluteTestFile);
48654
49172
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
48655
49173
  let match;
48656
49174
  match = importRegex.exec(content);
@@ -48658,8 +49176,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48658
49176
  const importPath = match[1];
48659
49177
  let resolvedImport;
48660
49178
  if (importPath.startsWith(".")) {
48661
- resolvedImport = path38.resolve(testDir, importPath);
48662
- const existingExt = path38.extname(resolvedImport);
49179
+ resolvedImport = path39.resolve(testDir, importPath);
49180
+ const existingExt = path39.extname(resolvedImport);
48663
49181
  if (!existingExt) {
48664
49182
  for (const extToTry of [
48665
49183
  ".ts",
@@ -48679,12 +49197,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48679
49197
  } else {
48680
49198
  continue;
48681
49199
  }
48682
- const importBasename = path38.basename(resolvedImport, path38.extname(resolvedImport));
48683
- const importDir = path38.dirname(resolvedImport);
49200
+ const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
49201
+ const importDir = path39.dirname(resolvedImport);
48684
49202
  for (const sourceFile of absoluteSourceFiles) {
48685
- const sourceDir = path38.dirname(sourceFile);
48686
- const sourceBasename = path38.basename(sourceFile, path38.extname(sourceFile));
48687
- const isRelatedDir = importDir === sourceDir || importDir === path38.join(sourceDir, "__tests__") || importDir === path38.join(sourceDir, "tests") || importDir === path38.join(sourceDir, "test") || importDir === path38.join(sourceDir, "spec");
49203
+ const sourceDir = path39.dirname(sourceFile);
49204
+ const sourceBasename = path39.basename(sourceFile, path39.extname(sourceFile));
49205
+ const isRelatedDir = importDir === sourceDir || importDir === path39.join(sourceDir, "__tests__") || importDir === path39.join(sourceDir, "tests") || importDir === path39.join(sourceDir, "test") || importDir === path39.join(sourceDir, "spec");
48688
49206
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
48689
49207
  dedupePush(testFiles, testFile);
48690
49208
  break;
@@ -48697,8 +49215,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48697
49215
  while (match !== null) {
48698
49216
  const importPath = match[1];
48699
49217
  if (importPath.startsWith(".")) {
48700
- let resolvedImport = path38.resolve(testDir, importPath);
48701
- const existingExt = path38.extname(resolvedImport);
49218
+ let resolvedImport = path39.resolve(testDir, importPath);
49219
+ const existingExt = path39.extname(resolvedImport);
48702
49220
  if (!existingExt) {
48703
49221
  for (const extToTry of [
48704
49222
  ".ts",
@@ -48715,12 +49233,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
48715
49233
  }
48716
49234
  }
48717
49235
  }
48718
- const importDir = path38.dirname(resolvedImport);
48719
- const importBasename = path38.basename(resolvedImport, path38.extname(resolvedImport));
49236
+ const importDir = path39.dirname(resolvedImport);
49237
+ const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
48720
49238
  for (const sourceFile of absoluteSourceFiles) {
48721
- const sourceDir = path38.dirname(sourceFile);
48722
- const sourceBasename = path38.basename(sourceFile, path38.extname(sourceFile));
48723
- const isRelatedDir = importDir === sourceDir || importDir === path38.join(sourceDir, "__tests__") || importDir === path38.join(sourceDir, "tests") || importDir === path38.join(sourceDir, "test") || importDir === path38.join(sourceDir, "spec");
49239
+ const sourceDir = path39.dirname(sourceFile);
49240
+ const sourceBasename = path39.basename(sourceFile, path39.extname(sourceFile));
49241
+ const isRelatedDir = importDir === sourceDir || importDir === path39.join(sourceDir, "__tests__") || importDir === path39.join(sourceDir, "tests") || importDir === path39.join(sourceDir, "test") || importDir === path39.join(sourceDir, "spec");
48724
49242
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
48725
49243
  dedupePush(testFiles, testFile);
48726
49244
  break;
@@ -48830,8 +49348,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
48830
49348
  return ["mvn", "test"];
48831
49349
  case "gradle": {
48832
49350
  const isWindows = process.platform === "win32";
48833
- const hasGradlewBat = fs22.existsSync(path38.join(baseDir, "gradlew.bat"));
48834
- const hasGradlew = fs22.existsSync(path38.join(baseDir, "gradlew"));
49351
+ const hasGradlewBat = fs22.existsSync(path39.join(baseDir, "gradlew.bat"));
49352
+ const hasGradlew = fs22.existsSync(path39.join(baseDir, "gradlew"));
48835
49353
  if (hasGradlewBat && isWindows)
48836
49354
  return ["gradlew.bat", "test"];
48837
49355
  if (hasGradlew)
@@ -48848,7 +49366,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
48848
49366
  "cmake-build-release",
48849
49367
  "out"
48850
49368
  ];
48851
- const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(path38.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
49369
+ const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(path39.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
48852
49370
  return ["ctest", "--test-dir", actualBuildDir];
48853
49371
  }
48854
49372
  case "swift-test":
@@ -49280,11 +49798,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
49280
49798
  };
49281
49799
  }
49282
49800
  const startTime = Date.now();
49283
- const vitestJsonOutputPath = framework === "vitest" ? path38.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
49801
+ const vitestJsonOutputPath = framework === "vitest" ? path39.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
49284
49802
  try {
49285
49803
  if (vitestJsonOutputPath) {
49286
49804
  try {
49287
- fs22.mkdirSync(path38.dirname(vitestJsonOutputPath), { recursive: true });
49805
+ fs22.mkdirSync(path39.dirname(vitestJsonOutputPath), { recursive: true });
49288
49806
  if (fs22.existsSync(vitestJsonOutputPath)) {
49289
49807
  fs22.unlinkSync(vitestJsonOutputPath);
49290
49808
  }
@@ -49400,10 +49918,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
49400
49918
  }
49401
49919
  function normalizeHistoryTestFile(testFile, workingDir) {
49402
49920
  const normalized = testFile.replace(/\\/g, "/");
49403
- if (!path38.isAbsolute(testFile))
49921
+ if (!path39.isAbsolute(testFile))
49404
49922
  return normalized;
49405
- const relative9 = path38.relative(workingDir, testFile);
49406
- if (relative9.startsWith("..") || path38.isAbsolute(relative9)) {
49923
+ const relative9 = path39.relative(workingDir, testFile);
49924
+ if (relative9.startsWith("..") || path39.isAbsolute(relative9)) {
49407
49925
  return normalized;
49408
49926
  }
49409
49927
  return relative9.replace(/\\/g, "/");
@@ -49741,7 +50259,7 @@ var init_test_runner = __esm(() => {
49741
50259
  const sourceFiles = args.files.filter((file3) => {
49742
50260
  if (directTestFiles.includes(file3))
49743
50261
  return false;
49744
- const ext = path38.extname(file3).toLowerCase();
50262
+ const ext = path39.extname(file3).toLowerCase();
49745
50263
  return SOURCE_EXTENSIONS.has(ext);
49746
50264
  });
49747
50265
  const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
@@ -49787,7 +50305,7 @@ var init_test_runner = __esm(() => {
49787
50305
  if (isConventionTestFilePath(f)) {
49788
50306
  return false;
49789
50307
  }
49790
- const ext = path38.extname(f).toLowerCase();
50308
+ const ext = path39.extname(f).toLowerCase();
49791
50309
  return SOURCE_EXTENSIONS.has(ext);
49792
50310
  });
49793
50311
  if (sourceFiles.length === 0) {
@@ -49837,7 +50355,7 @@ var init_test_runner = __esm(() => {
49837
50355
  if (isConventionTestFilePath(f)) {
49838
50356
  return false;
49839
50357
  }
49840
- const ext = path38.extname(f).toLowerCase();
50358
+ const ext = path39.extname(f).toLowerCase();
49841
50359
  return SOURCE_EXTENSIONS.has(ext);
49842
50360
  });
49843
50361
  if (sourceFiles.length === 0) {
@@ -49889,8 +50407,8 @@ var init_test_runner = __esm(() => {
49889
50407
  }
49890
50408
  if (impactResult.impactedTests.length > 0) {
49891
50409
  testFiles = impactResult.impactedTests.map((absPath) => {
49892
- const relativePath = path38.relative(workingDir, absPath);
49893
- return path38.isAbsolute(relativePath) ? absPath : relativePath;
50410
+ const relativePath = path39.relative(workingDir, absPath);
50411
+ return path39.isAbsolute(relativePath) ? absPath : relativePath;
49894
50412
  });
49895
50413
  } else {
49896
50414
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -49966,7 +50484,7 @@ var init_test_runner = __esm(() => {
49966
50484
 
49967
50485
  // src/services/preflight-service.ts
49968
50486
  import * as fs23 from "fs";
49969
- import * as path39 from "path";
50487
+ import * as path40 from "path";
49970
50488
  function validateDirectoryPath(dir) {
49971
50489
  if (!dir || typeof dir !== "string") {
49972
50490
  throw new Error("Directory path is required");
@@ -49974,8 +50492,8 @@ function validateDirectoryPath(dir) {
49974
50492
  if (dir.includes("..")) {
49975
50493
  throw new Error("Directory path must not contain path traversal sequences");
49976
50494
  }
49977
- const normalized = path39.normalize(dir);
49978
- const absolutePath = path39.isAbsolute(normalized) ? normalized : path39.resolve(normalized);
50495
+ const normalized = path40.normalize(dir);
50496
+ const absolutePath = path40.isAbsolute(normalized) ? normalized : path40.resolve(normalized);
49979
50497
  return absolutePath;
49980
50498
  }
49981
50499
  function validateTimeout(timeoutMs, defaultValue) {
@@ -49998,7 +50516,7 @@ function validateTimeout(timeoutMs, defaultValue) {
49998
50516
  }
49999
50517
  function getPackageVersion(dir) {
50000
50518
  try {
50001
- const packagePath = path39.join(dir, "package.json");
50519
+ const packagePath = path40.join(dir, "package.json");
50002
50520
  if (fs23.existsSync(packagePath)) {
50003
50521
  const content = fs23.readFileSync(packagePath, "utf-8");
50004
50522
  const pkg = JSON.parse(content);
@@ -50009,7 +50527,7 @@ function getPackageVersion(dir) {
50009
50527
  }
50010
50528
  function getChangelogVersion(dir) {
50011
50529
  try {
50012
- const changelogPath = path39.join(dir, "CHANGELOG.md");
50530
+ const changelogPath = path40.join(dir, "CHANGELOG.md");
50013
50531
  if (fs23.existsSync(changelogPath)) {
50014
50532
  const content = fs23.readFileSync(changelogPath, "utf-8");
50015
50533
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
@@ -50023,7 +50541,7 @@ function getChangelogVersion(dir) {
50023
50541
  function getVersionFileVersion(dir) {
50024
50542
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
50025
50543
  for (const file3 of possibleFiles) {
50026
- const filePath = path39.join(dir, file3);
50544
+ const filePath = path40.join(dir, file3);
50027
50545
  if (fs23.existsSync(filePath)) {
50028
50546
  try {
50029
50547
  const content = fs23.readFileSync(filePath, "utf-8").trim();
@@ -50039,9 +50557,9 @@ function getVersionFileVersion(dir) {
50039
50557
  async function runVersionCheck(dir, _timeoutMs) {
50040
50558
  const startTime = Date.now();
50041
50559
  try {
50042
- const packageVersion = _internals26.getPackageVersion(dir);
50043
- const changelogVersion = _internals26.getChangelogVersion(dir);
50044
- const versionFileVersion = _internals26.getVersionFileVersion(dir);
50560
+ const packageVersion = _internals27.getPackageVersion(dir);
50561
+ const changelogVersion = _internals27.getChangelogVersion(dir);
50562
+ const versionFileVersion = _internals27.getVersionFileVersion(dir);
50045
50563
  const versions3 = [];
50046
50564
  if (packageVersion)
50047
50565
  versions3.push(`package.json: ${packageVersion}`);
@@ -50313,7 +50831,22 @@ async function runEvidenceCheck(dir) {
50313
50831
  };
50314
50832
  }
50315
50833
  const evidenceTaskIds = new Set(await listEvidenceTaskIds(dir));
50316
- const missingEvidence = completedTaskIds.filter((id) => !evidenceTaskIds.has(id));
50834
+ const missingEvidence = [];
50835
+ for (const id of completedTaskIds) {
50836
+ const gateStatus = await getDurableGateEvidenceStatusForTask(dir, id);
50837
+ if (gateStatus.isComplete) {
50838
+ continue;
50839
+ }
50840
+ if (gateStatus.evidenceExists && gateStatus.missingGates.length > 0) {
50841
+ missingEvidence.push(id);
50842
+ continue;
50843
+ }
50844
+ if (evidenceTaskIds.has(id)) {
50845
+ continue;
50846
+ }
50847
+ missingEvidence.push(id);
50848
+ }
50849
+ const completedWithEvidence = completedTaskIds.length - missingEvidence.length;
50317
50850
  if (missingEvidence.length > 0) {
50318
50851
  return {
50319
50852
  type: "evidence",
@@ -50321,7 +50854,7 @@ async function runEvidenceCheck(dir) {
50321
50854
  message: `${missingEvidence.length} completed task(s) missing evidence`,
50322
50855
  details: {
50323
50856
  totalCompleted: completedTaskIds.length,
50324
- totalWithEvidence: evidenceTaskIds.size,
50857
+ totalWithEvidence: completedWithEvidence,
50325
50858
  missingTasks: missingEvidence.slice(0, 10),
50326
50859
  missingCount: missingEvidence.length
50327
50860
  },
@@ -50334,7 +50867,7 @@ async function runEvidenceCheck(dir) {
50334
50867
  message: `All ${completedTaskIds.length} completed tasks have evidence`,
50335
50868
  details: {
50336
50869
  totalCompleted: completedTaskIds.length,
50337
- totalWithEvidence: evidenceTaskIds.size
50870
+ totalWithEvidence: completedWithEvidence
50338
50871
  },
50339
50872
  durationMs: Date.now() - startTime
50340
50873
  };
@@ -50350,7 +50883,7 @@ async function runEvidenceCheck(dir) {
50350
50883
  async function runRequirementCoverageCheck(dir, currentPhase) {
50351
50884
  const startTime = Date.now();
50352
50885
  try {
50353
- const specPath = path39.join(dir, ".swarm", "spec.md");
50886
+ const specPath = path40.join(dir, ".swarm", "spec.md");
50354
50887
  if (!fs23.existsSync(specPath)) {
50355
50888
  return {
50356
50889
  type: "req_coverage",
@@ -50391,7 +50924,7 @@ async function runPreflight(dir, phase, config3) {
50391
50924
  const reportId = `preflight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
50392
50925
  let validatedDir;
50393
50926
  try {
50394
- validatedDir = _internals26.validateDirectoryPath(dir);
50927
+ validatedDir = _internals27.validateDirectoryPath(dir);
50395
50928
  } catch (error93) {
50396
50929
  return {
50397
50930
  id: reportId,
@@ -50411,7 +50944,7 @@ async function runPreflight(dir, phase, config3) {
50411
50944
  }
50412
50945
  let validatedTimeout;
50413
50946
  try {
50414
- validatedTimeout = _internals26.validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
50947
+ validatedTimeout = _internals27.validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
50415
50948
  } catch (error93) {
50416
50949
  return {
50417
50950
  id: reportId,
@@ -50452,12 +50985,12 @@ async function runPreflight(dir, phase, config3) {
50452
50985
  });
50453
50986
  const checks5 = [];
50454
50987
  log("[Preflight] Running lint check...");
50455
- const lintResult = await _internals26.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
50988
+ const lintResult = await _internals27.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
50456
50989
  checks5.push(lintResult);
50457
50990
  log(`[Preflight] Lint check: ${lintResult.status} ${lintResult.message}`);
50458
50991
  if (!cfg.skipTests) {
50459
50992
  log("[Preflight] Running tests check...");
50460
- const testsResult = await _internals26.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
50993
+ const testsResult = await _internals27.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
50461
50994
  checks5.push(testsResult);
50462
50995
  log(`[Preflight] Tests check: ${testsResult.status} ${testsResult.message}`);
50463
50996
  } else {
@@ -50469,7 +51002,7 @@ async function runPreflight(dir, phase, config3) {
50469
51002
  }
50470
51003
  if (!cfg.skipSecrets) {
50471
51004
  log("[Preflight] Running secrets check...");
50472
- const secretsResult = await _internals26.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
51005
+ const secretsResult = await _internals27.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
50473
51006
  checks5.push(secretsResult);
50474
51007
  log(`[Preflight] Secrets check: ${secretsResult.status} ${secretsResult.message}`);
50475
51008
  } else {
@@ -50481,7 +51014,7 @@ async function runPreflight(dir, phase, config3) {
50481
51014
  }
50482
51015
  if (!cfg.skipEvidence) {
50483
51016
  log("[Preflight] Running evidence check...");
50484
- const evidenceResult = await _internals26.runEvidenceCheck(validatedDir);
51017
+ const evidenceResult = await _internals27.runEvidenceCheck(validatedDir);
50485
51018
  checks5.push(evidenceResult);
50486
51019
  log(`[Preflight] Evidence check: ${evidenceResult.status} ${evidenceResult.message}`);
50487
51020
  } else {
@@ -50492,12 +51025,12 @@ async function runPreflight(dir, phase, config3) {
50492
51025
  });
50493
51026
  }
50494
51027
  log("[Preflight] Running requirement coverage check...");
50495
- const reqCoverageResult = await _internals26.runRequirementCoverageCheck(validatedDir, phase);
51028
+ const reqCoverageResult = await _internals27.runRequirementCoverageCheck(validatedDir, phase);
50496
51029
  checks5.push(reqCoverageResult);
50497
51030
  log(`[Preflight] Requirement coverage check: ${reqCoverageResult.status} ${reqCoverageResult.message}`);
50498
51031
  if (!cfg.skipVersion) {
50499
51032
  log("[Preflight] Running version check...");
50500
- const versionResult = await _internals26.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
51033
+ const versionResult = await _internals27.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
50501
51034
  checks5.push(versionResult);
50502
51035
  log(`[Preflight] Version check: ${versionResult.status} ${versionResult.message}`);
50503
51036
  } else {
@@ -50560,11 +51093,12 @@ function formatPreflightMarkdown(report) {
50560
51093
  async function handlePreflightCommand(directory, _args) {
50561
51094
  const plan = await loadPlan(directory);
50562
51095
  const phase = plan?.current_phase ?? 1;
50563
- const report = await _internals26.runPreflight(directory, phase);
50564
- return _internals26.formatPreflightMarkdown(report);
51096
+ const report = await _internals27.runPreflight(directory, phase);
51097
+ return _internals27.formatPreflightMarkdown(report);
50565
51098
  }
50566
- var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG, _internals26;
51099
+ var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG, _internals27;
50567
51100
  var init_preflight_service = __esm(() => {
51101
+ init_gate_bridge();
50568
51102
  init_manager2();
50569
51103
  init_manager();
50570
51104
  init_lint();
@@ -50580,7 +51114,7 @@ var init_preflight_service = __esm(() => {
50580
51114
  testScope: "convention",
50581
51115
  linter: "biome"
50582
51116
  };
50583
- _internals26 = {
51117
+ _internals27 = {
50584
51118
  runPreflight,
50585
51119
  formatPreflightMarkdown,
50586
51120
  handlePreflightCommand,
@@ -51467,7 +52001,7 @@ var init_manager3 = __esm(() => {
51467
52001
 
51468
52002
  // src/commands/reset.ts
51469
52003
  import * as fs24 from "fs";
51470
- import * as path40 from "path";
52004
+ import * as path41 from "path";
51471
52005
  async function handleResetCommand(directory, args) {
51472
52006
  const hasConfirm = args.includes("--confirm");
51473
52007
  if (!hasConfirm) {
@@ -51507,7 +52041,7 @@ async function handleResetCommand(directory, args) {
51507
52041
  }
51508
52042
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
51509
52043
  try {
51510
- const rootPath = path40.join(directory, filename);
52044
+ const rootPath = path41.join(directory, filename);
51511
52045
  if (fs24.existsSync(rootPath)) {
51512
52046
  fs24.unlinkSync(rootPath);
51513
52047
  results.push(`- \u2705 Deleted ${filename} (root)`);
@@ -51547,7 +52081,7 @@ var init_reset = __esm(() => {
51547
52081
 
51548
52082
  // src/commands/reset-session.ts
51549
52083
  import * as fs25 from "fs";
51550
- import * as path41 from "path";
52084
+ import * as path42 from "path";
51551
52085
  async function handleResetSessionCommand(directory, _args) {
51552
52086
  const results = [];
51553
52087
  try {
@@ -51562,13 +52096,13 @@ async function handleResetSessionCommand(directory, _args) {
51562
52096
  results.push("\u274C Failed to delete state.json");
51563
52097
  }
51564
52098
  try {
51565
- const sessionDir = path41.dirname(validateSwarmPath(directory, "session/state.json"));
52099
+ const sessionDir = path42.dirname(validateSwarmPath(directory, "session/state.json"));
51566
52100
  if (fs25.existsSync(sessionDir)) {
51567
52101
  const files = fs25.readdirSync(sessionDir);
51568
52102
  const otherFiles = files.filter((f) => f !== "state.json");
51569
52103
  let deletedCount = 0;
51570
52104
  for (const file3 of otherFiles) {
51571
- const filePath = path41.join(sessionDir, file3);
52105
+ const filePath = path42.join(sessionDir, file3);
51572
52106
  if (fs25.lstatSync(filePath).isFile()) {
51573
52107
  fs25.unlinkSync(filePath);
51574
52108
  deletedCount++;
@@ -51600,7 +52134,7 @@ var init_reset_session = __esm(() => {
51600
52134
  });
51601
52135
 
51602
52136
  // src/summaries/manager.ts
51603
- import * as path42 from "path";
52137
+ import * as path43 from "path";
51604
52138
  function sanitizeSummaryId(id) {
51605
52139
  if (!id || id.length === 0) {
51606
52140
  throw new Error("Invalid summary ID: empty string");
@@ -51623,7 +52157,7 @@ function sanitizeSummaryId(id) {
51623
52157
  }
51624
52158
  async function loadFullOutput(directory, id) {
51625
52159
  const sanitizedId = sanitizeSummaryId(id);
51626
- const relativePath = path42.join("summaries", `${sanitizedId}.json`);
52160
+ const relativePath = path43.join("summaries", `${sanitizedId}.json`);
51627
52161
  validateSwarmPath(directory, relativePath);
51628
52162
  const content = await readSwarmFileAsync(directory, relativePath);
51629
52163
  if (content === null) {
@@ -51686,7 +52220,7 @@ var init_retrieve = __esm(() => {
51686
52220
 
51687
52221
  // src/commands/rollback.ts
51688
52222
  import * as fs26 from "fs";
51689
- import * as path43 from "path";
52223
+ import * as path44 from "path";
51690
52224
  async function handleRollbackCommand(directory, args) {
51691
52225
  const phaseArg = args[0];
51692
52226
  if (!phaseArg) {
@@ -51751,8 +52285,8 @@ async function handleRollbackCommand(directory, args) {
51751
52285
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
51752
52286
  continue;
51753
52287
  }
51754
- const src = path43.join(checkpointDir, file3);
51755
- const dest = path43.join(swarmDir, file3);
52288
+ const src = path44.join(checkpointDir, file3);
52289
+ const dest = path44.join(swarmDir, file3);
51756
52290
  try {
51757
52291
  fs26.cpSync(src, dest, { recursive: true, force: true });
51758
52292
  successes.push(file3);
@@ -51771,12 +52305,12 @@ async function handleRollbackCommand(directory, args) {
51771
52305
  ].join(`
51772
52306
  `);
51773
52307
  }
51774
- const existingLedgerPath = path43.join(swarmDir, "plan-ledger.jsonl");
52308
+ const existingLedgerPath = path44.join(swarmDir, "plan-ledger.jsonl");
51775
52309
  if (fs26.existsSync(existingLedgerPath)) {
51776
52310
  fs26.unlinkSync(existingLedgerPath);
51777
52311
  }
51778
52312
  try {
51779
- const planJsonPath = path43.join(swarmDir, "plan.json");
52313
+ const planJsonPath = path44.join(swarmDir, "plan.json");
51780
52314
  if (fs26.existsSync(planJsonPath)) {
51781
52315
  const planRaw = fs26.readFileSync(planJsonPath, "utf-8");
51782
52316
  const plan = PlanSchema.parse(JSON.parse(planRaw));
@@ -51837,7 +52371,7 @@ async function handleSimulateCommand(directory, args) {
51837
52371
  }
51838
52372
  let darkMatterPairs;
51839
52373
  try {
51840
- darkMatterPairs = await _internals10.detectDarkMatter(directory, options);
52374
+ darkMatterPairs = await _internals11.detectDarkMatter(directory, options);
51841
52375
  } catch (err) {
51842
52376
  const errMsg = err instanceof Error ? err.message : String(err);
51843
52377
  return `## Simulate Report
@@ -51867,9 +52401,9 @@ Ensure this is a git repository with commit history.`;
51867
52401
  `);
51868
52402
  try {
51869
52403
  const fs27 = await import("fs/promises");
51870
- const path44 = await import("path");
51871
- const reportPath = path44.join(directory, ".swarm", "simulate-report.md");
51872
- await fs27.mkdir(path44.dirname(reportPath), { recursive: true });
52404
+ const path45 = await import("path");
52405
+ const reportPath = path45.join(directory, ".swarm", "simulate-report.md");
52406
+ await fs27.mkdir(path45.dirname(reportPath), { recursive: true });
51873
52407
  await fs27.writeFile(reportPath, report, "utf-8");
51874
52408
  } catch (err) {
51875
52409
  const writeErr = err instanceof Error ? err.message : String(err);
@@ -51893,12 +52427,12 @@ async function handleSpecifyCommand(_directory, args) {
51893
52427
 
51894
52428
  // src/turbo/lean/state.ts
51895
52429
  import * as fs27 from "fs";
51896
- import * as path44 from "path";
52430
+ import * as path45 from "path";
51897
52431
  function nowISO2() {
51898
52432
  return new Date().toISOString();
51899
52433
  }
51900
52434
  function ensureSwarmDir2(directory) {
51901
- const swarmDir = path44.resolve(directory, ".swarm");
52435
+ const swarmDir = path45.resolve(directory, ".swarm");
51902
52436
  if (!fs27.existsSync(swarmDir)) {
51903
52437
  fs27.mkdirSync(swarmDir, { recursive: true });
51904
52438
  }
@@ -51942,7 +52476,7 @@ function markStateUnreadable2(directory, reason) {
51942
52476
  }
51943
52477
  function readPersisted2(directory) {
51944
52478
  try {
51945
- const filePath = path44.join(directory, ".swarm", STATE_FILE2);
52479
+ const filePath = path45.join(directory, ".swarm", STATE_FILE2);
51946
52480
  if (!fs27.existsSync(filePath)) {
51947
52481
  const seed = emptyPersisted2();
51948
52482
  try {
@@ -51978,7 +52512,7 @@ function writePersisted2(directory, persisted) {
51978
52512
  let payload;
51979
52513
  try {
51980
52514
  ensureSwarmDir2(directory);
51981
- filePath = path44.join(directory, ".swarm", STATE_FILE2);
52515
+ filePath = path45.join(directory, ".swarm", STATE_FILE2);
51982
52516
  tmpPath = `${filePath}.tmp.${Date.now()}`;
51983
52517
  persisted.updatedAt = nowISO2();
51984
52518
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -52105,10 +52639,10 @@ var init_context_budget_service = __esm(() => {
52105
52639
 
52106
52640
  // src/services/status-service.ts
52107
52641
  import * as fsSync2 from "fs";
52108
- import * as path45 from "path";
52642
+ import * as path46 from "path";
52109
52643
  function readSpecStalenessSnapshot(directory) {
52110
52644
  try {
52111
- const p = path45.join(directory, ".swarm", "spec-staleness.json");
52645
+ const p = path46.join(directory, ".swarm", "spec-staleness.json");
52112
52646
  if (!fsSync2.existsSync(p))
52113
52647
  return { stale: false };
52114
52648
  const raw = fsSync2.readFileSync(p, "utf-8");
@@ -52202,7 +52736,7 @@ async function getStatusData(directory, agents) {
52202
52736
  }
52203
52737
  function enrichWithLeanTurbo(status, directory) {
52204
52738
  const turboMode = hasActiveTurboMode();
52205
- const leanActive = _internals27.hasActiveLeanTurbo();
52739
+ const leanActive = _internals28.hasActiveLeanTurbo();
52206
52740
  let turboStrategy = "off";
52207
52741
  if (leanActive) {
52208
52742
  turboStrategy = "lean";
@@ -52221,7 +52755,7 @@ function enrichWithLeanTurbo(status, directory) {
52221
52755
  }
52222
52756
  }
52223
52757
  if (leanSessionID) {
52224
- const runState = _internals27.loadLeanTurboRunState(directory, leanSessionID);
52758
+ const runState = _internals28.loadLeanTurboRunState(directory, leanSessionID);
52225
52759
  if (runState) {
52226
52760
  status.leanTurboPhase = runState.phase;
52227
52761
  status.leanMaxParallelCoders = runState.maxParallelCoders;
@@ -52253,7 +52787,7 @@ function enrichWithLeanTurbo(status, directory) {
52253
52787
  }
52254
52788
  }
52255
52789
  }
52256
- status.fullAutoActive = _internals27.hasActiveFullAuto();
52790
+ status.fullAutoActive = _internals28.hasActiveFullAuto();
52257
52791
  return status;
52258
52792
  }
52259
52793
  function formatStatusMarkdown(status) {
@@ -52335,7 +52869,7 @@ async function handleStatusCommand(directory, agents) {
52335
52869
  }
52336
52870
  return formatStatusMarkdown(statusData);
52337
52871
  }
52338
- var _internals27;
52872
+ var _internals28;
52339
52873
  var init_status_service = __esm(() => {
52340
52874
  init_extractors();
52341
52875
  init_utils2();
@@ -52344,7 +52878,7 @@ var init_status_service = __esm(() => {
52344
52878
  init_state3();
52345
52879
  init_compaction_service();
52346
52880
  init_context_budget_service();
52347
- _internals27 = {
52881
+ _internals28 = {
52348
52882
  loadLeanTurboRunState,
52349
52883
  hasActiveLeanTurbo,
52350
52884
  hasActiveFullAuto
@@ -52435,7 +52969,7 @@ async function handleTurboCommand(directory, args, sessionID) {
52435
52969
  if (arg0 === "on") {
52436
52970
  let strategy = "standard";
52437
52971
  try {
52438
- const { config: config3 } = _internals28.loadPluginConfigWithMeta(directory);
52972
+ const { config: config3 } = _internals29.loadPluginConfigWithMeta(directory);
52439
52973
  if (config3.turbo?.strategy === "lean") {
52440
52974
  strategy = "lean";
52441
52975
  }
@@ -52490,7 +53024,7 @@ function enableLeanTurbo(session, directory, sessionID) {
52490
53024
  let maxParallelCoders = 4;
52491
53025
  let conflictPolicy = "serialize";
52492
53026
  try {
52493
- const { config: config3 } = _internals28.loadPluginConfigWithMeta(directory);
53027
+ const { config: config3 } = _internals29.loadPluginConfigWithMeta(directory);
52494
53028
  const leanConfig = config3.turbo?.lean;
52495
53029
  if (leanConfig) {
52496
53030
  maxParallelCoders = leanConfig.max_parallel_coders ?? 4;
@@ -52560,13 +53094,13 @@ function buildStatusMessage(session, directory, sessionID) {
52560
53094
  ].join(`
52561
53095
  `);
52562
53096
  }
52563
- var _internals28;
53097
+ var _internals29;
52564
53098
  var init_turbo = __esm(() => {
52565
53099
  init_config();
52566
53100
  init_state();
52567
53101
  init_state3();
52568
53102
  init_logger();
52569
- _internals28 = {
53103
+ _internals29 = {
52570
53104
  loadPluginConfigWithMeta
52571
53105
  };
52572
53106
  });
@@ -52634,7 +53168,7 @@ var init_write_retro2 = __esm(() => {
52634
53168
 
52635
53169
  // src/commands/command-dispatch.ts
52636
53170
  import fs28 from "fs";
52637
- import path46 from "path";
53171
+ import path47 from "path";
52638
53172
  function normalizeSwarmCommandInput(command, argumentText) {
52639
53173
  if (command !== "swarm" && !command.startsWith("swarm-")) {
52640
53174
  return { isSwarmCommand: false, tokens: [] };
@@ -52659,7 +53193,7 @@ function formatCommandNotFound(tokens) {
52659
53193
  const attemptedCommand = tokens[0] || "";
52660
53194
  const MAX_DISPLAY = 100;
52661
53195
  const displayCommand = attemptedCommand.length > MAX_DISPLAY ? `${attemptedCommand.slice(0, MAX_DISPLAY)}...` : attemptedCommand;
52662
- const similar = _internals29.findSimilarCommands(attemptedCommand);
53196
+ const similar = _internals30.findSimilarCommands(attemptedCommand);
52663
53197
  const header = `Command \`/swarm ${displayCommand}\` not found.`;
52664
53198
  const suggestions = similar.length > 0 ? `Did you mean:
52665
53199
  ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
@@ -52670,9 +53204,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
52670
53204
  `);
52671
53205
  }
52672
53206
  function maybeMarkFirstRun(directory) {
52673
- const sentinelPath = path46.join(directory, ".swarm", ".first-run-complete");
53207
+ const sentinelPath = path47.join(directory, ".swarm", ".first-run-complete");
52674
53208
  try {
52675
- const swarmDir = path46.join(directory, ".swarm");
53209
+ const swarmDir = path47.join(directory, ".swarm");
52676
53210
  fs28.mkdirSync(swarmDir, { recursive: true });
52677
53211
  fs28.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
52678
53212
  `, { flag: "wx" });
@@ -53108,7 +53642,7 @@ async function buildSwarmCommandPrompt(args) {
53108
53642
  activeAgentName,
53109
53643
  registeredAgents
53110
53644
  } = args;
53111
- const resolved = _internals29.resolveCommand(tokens);
53645
+ const resolved = _internals30.resolveCommand(tokens);
53112
53646
  if (!resolved) {
53113
53647
  if (tokens.length === 0) {
53114
53648
  return buildHelpText();
@@ -53259,7 +53793,7 @@ function findSimilarCommands(query) {
53259
53793
  }
53260
53794
  const scored = VALID_COMMANDS.map((cmd) => {
53261
53795
  const cmdLower = cmd.toLowerCase();
53262
- const fullScore = _internals29.levenshteinDistance(q, cmdLower);
53796
+ const fullScore = _internals30.levenshteinDistance(q, cmdLower);
53263
53797
  let tokenScore = Infinity;
53264
53798
  if (cmd.includes(" ") || cmd.includes("-")) {
53265
53799
  const qTokens = q.split(/[\s-]+/);
@@ -53272,7 +53806,7 @@ function findSimilarCommands(query) {
53272
53806
  for (const ct of cmdTokens) {
53273
53807
  if (ct.length === 0)
53274
53808
  continue;
53275
- const dist = _internals29.levenshteinDistance(qt, ct);
53809
+ const dist = _internals30.levenshteinDistance(qt, ct);
53276
53810
  if (dist < minDist)
53277
53811
  minDist = dist;
53278
53812
  }
@@ -53282,7 +53816,7 @@ function findSimilarCommands(query) {
53282
53816
  }
53283
53817
  const dashStrippedQ = q.replace(/-/g, "");
53284
53818
  const dashStrippedCmd = cmdLower.replace(/-/g, "");
53285
- const dashScore = _internals29.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
53819
+ const dashScore = _internals30.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
53286
53820
  const score = Math.min(fullScore, tokenScore, dashScore);
53287
53821
  return { cmd, score };
53288
53822
  });
@@ -53314,11 +53848,11 @@ async function handleHelpCommand(ctx) {
53314
53848
  return buildHelpText2();
53315
53849
  }
53316
53850
  const tokens = targetCommand.split(/\s+/);
53317
- const resolved = _internals29.resolveCommand(tokens);
53851
+ const resolved = _internals30.resolveCommand(tokens);
53318
53852
  if (resolved) {
53319
- return _internals29.buildDetailedHelp(resolved.key, resolved.entry);
53853
+ return _internals30.buildDetailedHelp(resolved.key, resolved.entry);
53320
53854
  }
53321
- const similar = _internals29.findSimilarCommands(targetCommand);
53855
+ const similar = _internals30.findSimilarCommands(targetCommand);
53322
53856
  const { buildHelpText: fullHelp } = await Promise.resolve().then(() => (init_commands(), exports_commands));
53323
53857
  if (similar.length > 0) {
53324
53858
  return `Command '/swarm ${targetCommand}' not found.
@@ -53354,24 +53888,24 @@ function validateAliases() {
53354
53888
  }
53355
53889
  aliasTargets.get(target).push(name);
53356
53890
  const visited = new Set;
53357
- const path47 = [];
53891
+ const path48 = [];
53358
53892
  let current = target;
53359
53893
  while (current) {
53360
53894
  const currentEntry = COMMAND_REGISTRY[current];
53361
53895
  if (!currentEntry)
53362
53896
  break;
53363
53897
  if (visited.has(current)) {
53364
- const cycleStart = path47.indexOf(current);
53898
+ const cycleStart = path48.indexOf(current);
53365
53899
  const fullChain = [
53366
53900
  name,
53367
- ...path47.slice(0, cycleStart > 0 ? cycleStart : path47.length),
53901
+ ...path48.slice(0, cycleStart > 0 ? cycleStart : path48.length),
53368
53902
  current
53369
53903
  ].join(" \u2192 ");
53370
53904
  errors5.push(`Circular alias detected: ${fullChain}`);
53371
53905
  break;
53372
53906
  }
53373
53907
  visited.add(current);
53374
- path47.push(current);
53908
+ path48.push(current);
53375
53909
  current = currentEntry.aliasOf || "";
53376
53910
  }
53377
53911
  }
@@ -53412,7 +53946,7 @@ function resolveCommand(tokens) {
53412
53946
  }
53413
53947
  return null;
53414
53948
  }
53415
- var COMMAND_REGISTRY, VALID_COMMANDS, _internals29, validation;
53949
+ var COMMAND_REGISTRY, VALID_COMMANDS, _internals30, validation;
53416
53950
  var init_registry = __esm(() => {
53417
53951
  init_acknowledge_spec_drift();
53418
53952
  init_agents();
@@ -53482,7 +54016,7 @@ var init_registry = __esm(() => {
53482
54016
  clashesWithNativeCcCommand: "/agents"
53483
54017
  },
53484
54018
  help: {
53485
- handler: (ctx) => _internals29.handleHelpCommand(ctx),
54019
+ handler: (ctx) => _internals30.handleHelpCommand(ctx),
53486
54020
  description: "Show help for swarm commands",
53487
54021
  category: "core",
53488
54022
  args: "[command]",
@@ -53854,7 +54388,7 @@ Subcommands:
53854
54388
  }
53855
54389
  };
53856
54390
  VALID_COMMANDS = Object.keys(COMMAND_REGISTRY);
53857
- _internals29 = {
54391
+ _internals30 = {
53858
54392
  handleHelpCommand,
53859
54393
  validateAliases,
53860
54394
  resolveCommand,
@@ -53862,7 +54396,7 @@ Subcommands:
53862
54396
  findSimilarCommands,
53863
54397
  buildDetailedHelp
53864
54398
  };
53865
- validation = _internals29.validateAliases();
54399
+ validation = _internals30.validateAliases();
53866
54400
  if (!validation.valid) {
53867
54401
  throw new Error(`COMMAND_REGISTRY alias validation failed:
53868
54402
  ${validation.errors.join(`
@@ -53882,53 +54416,53 @@ init_cache_paths();
53882
54416
  init_constants();
53883
54417
  import * as fs29 from "fs";
53884
54418
  import * as os7 from "os";
53885
- import * as path47 from "path";
54419
+ import * as path48 from "path";
53886
54420
  var { version: version4 } = package_default;
53887
54421
  var CONFIG_DIR = getPluginConfigDir();
53888
- var OPENCODE_CONFIG_PATH = path47.join(CONFIG_DIR, "opencode.json");
53889
- var PLUGIN_CONFIG_PATH = path47.join(CONFIG_DIR, "opencode-swarm.json");
53890
- var PROMPTS_DIR = path47.join(CONFIG_DIR, "opencode-swarm");
54422
+ var OPENCODE_CONFIG_PATH = path48.join(CONFIG_DIR, "opencode.json");
54423
+ var PLUGIN_CONFIG_PATH = path48.join(CONFIG_DIR, "opencode-swarm.json");
54424
+ var PROMPTS_DIR = path48.join(CONFIG_DIR, "opencode-swarm");
53891
54425
  var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
53892
54426
  var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
53893
54427
  function isSafeCachePath(p) {
53894
- const resolved = path47.resolve(p);
53895
- const home = path47.resolve(os7.homedir());
54428
+ const resolved = path48.resolve(p);
54429
+ const home = path48.resolve(os7.homedir());
53896
54430
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
53897
54431
  return false;
53898
54432
  }
53899
- const segments = resolved.split(path47.sep).filter((s) => s.length > 0);
54433
+ const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
53900
54434
  if (segments.length < 4) {
53901
54435
  return false;
53902
54436
  }
53903
- const leaf = path47.basename(resolved);
54437
+ const leaf = path48.basename(resolved);
53904
54438
  if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
53905
54439
  return false;
53906
54440
  }
53907
- const parent = path47.basename(path47.dirname(resolved));
54441
+ const parent = path48.basename(path48.dirname(resolved));
53908
54442
  if (parent !== "packages" && parent !== "node_modules") {
53909
54443
  return false;
53910
54444
  }
53911
- const grandparent = path47.basename(path47.dirname(path47.dirname(resolved)));
54445
+ const grandparent = path48.basename(path48.dirname(path48.dirname(resolved)));
53912
54446
  if (grandparent !== "opencode") {
53913
54447
  return false;
53914
54448
  }
53915
54449
  return true;
53916
54450
  }
53917
54451
  function isSafeLockFilePath(p) {
53918
- const resolved = path47.resolve(p);
53919
- const home = path47.resolve(os7.homedir());
54452
+ const resolved = path48.resolve(p);
54453
+ const home = path48.resolve(os7.homedir());
53920
54454
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
53921
54455
  return false;
53922
54456
  }
53923
- const segments = resolved.split(path47.sep).filter((s) => s.length > 0);
54457
+ const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
53924
54458
  if (segments.length < 4) {
53925
54459
  return false;
53926
54460
  }
53927
- const leaf = path47.basename(resolved);
54461
+ const leaf = path48.basename(resolved);
53928
54462
  if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
53929
54463
  return false;
53930
54464
  }
53931
- const parent = path47.basename(path47.dirname(resolved));
54465
+ const parent = path48.basename(path48.dirname(resolved));
53932
54466
  if (parent !== "opencode") {
53933
54467
  return false;
53934
54468
  }
@@ -53954,8 +54488,8 @@ function saveJson(filepath, data) {
53954
54488
  }
53955
54489
  function writeProjectConfigIfMissing(cwd) {
53956
54490
  try {
53957
- const opencodeDir = path47.join(cwd, ".opencode");
53958
- const projectConfigPath = path47.join(opencodeDir, "opencode-swarm.json");
54491
+ const opencodeDir = path48.join(cwd, ".opencode");
54492
+ const projectConfigPath = path48.join(opencodeDir, "opencode-swarm.json");
53959
54493
  if (fs29.existsSync(projectConfigPath)) {
53960
54494
  return;
53961
54495
  }
@@ -53972,7 +54506,7 @@ async function install() {
53972
54506
  `);
53973
54507
  ensureDir(CONFIG_DIR);
53974
54508
  ensureDir(PROMPTS_DIR);
53975
- const LEGACY_CONFIG_PATH = path47.join(CONFIG_DIR, "config.json");
54509
+ const LEGACY_CONFIG_PATH = path48.join(CONFIG_DIR, "config.json");
53976
54510
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
53977
54511
  if (!opencodeConfig) {
53978
54512
  const legacyConfig = loadJson(LEGACY_CONFIG_PATH);