kairn-cli 2.7.1 → 2.7.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.js CHANGED
@@ -2904,6 +2904,14 @@ async function renderAffectedFiles(ir, targetDir, touchedCategories) {
2904
2904
  if (touchedCategories.has("agents")) {
2905
2905
  await deleteOrphanedFiles(targetDir, "agents", fileMap);
2906
2906
  }
2907
+ if (touchedCategories.has("mcp") && !fileMap.has(".mcp.json")) {
2908
+ await fs22.unlink(path22.join(targetDir, ".mcp.json")).catch(() => {
2909
+ });
2910
+ }
2911
+ if (touchedCategories.has("settings") && !fileMap.has("settings.json")) {
2912
+ await fs22.unlink(path22.join(targetDir, "settings.json")).catch(() => {
2913
+ });
2914
+ }
2907
2915
  }
2908
2916
  function getFileCategory(relativePath) {
2909
2917
  if (relativePath === "CLAUDE.md") return "claude_md";
@@ -3488,7 +3496,7 @@ async function evolve(workspacePath, tasks, kairnConfig, evolveConfig, onProgres
3488
3496
  }
3489
3497
  if (useThompson) {
3490
3498
  const scoreMap = {};
3491
- for (const [taskId, score] of Object.entries(results)) {
3499
+ for (const [taskId, score] of Object.entries(evalResults)) {
3492
3500
  scoreMap[taskId] = score.score ?? (score.pass ? 100 : 0);
3493
3501
  }
3494
3502
  beliefs = updateBeliefs(beliefs, scoreMap);
@@ -8719,7 +8727,81 @@ async function listFilesRecursive(dir) {
8719
8727
  await walk(dir);
8720
8728
  return results;
8721
8729
  }
8722
- async function applyEvolution(workspacePath, projectRoot, targetIteration) {
8730
+ async function findBestPBTHarness(workspacePath) {
8731
+ const branchesDir = path27.join(workspacePath, "branches");
8732
+ let branchEntries;
8733
+ try {
8734
+ branchEntries = await fs27.readdir(branchesDir);
8735
+ } catch {
8736
+ return null;
8737
+ }
8738
+ let bestScore = -Infinity;
8739
+ let bestPath = "";
8740
+ let bestLabel = "";
8741
+ for (const branchId of branchEntries) {
8742
+ const branchPath = path27.join(branchesDir, branchId);
8743
+ const branchIterations = await listIterations(branchPath);
8744
+ if (branchIterations.length === 0) continue;
8745
+ const bestIter = await findBestIteration(branchPath, branchIterations);
8746
+ const log = await loadIterationLog(branchPath, bestIter);
8747
+ const score = log?.score ?? 0;
8748
+ if (score > bestScore) {
8749
+ bestScore = score;
8750
+ bestPath = path27.join(branchPath, "iterations", bestIter.toString(), "harness");
8751
+ bestLabel = `branch ${branchId}, iteration ${bestIter} (${score.toFixed(1)}%)`;
8752
+ }
8753
+ }
8754
+ const synthesisHarness = path27.join(workspacePath, "synthesis", "harness");
8755
+ try {
8756
+ await fs27.access(synthesisHarness);
8757
+ const synthesisLog = await loadIterationLog(workspacePath, 999);
8758
+ const synthScore = synthesisLog?.score ?? 0;
8759
+ if (synthScore > bestScore) {
8760
+ bestScore = synthScore;
8761
+ bestPath = synthesisHarness;
8762
+ bestLabel = `Meta-Principal synthesis (${synthScore.toFixed(1)}%)`;
8763
+ }
8764
+ } catch {
8765
+ }
8766
+ if (!bestPath) return null;
8767
+ return { harnessPath: bestPath, label: bestLabel };
8768
+ }
8769
+ async function applyEvolution(workspacePath, projectRoot, targetIteration, pbt) {
8770
+ if (pbt) {
8771
+ const pbtResult = await findBestPBTHarness(workspacePath);
8772
+ if (!pbtResult) {
8773
+ throw new Error("No PBT results found. Run `kairn evolve pbt` first.");
8774
+ }
8775
+ const claudeDir2 = path27.join(projectRoot, ".claude");
8776
+ const diffPreview2 = await generateDiff2(claudeDir2, pbtResult.harnessPath);
8777
+ const currentFiles2 = await listFilesRecursive(claudeDir2);
8778
+ const targetFiles2 = await listFilesRecursive(pbtResult.harnessPath);
8779
+ const allPaths2 = /* @__PURE__ */ new Set([...currentFiles2, ...targetFiles2]);
8780
+ const filesChanged2 = [];
8781
+ for (const filePath of allPaths2) {
8782
+ const currentContent = await fs27.readFile(path27.join(claudeDir2, filePath), "utf-8").catch(() => null);
8783
+ const targetContent = await fs27.readFile(path27.join(pbtResult.harnessPath, filePath), "utf-8").catch(() => null);
8784
+ if (currentContent !== targetContent) {
8785
+ filesChanged2.push(filePath);
8786
+ }
8787
+ }
8788
+ await fs27.rm(claudeDir2, { recursive: true, force: true });
8789
+ await copyDir(pbtResult.harnessPath, claudeDir2);
8790
+ const harnessMcpJson2 = path27.join(pbtResult.harnessPath, ".mcp.json");
8791
+ const projectMcpJson2 = path27.join(projectRoot, ".mcp.json");
8792
+ try {
8793
+ await fs27.access(harnessMcpJson2);
8794
+ await fs27.copyFile(harnessMcpJson2, projectMcpJson2);
8795
+ if (!filesChanged2.includes(".mcp.json")) filesChanged2.push(".mcp.json");
8796
+ } catch {
8797
+ }
8798
+ return {
8799
+ iteration: -1,
8800
+ // signals PBT source
8801
+ filesChanged: filesChanged2,
8802
+ diffPreview: diffPreview2
8803
+ };
8804
+ }
8723
8805
  const iterations = await listIterations(workspacePath);
8724
8806
  if (iterations.length === 0) {
8725
8807
  throw new Error("No iterations found in workspace. Run `kairn evolve run` first.");
@@ -9290,7 +9372,7 @@ evolveCommand.command("pbt").description("Run Population-Based Training with par
9290
9372
  process.exit(1);
9291
9373
  }
9292
9374
  });
9293
- evolveCommand.command("apply").description("Apply the best evolved harness to your project").option("--iter <n>", "Apply a specific iteration instead of the best").option("--force", "Apply even if git working tree is dirty").option("--no-commit", "Skip automatic git commit after applying").action(async (options) => {
9375
+ evolveCommand.command("apply").description("Apply the best evolved harness to your project").option("--iter <n>", "Apply a specific iteration instead of the best").option("--pbt", "Apply best PBT result (branch winner or synthesis)").option("--force", "Apply even if git working tree is dirty").option("--no-commit", "Skip automatic git commit after applying").action(async (options) => {
9294
9376
  try {
9295
9377
  const projectRoot = process.cwd();
9296
9378
  const workspace = path30.join(projectRoot, ".kairn-evolve");
@@ -9309,7 +9391,7 @@ evolveCommand.command("apply").description("Apply the best evolved harness to yo
9309
9391
  process.exit(1);
9310
9392
  }
9311
9393
  }
9312
- const result = await applyEvolution(workspace, projectRoot, targetIteration);
9394
+ const result = await applyEvolution(workspace, projectRoot, targetIteration, options.pbt);
9313
9395
  if (result.diffPreview) {
9314
9396
  console.log(ui.section("Changes"));
9315
9397
  for (const line of result.diffPreview.split("\n")) {