majlis 0.6.1 → 0.6.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.
Files changed (2) hide show
  1. package/dist/cli.js +368 -203
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -435,6 +435,10 @@ var init_format = __esm({
435
435
  // src/commands/init.ts
436
436
  var init_exports = {};
437
437
  __export(init_exports, {
438
+ AGENT_DEFINITIONS: () => AGENT_DEFINITIONS,
439
+ CLAUDE_MD_SECTION: () => CLAUDE_MD_SECTION,
440
+ HOOKS_CONFIG: () => HOOKS_CONFIG,
441
+ SLASH_COMMANDS: () => SLASH_COMMANDS,
438
442
  init: () => init
439
443
  });
440
444
  async function init(_args) {
@@ -1435,6 +1439,193 @@ Run \`majlis status\` for live experiment state and cycle position.
1435
1439
  }
1436
1440
  });
1437
1441
 
1442
+ // src/git.ts
1443
+ function autoCommit(root, message) {
1444
+ try {
1445
+ (0, import_node_child_process.execSync)("git add docs/ .majlis/scripts/ 2>/dev/null; true", {
1446
+ cwd: root,
1447
+ encoding: "utf-8",
1448
+ stdio: ["pipe", "pipe", "pipe"]
1449
+ });
1450
+ const diff = (0, import_node_child_process.execSync)("git diff --cached --stat", {
1451
+ cwd: root,
1452
+ encoding: "utf-8",
1453
+ stdio: ["pipe", "pipe", "pipe"]
1454
+ }).trim();
1455
+ if (!diff) return;
1456
+ (0, import_node_child_process.execSync)(`git commit -m ${JSON.stringify(`[majlis] ${message}`)}`, {
1457
+ cwd: root,
1458
+ encoding: "utf-8",
1459
+ stdio: ["pipe", "pipe", "pipe"]
1460
+ });
1461
+ info(`Auto-committed: ${message}`);
1462
+ } catch {
1463
+ }
1464
+ }
1465
+ var import_node_child_process;
1466
+ var init_git = __esm({
1467
+ "src/git.ts"() {
1468
+ "use strict";
1469
+ import_node_child_process = require("child_process");
1470
+ init_format();
1471
+ }
1472
+ });
1473
+
1474
+ // src/commands/upgrade.ts
1475
+ var upgrade_exports = {};
1476
+ __export(upgrade_exports, {
1477
+ upgrade: () => upgrade
1478
+ });
1479
+ async function upgrade(_args) {
1480
+ const root = findProjectRoot();
1481
+ if (!root) throw new Error("Not in a Majlis project. Run `majlis init` first.");
1482
+ header(`Upgrading to Majlis v${VERSION}`);
1483
+ let updated = 0;
1484
+ let added = 0;
1485
+ const majlisAgentsDir = path3.join(root, ".majlis", "agents");
1486
+ const claudeAgentsDir = path3.join(root, ".claude", "agents");
1487
+ mkdirSafe2(majlisAgentsDir);
1488
+ mkdirSafe2(claudeAgentsDir);
1489
+ for (const [name, content] of Object.entries(AGENT_DEFINITIONS)) {
1490
+ const majlisPath = path3.join(majlisAgentsDir, `${name}.md`);
1491
+ const claudePath = path3.join(claudeAgentsDir, `${name}.md`);
1492
+ const existed = fs3.existsSync(majlisPath);
1493
+ const current = existed ? fs3.readFileSync(majlisPath, "utf-8") : "";
1494
+ if (current !== content) {
1495
+ fs3.writeFileSync(majlisPath, content);
1496
+ fs3.writeFileSync(claudePath, content);
1497
+ if (existed) {
1498
+ info(` Updated agent: ${name}`);
1499
+ updated++;
1500
+ } else {
1501
+ info(` Added agent: ${name}`);
1502
+ added++;
1503
+ }
1504
+ }
1505
+ }
1506
+ try {
1507
+ for (const file of fs3.readdirSync(majlisAgentsDir)) {
1508
+ const name = file.replace(".md", "");
1509
+ if (!AGENT_DEFINITIONS[name]) {
1510
+ fs3.unlinkSync(path3.join(majlisAgentsDir, file));
1511
+ try {
1512
+ fs3.unlinkSync(path3.join(claudeAgentsDir, file));
1513
+ } catch {
1514
+ }
1515
+ info(` Removed deprecated agent: ${name}`);
1516
+ updated++;
1517
+ }
1518
+ }
1519
+ } catch {
1520
+ }
1521
+ const commandsDir = path3.join(root, ".claude", "commands");
1522
+ mkdirSafe2(commandsDir);
1523
+ for (const [name, cmd] of Object.entries(SLASH_COMMANDS)) {
1524
+ const cmdPath = path3.join(commandsDir, `${name}.md`);
1525
+ const content = `---
1526
+ description: ${cmd.description}
1527
+ ---
1528
+ ${cmd.body}
1529
+ `;
1530
+ const existed = fs3.existsSync(cmdPath);
1531
+ const current = existed ? fs3.readFileSync(cmdPath, "utf-8") : "";
1532
+ if (current !== content) {
1533
+ fs3.writeFileSync(cmdPath, content);
1534
+ if (existed) {
1535
+ updated++;
1536
+ } else {
1537
+ added++;
1538
+ }
1539
+ info(` ${existed ? "Updated" : "Added"} command: /${name}`);
1540
+ }
1541
+ }
1542
+ const settingsPath = path3.join(root, ".claude", "settings.json");
1543
+ try {
1544
+ if (fs3.existsSync(settingsPath)) {
1545
+ const existing = JSON.parse(fs3.readFileSync(settingsPath, "utf-8"));
1546
+ const before = JSON.stringify(existing.hooks);
1547
+ existing.hooks = { ...existing.hooks, ...HOOKS_CONFIG.hooks };
1548
+ if (JSON.stringify(existing.hooks) !== before) {
1549
+ fs3.writeFileSync(settingsPath, JSON.stringify(existing, null, 2));
1550
+ info(" Updated hooks in .claude/settings.json");
1551
+ updated++;
1552
+ }
1553
+ } else {
1554
+ fs3.writeFileSync(settingsPath, JSON.stringify(HOOKS_CONFIG, null, 2));
1555
+ info(" Created .claude/settings.json");
1556
+ added++;
1557
+ }
1558
+ } catch {
1559
+ warn(" Could not update .claude/settings.json");
1560
+ }
1561
+ const docDirs = [
1562
+ "inbox",
1563
+ "experiments",
1564
+ "decisions",
1565
+ "classification",
1566
+ "doubts",
1567
+ "challenges",
1568
+ "verification",
1569
+ "reframes",
1570
+ "rihla",
1571
+ "synthesis",
1572
+ "diagnosis"
1573
+ ];
1574
+ for (const dir of docDirs) {
1575
+ const dirPath = path3.join(root, "docs", dir);
1576
+ if (!fs3.existsSync(dirPath)) {
1577
+ fs3.mkdirSync(dirPath, { recursive: true });
1578
+ info(` Added docs/${dir}/`);
1579
+ added++;
1580
+ }
1581
+ }
1582
+ const claudeMdPath = path3.join(root, "CLAUDE.md");
1583
+ if (fs3.existsSync(claudeMdPath)) {
1584
+ const existing = fs3.readFileSync(claudeMdPath, "utf-8");
1585
+ if (existing.includes("## Majlis Protocol")) {
1586
+ const replaced = existing.replace(
1587
+ /## Majlis Protocol[\s\S]*?(?=\n## [^M]|\n## $|$)/,
1588
+ CLAUDE_MD_SECTION.trim()
1589
+ );
1590
+ if (replaced !== existing) {
1591
+ fs3.writeFileSync(claudeMdPath, replaced);
1592
+ info(" Updated Majlis Protocol in CLAUDE.md");
1593
+ updated++;
1594
+ }
1595
+ } else {
1596
+ fs3.writeFileSync(claudeMdPath, existing + "\n" + CLAUDE_MD_SECTION);
1597
+ info(" Appended Majlis Protocol to CLAUDE.md");
1598
+ added++;
1599
+ }
1600
+ }
1601
+ if (updated === 0 && added === 0) {
1602
+ success(`Already up to date (v${VERSION}).`);
1603
+ } else {
1604
+ autoCommit(root, `upgrade to v${VERSION}`);
1605
+ success(`Upgraded to v${VERSION}: ${updated} updated, ${added} added.`);
1606
+ }
1607
+ }
1608
+ function mkdirSafe2(dir) {
1609
+ if (!fs3.existsSync(dir)) {
1610
+ fs3.mkdirSync(dir, { recursive: true });
1611
+ }
1612
+ }
1613
+ var fs3, path3, VERSION;
1614
+ var init_upgrade = __esm({
1615
+ "src/commands/upgrade.ts"() {
1616
+ "use strict";
1617
+ fs3 = __toESM(require("fs"));
1618
+ path3 = __toESM(require("path"));
1619
+ init_connection();
1620
+ init_init();
1621
+ init_git();
1622
+ init_format();
1623
+ VERSION = JSON.parse(
1624
+ fs3.readFileSync(path3.join(__dirname, "..", "package.json"), "utf-8")
1625
+ ).version;
1626
+ }
1627
+ });
1628
+
1438
1629
  // src/db/queries.ts
1439
1630
  function createExperiment(db, slug, branch, hypothesis, subType, classificationRef) {
1440
1631
  const stmt = db.prepare(`
@@ -1869,13 +2060,13 @@ var init_queries = __esm({
1869
2060
  // src/config.ts
1870
2061
  function loadConfig(projectRoot) {
1871
2062
  if (_cachedConfig && _cachedRoot === projectRoot) return _cachedConfig;
1872
- const configPath = path3.join(projectRoot, ".majlis", "config.json");
1873
- if (!fs3.existsSync(configPath)) {
2063
+ const configPath = path4.join(projectRoot, ".majlis", "config.json");
2064
+ if (!fs4.existsSync(configPath)) {
1874
2065
  _cachedConfig = { ...DEFAULT_CONFIG2 };
1875
2066
  _cachedRoot = projectRoot;
1876
2067
  return _cachedConfig;
1877
2068
  }
1878
- const loaded = JSON.parse(fs3.readFileSync(configPath, "utf-8"));
2069
+ const loaded = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
1879
2070
  _cachedConfig = {
1880
2071
  ...DEFAULT_CONFIG2,
1881
2072
  ...loaded,
@@ -1889,7 +2080,7 @@ function loadConfig(projectRoot) {
1889
2080
  }
1890
2081
  function readFileOrEmpty(filePath) {
1891
2082
  try {
1892
- return fs3.readFileSync(filePath, "utf-8");
2083
+ return fs4.readFileSync(filePath, "utf-8");
1893
2084
  } catch {
1894
2085
  return "";
1895
2086
  }
@@ -1904,21 +2095,21 @@ function truncateContext(content, limit) {
1904
2095
  return content.slice(0, limit) + "\n[TRUNCATED]";
1905
2096
  }
1906
2097
  function readLatestDiagnosis(projectRoot) {
1907
- const dir = path3.join(projectRoot, "docs", "diagnosis");
2098
+ const dir = path4.join(projectRoot, "docs", "diagnosis");
1908
2099
  try {
1909
- const files = fs3.readdirSync(dir).filter((f) => f.startsWith("diagnosis-") && f.endsWith(".md")).sort().reverse();
2100
+ const files = fs4.readdirSync(dir).filter((f) => f.startsWith("diagnosis-") && f.endsWith(".md")).sort().reverse();
1910
2101
  if (files.length === 0) return "";
1911
- return fs3.readFileSync(path3.join(dir, files[0]), "utf-8");
2102
+ return fs4.readFileSync(path4.join(dir, files[0]), "utf-8");
1912
2103
  } catch {
1913
2104
  return "";
1914
2105
  }
1915
2106
  }
1916
- var fs3, path3, DEFAULT_CONFIG2, _cachedConfig, _cachedRoot, CONTEXT_LIMITS;
2107
+ var fs4, path4, DEFAULT_CONFIG2, _cachedConfig, _cachedRoot, CONTEXT_LIMITS;
1917
2108
  var init_config = __esm({
1918
2109
  "src/config.ts"() {
1919
2110
  "use strict";
1920
- fs3 = __toESM(require("fs"));
1921
- path3 = __toESM(require("path"));
2111
+ fs4 = __toESM(require("fs"));
2112
+ path4 = __toESM(require("path"));
1922
2113
  DEFAULT_CONFIG2 = {
1923
2114
  project: { name: "", description: "", objective: "" },
1924
2115
  metrics: { command: "", fixtures: [], tracked: {} },
@@ -2247,11 +2438,11 @@ var init_parse = __esm({
2247
2438
  // src/agents/spawn.ts
2248
2439
  function loadAgentDefinition(role, projectRoot) {
2249
2440
  const root = projectRoot ?? findProjectRoot() ?? process.cwd();
2250
- const filePath = path4.join(root, ".majlis", "agents", `${role}.md`);
2251
- if (!fs4.existsSync(filePath)) {
2441
+ const filePath = path5.join(root, ".majlis", "agents", `${role}.md`);
2442
+ if (!fs5.existsSync(filePath)) {
2252
2443
  throw new Error(`Agent definition not found: ${filePath}`);
2253
2444
  }
2254
- const content = fs4.readFileSync(filePath, "utf-8");
2445
+ const content = fs5.readFileSync(filePath, "utf-8");
2255
2446
  const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
2256
2447
  if (!frontmatterMatch) {
2257
2448
  throw new Error(`Invalid agent definition (missing YAML frontmatter): ${filePath}`);
@@ -2459,15 +2650,15 @@ async function spawnRecovery(role, partialOutput, context, projectRoot) {
2459
2650
  const root = projectRoot ?? findProjectRoot() ?? process.cwd();
2460
2651
  const expSlug = context.experiment?.slug ?? "unknown";
2461
2652
  console.log(`[recovery] Cleaning up after truncated ${role} for ${expSlug}...`);
2462
- const expDocPath = path4.join(
2653
+ const expDocPath = path5.join(
2463
2654
  root,
2464
2655
  "docs",
2465
2656
  "experiments",
2466
2657
  `${String(context.experiment?.id ?? 0).padStart(3, "0")}-${expSlug}.md`
2467
2658
  );
2468
- const templatePath = path4.join(root, "docs", "experiments", "_TEMPLATE.md");
2469
- const template = fs4.existsSync(templatePath) ? fs4.readFileSync(templatePath, "utf-8") : "";
2470
- const currentDoc = fs4.existsSync(expDocPath) ? fs4.readFileSync(expDocPath, "utf-8") : "";
2659
+ const templatePath = path5.join(root, "docs", "experiments", "_TEMPLATE.md");
2660
+ const template = fs5.existsSync(templatePath) ? fs5.readFileSync(templatePath, "utf-8") : "";
2661
+ const currentDoc = fs5.existsSync(expDocPath) ? fs5.readFileSync(expDocPath, "utf-8") : "";
2471
2662
  const prompt = `The ${role} agent was truncated (hit max turns) while working on experiment "${expSlug}".
2472
2663
 
2473
2664
  Here is the partial agent output (reasoning + tool calls):
@@ -2630,23 +2821,23 @@ function writeArtifact(role, context, markdown, projectRoot) {
2630
2821
  const dir = dirMap[role];
2631
2822
  if (!dir) return null;
2632
2823
  if (role === "builder" || role === "compressor" || role === "diagnostician") return null;
2633
- const fullDir = path4.join(projectRoot, dir);
2634
- if (!fs4.existsSync(fullDir)) {
2635
- fs4.mkdirSync(fullDir, { recursive: true });
2824
+ const fullDir = path5.join(projectRoot, dir);
2825
+ if (!fs5.existsSync(fullDir)) {
2826
+ fs5.mkdirSync(fullDir, { recursive: true });
2636
2827
  }
2637
2828
  const expSlug = context.experiment?.slug ?? "general";
2638
2829
  const nextNum = String(context.experiment?.id ?? 1).padStart(3, "0");
2639
2830
  const filename = `${nextNum}-${role}-${expSlug}.md`;
2640
- const target = path4.join(fullDir, filename);
2641
- fs4.writeFileSync(target, markdown);
2831
+ const target = path5.join(fullDir, filename);
2832
+ fs5.writeFileSync(target, markdown);
2642
2833
  return target;
2643
2834
  }
2644
- var fs4, path4, import_claude_agent_sdk2, ROLE_MAX_TURNS, CHECKPOINT_INTERVAL, DIM2, RESET2, CYAN2;
2835
+ var fs5, path5, import_claude_agent_sdk2, ROLE_MAX_TURNS, CHECKPOINT_INTERVAL, DIM2, RESET2, CYAN2;
2645
2836
  var init_spawn = __esm({
2646
2837
  "src/agents/spawn.ts"() {
2647
2838
  "use strict";
2648
- fs4 = __toESM(require("fs"));
2649
- path4 = __toESM(require("path"));
2839
+ fs5 = __toESM(require("fs"));
2840
+ path5 = __toESM(require("path"));
2650
2841
  import_claude_agent_sdk2 = require("@anthropic-ai/claude-agent-sdk");
2651
2842
  init_parse();
2652
2843
  init_connection();
@@ -2675,38 +2866,6 @@ var init_spawn = __esm({
2675
2866
  }
2676
2867
  });
2677
2868
 
2678
- // src/git.ts
2679
- function autoCommit(root, message) {
2680
- try {
2681
- (0, import_node_child_process.execSync)("git add docs/ .majlis/scripts/ 2>/dev/null; true", {
2682
- cwd: root,
2683
- encoding: "utf-8",
2684
- stdio: ["pipe", "pipe", "pipe"]
2685
- });
2686
- const diff = (0, import_node_child_process.execSync)("git diff --cached --stat", {
2687
- cwd: root,
2688
- encoding: "utf-8",
2689
- stdio: ["pipe", "pipe", "pipe"]
2690
- }).trim();
2691
- if (!diff) return;
2692
- (0, import_node_child_process.execSync)(`git commit -m ${JSON.stringify(`[majlis] ${message}`)}`, {
2693
- cwd: root,
2694
- encoding: "utf-8",
2695
- stdio: ["pipe", "pipe", "pipe"]
2696
- });
2697
- info(`Auto-committed: ${message}`);
2698
- } catch {
2699
- }
2700
- }
2701
- var import_node_child_process;
2702
- var init_git = __esm({
2703
- "src/git.ts"() {
2704
- "use strict";
2705
- import_node_child_process = require("child_process");
2706
- init_format();
2707
- }
2708
- });
2709
-
2710
2869
  // src/metrics.ts
2711
2870
  function compareMetrics(db, experimentId, config) {
2712
2871
  const before = getMetricsByExperimentAndPhase(db, experimentId, "before");
@@ -2926,13 +3085,13 @@ async function newExperiment(args) {
2926
3085
  const subType = getFlagValue(args, "--sub-type") ?? null;
2927
3086
  const exp = createExperiment(db, slug, branch, hypothesis, subType, null);
2928
3087
  success(`Created experiment #${exp.id}: ${exp.slug}`);
2929
- const docsDir = path5.join(root, "docs", "experiments");
2930
- const templatePath = path5.join(docsDir, "_TEMPLATE.md");
2931
- if (fs5.existsSync(templatePath)) {
2932
- const template = fs5.readFileSync(templatePath, "utf-8");
3088
+ const docsDir = path6.join(root, "docs", "experiments");
3089
+ const templatePath = path6.join(docsDir, "_TEMPLATE.md");
3090
+ if (fs6.existsSync(templatePath)) {
3091
+ const template = fs6.readFileSync(templatePath, "utf-8");
2933
3092
  const logContent = template.replace(/\{\{title\}\}/g, hypothesis).replace(/\{\{hypothesis\}\}/g, hypothesis).replace(/\{\{branch\}\}/g, branch).replace(/\{\{status\}\}/g, "classified").replace(/\{\{sub_type\}\}/g, subType ?? "unclassified").replace(/\{\{date\}\}/g, (/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
2934
- const logPath = path5.join(docsDir, `${paddedNum}-${slug}.md`);
2935
- fs5.writeFileSync(logPath, logContent);
3093
+ const logPath = path6.join(docsDir, `${paddedNum}-${slug}.md`);
3094
+ fs6.writeFileSync(logPath, logContent);
2936
3095
  info(`Created experiment log: docs/experiments/${paddedNum}-${slug}.md`);
2937
3096
  }
2938
3097
  autoCommit(root, `new: ${slug}`);
@@ -2988,12 +3147,12 @@ async function revert(args) {
2988
3147
  }
2989
3148
  info(`Experiment ${exp.slug} reverted to dead-end. Reason: ${reason}`);
2990
3149
  }
2991
- var fs5, path5, import_node_child_process3;
3150
+ var fs6, path6, import_node_child_process3;
2992
3151
  var init_experiment = __esm({
2993
3152
  "src/commands/experiment.ts"() {
2994
3153
  "use strict";
2995
- fs5 = __toESM(require("fs"));
2996
- path5 = __toESM(require("path"));
3154
+ fs6 = __toESM(require("fs"));
3155
+ path6 = __toESM(require("path"));
2997
3156
  import_node_child_process3 = require("child_process");
2998
3157
  init_connection();
2999
3158
  init_queries();
@@ -3135,12 +3294,12 @@ function queryDeadEnds(db, args, isJson) {
3135
3294
  console.log(table(["ID", "Sub-Type", "Approach", "Constraint"], rows));
3136
3295
  }
3137
3296
  function queryFragility(root, isJson) {
3138
- const fragPath = path6.join(root, "docs", "synthesis", "fragility.md");
3139
- if (!fs6.existsSync(fragPath)) {
3297
+ const fragPath = path7.join(root, "docs", "synthesis", "fragility.md");
3298
+ if (!fs7.existsSync(fragPath)) {
3140
3299
  info("No fragility map found.");
3141
3300
  return;
3142
3301
  }
3143
- const content = fs6.readFileSync(fragPath, "utf-8");
3302
+ const content = fs7.readFileSync(fragPath, "utf-8");
3144
3303
  if (isJson) {
3145
3304
  console.log(JSON.stringify({ content }, null, 2));
3146
3305
  return;
@@ -3196,7 +3355,7 @@ function queryCircuitBreakers(db, root, isJson) {
3196
3355
  function checkCommit(db) {
3197
3356
  let stdinData = "";
3198
3357
  try {
3199
- stdinData = fs6.readFileSync(0, "utf-8");
3358
+ stdinData = fs7.readFileSync(0, "utf-8");
3200
3359
  } catch {
3201
3360
  }
3202
3361
  if (stdinData) {
@@ -3221,12 +3380,12 @@ function checkCommit(db) {
3221
3380
  process.exit(1);
3222
3381
  }
3223
3382
  }
3224
- var fs6, path6;
3383
+ var fs7, path7;
3225
3384
  var init_query = __esm({
3226
3385
  "src/commands/query.ts"() {
3227
3386
  "use strict";
3228
- fs6 = __toESM(require("fs"));
3229
- path6 = __toESM(require("path"));
3387
+ fs7 = __toESM(require("fs"));
3388
+ path7 = __toESM(require("path"));
3230
3389
  init_connection();
3231
3390
  init_queries();
3232
3391
  init_config();
@@ -3518,23 +3677,23 @@ function gitRevert(branch, cwd) {
3518
3677
  }
3519
3678
  }
3520
3679
  function appendToFragilityMap(projectRoot, expSlug, gaps) {
3521
- const fragPath = path7.join(projectRoot, "docs", "synthesis", "fragility.md");
3680
+ const fragPath = path8.join(projectRoot, "docs", "synthesis", "fragility.md");
3522
3681
  let content = "";
3523
- if (fs7.existsSync(fragPath)) {
3524
- content = fs7.readFileSync(fragPath, "utf-8");
3682
+ if (fs8.existsSync(fragPath)) {
3683
+ content = fs8.readFileSync(fragPath, "utf-8");
3525
3684
  }
3526
3685
  const entry = `
3527
3686
  ## From experiment: ${expSlug}
3528
3687
  ${gaps}
3529
3688
  `;
3530
- fs7.writeFileSync(fragPath, content + entry);
3689
+ fs8.writeFileSync(fragPath, content + entry);
3531
3690
  }
3532
- var fs7, path7, import_node_child_process4;
3691
+ var fs8, path8, import_node_child_process4;
3533
3692
  var init_resolve = __esm({
3534
3693
  "src/resolve.ts"() {
3535
3694
  "use strict";
3536
- fs7 = __toESM(require("fs"));
3537
- path7 = __toESM(require("path"));
3695
+ fs8 = __toESM(require("fs"));
3696
+ path8 = __toESM(require("path"));
3538
3697
  init_types2();
3539
3698
  init_queries();
3540
3699
  init_spawn();
@@ -3606,8 +3765,8 @@ async function runResolve(db, exp, root) {
3606
3765
  }
3607
3766
  async function doGate(db, exp, root) {
3608
3767
  transition(exp.status, "gated" /* GATED */);
3609
- const synthesis = truncateContext(readFileOrEmpty(path8.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3610
- const fragility = truncateContext(readFileOrEmpty(path8.join(root, "docs", "synthesis", "fragility.md")), CONTEXT_LIMITS.fragility);
3768
+ const synthesis = truncateContext(readFileOrEmpty(path9.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3769
+ const fragility = truncateContext(readFileOrEmpty(path9.join(root, "docs", "synthesis", "fragility.md")), CONTEXT_LIMITS.fragility);
3611
3770
  const structuralDeadEnds = exp.sub_type ? listStructuralDeadEndsBySubType(db, exp.sub_type) : listStructuralDeadEnds(db);
3612
3771
  const result = await spawnAgent("gatekeeper", {
3613
3772
  experiment: {
@@ -3651,8 +3810,8 @@ async function doBuild(db, exp, root) {
3651
3810
  transition(exp.status, "building" /* BUILDING */);
3652
3811
  const deadEnds = exp.sub_type ? listDeadEndsBySubType(db, exp.sub_type) : listAllDeadEnds(db);
3653
3812
  const builderGuidance = getBuilderGuidance(db, exp.id);
3654
- const fragility = truncateContext(readFileOrEmpty(path8.join(root, "docs", "synthesis", "fragility.md")), CONTEXT_LIMITS.fragility);
3655
- const synthesis = truncateContext(readFileOrEmpty(path8.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3813
+ const fragility = truncateContext(readFileOrEmpty(path9.join(root, "docs", "synthesis", "fragility.md")), CONTEXT_LIMITS.fragility);
3814
+ const synthesis = truncateContext(readFileOrEmpty(path9.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3656
3815
  const confirmedDoubts = getConfirmedDoubts(db, exp.id);
3657
3816
  const config = loadConfig(root);
3658
3817
  const existingBaseline = getMetricsByExperimentAndPhase(db, exp.id, "before");
@@ -3747,7 +3906,7 @@ async function doChallenge(db, exp, root) {
3747
3906
  } catch {
3748
3907
  }
3749
3908
  if (gitDiff.length > 8e3) gitDiff = gitDiff.slice(0, 8e3) + "\n[DIFF TRUNCATED]";
3750
- const synthesis = truncateContext(readFileOrEmpty(path8.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3909
+ const synthesis = truncateContext(readFileOrEmpty(path9.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3751
3910
  let taskPrompt = `Construct adversarial test cases for experiment ${exp.slug}: ${exp.hypothesis}`;
3752
3911
  if (gitDiff) {
3753
3912
  taskPrompt += `
@@ -3780,9 +3939,9 @@ ${gitDiff}
3780
3939
  async function doDoubt(db, exp, root) {
3781
3940
  transition(exp.status, "doubted" /* DOUBTED */);
3782
3941
  const paddedNum = String(exp.id).padStart(3, "0");
3783
- const expDocPath = path8.join(root, "docs", "experiments", `${paddedNum}-${exp.slug}.md`);
3942
+ const expDocPath = path9.join(root, "docs", "experiments", `${paddedNum}-${exp.slug}.md`);
3784
3943
  const experimentDoc = truncateContext(readFileOrEmpty(expDocPath), CONTEXT_LIMITS.experimentDoc);
3785
- const synthesis = truncateContext(readFileOrEmpty(path8.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3944
+ const synthesis = truncateContext(readFileOrEmpty(path9.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3786
3945
  const deadEnds = exp.sub_type ? listDeadEndsBySubType(db, exp.sub_type) : listAllDeadEnds(db);
3787
3946
  let taskPrompt = `Doubt the work in experiment ${exp.slug}: ${exp.hypothesis}. Produce a doubt document with evidence for each doubt.`;
3788
3947
  if (experimentDoc) {
@@ -3821,8 +3980,8 @@ ${experimentDoc}
3821
3980
  }
3822
3981
  async function doScout(db, exp, root) {
3823
3982
  transition(exp.status, "scouted" /* SCOUTED */);
3824
- const synthesis = truncateContext(readFileOrEmpty(path8.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3825
- const fragility = truncateContext(readFileOrEmpty(path8.join(root, "docs", "synthesis", "fragility.md")), CONTEXT_LIMITS.fragility);
3983
+ const synthesis = truncateContext(readFileOrEmpty(path9.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
3984
+ const fragility = truncateContext(readFileOrEmpty(path9.join(root, "docs", "synthesis", "fragility.md")), CONTEXT_LIMITS.fragility);
3826
3985
  const deadEnds = exp.sub_type ? listDeadEndsBySubType(db, exp.sub_type) : listAllDeadEnds(db);
3827
3986
  const deadEndsSummary = deadEnds.map(
3828
3987
  (d) => `- [${d.category ?? "structural"}] ${d.approach}: ${d.why_failed}`
@@ -3869,12 +4028,12 @@ ${fragility}`;
3869
4028
  async function doVerify(db, exp, root) {
3870
4029
  transition(exp.status, "verifying" /* VERIFYING */);
3871
4030
  const doubts = getDoubtsByExperiment(db, exp.id);
3872
- const challengeDir = path8.join(root, "docs", "challenges");
4031
+ const challengeDir = path9.join(root, "docs", "challenges");
3873
4032
  let challenges = "";
3874
- if (fs8.existsSync(challengeDir)) {
3875
- const files = fs8.readdirSync(challengeDir).filter((f) => f.includes(exp.slug) && f.endsWith(".md"));
4033
+ if (fs9.existsSync(challengeDir)) {
4034
+ const files = fs9.readdirSync(challengeDir).filter((f) => f.includes(exp.slug) && f.endsWith(".md"));
3876
4035
  for (const f of files) {
3877
- challenges += fs8.readFileSync(path8.join(challengeDir, f), "utf-8") + "\n\n";
4036
+ challenges += fs9.readFileSync(path9.join(challengeDir, f), "utf-8") + "\n\n";
3878
4037
  }
3879
4038
  }
3880
4039
  const beforeMetrics = getMetricsByExperimentAndPhase(db, exp.id, "before");
@@ -3942,14 +4101,14 @@ async function doVerify(db, exp, root) {
3942
4101
  success(`Verification complete for ${exp.slug}. Run \`majlis resolve\` next.`);
3943
4102
  }
3944
4103
  async function doCompress(db, root) {
3945
- const synthesisPath = path8.join(root, "docs", "synthesis", "current.md");
3946
- const sizeBefore = fs8.existsSync(synthesisPath) ? fs8.statSync(synthesisPath).size : 0;
4104
+ const synthesisPath = path9.join(root, "docs", "synthesis", "current.md");
4105
+ const sizeBefore = fs9.existsSync(synthesisPath) ? fs9.statSync(synthesisPath).size : 0;
3947
4106
  const sessionCount = getSessionsSinceCompression(db);
3948
4107
  const dbExport = exportForCompressor(db);
3949
4108
  const result = await spawnAgent("compressor", {
3950
4109
  taskPrompt: "## Structured Data (CANONICAL \u2014 from SQLite database)\nThe database export below is the source of truth. docs/ files are agent artifacts that may contain stale or incorrect information. Cross-reference everything against this data.\n\n" + dbExport + "\n\n## Your Task\nRead ALL experiments, decisions, doubts, challenges, verification reports, reframes, and recent diffs. Cross-reference for contradictions, redundancies, and patterns. REWRITE docs/synthesis/current.md \u2014 shorter and denser. Update docs/synthesis/fragility.md with current weak areas. Update docs/synthesis/dead-ends.md with structural constraints from rejected experiments."
3951
4110
  }, root);
3952
- const sizeAfter = fs8.existsSync(synthesisPath) ? fs8.statSync(synthesisPath).size : 0;
4111
+ const sizeAfter = fs9.existsSync(synthesisPath) ? fs9.statSync(synthesisPath).size : 0;
3953
4112
  recordCompression(db, sessionCount, sizeBefore, sizeAfter);
3954
4113
  autoCommit(root, "compress: update synthesis");
3955
4114
  success(`Compression complete. Synthesis: ${sizeBefore}B \u2192 ${sizeAfter}B`);
@@ -4041,12 +4200,12 @@ function ingestStructuredOutput(db, experimentId, structured) {
4041
4200
  info(`Ingested ${structured.findings.length} finding(s)`);
4042
4201
  }
4043
4202
  }
4044
- var fs8, path8, import_node_child_process5;
4203
+ var fs9, path9, import_node_child_process5;
4045
4204
  var init_cycle = __esm({
4046
4205
  "src/commands/cycle.ts"() {
4047
4206
  "use strict";
4048
- fs8 = __toESM(require("fs"));
4049
- path8 = __toESM(require("path"));
4207
+ fs9 = __toESM(require("fs"));
4208
+ path9 = __toESM(require("path"));
4050
4209
  import_node_child_process5 = require("child_process");
4051
4210
  init_connection();
4052
4211
  init_queries();
@@ -4074,10 +4233,10 @@ async function classify(args) {
4074
4233
  if (!domain) {
4075
4234
  throw new Error('Usage: majlis classify "domain description"');
4076
4235
  }
4077
- const synthesisPath = path9.join(root, "docs", "synthesis", "current.md");
4078
- const synthesis = fs9.existsSync(synthesisPath) ? fs9.readFileSync(synthesisPath, "utf-8") : "";
4079
- const deadEndsPath = path9.join(root, "docs", "synthesis", "dead-ends.md");
4080
- const deadEnds = fs9.existsSync(deadEndsPath) ? fs9.readFileSync(deadEndsPath, "utf-8") : "";
4236
+ const synthesisPath = path10.join(root, "docs", "synthesis", "current.md");
4237
+ const synthesis = fs10.existsSync(synthesisPath) ? fs10.readFileSync(synthesisPath, "utf-8") : "";
4238
+ const deadEndsPath = path10.join(root, "docs", "synthesis", "dead-ends.md");
4239
+ const deadEnds = fs10.existsSync(deadEndsPath) ? fs10.readFileSync(deadEndsPath, "utf-8") : "";
4081
4240
  info(`Classifying problem domain: ${domain}`);
4082
4241
  const result = await spawnAgent("builder", {
4083
4242
  synthesis,
@@ -4096,22 +4255,22 @@ Write the classification to docs/classification/ following the template.`
4096
4255
  async function reframe(args) {
4097
4256
  const root = findProjectRoot();
4098
4257
  if (!root) throw new Error("Not in a Majlis project. Run `majlis init` first.");
4099
- const classificationDir = path9.join(root, "docs", "classification");
4258
+ const classificationDir = path10.join(root, "docs", "classification");
4100
4259
  let classificationContent = "";
4101
- if (fs9.existsSync(classificationDir)) {
4102
- const files = fs9.readdirSync(classificationDir).filter((f) => f.endsWith(".md") && !f.startsWith("_"));
4260
+ if (fs10.existsSync(classificationDir)) {
4261
+ const files = fs10.readdirSync(classificationDir).filter((f) => f.endsWith(".md") && !f.startsWith("_"));
4103
4262
  for (const f of files) {
4104
- classificationContent += fs9.readFileSync(path9.join(classificationDir, f), "utf-8") + "\n\n";
4263
+ classificationContent += fs10.readFileSync(path10.join(classificationDir, f), "utf-8") + "\n\n";
4105
4264
  }
4106
4265
  }
4107
- const synthesisPath = path9.join(root, "docs", "synthesis", "current.md");
4108
- const synthesis = fs9.existsSync(synthesisPath) ? fs9.readFileSync(synthesisPath, "utf-8") : "";
4109
- const deadEndsPath = path9.join(root, "docs", "synthesis", "dead-ends.md");
4110
- const deadEnds = fs9.existsSync(deadEndsPath) ? fs9.readFileSync(deadEndsPath, "utf-8") : "";
4111
- const configPath = path9.join(root, ".majlis", "config.json");
4266
+ const synthesisPath = path10.join(root, "docs", "synthesis", "current.md");
4267
+ const synthesis = fs10.existsSync(synthesisPath) ? fs10.readFileSync(synthesisPath, "utf-8") : "";
4268
+ const deadEndsPath = path10.join(root, "docs", "synthesis", "dead-ends.md");
4269
+ const deadEnds = fs10.existsSync(deadEndsPath) ? fs10.readFileSync(deadEndsPath, "utf-8") : "";
4270
+ const configPath = path10.join(root, ".majlis", "config.json");
4112
4271
  let problemStatement = "";
4113
- if (fs9.existsSync(configPath)) {
4114
- const config = JSON.parse(fs9.readFileSync(configPath, "utf-8"));
4272
+ if (fs10.existsSync(configPath)) {
4273
+ const config = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
4115
4274
  problemStatement = `${config.project?.description ?? ""}
4116
4275
  Objective: ${config.project?.objective ?? ""}`;
4117
4276
  }
@@ -4136,12 +4295,12 @@ Write to docs/reframes/.`
4136
4295
  autoCommit(root, `reframe: ${target.slice(0, 60)}`);
4137
4296
  success("Reframe complete. Check docs/reframes/ for the output.");
4138
4297
  }
4139
- var fs9, path9;
4298
+ var fs10, path10;
4140
4299
  var init_classify = __esm({
4141
4300
  "src/commands/classify.ts"() {
4142
4301
  "use strict";
4143
- fs9 = __toESM(require("fs"));
4144
- path9 = __toESM(require("path"));
4302
+ fs10 = __toESM(require("fs"));
4303
+ path10 = __toESM(require("path"));
4145
4304
  init_connection();
4146
4305
  init_spawn();
4147
4306
  init_git();
@@ -4163,15 +4322,15 @@ async function audit(args) {
4163
4322
  const experiments = listAllExperiments(db);
4164
4323
  const deadEnds = listAllDeadEnds(db);
4165
4324
  const circuitBreakers = getAllCircuitBreakerStates(db, config.cycle.circuit_breaker_threshold);
4166
- const classificationDir = path10.join(root, "docs", "classification");
4325
+ const classificationDir = path11.join(root, "docs", "classification");
4167
4326
  let classification = "";
4168
- if (fs10.existsSync(classificationDir)) {
4169
- const files = fs10.readdirSync(classificationDir).filter((f) => f.endsWith(".md") && !f.startsWith("_"));
4327
+ if (fs11.existsSync(classificationDir)) {
4328
+ const files = fs11.readdirSync(classificationDir).filter((f) => f.endsWith(".md") && !f.startsWith("_"));
4170
4329
  for (const f of files) {
4171
- classification += fs10.readFileSync(path10.join(classificationDir, f), "utf-8") + "\n\n";
4330
+ classification += fs11.readFileSync(path11.join(classificationDir, f), "utf-8") + "\n\n";
4172
4331
  }
4173
4332
  }
4174
- const synthesis = readFileOrEmpty(path10.join(root, "docs", "synthesis", "current.md"));
4333
+ const synthesis = readFileOrEmpty(path11.join(root, "docs", "synthesis", "current.md"));
4175
4334
  header("Maqasid Check \u2014 Purpose Audit");
4176
4335
  const trippedBreakers = circuitBreakers.filter((cb) => cb.tripped);
4177
4336
  if (trippedBreakers.length > 0) {
@@ -4215,12 +4374,12 @@ Output: either "classification confirmed \u2014 continue" or "re-classify from X
4215
4374
  }, root);
4216
4375
  success("Purpose audit complete. Review the output above.");
4217
4376
  }
4218
- var fs10, path10;
4377
+ var fs11, path11;
4219
4378
  var init_audit = __esm({
4220
4379
  "src/commands/audit.ts"() {
4221
4380
  "use strict";
4222
- fs10 = __toESM(require("fs"));
4223
- path10 = __toESM(require("path"));
4381
+ fs11 = __toESM(require("fs"));
4382
+ path11 = __toESM(require("path"));
4224
4383
  init_connection();
4225
4384
  init_queries();
4226
4385
  init_spawn();
@@ -4505,9 +4664,9 @@ async function run(args) {
4505
4664
  info("Run `majlis status` to see final state.");
4506
4665
  }
4507
4666
  async function deriveNextHypothesis(goal, root, db) {
4508
- const synthesis = truncateContext(readFileOrEmpty(path11.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
4509
- const fragility = truncateContext(readFileOrEmpty(path11.join(root, "docs", "synthesis", "fragility.md")), CONTEXT_LIMITS.fragility);
4510
- const deadEndsDoc = truncateContext(readFileOrEmpty(path11.join(root, "docs", "synthesis", "dead-ends.md")), CONTEXT_LIMITS.deadEnds);
4667
+ const synthesis = truncateContext(readFileOrEmpty(path12.join(root, "docs", "synthesis", "current.md")), CONTEXT_LIMITS.synthesis);
4668
+ const fragility = truncateContext(readFileOrEmpty(path12.join(root, "docs", "synthesis", "fragility.md")), CONTEXT_LIMITS.fragility);
4669
+ const deadEndsDoc = truncateContext(readFileOrEmpty(path12.join(root, "docs", "synthesis", "dead-ends.md")), CONTEXT_LIMITS.deadEnds);
4511
4670
  const diagnosis = truncateContext(readLatestDiagnosis(root), CONTEXT_LIMITS.synthesis);
4512
4671
  const deadEnds = listAllDeadEnds(db);
4513
4672
  const config = loadConfig(root);
@@ -4625,23 +4784,23 @@ async function createNewExperiment(db, root, hypothesis) {
4625
4784
  const exp = createExperiment(db, finalSlug, branch, hypothesis, null, null);
4626
4785
  updateExperimentStatus(db, exp.id, "reframed");
4627
4786
  exp.status = "reframed";
4628
- const docsDir = path11.join(root, "docs", "experiments");
4629
- const templatePath = path11.join(docsDir, "_TEMPLATE.md");
4630
- if (fs11.existsSync(templatePath)) {
4631
- const template = fs11.readFileSync(templatePath, "utf-8");
4787
+ const docsDir = path12.join(root, "docs", "experiments");
4788
+ const templatePath = path12.join(docsDir, "_TEMPLATE.md");
4789
+ if (fs12.existsSync(templatePath)) {
4790
+ const template = fs12.readFileSync(templatePath, "utf-8");
4632
4791
  const logContent = template.replace(/\{\{title\}\}/g, hypothesis).replace(/\{\{hypothesis\}\}/g, hypothesis).replace(/\{\{branch\}\}/g, branch).replace(/\{\{status\}\}/g, "classified").replace(/\{\{sub_type\}\}/g, "unclassified").replace(/\{\{date\}\}/g, (/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
4633
- const logPath = path11.join(docsDir, `${paddedNum}-${finalSlug}.md`);
4634
- fs11.writeFileSync(logPath, logContent);
4792
+ const logPath = path12.join(docsDir, `${paddedNum}-${finalSlug}.md`);
4793
+ fs12.writeFileSync(logPath, logContent);
4635
4794
  info(`Created experiment log: docs/experiments/${paddedNum}-${finalSlug}.md`);
4636
4795
  }
4637
4796
  return exp;
4638
4797
  }
4639
- var fs11, path11, import_node_child_process6;
4798
+ var fs12, path12, import_node_child_process6;
4640
4799
  var init_run = __esm({
4641
4800
  "src/commands/run.ts"() {
4642
4801
  "use strict";
4643
- fs11 = __toESM(require("fs"));
4644
- path11 = __toESM(require("path"));
4802
+ fs12 = __toESM(require("fs"));
4803
+ path12 = __toESM(require("path"));
4645
4804
  import_node_child_process6 = require("child_process");
4646
4805
  init_connection();
4647
4806
  init_queries();
@@ -4658,9 +4817,9 @@ var init_run = __esm({
4658
4817
 
4659
4818
  // src/swarm/worktree.ts
4660
4819
  function createWorktree(mainRoot, slug, paddedNum) {
4661
- const projectName = path12.basename(mainRoot);
4820
+ const projectName = path13.basename(mainRoot);
4662
4821
  const worktreeName = `${projectName}-swarm-${paddedNum}-${slug}`;
4663
- const worktreePath = path12.join(path12.dirname(mainRoot), worktreeName);
4822
+ const worktreePath = path13.join(path13.dirname(mainRoot), worktreeName);
4664
4823
  const branch = `swarm/${paddedNum}-${slug}`;
4665
4824
  (0, import_node_child_process7.execSync)(`git worktree add ${JSON.stringify(worktreePath)} -b ${branch}`, {
4666
4825
  cwd: mainRoot,
@@ -4677,36 +4836,36 @@ function createWorktree(mainRoot, slug, paddedNum) {
4677
4836
  };
4678
4837
  }
4679
4838
  function initializeWorktree(mainRoot, worktreePath) {
4680
- const majlisDir = path12.join(worktreePath, ".majlis");
4681
- fs12.mkdirSync(majlisDir, { recursive: true });
4682
- const configSrc = path12.join(mainRoot, ".majlis", "config.json");
4683
- if (fs12.existsSync(configSrc)) {
4684
- fs12.copyFileSync(configSrc, path12.join(majlisDir, "config.json"));
4685
- }
4686
- const agentsSrc = path12.join(mainRoot, ".majlis", "agents");
4687
- if (fs12.existsSync(agentsSrc)) {
4688
- const agentsDst = path12.join(majlisDir, "agents");
4689
- fs12.mkdirSync(agentsDst, { recursive: true });
4690
- for (const file of fs12.readdirSync(agentsSrc)) {
4691
- fs12.copyFileSync(path12.join(agentsSrc, file), path12.join(agentsDst, file));
4839
+ const majlisDir = path13.join(worktreePath, ".majlis");
4840
+ fs13.mkdirSync(majlisDir, { recursive: true });
4841
+ const configSrc = path13.join(mainRoot, ".majlis", "config.json");
4842
+ if (fs13.existsSync(configSrc)) {
4843
+ fs13.copyFileSync(configSrc, path13.join(majlisDir, "config.json"));
4844
+ }
4845
+ const agentsSrc = path13.join(mainRoot, ".majlis", "agents");
4846
+ if (fs13.existsSync(agentsSrc)) {
4847
+ const agentsDst = path13.join(majlisDir, "agents");
4848
+ fs13.mkdirSync(agentsDst, { recursive: true });
4849
+ for (const file of fs13.readdirSync(agentsSrc)) {
4850
+ fs13.copyFileSync(path13.join(agentsSrc, file), path13.join(agentsDst, file));
4692
4851
  }
4693
4852
  }
4694
- const synthSrc = path12.join(mainRoot, "docs", "synthesis");
4695
- if (fs12.existsSync(synthSrc)) {
4696
- const synthDst = path12.join(worktreePath, "docs", "synthesis");
4697
- fs12.mkdirSync(synthDst, { recursive: true });
4698
- for (const file of fs12.readdirSync(synthSrc)) {
4699
- const srcFile = path12.join(synthSrc, file);
4700
- if (fs12.statSync(srcFile).isFile()) {
4701
- fs12.copyFileSync(srcFile, path12.join(synthDst, file));
4853
+ const synthSrc = path13.join(mainRoot, "docs", "synthesis");
4854
+ if (fs13.existsSync(synthSrc)) {
4855
+ const synthDst = path13.join(worktreePath, "docs", "synthesis");
4856
+ fs13.mkdirSync(synthDst, { recursive: true });
4857
+ for (const file of fs13.readdirSync(synthSrc)) {
4858
+ const srcFile = path13.join(synthSrc, file);
4859
+ if (fs13.statSync(srcFile).isFile()) {
4860
+ fs13.copyFileSync(srcFile, path13.join(synthDst, file));
4702
4861
  }
4703
4862
  }
4704
4863
  }
4705
- const templateSrc = path12.join(mainRoot, "docs", "experiments", "_TEMPLATE.md");
4706
- if (fs12.existsSync(templateSrc)) {
4707
- const expDir = path12.join(worktreePath, "docs", "experiments");
4708
- fs12.mkdirSync(expDir, { recursive: true });
4709
- fs12.copyFileSync(templateSrc, path12.join(expDir, "_TEMPLATE.md"));
4864
+ const templateSrc = path13.join(mainRoot, "docs", "experiments", "_TEMPLATE.md");
4865
+ if (fs13.existsSync(templateSrc)) {
4866
+ const expDir = path13.join(worktreePath, "docs", "experiments");
4867
+ fs13.mkdirSync(expDir, { recursive: true });
4868
+ fs13.copyFileSync(templateSrc, path13.join(expDir, "_TEMPLATE.md"));
4710
4869
  }
4711
4870
  const db = openDbAt(worktreePath);
4712
4871
  db.close();
@@ -4738,12 +4897,12 @@ function cleanupWorktree(mainRoot, wt) {
4738
4897
  } catch {
4739
4898
  }
4740
4899
  }
4741
- var fs12, path12, import_node_child_process7;
4900
+ var fs13, path13, import_node_child_process7;
4742
4901
  var init_worktree = __esm({
4743
4902
  "src/swarm/worktree.ts"() {
4744
4903
  "use strict";
4745
- fs12 = __toESM(require("fs"));
4746
- path12 = __toESM(require("path"));
4904
+ fs13 = __toESM(require("fs"));
4905
+ path13 = __toESM(require("path"));
4747
4906
  import_node_child_process7 = require("child_process");
4748
4907
  init_connection();
4749
4908
  init_format();
@@ -4762,12 +4921,12 @@ async function runExperimentInWorktree(wt) {
4762
4921
  exp = createExperiment(db, wt.slug, wt.branch, wt.hypothesis, null, null);
4763
4922
  updateExperimentStatus(db, exp.id, "reframed");
4764
4923
  exp.status = "reframed";
4765
- const templatePath = path13.join(wt.path, "docs", "experiments", "_TEMPLATE.md");
4766
- if (fs13.existsSync(templatePath)) {
4767
- const template = fs13.readFileSync(templatePath, "utf-8");
4924
+ const templatePath = path14.join(wt.path, "docs", "experiments", "_TEMPLATE.md");
4925
+ if (fs14.existsSync(templatePath)) {
4926
+ const template = fs14.readFileSync(templatePath, "utf-8");
4768
4927
  const logContent = template.replace(/\{\{title\}\}/g, wt.hypothesis).replace(/\{\{hypothesis\}\}/g, wt.hypothesis).replace(/\{\{branch\}\}/g, wt.branch).replace(/\{\{status\}\}/g, "classified").replace(/\{\{sub_type\}\}/g, "unclassified").replace(/\{\{date\}\}/g, (/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
4769
- const logPath = path13.join(wt.path, "docs", "experiments", `${wt.paddedNum}-${wt.slug}.md`);
4770
- fs13.writeFileSync(logPath, logContent);
4928
+ const logPath = path14.join(wt.path, "docs", "experiments", `${wt.paddedNum}-${wt.slug}.md`);
4929
+ fs14.writeFileSync(logPath, logContent);
4771
4930
  }
4772
4931
  info(`${label} Starting: ${wt.hypothesis}`);
4773
4932
  while (stepCount < MAX_STEPS) {
@@ -4890,12 +5049,12 @@ function statusToStepName(status2) {
4890
5049
  return null;
4891
5050
  }
4892
5051
  }
4893
- var fs13, path13, MAX_STEPS;
5052
+ var fs14, path14, MAX_STEPS;
4894
5053
  var init_runner = __esm({
4895
5054
  "src/swarm/runner.ts"() {
4896
5055
  "use strict";
4897
- fs13 = __toESM(require("fs"));
4898
- path13 = __toESM(require("path"));
5056
+ fs14 = __toESM(require("fs"));
5057
+ path14 = __toESM(require("path"));
4899
5058
  init_connection();
4900
5059
  init_queries();
4901
5060
  init_machine();
@@ -5181,15 +5340,15 @@ function isMergeable(grade) {
5181
5340
  }
5182
5341
  async function deriveMultipleHypotheses(goal, root, count) {
5183
5342
  const synthesis = truncateContext(
5184
- readFileOrEmpty(path14.join(root, "docs", "synthesis", "current.md")),
5343
+ readFileOrEmpty(path15.join(root, "docs", "synthesis", "current.md")),
5185
5344
  CONTEXT_LIMITS.synthesis
5186
5345
  );
5187
5346
  const fragility = truncateContext(
5188
- readFileOrEmpty(path14.join(root, "docs", "synthesis", "fragility.md")),
5347
+ readFileOrEmpty(path15.join(root, "docs", "synthesis", "fragility.md")),
5189
5348
  CONTEXT_LIMITS.fragility
5190
5349
  );
5191
5350
  const deadEndsDoc = truncateContext(
5192
- readFileOrEmpty(path14.join(root, "docs", "synthesis", "dead-ends.md")),
5351
+ readFileOrEmpty(path15.join(root, "docs", "synthesis", "dead-ends.md")),
5193
5352
  CONTEXT_LIMITS.deadEnds
5194
5353
  );
5195
5354
  const diagnosis = truncateContext(readLatestDiagnosis(root), CONTEXT_LIMITS.synthesis);
@@ -5279,11 +5438,11 @@ If the goal is met:
5279
5438
  warn("Planner did not return structured hypotheses. Using goal as single hypothesis.");
5280
5439
  return [goal];
5281
5440
  }
5282
- var path14, import_node_child_process8, MAX_PARALLEL, DEFAULT_PARALLEL;
5441
+ var path15, import_node_child_process8, MAX_PARALLEL, DEFAULT_PARALLEL;
5283
5442
  var init_swarm = __esm({
5284
5443
  "src/commands/swarm.ts"() {
5285
5444
  "use strict";
5286
- path14 = __toESM(require("path"));
5445
+ path15 = __toESM(require("path"));
5287
5446
  import_node_child_process8 = require("child_process");
5288
5447
  init_connection();
5289
5448
  init_queries();
@@ -5309,16 +5468,16 @@ async function diagnose(args) {
5309
5468
  const db = getDb(root);
5310
5469
  const focus = args.filter((a) => !a.startsWith("--")).join(" ");
5311
5470
  const keepScripts = args.includes("--keep-scripts");
5312
- const scriptsDir = path15.join(root, ".majlis", "scripts");
5313
- if (!fs14.existsSync(scriptsDir)) {
5314
- fs14.mkdirSync(scriptsDir, { recursive: true });
5471
+ const scriptsDir = path16.join(root, ".majlis", "scripts");
5472
+ if (!fs15.existsSync(scriptsDir)) {
5473
+ fs15.mkdirSync(scriptsDir, { recursive: true });
5315
5474
  }
5316
5475
  header("Deep Diagnosis");
5317
5476
  if (focus) info(`Focus: ${focus}`);
5318
5477
  const dbExport = exportForDiagnostician(db);
5319
- const synthesis = readFileOrEmpty(path15.join(root, "docs", "synthesis", "current.md"));
5320
- const fragility = readFileOrEmpty(path15.join(root, "docs", "synthesis", "fragility.md"));
5321
- const deadEndsDoc = readFileOrEmpty(path15.join(root, "docs", "synthesis", "dead-ends.md"));
5478
+ const synthesis = readFileOrEmpty(path16.join(root, "docs", "synthesis", "current.md"));
5479
+ const fragility = readFileOrEmpty(path16.join(root, "docs", "synthesis", "fragility.md"));
5480
+ const deadEndsDoc = readFileOrEmpty(path16.join(root, "docs", "synthesis", "dead-ends.md"));
5322
5481
  const config = loadConfig(root);
5323
5482
  let metricsOutput = "";
5324
5483
  if (config.metrics?.command) {
@@ -5369,13 +5528,13 @@ Perform a deep diagnostic analysis of this project. Identify root causes, recurr
5369
5528
  Remember: you may write files ONLY to .majlis/scripts/. You cannot modify project code.`;
5370
5529
  info("Spawning diagnostician (60 turns, full DB access)...");
5371
5530
  const result = await spawnAgent("diagnostician", { taskPrompt }, root);
5372
- const diagnosisDir = path15.join(root, "docs", "diagnosis");
5373
- if (!fs14.existsSync(diagnosisDir)) {
5374
- fs14.mkdirSync(diagnosisDir, { recursive: true });
5531
+ const diagnosisDir = path16.join(root, "docs", "diagnosis");
5532
+ if (!fs15.existsSync(diagnosisDir)) {
5533
+ fs15.mkdirSync(diagnosisDir, { recursive: true });
5375
5534
  }
5376
5535
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
5377
- const artifactPath = path15.join(diagnosisDir, `diagnosis-${timestamp}.md`);
5378
- fs14.writeFileSync(artifactPath, result.output);
5536
+ const artifactPath = path16.join(diagnosisDir, `diagnosis-${timestamp}.md`);
5537
+ fs15.writeFileSync(artifactPath, result.output);
5379
5538
  info(`Diagnostic report: docs/diagnosis/diagnosis-${timestamp}.md`);
5380
5539
  if (result.structured?.diagnosis) {
5381
5540
  const d = result.structured.diagnosis;
@@ -5388,11 +5547,11 @@ Remember: you may write files ONLY to .majlis/scripts/. You cannot modify projec
5388
5547
  }
5389
5548
  if (!keepScripts) {
5390
5549
  try {
5391
- const files = fs14.readdirSync(scriptsDir);
5550
+ const files = fs15.readdirSync(scriptsDir);
5392
5551
  for (const f of files) {
5393
- fs14.unlinkSync(path15.join(scriptsDir, f));
5552
+ fs15.unlinkSync(path16.join(scriptsDir, f));
5394
5553
  }
5395
- fs14.rmdirSync(scriptsDir);
5554
+ fs15.rmdirSync(scriptsDir);
5396
5555
  info("Cleaned up .majlis/scripts/");
5397
5556
  } catch {
5398
5557
  }
@@ -5405,12 +5564,12 @@ Remember: you may write files ONLY to .majlis/scripts/. You cannot modify projec
5405
5564
  autoCommit(root, `diagnosis: ${focus || "general"}`);
5406
5565
  success("Diagnosis complete.");
5407
5566
  }
5408
- var fs14, path15, import_node_child_process9;
5567
+ var fs15, path16, import_node_child_process9;
5409
5568
  var init_diagnose = __esm({
5410
5569
  "src/commands/diagnose.ts"() {
5411
5570
  "use strict";
5412
- fs14 = __toESM(require("fs"));
5413
- path15 = __toESM(require("path"));
5571
+ fs15 = __toESM(require("fs"));
5572
+ path16 = __toESM(require("path"));
5414
5573
  import_node_child_process9 = require("child_process");
5415
5574
  init_connection();
5416
5575
  init_queries();
@@ -5422,10 +5581,10 @@ var init_diagnose = __esm({
5422
5581
  });
5423
5582
 
5424
5583
  // src/cli.ts
5425
- var fs15 = __toESM(require("fs"));
5426
- var path16 = __toESM(require("path"));
5427
- var VERSION = JSON.parse(
5428
- fs15.readFileSync(path16.join(__dirname, "..", "package.json"), "utf-8")
5584
+ var fs16 = __toESM(require("fs"));
5585
+ var path17 = __toESM(require("path"));
5586
+ var VERSION2 = JSON.parse(
5587
+ fs16.readFileSync(path17.join(__dirname, "..", "package.json"), "utf-8")
5429
5588
  ).version;
5430
5589
  async function main() {
5431
5590
  let sigintCount = 0;
@@ -5438,7 +5597,7 @@ async function main() {
5438
5597
  });
5439
5598
  const args = process.argv.slice(2);
5440
5599
  if (args.includes("--version") || args.includes("-v")) {
5441
- console.log(VERSION);
5600
+ console.log(VERSION2);
5442
5601
  return;
5443
5602
  }
5444
5603
  if (args.includes("--help") || args.includes("-h") || args.length === 0) {
@@ -5455,6 +5614,11 @@ async function main() {
5455
5614
  await init2(rest);
5456
5615
  break;
5457
5616
  }
5617
+ case "upgrade": {
5618
+ const { upgrade: upgrade2 } = await Promise.resolve().then(() => (init_upgrade(), upgrade_exports));
5619
+ await upgrade2(rest);
5620
+ break;
5621
+ }
5458
5622
  case "status": {
5459
5623
  const { status: status2 } = await Promise.resolve().then(() => (init_status(), status_exports));
5460
5624
  await status2(isJson);
@@ -5563,12 +5727,13 @@ async function main() {
5563
5727
  }
5564
5728
  function printHelp() {
5565
5729
  console.log(`
5566
- majlis v${VERSION} \u2014 Structured multi-agent problem solving
5730
+ majlis v${VERSION2} \u2014 Structured multi-agent problem solving
5567
5731
 
5568
5732
  Usage: majlis <command> [options]
5569
5733
 
5570
5734
  Lifecycle:
5571
5735
  init Initialize Majlis in current project
5736
+ upgrade Sync agents, commands, hooks from CLI version
5572
5737
  status [--json] Show experiment states and cycle position
5573
5738
 
5574
5739
  Experiments:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "majlis",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Multi-agent workflow CLI for structured doubt, independent verification, and compressed knowledge",
5
5
  "bin": {
6
6
  "majlis": "./dist/cli.js"