opencode-swarm 7.24.0 → 7.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ var package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "opencode-swarm",
36
- version: "7.24.0",
36
+ version: "7.25.0",
37
37
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
38
38
  main: "dist/index.js",
39
39
  types: "dist/index.d.ts",
@@ -42694,6 +42694,20 @@ function normalizeEntry(raw) {
42694
42694
  ro.failed_after_shown_count = typeof ro.failed_after_count === "number" ? ro.failed_after_count : 0;
42695
42695
  }
42696
42696
  }
42697
+ try {
42698
+ if (typeof obj.encounter_score !== "number" || Number.isNaN(obj.encounter_score)) {
42699
+ obj.encounter_score = 0;
42700
+ }
42701
+ } catch {
42702
+ try {
42703
+ Object.defineProperty(obj, "encounter_score", {
42704
+ value: 0,
42705
+ writable: true,
42706
+ configurable: true,
42707
+ enumerable: true
42708
+ });
42709
+ } catch {}
42710
+ }
42697
42711
  const arrayFields = [
42698
42712
  "triggers",
42699
42713
  "required_actions",
@@ -44618,12 +44632,26 @@ import path19 from "node:path";
44618
44632
  function isAlreadyInHive(entry, hiveEntries, threshold) {
44619
44633
  return findNearDuplicate(entry.lesson, hiveEntries, threshold) !== undefined;
44620
44634
  }
44621
- function countDistinctPhases(confirmedBy) {
44635
+ function isHiveEligible(entry, autoPromoteDays) {
44622
44636
  const phaseNumbers = new Set;
44623
- for (const record3 of confirmedBy) {
44624
- phaseNumbers.add(record3.phase_number);
44637
+ for (const record3 of entry.confirmed_by ?? []) {
44638
+ if (record3 && typeof record3.phase_number === "number") {
44639
+ phaseNumbers.add(record3.phase_number);
44640
+ }
44641
+ }
44642
+ if (entry.hive_eligible === true && phaseNumbers.size >= 3) {
44643
+ return true;
44644
+ }
44645
+ if ((entry.tags ?? []).includes("hive-fast-track")) {
44646
+ return true;
44625
44647
  }
44626
- return phaseNumbers.size;
44648
+ const createdMs = Date.parse(entry.created_at);
44649
+ const ageMs = Number.isFinite(createdMs) ? Date.now() - createdMs : 0;
44650
+ const ageThresholdMs = autoPromoteDays * 86400000;
44651
+ if (ageMs >= ageThresholdMs) {
44652
+ return true;
44653
+ }
44654
+ return false;
44627
44655
  }
44628
44656
  function countDistinctProjects(confirmedBy) {
44629
44657
  const projectNames = new Set;
@@ -44641,12 +44669,6 @@ function calculateEncounterScore(currentScore, isSameProject, config3) {
44641
44669
  const newScore = currentScore + increment;
44642
44670
  return Math.min(Math.max(newScore, config3.min_encounter_score), config3.max_encounter_score);
44643
44671
  }
44644
- function getEntryAgeMs(createdAt) {
44645
- const createdTime = new Date(createdAt).getTime();
44646
- if (Number.isNaN(createdTime))
44647
- return 0;
44648
- return Date.now() - createdTime;
44649
- }
44650
44672
  async function checkHivePromotions(swarmEntries, config3) {
44651
44673
  let newPromotions = 0;
44652
44674
  let encountersIncremented = 0;
@@ -44665,19 +44687,7 @@ async function checkHivePromotions(swarmEntries, config3) {
44665
44687
  if (isAlreadyInHive(swarmEntry, hiveEntries, config3.dedup_threshold)) {
44666
44688
  continue;
44667
44689
  }
44668
- let shouldPromote = false;
44669
- if (swarmEntry.hive_eligible === true && countDistinctPhases(swarmEntry.confirmed_by) >= 3) {
44670
- shouldPromote = true;
44671
- }
44672
- if (swarmEntry.tags.includes("hive-fast-track")) {
44673
- shouldPromote = true;
44674
- }
44675
- const ageMs = getEntryAgeMs(swarmEntry.created_at);
44676
- const ageThresholdMs = config3.auto_promote_days * 86400000;
44677
- if (ageMs >= ageThresholdMs) {
44678
- shouldPromote = true;
44679
- }
44680
- if (!shouldPromote) {
44690
+ if (!isHiveEligible(swarmEntry, config3.auto_promote_days)) {
44681
44691
  continue;
44682
44692
  }
44683
44693
  const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
@@ -46554,12 +46564,14 @@ async function handleCloseCommand(directory, args2, options = {}) {
46554
46564
  if (planExists) {
46555
46565
  planAlreadyDone = phases.length > 0 && phases.every((p) => p.status === "complete" || p.status === "completed" || p.status === "blocked" || p.status === "closed");
46556
46566
  }
46557
- const config3 = KnowledgeConfigSchema.parse({});
46567
+ const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
46568
+ const config3 = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
46558
46569
  const projectName = planData.title ?? "Unknown Project";
46559
46570
  const closedPhases = [];
46560
46571
  const closedTasks = [];
46561
46572
  const warnings = [];
46562
46573
  let hivePromoted = 0;
46574
+ let hiveSkipped = 0;
46563
46575
  if (!planAlreadyDone) {
46564
46576
  for (const phase of inProgressPhases) {
46565
46577
  closedPhases.push(phase.id);
@@ -46682,23 +46694,35 @@ async function handleCloseCommand(directory, args2, options = {}) {
46682
46694
  await fs13.unlink(lessonsFilePath).catch(() => {});
46683
46695
  }
46684
46696
  if (curationSucceeded) {
46685
- try {
46686
- const knowledgePath = resolveSwarmKnowledgePath(directory);
46687
- const entries = await readKnowledge(knowledgePath);
46688
- if (entries.length > 0) {
46689
- for (const entry of entries) {
46690
- try {
46691
- await promoteToHive(directory, entry.lesson, entry.category);
46692
- hivePromoted++;
46693
- } catch (promotionErr) {
46694
- const msg = promotionErr instanceof Error ? promotionErr.message : String(promotionErr);
46695
- warnings.push(`Hive promotion skipped for lesson: ${msg}`);
46697
+ if (config3.hive_enabled === false) {} else {
46698
+ try {
46699
+ const knowledgePath = resolveSwarmKnowledgePath(directory);
46700
+ const entries = await readKnowledge(knowledgePath);
46701
+ const autoPromoteDays = config3.auto_promote_days;
46702
+ if (entries.length > 0) {
46703
+ for (const entry of entries) {
46704
+ if (!isHiveEligible(entry, autoPromoteDays)) {
46705
+ hiveSkipped++;
46706
+ continue;
46707
+ }
46708
+ try {
46709
+ const result = await promoteToHive(directory, entry.lesson, entry.category);
46710
+ if (!result.includes("already exists")) {
46711
+ hivePromoted++;
46712
+ }
46713
+ } catch (promotionErr) {
46714
+ const msg = promotionErr instanceof Error ? promotionErr.message : String(promotionErr);
46715
+ warnings.push(`Hive promotion skipped for lesson: ${msg}`);
46716
+ }
46717
+ }
46718
+ if (hiveSkipped > 0) {
46719
+ warnings.push(`${hiveSkipped} swarm knowledge entr${hiveSkipped === 1 ? "y" : "ies"} not eligible for hive promotion`);
46696
46720
  }
46697
46721
  }
46722
+ } catch (hiveErr) {
46723
+ const msg = hiveErr instanceof Error ? hiveErr.message : String(hiveErr);
46724
+ warnings.push(`Hive promotion failed: ${msg}`);
46698
46725
  }
46699
- } catch (hiveErr) {
46700
- const msg = hiveErr instanceof Error ? hiveErr.message : String(hiveErr);
46701
- warnings.push(`Hive promotion failed: ${msg}`);
46702
46726
  }
46703
46727
  }
46704
46728
  const fallbackKnowledgeCreated = curationResult?.stored ?? 0;
@@ -46715,8 +46739,8 @@ async function handleCloseCommand(directory, args2, options = {}) {
46715
46739
  let skillReviewSummary = "";
46716
46740
  if (runSkillReview) {
46717
46741
  try {
46718
- const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
46719
- const skillImproverConfig = SkillImproverConfigSchema.parse(loadedConfig.skill_improver ?? {});
46742
+ const { config: loadedConfig2 } = loadPluginConfigWithMeta(directory);
46743
+ const skillImproverConfig = SkillImproverConfigSchema.parse(loadedConfig2.skill_improver ?? {});
46720
46744
  const skillReviewResult = await runAbortableSkillReview({
46721
46745
  directory,
46722
46746
  config: skillImproverConfig,
@@ -47081,7 +47105,6 @@ var init_close = __esm(() => {
47081
47105
  "handoff-prompt.md",
47082
47106
  "handoff-consumed.md",
47083
47107
  "escalation-report.md",
47084
- "knowledge.jsonl",
47085
47108
  "knowledge-rejected.jsonl",
47086
47109
  "repo-graph.json",
47087
47110
  "doc-manifest.json",
@@ -54967,7 +54990,14 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
54967
54990
  return args2;
54968
54991
  }
54969
54992
  case "vitest": {
54970
- const args2 = ["npx", "vitest", "run"];
54993
+ const args2 = [
54994
+ "npx",
54995
+ "vitest",
54996
+ "run",
54997
+ "--reporter=json",
54998
+ "--outputFile",
54999
+ ".swarm/cache/test-runner-vitest.json"
55000
+ ];
54971
55001
  if (coverage)
54972
55002
  args2.push("--coverage");
54973
55003
  if (scope !== "all" && files.length > 0)
@@ -54975,7 +55005,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
54975
55005
  return args2;
54976
55006
  }
54977
55007
  case "jest": {
54978
- const args2 = ["npx", "jest"];
55008
+ const args2 = ["npx", "jest", "--json"];
54979
55009
  if (coverage)
54980
55010
  args2.push("--coverage");
54981
55011
  if (scope !== "all" && files.length > 0)
@@ -56210,6 +56240,42 @@ function sanitizeChangedFiles(changedFiles) {
56210
56240
  const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !DANGEROUS_PROPERTY_NAMES.has(f));
56211
56241
  return validFiles.slice(0, MAX_CHANGED_FILES);
56212
56242
  }
56243
+ function isTestRunResult(value) {
56244
+ return value === "pass" || value === "fail" || value === "skip";
56245
+ }
56246
+ function parseStoredRecord(value) {
56247
+ if (typeof value !== "object" || value === null)
56248
+ return null;
56249
+ const record3 = value;
56250
+ if (typeof record3.testFile !== "string" || record3.testFile.length === 0) {
56251
+ return null;
56252
+ }
56253
+ if (typeof record3.testName !== "string" || record3.testName.length === 0) {
56254
+ return null;
56255
+ }
56256
+ if (typeof record3.taskId !== "string" || record3.taskId.length === 0) {
56257
+ return null;
56258
+ }
56259
+ if (!isTestRunResult(record3.result))
56260
+ return null;
56261
+ if (typeof record3.durationMs !== "number" || !Number.isFinite(record3.durationMs)) {
56262
+ return null;
56263
+ }
56264
+ if (typeof record3.timestamp !== "string" || Number.isNaN(Date.parse(record3.timestamp))) {
56265
+ return null;
56266
+ }
56267
+ return {
56268
+ timestamp: record3.timestamp,
56269
+ taskId: record3.taskId,
56270
+ testFile: record3.testFile,
56271
+ testName: record3.testName,
56272
+ result: record3.result,
56273
+ durationMs: Math.max(0, record3.durationMs),
56274
+ errorMessage: typeof record3.errorMessage === "string" ? sanitizeErrorMessage(record3.errorMessage) : undefined,
56275
+ stackPrefix: typeof record3.stackPrefix === "string" ? sanitizeStackPrefix(record3.stackPrefix) : undefined,
56276
+ changedFiles: sanitizeChangedFiles(Array.isArray(record3.changedFiles) ? record3.changedFiles : [])
56277
+ };
56278
+ }
56213
56279
  function appendTestRun(record3, workingDir) {
56214
56280
  if (typeof record3.testFile !== "string" || record3.testFile.length === 0) {
56215
56281
  throw new TypeError("testFile must be a non-empty string");
@@ -56247,16 +56313,16 @@ function appendTestRun(record3, workingDir) {
56247
56313
  }
56248
56314
  const existingRecords = readAllRecords(historyPath);
56249
56315
  existingRecords.push(sanitizedRecord);
56250
- const recordsByFile = new Map;
56316
+ const recordsByTest = new Map;
56251
56317
  for (const rec of existingRecords) {
56252
- const normalizedFile = rec.testFile.toLowerCase();
56253
- if (!recordsByFile.has(normalizedFile)) {
56254
- recordsByFile.set(normalizedFile, []);
56318
+ const normalizedKey = `${rec.testFile.toLowerCase()}|${rec.testName.toLowerCase()}`;
56319
+ if (!recordsByTest.has(normalizedKey)) {
56320
+ recordsByTest.set(normalizedKey, []);
56255
56321
  }
56256
- recordsByFile.get(normalizedFile).push(rec);
56322
+ recordsByTest.get(normalizedKey).push(rec);
56257
56323
  }
56258
56324
  const prunedRecords = [];
56259
- for (const [, records] of recordsByFile) {
56325
+ for (const [, records] of recordsByTest) {
56260
56326
  records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
56261
56327
  const toKeep = records.slice(-MAX_HISTORY_PER_TEST);
56262
56328
  prunedRecords.push(...toKeep);
@@ -56296,8 +56362,9 @@ function readAllRecords(historyPath) {
56296
56362
  }
56297
56363
  try {
56298
56364
  const parsed = JSON.parse(trimmed);
56299
- if (typeof parsed === "object" && parsed !== null && "testFile" in parsed && "testName" in parsed && "result" in parsed) {
56300
- records.push(parsed);
56365
+ const record3 = parseStoredRecord(parsed);
56366
+ if (record3) {
56367
+ records.push(record3);
56301
56368
  }
56302
56369
  } catch {}
56303
56370
  }
@@ -57336,7 +57403,14 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
57336
57403
  return args2;
57337
57404
  }
57338
57405
  case "vitest": {
57339
- const args2 = ["npx", "vitest", "run"];
57406
+ const args2 = [
57407
+ "npx",
57408
+ "vitest",
57409
+ "run",
57410
+ "--reporter=json",
57411
+ "--outputFile",
57412
+ VITEST_JSON_OUTPUT_RELATIVE_PATH
57413
+ ];
57340
57414
  if (coverage)
57341
57415
  args2.push("--coverage");
57342
57416
  if (scope !== "all" && files.length > 0) {
@@ -57345,7 +57419,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
57345
57419
  return args2;
57346
57420
  }
57347
57421
  case "jest": {
57348
- const args2 = ["npx", "jest"];
57422
+ const args2 = ["npx", "jest", "--json"];
57349
57423
  if (coverage)
57350
57424
  args2.push("--coverage");
57351
57425
  if (scope !== "all" && files.length > 0) {
@@ -57441,6 +57515,122 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
57441
57515
  return null;
57442
57516
  }
57443
57517
  }
57518
+ function mapFrameworkStatusToResult(status) {
57519
+ if (typeof status !== "string")
57520
+ return null;
57521
+ const normalized = status.toLowerCase();
57522
+ if (normalized === "pass" || normalized === "passed")
57523
+ return "pass";
57524
+ if (normalized === "fail" || normalized === "failed")
57525
+ return "fail";
57526
+ if (normalized === "skip" || normalized === "skipped" || normalized === "pending" || normalized === "todo") {
57527
+ return "skip";
57528
+ }
57529
+ return null;
57530
+ }
57531
+ function firstLine(value) {
57532
+ if (typeof value !== "string")
57533
+ return;
57534
+ const line = value.split(`
57535
+ `).find((part) => part.trim().length > 0)?.trim();
57536
+ return line && line.length > 0 ? line : undefined;
57537
+ }
57538
+ function parseJestLikeJsonTestResults(payload) {
57539
+ if (typeof payload !== "object" || payload === null)
57540
+ return [];
57541
+ const rawSuites = payload.testResults;
57542
+ if (!Array.isArray(rawSuites))
57543
+ return [];
57544
+ const parsed = [];
57545
+ for (const suite of rawSuites) {
57546
+ if (typeof suite !== "object" || suite === null)
57547
+ continue;
57548
+ const suiteObj = suite;
57549
+ const rawFile = typeof suiteObj.name === "string" ? suiteObj.name : typeof suiteObj.testFilePath === "string" ? suiteObj.testFilePath : undefined;
57550
+ if (!rawFile)
57551
+ continue;
57552
+ const testFile = rawFile.replace(/\\/g, "/");
57553
+ const assertionResults = suiteObj.assertionResults;
57554
+ if (!Array.isArray(assertionResults))
57555
+ continue;
57556
+ for (const assertion of assertionResults) {
57557
+ if (typeof assertion !== "object" || assertion === null)
57558
+ continue;
57559
+ const assertionObj = assertion;
57560
+ const result = mapFrameworkStatusToResult(assertionObj.status);
57561
+ const testName = typeof assertionObj.fullName === "string" ? assertionObj.fullName : typeof assertionObj.title === "string" ? assertionObj.title : undefined;
57562
+ if (!result || !testName || testName.length === 0)
57563
+ continue;
57564
+ const failureMessages = Array.isArray(assertionObj.failureMessages) ? assertionObj.failureMessages : [];
57565
+ const firstFailure = failureMessages.find((entry) => typeof entry === "string" && entry.length > 0);
57566
+ const durationMs = typeof assertionObj.duration === "number" && Number.isFinite(assertionObj.duration) ? Math.max(assertionObj.duration, 0) : 0;
57567
+ parsed.push({
57568
+ testFile,
57569
+ testName,
57570
+ result,
57571
+ durationMs,
57572
+ errorMessage: firstLine(firstFailure),
57573
+ stackPrefix: firstLine(firstFailure)
57574
+ });
57575
+ }
57576
+ }
57577
+ return parsed;
57578
+ }
57579
+ function parseBunJsonLines(output) {
57580
+ const parsed = [];
57581
+ for (const line of output.split(`
57582
+ `)) {
57583
+ const trimmed = line.trim();
57584
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}"))
57585
+ continue;
57586
+ try {
57587
+ const obj = JSON.parse(trimmed);
57588
+ const rawFile = typeof obj.file === "string" ? obj.file : typeof obj.testFile === "string" ? obj.testFile : typeof obj.path === "string" ? obj.path : undefined;
57589
+ const rawName = typeof obj.testName === "string" ? obj.testName : typeof obj.fullName === "string" ? obj.fullName : typeof obj.name === "string" ? obj.name : undefined;
57590
+ const result = mapFrameworkStatusToResult(typeof obj.status === "string" ? obj.status : obj.result);
57591
+ if (!rawFile || !rawName || !result)
57592
+ continue;
57593
+ const errorObj = typeof obj.error === "object" && obj.error !== null ? obj.error : undefined;
57594
+ const durationMs = typeof obj.durationMs === "number" && Number.isFinite(obj.durationMs) ? Math.max(obj.durationMs, 0) : typeof obj.duration === "number" && Number.isFinite(obj.duration) ? Math.max(obj.duration, 0) : 0;
57595
+ parsed.push({
57596
+ testFile: rawFile.replace(/\\/g, "/"),
57597
+ testName: rawName,
57598
+ result,
57599
+ durationMs,
57600
+ errorMessage: firstLine(errorObj?.message ?? obj.errorMessage),
57601
+ stackPrefix: firstLine(errorObj?.stack)
57602
+ });
57603
+ } catch {}
57604
+ }
57605
+ return parsed;
57606
+ }
57607
+ function parseFrameworkJsonTestResults(framework, output) {
57608
+ const jsonMatch = output.match(/\{[\s\S]*"testResults"[\s\S]*\}/);
57609
+ if (jsonMatch) {
57610
+ try {
57611
+ const parsed = JSON.parse(jsonMatch[0]);
57612
+ const testResults = parseJestLikeJsonTestResults(parsed);
57613
+ if (testResults.length > 0)
57614
+ return testResults;
57615
+ } catch {}
57616
+ }
57617
+ for (const line of output.split(`
57618
+ `)) {
57619
+ const trimmed = line.trim();
57620
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}"))
57621
+ continue;
57622
+ try {
57623
+ const parsed = JSON.parse(trimmed);
57624
+ const testResults = parseJestLikeJsonTestResults(parsed);
57625
+ if (testResults.length > 0)
57626
+ return testResults;
57627
+ } catch {}
57628
+ }
57629
+ if (framework === "bun") {
57630
+ return parseBunJsonLines(output);
57631
+ }
57632
+ return [];
57633
+ }
57444
57634
  function parseTestOutput2(framework, output) {
57445
57635
  const totals = {
57446
57636
  passed: 0,
@@ -57728,7 +57918,16 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
57728
57918
  };
57729
57919
  }
57730
57920
  const startTime = Date.now();
57921
+ const vitestJsonOutputPath = framework === "vitest" ? path46.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
57731
57922
  try {
57923
+ if (vitestJsonOutputPath) {
57924
+ try {
57925
+ fs29.mkdirSync(path46.dirname(vitestJsonOutputPath), { recursive: true });
57926
+ if (fs29.existsSync(vitestJsonOutputPath)) {
57927
+ fs29.unlinkSync(vitestJsonOutputPath);
57928
+ }
57929
+ } catch {}
57930
+ }
57732
57931
  const proc = bunSpawn(command, {
57733
57932
  stdout: "pipe",
57734
57933
  stderr: "pipe",
@@ -57749,13 +57948,37 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
57749
57948
  output += (output ? `
57750
57949
  ` : "") + stderrResult.text;
57751
57950
  }
57951
+ if (vitestJsonOutputPath) {
57952
+ try {
57953
+ if (fs29.existsSync(vitestJsonOutputPath)) {
57954
+ const vitestJsonOutput = fs29.readFileSync(vitestJsonOutputPath, "utf-8");
57955
+ if (vitestJsonOutput.trim().length > 0) {
57956
+ output += (output ? `
57957
+ ` : "") + vitestJsonOutput;
57958
+ }
57959
+ }
57960
+ } catch {}
57961
+ }
57752
57962
  if (stdoutResult.truncated || stderrResult.truncated) {
57753
57963
  output += `
57754
57964
  ... (output truncated at stream read limit)`;
57755
57965
  }
57756
57966
  const useDispatchParse = process.env.SWARM_LANG_BACKEND !== "legacy";
57757
57967
  const parsed = useDispatchParse ? await parseTestOutputViaDispatch(framework, output, cwd) ?? parseTestOutput2(framework, output) : parseTestOutput2(framework, output);
57758
- const { totals, coveragePercent } = parsed;
57968
+ const parsedTestCases = parseFrameworkJsonTestResults(framework, output);
57969
+ const totals = { ...parsed.totals };
57970
+ const { coveragePercent } = parsed;
57971
+ if (totals.total === 0 && parsedTestCases.length > 0) {
57972
+ for (const entry of parsedTestCases) {
57973
+ if (entry.result === "pass")
57974
+ totals.passed++;
57975
+ else if (entry.result === "fail")
57976
+ totals.failed++;
57977
+ else
57978
+ totals.skipped++;
57979
+ }
57980
+ totals.total = parsedTestCases.length;
57981
+ }
57759
57982
  const isTimeout = exitCode === -1;
57760
57983
  const testPassed = exitCode === 0 && totals.failed === 0;
57761
57984
  if (testPassed) {
@@ -57768,7 +57991,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
57768
57991
  duration_ms,
57769
57992
  totals,
57770
57993
  rawOutput: output,
57771
- outcome: "pass"
57994
+ outcome: "pass",
57995
+ testCases: parsedTestCases
57772
57996
  };
57773
57997
  if (coveragePercent !== undefined) {
57774
57998
  result.coveragePercent = coveragePercent;
@@ -57790,7 +58014,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
57790
58014
  rawOutput: output,
57791
58015
  error: isTimeout ? `Tests timed out after ${timeout_ms}ms` : `Tests failed with ${totals.failed} failures`,
57792
58016
  message: isTimeout ? `${framework} tests timed out after ${timeout_ms}ms` : `${framework} tests failed (${totals.failed}/${totals.total} failed)`,
57793
- outcome: isTimeout ? "error" : "regression"
58017
+ outcome: isTimeout ? "error" : "regression",
58018
+ testCases: parsedTestCases
57794
58019
  };
57795
58020
  if (coveragePercent !== undefined) {
57796
58021
  result.coveragePercent = coveragePercent;
@@ -57811,25 +58036,78 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
57811
58036
  };
57812
58037
  }
57813
58038
  }
57814
- function recordAndAnalyzeResults(result, testFiles, workingDir, sourceFiles) {
58039
+ function normalizeHistoryTestFile(testFile, workingDir) {
58040
+ const normalized = testFile.replace(/\\/g, "/");
58041
+ if (!path46.isAbsolute(testFile))
58042
+ return normalized;
58043
+ const relative9 = path46.relative(workingDir, testFile);
58044
+ if (relative9.startsWith("..") || path46.isAbsolute(relative9)) {
58045
+ return normalized;
58046
+ }
58047
+ return relative9.replace(/\\/g, "/");
58048
+ }
58049
+ function combineAggregateResult(current, next) {
58050
+ if (current === "fail" || next === "fail")
58051
+ return "fail";
58052
+ if (current === "pass" || next === "pass")
58053
+ return "pass";
58054
+ return "skip";
58055
+ }
58056
+ function recordAndAnalyzeResults(result, testFiles, workingDir, sourceFiles, parsedTestCases) {
57815
58057
  if (!result.totals || result.totals.total === 0)
57816
58058
  return;
57817
58059
  const now = new Date().toISOString();
57818
58060
  const changedFiles = (sourceFiles && sourceFiles.length > 0 ? sourceFiles : testFiles).map((f) => f.replace(/\\/g, "/"));
57819
- for (const testFile of testFiles) {
58061
+ const aggregateResultsByFile = new Map;
58062
+ const validParsedCases = parsedTestCases?.filter((parsedCase) => parsedCase.testFile.length > 0 && parsedCase.testName.length > 0) ?? [];
58063
+ for (const parsedCase of validParsedCases) {
58064
+ const normalizedTestFile = normalizeHistoryTestFile(parsedCase.testFile, workingDir);
57820
58065
  try {
57821
58066
  appendTestRun({
57822
58067
  timestamp: now,
57823
58068
  taskId: "auto",
57824
- testFile: testFile.replace(/\\/g, "/"),
57825
- testName: "(aggregate)",
57826
- result: result.success ? "pass" : "fail",
58069
+ testFile: normalizedTestFile,
58070
+ testName: parsedCase.testName,
58071
+ result: parsedCase.result,
58072
+ durationMs: parsedCase.durationMs,
58073
+ errorMessage: parsedCase.errorMessage,
58074
+ stackPrefix: parsedCase.stackPrefix,
58075
+ changedFiles
58076
+ }, workingDir);
58077
+ } catch {}
58078
+ aggregateResultsByFile.set(normalizedTestFile, combineAggregateResult(aggregateResultsByFile.get(normalizedTestFile), parsedCase.result));
58079
+ }
58080
+ if (aggregateResultsByFile.size === 0) {
58081
+ const aggregateResult = result.success ? "pass" : "fail";
58082
+ for (const testFile of testFiles) {
58083
+ aggregateResultsByFile.set(testFile.replace(/\\/g, "/"), aggregateResult);
58084
+ }
58085
+ }
58086
+ for (const [testFile, aggregateResult] of aggregateResultsByFile) {
58087
+ try {
58088
+ appendTestRun({
58089
+ timestamp: now,
58090
+ taskId: "auto",
58091
+ testFile,
58092
+ testName: AGGREGATE_TEST_NAME,
58093
+ result: aggregateResult,
57827
58094
  durationMs: result.duration_ms || 0,
57828
58095
  changedFiles
57829
58096
  }, workingDir);
57830
58097
  } catch {}
57831
58098
  }
57832
58099
  }
58100
+ function selectHistoryForAnalysis(history) {
58101
+ const filesWithIndividualRecords = new Set;
58102
+ for (const record3 of history) {
58103
+ if (record3.testName !== AGGREGATE_TEST_NAME) {
58104
+ filesWithIndividualRecords.add(record3.testFile.toLowerCase());
58105
+ }
58106
+ }
58107
+ if (filesWithIndividualRecords.size === 0)
58108
+ return history;
58109
+ return history.filter((record3) => record3.testName !== AGGREGATE_TEST_NAME || !filesWithIndividualRecords.has(record3.testFile.toLowerCase()));
58110
+ }
57833
58111
  function analyzeFailures(workingDir) {
57834
58112
  const report = {
57835
58113
  flakyTests: [],
@@ -57837,7 +58115,7 @@ function analyzeFailures(workingDir) {
57837
58115
  quarantinedFailures: []
57838
58116
  };
57839
58117
  try {
57840
- const history = getAllHistory(workingDir);
58118
+ const history = selectHistoryForAnalysis(getAllHistory(workingDir));
57841
58119
  if (history.length === 0)
57842
58120
  return report;
57843
58121
  report.flakyTests = detectFlakyTests(history);
@@ -57858,7 +58136,7 @@ function analyzeFailures(workingDir) {
57858
58136
  } catch {}
57859
58137
  return report;
57860
58138
  }
57861
- var MAX_OUTPUT_BYTES3 = 512000, MAX_COMMAND_LENGTH2 = 500, DEFAULT_TIMEOUT_MS = 60000, MAX_TIMEOUT_MS = 300000, MAX_SAFE_TEST_FILES = 50, MAX_SAFE_SOURCE_FILES = 1, POWERSHELL_METACHARACTERS, DISPATCH_FRAMEWORK_MAP, COMPOUND_TEST_EXTENSIONS, TEST_DIRECTORY_NAMES, SOURCE_EXTENSIONS, SKIP_DIRECTORIES, test_runner;
58139
+ var MAX_OUTPUT_BYTES3 = 512000, MAX_COMMAND_LENGTH2 = 500, DEFAULT_TIMEOUT_MS = 60000, MAX_TIMEOUT_MS = 300000, MAX_SAFE_TEST_FILES = 50, MAX_SAFE_SOURCE_FILES = 1, AGGREGATE_TEST_NAME = "(aggregate)", VITEST_JSON_OUTPUT_RELATIVE_PATH = ".swarm/cache/test-runner-vitest.json", POWERSHELL_METACHARACTERS, DISPATCH_FRAMEWORK_MAP, COMPOUND_TEST_EXTENSIONS, TEST_DIRECTORY_NAMES, SOURCE_EXTENSIONS, SKIP_DIRECTORIES, test_runner;
57862
58140
  var init_test_runner = __esm(() => {
57863
58141
  init_zod();
57864
58142
  init_discovery();
@@ -58304,7 +58582,7 @@ var init_test_runner = __esm(() => {
58304
58582
  return JSON.stringify(errorResult, null, 2);
58305
58583
  }
58306
58584
  const result = await runTests(framework, effectiveScope, testFiles, coverage, timeout_ms, workingDir);
58307
- recordAndAnalyzeResults(result, testFiles, workingDir, _files.length > 0 ? _files : undefined);
58585
+ recordAndAnalyzeResults(result, testFiles, workingDir, _files.length > 0 ? _files : undefined, result.testCases);
58308
58586
  let historyReport;
58309
58587
  if (!result.success && result.totals && result.totals.failed > 0) {
58310
58588
  historyReport = analyzeFailures(workingDir);
@@ -59981,7 +60259,7 @@ var init_reset_session = __esm(() => {
59981
60259
  });
59982
60260
 
59983
60261
  // src/summaries/manager.ts
59984
- import { mkdirSync as mkdirSync14, readdirSync as readdirSync13, renameSync as renameSync11, rmSync as rmSync4, statSync as statSync12 } from "node:fs";
60262
+ import { mkdirSync as mkdirSync15, readdirSync as readdirSync13, renameSync as renameSync11, rmSync as rmSync4, statSync as statSync12 } from "node:fs";
59985
60263
  import * as path50 from "node:path";
59986
60264
  function sanitizeSummaryId(id) {
59987
60265
  if (!id || id.length === 0) {
@@ -60027,7 +60305,7 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
60027
60305
  originalBytes: Buffer.byteLength(fullOutput, "utf8")
60028
60306
  };
60029
60307
  const entryJson = JSON.stringify(entry);
60030
- mkdirSync14(summaryDir, { recursive: true });
60308
+ mkdirSync15(summaryDir, { recursive: true });
60031
60309
  const tempPath = path50.join(summaryDir, `${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);
60032
60310
  try {
60033
60311
  await bunWrite(tempPath, entryJson);
@@ -67144,12 +67422,12 @@ __export(exports_evidence_summary_integration, {
67144
67422
  createEvidenceSummaryIntegration: () => createEvidenceSummaryIntegration,
67145
67423
  EvidenceSummaryIntegration: () => EvidenceSummaryIntegration
67146
67424
  });
67147
- import { existsSync as existsSync32, mkdirSync as mkdirSync16, writeFileSync as writeFileSync8 } from "node:fs";
67425
+ import { existsSync as existsSync32, mkdirSync as mkdirSync17, writeFileSync as writeFileSync8 } from "node:fs";
67148
67426
  import * as path57 from "node:path";
67149
67427
  function persistSummary(projectDir, artifact, filename) {
67150
67428
  const swarmPath = path57.join(projectDir, ".swarm");
67151
67429
  if (!existsSync32(swarmPath)) {
67152
- mkdirSync16(swarmPath, { recursive: true });
67430
+ mkdirSync17(swarmPath, { recursive: true });
67153
67431
  }
67154
67432
  const artifactPath = path57.join(swarmPath, filename);
67155
67433
  const content = JSON.stringify(artifact, null, 2);
@@ -72079,7 +72357,7 @@ var init_curator_drift = __esm(() => {
72079
72357
  var exports_project_context = {};
72080
72358
  __export(exports_project_context, {
72081
72359
  buildProjectContext: () => buildProjectContext,
72082
- _internals: () => _internals55,
72360
+ _internals: () => _internals56,
72083
72361
  LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
72084
72362
  });
72085
72363
  import * as fs112 from "node:fs";
@@ -72163,7 +72441,7 @@ function selectLintCommand(backend, directory) {
72163
72441
  return null;
72164
72442
  }
72165
72443
  async function buildProjectContext(directory) {
72166
- const backend = await _internals55.pickBackend(directory);
72444
+ const backend = await _internals56.pickBackend(directory);
72167
72445
  if (!backend)
72168
72446
  return null;
72169
72447
  const ctx = emptyProjectContext();
@@ -72194,16 +72472,16 @@ async function buildProjectContext(directory) {
72194
72472
  if (backend.prompts.reviewerChecklist.length > 0) {
72195
72473
  ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
72196
72474
  }
72197
- const profiles = _internals55.pickedProfiles(directory);
72475
+ const profiles = _internals56.pickedProfiles(directory);
72198
72476
  if (profiles.length > 1) {
72199
72477
  ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
72200
72478
  }
72201
72479
  return ctx;
72202
72480
  }
72203
- var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals55;
72481
+ var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals56;
72204
72482
  var init_project_context = __esm(() => {
72205
72483
  init_dispatch();
72206
- _internals55 = {
72484
+ _internals56 = {
72207
72485
  pickBackend,
72208
72486
  pickedProfiles
72209
72487
  };
@@ -73096,7 +73374,7 @@ init_state();
73096
73374
  init_utils();
73097
73375
  init_bun_compat();
73098
73376
  init_utils2();
73099
- import { renameSync as renameSync13, unlinkSync as unlinkSync10 } from "node:fs";
73377
+ import { renameSync as renameSync13, unlinkSync as unlinkSync11 } from "node:fs";
73100
73378
  import * as nodePath2 from "node:path";
73101
73379
  function createAgentActivityHooks(config3, directory) {
73102
73380
  if (config3.hooks?.agent_activity === false) {
@@ -73174,7 +73452,7 @@ async function doFlush(directory) {
73174
73452
  renameSync13(tempPath, path62);
73175
73453
  } catch (writeError) {
73176
73454
  try {
73177
- unlinkSync10(tempPath);
73455
+ unlinkSync11(tempPath);
73178
73456
  } catch {}
73179
73457
  throw writeError;
73180
73458
  }
@@ -87150,7 +87428,7 @@ ${body2}`);
87150
87428
  import {
87151
87429
  appendFileSync as appendFileSync12,
87152
87430
  existsSync as existsSync53,
87153
- mkdirSync as mkdirSync24,
87431
+ mkdirSync as mkdirSync25,
87154
87432
  readFileSync as readFileSync44,
87155
87433
  writeFileSync as writeFileSync17
87156
87434
  } from "node:fs";
@@ -87189,7 +87467,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
87189
87467
  throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
87190
87468
  }
87191
87469
  const dir = join83(workingDir, EVIDENCE_DIR2);
87192
- mkdirSync24(dir, { recursive: true });
87470
+ mkdirSync25(dir, { recursive: true });
87193
87471
  const filePath = join83(dir, `${synthesis.taskId}.json`);
87194
87472
  const existingRoot = Object.create(null);
87195
87473
  if (existsSync53(filePath)) {
@@ -87225,7 +87503,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
87225
87503
  writeFileSync17(filePath, JSON.stringify(updated, null, 2));
87226
87504
  try {
87227
87505
  const councilDir = join83(workingDir, ".swarm", "council");
87228
- mkdirSync24(councilDir, { recursive: true });
87506
+ mkdirSync25(councilDir, { recursive: true });
87229
87507
  const auditLine = JSON.stringify({
87230
87508
  round: synthesis.roundNumber,
87231
87509
  verdict: synthesis.overallVerdict,
@@ -87554,12 +87832,12 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
87554
87832
  }
87555
87833
 
87556
87834
  // src/council/criteria-store.ts
87557
- import { existsSync as existsSync54, mkdirSync as mkdirSync25, readFileSync as readFileSync45, writeFileSync as writeFileSync18 } from "node:fs";
87835
+ import { existsSync as existsSync54, mkdirSync as mkdirSync26, readFileSync as readFileSync45, writeFileSync as writeFileSync18 } from "node:fs";
87558
87836
  import { join as join84 } from "node:path";
87559
87837
  var COUNCIL_DIR = ".swarm/council";
87560
87838
  function writeCriteria(workingDir, taskId, criteria) {
87561
87839
  const dir = join84(workingDir, COUNCIL_DIR);
87562
- mkdirSync25(dir, { recursive: true });
87840
+ mkdirSync26(dir, { recursive: true });
87563
87841
  const payload = {
87564
87842
  taskId,
87565
87843
  criteria,
@@ -89413,12 +89691,12 @@ function extractFilename(code, language, index) {
89413
89691
  `);
89414
89692
  const ext = EXT_MAP[language.toLowerCase()] ?? ".txt";
89415
89693
  if (lines.length > 0) {
89416
- const firstLine = lines[0].trim();
89417
- const filenameMatch = firstLine.match(/^[#/]+\s*filename[:\s]+(\S+\.\w+)/i);
89694
+ const firstLine2 = lines[0].trim();
89695
+ const filenameMatch = firstLine2.match(/^[#/]+\s*filename[:\s]+(\S+\.\w+)/i);
89418
89696
  if (filenameMatch) {
89419
89697
  return filenameMatch[1];
89420
89698
  }
89421
- const bareMatch = firstLine.match(/^[#/]+\s*(\w+\.\w+)\s*$/);
89699
+ const bareMatch = firstLine2.match(/^[#/]+\s*(\w+\.\w+)\s*$/);
89422
89700
  if (bareMatch) {
89423
89701
  return bareMatch[1];
89424
89702
  }
@@ -90429,7 +90707,7 @@ function formatHiveEntry(entry) {
90429
90707
  lines.push(` Category: ${entry.category}`);
90430
90708
  lines.push(` Status: ${entry.status}`);
90431
90709
  lines.push(` Confidence: ${entry.confidence.toFixed(2)}`);
90432
- lines.push(` Encounter Score: ${entry.encounter_score.toFixed(2)}`);
90710
+ lines.push(` Encounter Score: ${entry.encounter_score?.toFixed(2) ?? "N/A"}`);
90433
90711
  lines.push(` Source Project: ${entry.source_project}`);
90434
90712
  lines.push(` Confirmed by: ${entry.confirmed_by.length} project(s)`);
90435
90713
  return lines.join(`
@@ -99907,10 +100185,10 @@ init_zod();
99907
100185
  init_loader();
99908
100186
  import {
99909
100187
  existsSync as existsSync72,
99910
- mkdirSync as mkdirSync31,
100188
+ mkdirSync as mkdirSync32,
99911
100189
  readFileSync as readFileSync63,
99912
100190
  renameSync as renameSync20,
99913
- unlinkSync as unlinkSync15,
100191
+ unlinkSync as unlinkSync16,
99914
100192
  writeFileSync as writeFileSync25
99915
100193
  } from "node:fs";
99916
100194
  import path124 from "node:path";
@@ -100106,7 +100384,7 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
100106
100384
  }
100107
100385
  function writePhaseCouncilEvidence(workingDir, synthesis) {
100108
100386
  const evidenceDir = path124.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
100109
- mkdirSync31(evidenceDir, { recursive: true });
100387
+ mkdirSync32(evidenceDir, { recursive: true });
100110
100388
  const evidenceFile = path124.join(evidenceDir, "phase-council.json");
100111
100389
  const evidenceBundle = {
100112
100390
  entries: [
@@ -100144,7 +100422,7 @@ function writePhaseCouncilEvidence(workingDir, synthesis) {
100144
100422
  renameSync20(tempFile, evidenceFile);
100145
100423
  } finally {
100146
100424
  if (existsSync72(tempFile)) {
100147
- unlinkSync15(tempFile);
100425
+ unlinkSync16(tempFile);
100148
100426
  }
100149
100427
  }
100150
100428
  }
@@ -102351,7 +102629,7 @@ import * as path131 from "node:path";
102351
102629
 
102352
102630
  // src/mutation/engine.ts
102353
102631
  import { spawnSync as spawnSync3 } from "node:child_process";
102354
- import { unlinkSync as unlinkSync16, writeFileSync as writeFileSync26 } from "node:fs";
102632
+ import { unlinkSync as unlinkSync17, writeFileSync as writeFileSync26 } from "node:fs";
102355
102633
  import * as path130 from "node:path";
102356
102634
 
102357
102635
  // src/mutation/equivalence.ts
@@ -102483,6 +102761,12 @@ async function batchCheckEquivalence(patches, llmJudge) {
102483
102761
  var MUTATION_TIMEOUT_MS = 30000;
102484
102762
  var TOTAL_BUDGET_MS = 300000;
102485
102763
  var GIT_APPLY_TIMEOUT_MS = 5000;
102764
+ var _internals51 = {
102765
+ executeMutation,
102766
+ computeReport,
102767
+ executeMutationSuite,
102768
+ spawnSync: spawnSync3
102769
+ };
102486
102770
  async function executeMutation(patch, testCommand, _testFiles, workingDir) {
102487
102771
  const startTime = Date.now();
102488
102772
  let outcome = "survived";
@@ -102509,7 +102793,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
102509
102793
  };
102510
102794
  }
102511
102795
  try {
102512
- const applyResult = spawnSync3("git", ["apply", "--", patchFile], {
102796
+ const applyResult = _internals51.spawnSync("git", ["apply", "--", patchFile], {
102513
102797
  cwd: workingDir,
102514
102798
  timeout: GIT_APPLY_TIMEOUT_MS,
102515
102799
  stdio: "pipe"
@@ -102538,7 +102822,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
102538
102822
  }
102539
102823
  let testPassed = false;
102540
102824
  try {
102541
- const spawnResult = spawnSync3(testCommand[0], testCommand.slice(1), {
102825
+ const spawnResult = _internals51.spawnSync(testCommand[0], testCommand.slice(1), {
102542
102826
  cwd: workingDir,
102543
102827
  timeout: MUTATION_TIMEOUT_MS,
102544
102828
  stdio: "pipe"
@@ -102571,7 +102855,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
102571
102855
  } finally {
102572
102856
  if (patchFile) {
102573
102857
  try {
102574
- const revertResult = spawnSync3("git", ["apply", "-R", "--", patchFile], {
102858
+ const revertResult = _internals51.spawnSync("git", ["apply", "-R", "--", patchFile], {
102575
102859
  cwd: workingDir,
102576
102860
  timeout: GIT_APPLY_TIMEOUT_MS,
102577
102861
  stdio: "pipe"
@@ -102590,7 +102874,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
102590
102874
  revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
102591
102875
  }
102592
102876
  try {
102593
- unlinkSync16(patchFile);
102877
+ unlinkSync17(patchFile);
102594
102878
  } catch (_unlinkErr) {}
102595
102879
  }
102596
102880
  }
@@ -102764,7 +103048,7 @@ async function executeMutationSuite(patches, testCommand, testFiles, workingDir,
102764
103048
  }
102765
103049
 
102766
103050
  // src/mutation/gate.ts
102767
- var _internals51 = {
103051
+ var _internals52 = {
102768
103052
  evaluateMutationGate,
102769
103053
  buildTestImprovementPrompt,
102770
103054
  buildMessage
@@ -102785,8 +103069,8 @@ function evaluateMutationGate(report, passThreshold = PASS_THRESHOLD, warnThresh
102785
103069
  } else {
102786
103070
  verdict = "fail";
102787
103071
  }
102788
- const testImprovementPrompt = _internals51.buildTestImprovementPrompt(report, passThreshold, verdict);
102789
- const message = _internals51.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
103072
+ const testImprovementPrompt = _internals52.buildTestImprovementPrompt(report, passThreshold, verdict);
103073
+ const message = _internals52.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
102790
103074
  return {
102791
103075
  verdict,
102792
103076
  killRate: report.killRate,
@@ -103403,7 +103687,7 @@ import * as path135 from "node:path";
103403
103687
  init_bun_compat();
103404
103688
  import * as fs104 from "node:fs";
103405
103689
  import * as path134 from "node:path";
103406
- var _internals52 = { bunSpawn };
103690
+ var _internals53 = { bunSpawn };
103407
103691
  var _swarmGitExcludedChecked = false;
103408
103692
  function fileCoversSwarm(content) {
103409
103693
  for (const rawLine of content.split(`
@@ -103436,7 +103720,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
103436
103720
  checkIgnoreExitCode
103437
103721
  ] = await Promise.all([
103438
103722
  (async () => {
103439
- const proc = _internals52.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
103723
+ const proc = _internals53.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
103440
103724
  try {
103441
103725
  return await Promise.all([proc.exited, proc.stdout.text()]);
103442
103726
  } finally {
@@ -103446,7 +103730,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
103446
103730
  }
103447
103731
  })(),
103448
103732
  (async () => {
103449
- const proc = _internals52.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
103733
+ const proc = _internals53.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
103450
103734
  try {
103451
103735
  return await Promise.all([proc.exited, proc.stdout.text()]);
103452
103736
  } finally {
@@ -103456,7 +103740,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
103456
103740
  }
103457
103741
  })(),
103458
103742
  (async () => {
103459
- const proc = _internals52.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
103743
+ const proc = _internals53.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
103460
103744
  try {
103461
103745
  return await proc.exited;
103462
103746
  } finally {
@@ -103495,7 +103779,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
103495
103779
  }
103496
103780
  } catch {}
103497
103781
  }
103498
- const trackedProc = _internals52.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
103782
+ const trackedProc = _internals53.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
103499
103783
  let trackedExitCode;
103500
103784
  let trackedOutput;
103501
103785
  try {
@@ -103520,7 +103804,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
103520
103804
  }
103521
103805
 
103522
103806
  // src/hooks/diff-scope.ts
103523
- var _internals53 = { bunSpawn };
103807
+ var _internals54 = { bunSpawn };
103524
103808
  function getDeclaredScope(taskId, directory) {
103525
103809
  try {
103526
103810
  const planPath = path135.join(directory, ".swarm", "plan.json");
@@ -103555,7 +103839,7 @@ var GIT_DIFF_SPAWN_OPTIONS = {
103555
103839
  };
103556
103840
  async function getChangedFiles(directory) {
103557
103841
  try {
103558
- const proc = _internals53.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
103842
+ const proc = _internals54.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
103559
103843
  cwd: directory,
103560
103844
  ...GIT_DIFF_SPAWN_OPTIONS
103561
103845
  });
@@ -103572,7 +103856,7 @@ async function getChangedFiles(directory) {
103572
103856
  return stdout.trim().split(`
103573
103857
  `).map((f) => f.trim()).filter((f) => f.length > 0);
103574
103858
  }
103575
- const proc2 = _internals53.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
103859
+ const proc2 = _internals54.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
103576
103860
  cwd: directory,
103577
103861
  ...GIT_DIFF_SPAWN_OPTIONS
103578
103862
  });
@@ -103630,7 +103914,7 @@ init_telemetry();
103630
103914
  init_file_locks();
103631
103915
  import * as fs106 from "node:fs";
103632
103916
  import * as path136 from "node:path";
103633
- var _internals54 = {
103917
+ var _internals55 = {
103634
103918
  listActiveLocks,
103635
103919
  verifyLeanTurboTaskCompletion
103636
103920
  };
@@ -103772,7 +104056,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
103772
104056
  }
103773
104057
  };
103774
104058
  }
103775
- const activeLocks = _internals54.listActiveLocks(directory);
104059
+ const activeLocks = _internals55.listActiveLocks(directory);
103776
104060
  const laneLocks = activeLocks.filter((lock) => lock.laneId === lane.laneId);
103777
104061
  if (laneLocks.length > 0) {
103778
104062
  return {