dreamcontext 0.7.0 → 0.7.1

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 (131) hide show
  1. package/agents/sleep-tasks.md +20 -0
  2. package/dist/agents/sleep-tasks.md +20 -0
  3. package/dist/dashboard/assets/{BrainCanvas3D-lFgJbbhZ.js → BrainCanvas3D-Bb8WCKrn.js} +21 -21
  4. package/dist/dashboard/assets/{_baseUniq-BpANgc_i.js → _baseUniq-BatmaIH2.js} +1 -1
  5. package/dist/dashboard/assets/ar-SA-G6X2FPQ2-D5ja_wjH.js +10 -0
  6. package/dist/dashboard/assets/{arc-CX32Jm7E.js → arc-DqjLlF-x.js} +1 -1
  7. package/dist/dashboard/assets/{architectureDiagram-Q4EWVU46-ARASlGxO.js → architectureDiagram-Q4EWVU46-u9hbL6uu.js} +1 -1
  8. package/dist/dashboard/assets/az-AZ-76LH7QW2-CCrmRwql.js +1 -0
  9. package/dist/dashboard/assets/bg-BG-XCXSNQG7-ByFwPOzm.js +5 -0
  10. package/dist/dashboard/assets/{blockDiagram-DXYQGD6D-BBvsYm9E.js → blockDiagram-DXYQGD6D-dX-e3JNh.js} +1 -1
  11. package/dist/dashboard/assets/bn-BD-2XOGV67Q-CqnEIuTG.js +5 -0
  12. package/dist/dashboard/assets/{c4Diagram-AHTNJAMY-ChSUfXR9.js → c4Diagram-AHTNJAMY-DAT2Y4Ei.js} +1 -1
  13. package/dist/dashboard/assets/ca-ES-6MX7JW3Y-DxUow-Oi.js +8 -0
  14. package/dist/dashboard/assets/channel-JlaJkLX7.js +1 -0
  15. package/dist/dashboard/assets/{chunk-4BX2VUAB-COHoVEpt.js → chunk-4BX2VUAB-ng6_uP1b.js} +1 -1
  16. package/dist/dashboard/assets/{chunk-4TB4RGXK-DKJFLaTC.js → chunk-4TB4RGXK-JyQRd6F4.js} +1 -1
  17. package/dist/dashboard/assets/{chunk-55IACEB6-CKZPWZRu.js → chunk-55IACEB6-WENWKOcW.js} +1 -1
  18. package/dist/dashboard/assets/{chunk-EDXVE4YY-k1y4mGUJ.js → chunk-EDXVE4YY-BupZpcZ0.js} +1 -1
  19. package/dist/dashboard/assets/{chunk-FMBD7UC4-ixXe5R10.js → chunk-FMBD7UC4-6-Dp_BQr.js} +1 -1
  20. package/dist/dashboard/assets/{chunk-OYMX7WX6-NDFap7xg.js → chunk-OYMX7WX6-CRMXMXMR.js} +1 -1
  21. package/dist/dashboard/assets/{chunk-QZHKN3VN-vY0UpHjB.js → chunk-QZHKN3VN-CdV3chea.js} +1 -1
  22. package/dist/dashboard/assets/{chunk-YZCP3GAM-yztvsKR-.js → chunk-YZCP3GAM-DGd7UTQr.js} +1 -1
  23. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-BBVZgLT7.js +1 -0
  24. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-BBVZgLT7.js +1 -0
  25. package/dist/dashboard/assets/clone-DSjY5D8g.js +1 -0
  26. package/dist/dashboard/assets/{cose-bilkent-S5V4N54A-DKXM5Fh5.js → cose-bilkent-S5V4N54A-86wk8_0k.js} +1 -1
  27. package/dist/dashboard/assets/cs-CZ-2BRQDIVT-Vsx90G3k.js +11 -0
  28. package/dist/dashboard/assets/da-DK-5WZEPLOC-BqlSmIrC.js +5 -0
  29. package/dist/dashboard/assets/{dagre-KV5264BT-DN1Nlsmy.js → dagre-KV5264BT-BsnIu1de.js} +1 -1
  30. package/dist/dashboard/assets/de-DE-XR44H4JA-D1X2JmBd.js +8 -0
  31. package/dist/dashboard/assets/{diagram-5BDNPKRD-DnoJFRqR.js → diagram-5BDNPKRD-BfKZpkO_.js} +1 -1
  32. package/dist/dashboard/assets/{diagram-G4DWMVQ6-CF1_jTNI.js → diagram-G4DWMVQ6-BGEdOZis.js} +1 -1
  33. package/dist/dashboard/assets/{diagram-MMDJMWI5-D4-bZZEt.js → diagram-MMDJMWI5-4PK6U-9k.js} +1 -1
  34. package/dist/dashboard/assets/{diagram-TYMM5635-al8RqVgf.js → diagram-TYMM5635-Co4XFxnB.js} +1 -1
  35. package/dist/dashboard/assets/directory-open-01563666-DWU9wJ6I.js +1 -0
  36. package/dist/dashboard/assets/directory-open-4ed118d0-CunoC1EB.js +1 -0
  37. package/dist/dashboard/assets/el-GR-BZB4AONW-JfJ7Iw6d.js +10 -0
  38. package/dist/dashboard/assets/{erDiagram-SMLLAGMA-MEcC0rwO.js → erDiagram-SMLLAGMA-tggQbGeM.js} +1 -1
  39. package/dist/dashboard/assets/es-ES-U4NZUMDT-CrTG5SH1.js +9 -0
  40. package/dist/dashboard/assets/eu-ES-A7QVB2H4-CLi-f2S4.js +11 -0
  41. package/dist/dashboard/assets/extends-CF3RwP-h.js +1 -0
  42. package/dist/dashboard/assets/fa-IR-HGAKTJCU-B78t-ifl.js +8 -0
  43. package/dist/dashboard/assets/fi-FI-Z5N7JZ37-BiYGo0tM.js +6 -0
  44. package/dist/dashboard/assets/file-open-002ab408-DIuFHtCF.js +1 -0
  45. package/dist/dashboard/assets/file-open-7c801643-684qeFg4.js +1 -0
  46. package/dist/dashboard/assets/file-save-3189631c-C1wFhQhH.js +1 -0
  47. package/dist/dashboard/assets/file-save-745eba88-Bb9F9Kg7.js +1 -0
  48. package/dist/dashboard/assets/{flowDiagram-DWJPFMVM-DCLyNpW8.js → flowDiagram-DWJPFMVM-DfOOuTHa.js} +1 -1
  49. package/dist/dashboard/assets/fr-FR-RHASNOE6-CHuvxlm9.js +9 -0
  50. package/dist/dashboard/assets/{ganttDiagram-T4ZO3ILL-DfEvbbJK.js → ganttDiagram-T4ZO3ILL-CqRBfUlO.js} +1 -1
  51. package/dist/dashboard/assets/{gitGraphDiagram-UUTBAWPF-C_YozdVL.js → gitGraphDiagram-UUTBAWPF-DCooi0ou.js} +1 -1
  52. package/dist/dashboard/assets/gl-ES-HMX3MZ6V-DloFVgGH.js +10 -0
  53. package/dist/dashboard/assets/{graph-DpIXS1G1.js → graph-CbTgvSod.js} +1 -1
  54. package/dist/dashboard/assets/he-IL-6SHJWFNN-sKyHtCj5.js +10 -0
  55. package/dist/dashboard/assets/hi-IN-IWLTKZ5I-BDBktoGz.js +4 -0
  56. package/dist/dashboard/assets/hu-HU-A5ZG7DT2-CI0m6WdK.js +7 -0
  57. package/dist/dashboard/assets/id-ID-SAP4L64H-o3oCWYJ1.js +10 -0
  58. package/dist/dashboard/assets/image-blob-reduce.esm-D6s-rqMO.js +7 -0
  59. package/dist/dashboard/assets/index-BMwAG0PF.css +1 -0
  60. package/dist/dashboard/assets/index-BzUItYQF.js +19 -0
  61. package/dist/dashboard/assets/{index-Bo5CUa_M.js → index-CIMJcxbn.js} +178 -178
  62. package/dist/dashboard/assets/{infoDiagram-42DDH7IO-AdT6kjzj.js → infoDiagram-42DDH7IO-DvXAiIKM.js} +1 -1
  63. package/dist/dashboard/assets/{ishikawaDiagram-UXIWVN3A-B0_9IZVO.js → ishikawaDiagram-UXIWVN3A-B3k3F-SR.js} +1 -1
  64. package/dist/dashboard/assets/it-IT-JPQ66NNP-B69FvIBl.js +11 -0
  65. package/dist/dashboard/assets/ja-JP-DBVTYXUO-09Dz5R3w.js +8 -0
  66. package/dist/dashboard/assets/{journeyDiagram-VCZTEJTY-BveNBswQ.js → journeyDiagram-VCZTEJTY-3sYlQlzX.js} +1 -1
  67. package/dist/dashboard/assets/kaa-6HZHGXH3-SFvv5G_m.js +1 -0
  68. package/dist/dashboard/assets/kab-KAB-ZGHBKWFO-Cj4UcDfk.js +8 -0
  69. package/dist/dashboard/assets/{kanban-definition-6JOO6SKY-CFI8j4jR.js → kanban-definition-6JOO6SKY-cGLqpTJv.js} +1 -1
  70. package/dist/dashboard/assets/kk-KZ-P5N5QNE5-BVT_-IeJ.js +1 -0
  71. package/dist/dashboard/assets/km-KH-HSX4SM5Z-BpH_zneK.js +11 -0
  72. package/dist/dashboard/assets/ko-KR-MTYHY66A-BWtVfnIt.js +9 -0
  73. package/dist/dashboard/assets/ku-TR-6OUDTVRD-DKg1sGxW.js +9 -0
  74. package/dist/dashboard/assets/{layout-DI7XjZy1.js → layout-gKZamora.js} +1 -1
  75. package/dist/dashboard/assets/{linear-CSjp56iw.js → linear-DOSQ02II.js} +1 -1
  76. package/dist/dashboard/assets/lt-LT-XHIRWOB4-DFICvEvq.js +3 -0
  77. package/dist/dashboard/assets/lv-LV-5QDEKY6T-CeIp3POy.js +7 -0
  78. package/dist/dashboard/assets/min-BD9nuOyV.js +1 -0
  79. package/dist/dashboard/assets/{mindmap-definition-QFDTVHPH-C2mBnknr.js → mindmap-definition-QFDTVHPH-DNg9-qbI.js} +7 -7
  80. package/dist/dashboard/assets/mr-IN-CRQNXWMA-CMiofriy.js +13 -0
  81. package/dist/dashboard/assets/my-MM-5M5IBNSE-WhbW1bUQ.js +1 -0
  82. package/dist/dashboard/assets/nb-NO-T6EIAALU-kvj3GRtN.js +10 -0
  83. package/dist/dashboard/assets/nl-NL-IS3SIHDZ-BdYOVmBV.js +8 -0
  84. package/dist/dashboard/assets/nn-NO-6E72VCQL-BAI1MQoO.js +8 -0
  85. package/dist/dashboard/assets/oc-FR-POXYY2M6-ChavJGTr.js +8 -0
  86. package/dist/dashboard/assets/pa-IN-N4M65BXN-AWmvLRaa.js +4 -0
  87. package/dist/dashboard/assets/percentages-BXMCSKIN-QYboYPU4.js +215 -0
  88. package/dist/dashboard/assets/pica-DzAIGpll.js +7 -0
  89. package/dist/dashboard/assets/{pieDiagram-DEJITSTG-i_phWDqD.js → pieDiagram-DEJITSTG-C4ZFpuC0.js} +1 -1
  90. package/dist/dashboard/assets/pl-PL-T2D74RX3-C06LuJit.js +9 -0
  91. package/dist/dashboard/assets/pt-BR-5N22H2LF-DP-AXG39.js +9 -0
  92. package/dist/dashboard/assets/pt-PT-UZXXM6DQ-T-2COPG-.js +9 -0
  93. package/dist/dashboard/assets/{quadrantDiagram-34T5L4WZ-Dv7TGJjw.js → quadrantDiagram-34T5L4WZ-yvEQRUmq.js} +1 -1
  94. package/dist/dashboard/assets/{requirementDiagram-MS252O5E-CB2Jl-O5.js → requirementDiagram-MS252O5E-BkjbZkw1.js} +1 -1
  95. package/dist/dashboard/assets/ro-RO-JPDTUUEW-V8ShMmhj.js +11 -0
  96. package/dist/dashboard/assets/roundRect-0PYZxl1G.js +1 -0
  97. package/dist/dashboard/assets/ru-RU-B4JR7IUQ-Bk5QWjQg.js +9 -0
  98. package/dist/dashboard/assets/{sankeyDiagram-XADWPNL6-DxCoN-EI.js → sankeyDiagram-XADWPNL6-_6wZr0Q4.js} +1 -1
  99. package/dist/dashboard/assets/{sequenceDiagram-FGHM5R23-BeZyaehJ.js → sequenceDiagram-FGHM5R23-B03MUCIO.js} +1 -1
  100. package/dist/dashboard/assets/si-LK-N5RQ5JYF-DrLyNjX_.js +1 -0
  101. package/dist/dashboard/assets/sk-SK-C5VTKIMK-MG2XJDav.js +6 -0
  102. package/dist/dashboard/assets/sl-SI-NN7IZMDC-DyF2jYcb.js +6 -0
  103. package/dist/dashboard/assets/{stateDiagram-FHFEXIEX-D3AjQzD1.js → stateDiagram-FHFEXIEX-DW9W8hRb.js} +1 -1
  104. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-DGLHFCvB.js +1 -0
  105. package/dist/dashboard/assets/subset-shared.chunk-DxnLkUkc.js +84 -0
  106. package/dist/dashboard/assets/subset-worker.chunk-BCGTROg4.js +1 -0
  107. package/dist/dashboard/assets/sv-SE-XGPEYMSR-BJOlh7Ta.js +10 -0
  108. package/dist/dashboard/assets/ta-IN-2NMHFXQM-DbvdzD_M.js +9 -0
  109. package/dist/dashboard/assets/th-TH-HPSO5L25-BZoStbWu.js +2 -0
  110. package/dist/dashboard/assets/{timeline-definition-GMOUNBTQ-3l_8RFUg.js → timeline-definition-GMOUNBTQ-Cq3P6C9q.js} +1 -1
  111. package/dist/dashboard/assets/tr-TR-DEFEU3FU-D0q3dp6Y.js +7 -0
  112. package/dist/dashboard/assets/uk-UA-QMV73CPH-KQC76_Jh.js +6 -0
  113. package/dist/dashboard/assets/{vennDiagram-DHZGUBPP-2QiY25JD.js → vennDiagram-DHZGUBPP-BO3azTdL.js} +1 -1
  114. package/dist/dashboard/assets/vi-VN-M7AON7JQ-BsyXHyOP.js +5 -0
  115. package/dist/dashboard/assets/{wardley-RL74JXVD-DNLmFofz.js → wardley-RL74JXVD-BjaWFGf-.js} +1 -1
  116. package/dist/dashboard/assets/{wardleyDiagram-NUSXRM2D-BI0tupiS.js → wardleyDiagram-NUSXRM2D-D0Ghwhzw.js} +1 -1
  117. package/dist/dashboard/assets/{xychartDiagram-5P7HB3ND-CghXPE7_.js → xychartDiagram-5P7HB3ND-D1QYeAFg.js} +1 -1
  118. package/dist/dashboard/assets/zh-CN-LNUGB5OW-Cg54ea9D.js +10 -0
  119. package/dist/dashboard/assets/zh-HK-E62DVLB3-N7JXSzdg.js +1 -0
  120. package/dist/dashboard/assets/zh-TW-RAJ6MFWO-CTX6fzNp.js +9 -0
  121. package/dist/dashboard/index.html +2 -2
  122. package/dist/index.js +934 -290
  123. package/package.json +1 -1
  124. package/skill/SKILL.md +22 -0
  125. package/dist/dashboard/assets/channel-w_Bp182N.js +0 -1
  126. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-CcQxcqy9.js +0 -1
  127. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-CcQxcqy9.js +0 -1
  128. package/dist/dashboard/assets/clone-_znoR_ci.js +0 -1
  129. package/dist/dashboard/assets/index-DrqurW1c.css +0 -1
  130. package/dist/dashboard/assets/min-pAGUJmEC.js +0 -1
  131. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-Ci9v--xK.js +0 -1
package/dist/index.js CHANGED
@@ -441,9 +441,9 @@ function recordFile(manifest, relPath, version, kind) {
441
441
  function recordPack(manifest, name, version) {
442
442
  manifest.packs[name] = { version };
443
443
  }
444
- function recordPlatform(manifest, platform) {
445
- if (!manifest.platforms.includes(platform)) {
446
- manifest.platforms.push(platform);
444
+ function recordPlatform(manifest, platform2) {
445
+ if (!manifest.platforms.includes(platform2)) {
446
+ manifest.platforms.push(platform2);
447
447
  }
448
448
  }
449
449
  function diffManifests(oldM, nextM) {
@@ -570,11 +570,11 @@ import { join as join5 } from "path";
570
570
  import { fileURLToPath as fileURLToPath2 } from "url";
571
571
  import chalk2 from "chalk";
572
572
  import { select } from "@inquirer/prompts";
573
- function getFenceStart(platform) {
574
- return `<!-- dreamcontext:${platform}:start -->`;
573
+ function getFenceStart(platform2) {
574
+ return `<!-- dreamcontext:${platform2}:start -->`;
575
575
  }
576
- function getFenceEnd(platform) {
577
- return `<!-- dreamcontext:${platform}:end -->`;
576
+ function getFenceEnd(platform2) {
577
+ return `<!-- dreamcontext:${platform2}:end -->`;
578
578
  }
579
579
  function findTemplate(filename) {
580
580
  const candidates = [
@@ -588,18 +588,18 @@ function findTemplate(filename) {
588
588
  }
589
589
  return null;
590
590
  }
591
- function buildBlock(platform, templateBody) {
592
- return `${getFenceStart(platform)}
591
+ function buildBlock(platform2, templateBody) {
592
+ return `${getFenceStart(platform2)}
593
593
  ${templateBody.trim()}
594
- ${getFenceEnd(platform)}
594
+ ${getFenceEnd(platform2)}
595
595
  `;
596
596
  }
597
- function hasFence(content, platform) {
598
- return content.includes(getFenceStart(platform)) && content.includes(getFenceEnd(platform));
597
+ function hasFence(content, platform2) {
598
+ return content.includes(getFenceStart(platform2)) && content.includes(getFenceEnd(platform2));
599
599
  }
600
- function replaceFence(content, platform, block) {
601
- const startFence = getFenceStart(platform);
602
- const endFence = getFenceEnd(platform);
600
+ function replaceFence(content, platform2, block) {
601
+ const startFence = getFenceStart(platform2);
602
+ const endFence = getFenceEnd(platform2);
603
603
  const startIdx = content.indexOf(startFence);
604
604
  const endIdx = content.indexOf(endFence);
605
605
  if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) return content;
@@ -633,38 +633,38 @@ async function resolveMode(target, requested) {
633
633
  });
634
634
  return choice;
635
635
  }
636
- async function installInstructions(projectRoot, platform, requestedMode) {
637
- const spec = INSTRUCTION_SPECS[platform];
636
+ async function installInstructions(projectRoot, platform2, requestedMode) {
637
+ const spec = INSTRUCTION_SPECS[platform2];
638
638
  const templatePath = findTemplate(spec.templateFile);
639
639
  if (!templatePath) {
640
640
  throw new Error(`${spec.templateFile} template not found. Try reinstalling dreamcontext.`);
641
641
  }
642
642
  const templateBody = readFileSync5(templatePath, "utf-8");
643
- const block = buildBlock(platform, templateBody);
643
+ const block = buildBlock(platform2, templateBody);
644
644
  const target = join5(projectRoot, spec.targetFile);
645
645
  if (!existsSync5(target)) {
646
646
  writeFileSync5(target, block, "utf-8");
647
- return { action: "created", target, platform };
647
+ return { action: "created", target, platform: platform2 };
648
648
  }
649
649
  const existing = readFileSync5(target, "utf-8");
650
- if (hasFence(existing, platform)) {
651
- const next = replaceFence(existing, platform, block);
650
+ if (hasFence(existing, platform2)) {
651
+ const next = replaceFence(existing, platform2, block);
652
652
  writeFileSync5(target, next, "utf-8");
653
- return { action: "updated", target, platform };
653
+ return { action: "updated", target, platform: platform2 };
654
654
  }
655
655
  const mode = await resolveMode(spec.targetFile, requestedMode);
656
656
  if (mode === "skip") {
657
- return { action: "skipped", target, platform };
657
+ return { action: "skipped", target, platform: platform2 };
658
658
  }
659
659
  if (mode === "replace") {
660
660
  const backup = backupPath(target);
661
661
  copyFileSync(target, backup);
662
662
  writeFileSync5(target, block, "utf-8");
663
- return { action: "replaced", target, platform, backup };
663
+ return { action: "replaced", target, platform: platform2, backup };
664
664
  }
665
665
  const sep7 = existing.endsWith("\n") ? "\n" : "\n\n";
666
666
  writeFileSync5(target, existing + sep7 + block, "utf-8");
667
- return { action: "appended", target, platform };
667
+ return { action: "appended", target, platform: platform2 };
668
668
  }
669
669
  async function installClaudeMd(projectRoot, requestedMode) {
670
670
  return installInstructions(projectRoot, "claude", requestedMode);
@@ -727,8 +727,8 @@ function registerInstallInstructionsCommand(program) {
727
727
  return;
728
728
  }
729
729
  const platforms = parsePlatformsOption(opts.platforms);
730
- for (const platform of platforms) {
731
- const result = await installInstructions(projectRoot, platform, mode);
730
+ for (const platform2 of platforms) {
731
+ const result = await installInstructions(projectRoot, platform2, mode);
732
732
  printResult(result);
733
733
  }
734
734
  printDeprecationHint("install-instructions");
@@ -826,12 +826,12 @@ var init_claude_settings = __esm({
826
826
  import { existsSync as existsSync7, readFileSync as readFileSync7, readdirSync as readdirSync2 } from "fs";
827
827
  import { basename as basename2, join as join7 } from "path";
828
828
  import { fileURLToPath as fileURLToPath3 } from "url";
829
- function platformSkillRoot(projectRoot, platform) {
830
- if (platform === "claude") return join7(projectRoot, ".claude", "skills");
829
+ function platformSkillRoot(projectRoot, platform2) {
830
+ if (platform2 === "claude") return join7(projectRoot, ".claude", "skills");
831
831
  return join7(projectRoot, ".agents", "skills");
832
832
  }
833
- function isPackInstalledForPlatform(projectRoot, platform, name) {
834
- return existsSync7(join7(platformSkillRoot(projectRoot, platform), name, "SKILL.md"));
833
+ function isPackInstalledForPlatform(projectRoot, platform2, name) {
834
+ return existsSync7(join7(platformSkillRoot(projectRoot, platform2), name, "SKILL.md"));
835
835
  }
836
836
  function isSkillInstalled(projectRoot, name) {
837
837
  return SUPPORTED_PLATFORMS.some((p) => isPackInstalledForPlatform(projectRoot, p, name));
@@ -929,8 +929,8 @@ function writeCodexAgent(projectRoot, agentPath) {
929
929
  writeFileSync7(configPath2, lines.join("\n"), "utf-8");
930
930
  return `.codex/agents/${parsed.name}.toml`;
931
931
  }
932
- function installAgentForPlatform(platform, projectRoot, agentPath, agentName) {
933
- if (platform === "claude") {
932
+ function installAgentForPlatform(platform2, projectRoot, agentPath, agentName) {
933
+ if (platform2 === "claude") {
934
934
  const agentsDestDir = join8(projectRoot, ".claude", "agents");
935
935
  mkdirSync5(agentsDestDir, { recursive: true });
936
936
  const file = agentName ? `${agentName}.md` : basename3(agentPath);
@@ -944,10 +944,10 @@ function recordIfManifest(manifest, relPath, kind) {
944
944
  if (!manifest) return;
945
945
  recordFile(manifest, relPath, dreamcontextVersion(), kind);
946
946
  }
947
- function installPackFiles(pack, packsDir, projectRoot, catalog, platform, manifest) {
947
+ function installPackFiles(pack, packsDir, projectRoot, catalog, platform2, manifest) {
948
948
  const installed = [];
949
949
  const packSourceDir = join8(packsDir, pack.name);
950
- const skillRoot = platformSkillRoot(projectRoot, platform);
950
+ const skillRoot = platformSkillRoot(projectRoot, platform2);
951
951
  const skillDestDir = join8(skillRoot, pack.name);
952
952
  const skillRootRel = skillRoot.replace(projectRoot + sep, "");
953
953
  const baseSrc = join8(packSourceDir, "SKILL.md");
@@ -987,7 +987,7 @@ function installPackFiles(pack, packsDir, projectRoot, catalog, platform, manife
987
987
  if (!agentEntry) continue;
988
988
  const agentSrc = join8(packsDir, agentEntry.file);
989
989
  if (!existsSync8(agentSrc)) continue;
990
- const agentRel = installAgentForPlatform(platform, projectRoot, agentSrc, agentName);
990
+ const agentRel = installAgentForPlatform(platform2, projectRoot, agentSrc, agentName);
991
991
  recordIfManifest(manifest, agentRel, "pack-agent");
992
992
  installed.push(agentRel);
993
993
  }
@@ -997,10 +997,10 @@ function installPackFiles(pack, packsDir, projectRoot, catalog, platform, manife
997
997
  }
998
998
  return installed;
999
999
  }
1000
- function installStandaloneFiles(standalone, packsDir, projectRoot, platform, manifest) {
1000
+ function installStandaloneFiles(standalone, packsDir, projectRoot, platform2, manifest) {
1001
1001
  const src = join8(packsDir, standalone.file);
1002
1002
  if (!existsSync8(src)) return [];
1003
- const skillRoot = platformSkillRoot(projectRoot, platform);
1003
+ const skillRoot = platformSkillRoot(projectRoot, platform2);
1004
1004
  const destDir = join8(skillRoot, standalone.name);
1005
1005
  const skillRootRel = skillRoot.replace(projectRoot + sep, "");
1006
1006
  mkdirSync5(destDir, { recursive: true });
@@ -1027,12 +1027,12 @@ function installPack(name, projectRoot, platforms, manifest) {
1027
1027
  const pack = catalog.packs.find((p) => p.name === name);
1028
1028
  const standalone = catalog.standalone.find((s) => s.name === name);
1029
1029
  if (!pack && !standalone) throw new UnknownPackError(name);
1030
- for (const platform of platforms) recordPlatform(manifest, platform);
1030
+ for (const platform2 of platforms) recordPlatform(manifest, platform2);
1031
1031
  const installed = [];
1032
1032
  const warnings = [];
1033
1033
  if (pack) {
1034
- for (const platform of platforms) {
1035
- installed.push(...installPackFiles(pack, packsDir, projectRoot, catalog, platform, manifest));
1034
+ for (const platform2 of platforms) {
1035
+ installed.push(...installPackFiles(pack, packsDir, projectRoot, catalog, platform2, manifest));
1036
1036
  }
1037
1037
  if (pack.crossPackDeps?.length) {
1038
1038
  for (const dep of pack.crossPackDeps) {
@@ -1044,8 +1044,8 @@ function installPack(name, projectRoot, platforms, manifest) {
1044
1044
  }
1045
1045
  }
1046
1046
  } else if (standalone) {
1047
- for (const platform of platforms) {
1048
- installed.push(...installStandaloneFiles(standalone, packsDir, projectRoot, platform, manifest));
1047
+ for (const platform2 of platforms) {
1048
+ installed.push(...installStandaloneFiles(standalone, packsDir, projectRoot, platform2, manifest));
1049
1049
  }
1050
1050
  }
1051
1051
  return { installed, warnings };
@@ -1063,19 +1063,19 @@ function safeChildPath(baseDir, child) {
1063
1063
  if (target !== base && !target.startsWith(base + sep)) return null;
1064
1064
  return target;
1065
1065
  }
1066
- function collectSkillFiles(name, projectRoot, platform, manifest, skillDirAbs) {
1067
- const skillRoot = platformSkillRoot(projectRoot, platform);
1066
+ function collectSkillFiles(name, projectRoot, platform2, manifest, skillDirAbs) {
1067
+ const skillRoot = platformSkillRoot(projectRoot, platform2);
1068
1068
  const skillRootRel = skillRoot.replace(projectRoot + sep, "").split("\\").join("/");
1069
1069
  const prefix = `${skillRootRel}/${name}/`;
1070
1070
  const fromManifest = Object.entries(manifest.files).filter(([rel, entry]) => entry.kind === "pack-skill" && rel.startsWith(prefix)).map(([rel]) => rel);
1071
1071
  if (fromManifest.length > 0) return fromManifest;
1072
- if (!isPackInstalledForPlatform(projectRoot, platform, name)) return [];
1072
+ if (!isPackInstalledForPlatform(projectRoot, platform2, name)) return [];
1073
1073
  const files = [];
1074
1074
  walk(skillDirAbs, "", files);
1075
1075
  return files.map((f) => `${skillRootRel}/${name}/${f}`);
1076
1076
  }
1077
- function agentRelPaths(agentName, platform) {
1078
- if (platform === "claude") return [`.claude/agents/${agentName}.md`];
1077
+ function agentRelPaths(agentName, platform2) {
1078
+ if (platform2 === "claude") return [`.claude/agents/${agentName}.md`];
1079
1079
  return [`.codex/agents/${agentName}.toml`];
1080
1080
  }
1081
1081
  function uninstallPack(name, projectRoot, platforms, manifest) {
@@ -1090,14 +1090,14 @@ function uninstallPack(name, projectRoot, platforms, manifest) {
1090
1090
  const skipped = [];
1091
1091
  const warnings = [];
1092
1092
  const candidates = /* @__PURE__ */ new Set();
1093
- for (const platform of platforms) {
1094
- const skillRoot = platformSkillRoot(projectRoot, platform);
1093
+ for (const platform2 of platforms) {
1094
+ const skillRoot = platformSkillRoot(projectRoot, platform2);
1095
1095
  const skillDirAbs = resolveSkillDirToRemove(skillRoot, name);
1096
1096
  if (!skillDirAbs) {
1097
- warnings.push(`skipped ${platform}: "${name}" is not a valid skill directory`);
1097
+ warnings.push(`skipped ${platform2}: "${name}" is not a valid skill directory`);
1098
1098
  continue;
1099
1099
  }
1100
- for (const rel of collectSkillFiles(name, projectRoot, platform, manifest, skillDirAbs)) {
1100
+ for (const rel of collectSkillFiles(name, projectRoot, platform2, manifest, skillDirAbs)) {
1101
1101
  candidates.add(rel);
1102
1102
  }
1103
1103
  }
@@ -1109,8 +1109,8 @@ function uninstallPack(name, projectRoot, platforms, manifest) {
1109
1109
  warnings.push(`kept ${agentName} \u2014 still used by ${keptBy.name}`);
1110
1110
  continue;
1111
1111
  }
1112
- for (const platform of platforms) {
1113
- for (const rel of agentRelPaths(agentName, platform)) candidates.add(rel);
1112
+ for (const platform2 of platforms) {
1113
+ for (const rel of agentRelPaths(agentName, platform2)) candidates.add(rel);
1114
1114
  }
1115
1115
  }
1116
1116
  for (const rel of candidates) {
@@ -1128,8 +1128,8 @@ function uninstallPack(name, projectRoot, platforms, manifest) {
1128
1128
  warnings.push(`could not delete ${rel}: ${msg}`);
1129
1129
  }
1130
1130
  }
1131
- for (const platform of platforms) {
1132
- const skillRoot = platformSkillRoot(projectRoot, platform);
1131
+ for (const platform2 of platforms) {
1132
+ const skillRoot = platformSkillRoot(projectRoot, platform2);
1133
1133
  const skillDirAbs = resolveSkillDirToRemove(skillRoot, name);
1134
1134
  if (skillDirAbs && existsSync8(skillDirAbs)) {
1135
1135
  rmSync(skillDirAbs, { recursive: true, force: true });
@@ -1252,15 +1252,15 @@ ${block}`, "utf-8");
1252
1252
  writeFileSync8(configPath2, merged, "utf-8");
1253
1253
  return { created: false, updated: true };
1254
1254
  }
1255
- function platformLabel(platform) {
1256
- return platform === "claude" ? "Claude" : "Codex";
1255
+ function platformLabel(platform2) {
1256
+ return platform2 === "claude" ? "Claude" : "Codex";
1257
1257
  }
1258
- function platformPrefixed(platform, relPath) {
1259
- return `${chalk3.dim(`[${platform}]`)} ${relPath}`;
1258
+ function platformPrefixed(platform2, relPath) {
1259
+ return `${chalk3.dim(`[${platform2}]`)} ${relPath}`;
1260
1260
  }
1261
1261
  function labelInstalledPath(relPath) {
1262
- const platform = relPath.startsWith(".agents/") || relPath.startsWith(".codex/") ? "codex" : "claude";
1263
- return platformPrefixed(platform, relPath);
1262
+ const platform2 = relPath.startsWith(".agents/") || relPath.startsWith(".codex/") ? "codex" : "claude";
1263
+ return platformPrefixed(platform2, relPath);
1264
1264
  }
1265
1265
  function filterBatchDepWarnings(warnings, selectedNames) {
1266
1266
  return warnings.filter((w) => {
@@ -1446,7 +1446,7 @@ function directPackInstall(packNames, projectRoot, platforms, manifest) {
1446
1446
  return;
1447
1447
  }
1448
1448
  const localManifest = manifest ?? getOrCreateManifest(projectRoot);
1449
- for (const platform of platforms) recordPlatform(localManifest, platform);
1449
+ for (const platform2 of platforms) recordPlatform(localManifest, platform2);
1450
1450
  const { catalog } = loaded;
1451
1451
  const allInstalled = [];
1452
1452
  const warnings = [];
@@ -1483,7 +1483,7 @@ function installSingleSkill(skillName, projectRoot, platforms) {
1483
1483
  }
1484
1484
  const { catalog, packsDir } = loaded;
1485
1485
  const manifest = getOrCreateManifest(projectRoot);
1486
- for (const platform of platforms) recordPlatform(manifest, platform);
1486
+ for (const platform2 of platforms) recordPlatform(manifest, platform2);
1487
1487
  for (const pack of catalog.packs) {
1488
1488
  const sub = pack.subSkills.find((s) => s.name === skillName);
1489
1489
  if (!sub) continue;
@@ -1494,8 +1494,8 @@ function installSingleSkill(skillName, projectRoot, platforms) {
1494
1494
  return;
1495
1495
  }
1496
1496
  const installed = [];
1497
- for (const platform of platforms) {
1498
- const skillRoot = platformSkillRoot(projectRoot, platform);
1497
+ for (const platform2 of platforms) {
1498
+ const skillRoot = platformSkillRoot(projectRoot, platform2);
1499
1499
  const skillDestDir = join9(skillRoot, pack.name);
1500
1500
  const subDest = join9(skillDestDir, sub.file);
1501
1501
  mkdirSync6(dirname6(subDest), { recursive: true });
@@ -1503,7 +1503,7 @@ function installSingleSkill(skillName, projectRoot, platforms) {
1503
1503
  const skillRootRel = skillRoot.replace(projectRoot + "/", "");
1504
1504
  const subRel = `${skillRootRel}/${pack.name}/${sub.file}`;
1505
1505
  recordFile(manifest, subRel, dreamcontextVersion(), "pack-skill");
1506
- let label = platformPrefixed(platform, subRel);
1506
+ let label = platformPrefixed(platform2, subRel);
1507
1507
  if (sub.hasReferences) {
1508
1508
  const refSrcDir = join9(dirname6(subSrc), "references");
1509
1509
  if (existsSync9(refSrcDir)) {
@@ -1581,7 +1581,7 @@ function listAvailablePacks(projectRoot, platforms) {
1581
1581
  console.log(` ${chalk3.dim(pack.base)}`);
1582
1582
  for (const sub of pack.subSkills) {
1583
1583
  const subInstalled = platforms.every(
1584
- (platform) => existsSync9(join9(platformSkillRoot(projectRoot, platform), pack.name, sub.file))
1584
+ (platform2) => existsSync9(join9(platformSkillRoot(projectRoot, platform2), pack.name, sub.file))
1585
1585
  );
1586
1586
  const subStatus = subInstalled ? chalk3.green(" \u2713") : "";
1587
1587
  console.log(` ${chalk3.dim("\u2022")} ${sub.name}${subStatus} ${chalk3.dim("- " + sub.description)}`);
@@ -1616,65 +1616,65 @@ function printInstallSummary(installed, warnings) {
1616
1616
  ], { color: "green" }));
1617
1617
  console.log();
1618
1618
  }
1619
- async function installCoreForPlatform(platform, projectRoot, manifest) {
1619
+ async function installCoreForPlatform(platform2, projectRoot, manifest) {
1620
1620
  const installed = [];
1621
1621
  const notes = [];
1622
1622
  const skillSource = findPackageFile("skill", "SKILL.md");
1623
1623
  if (!skillSource) {
1624
1624
  throw new Error("SKILL.md not found in package. Try reinstalling dreamcontext.");
1625
1625
  }
1626
- if (manifest) recordPlatform(manifest, platform);
1627
- const skillRoot = platformSkillRoot(projectRoot, platform);
1626
+ if (manifest) recordPlatform(manifest, platform2);
1627
+ const skillRoot = platformSkillRoot(projectRoot, platform2);
1628
1628
  const skillDestDir = join9(skillRoot, "dreamcontext");
1629
1629
  const skillRootRel = skillRoot.replace(projectRoot + "/", "");
1630
1630
  mkdirSync6(skillDestDir, { recursive: true });
1631
1631
  writeFileSync8(join9(skillDestDir, "SKILL.md"), readFileSync9(skillSource, "utf-8"), "utf-8");
1632
1632
  const coreSkillRel = `${skillRootRel}/dreamcontext/SKILL.md`;
1633
1633
  recordIfManifest2(manifest, coreSkillRel, "core");
1634
- installed.push(platformPrefixed(platform, coreSkillRel));
1634
+ installed.push(platformPrefixed(platform2, coreSkillRel));
1635
1635
  const agentsSourceDir = findPackageDir("agents");
1636
1636
  if (agentsSourceDir) {
1637
1637
  const agentFiles = readdirSync4(agentsSourceDir).filter((f) => f.endsWith(".md"));
1638
1638
  for (const file of agentFiles) {
1639
1639
  const source = join9(agentsSourceDir, file);
1640
- const agentRel = installAgentForPlatform(platform, projectRoot, source);
1640
+ const agentRel = installAgentForPlatform(platform2, projectRoot, source);
1641
1641
  recordIfManifest2(manifest, agentRel, "agent");
1642
- installed.push(platformPrefixed(platform, agentRel));
1642
+ installed.push(platformPrefixed(platform2, agentRel));
1643
1643
  }
1644
1644
  }
1645
- if (platform === "claude") {
1645
+ if (platform2 === "claude") {
1646
1646
  const hookResult = ensureClaudeHooks(projectRoot);
1647
1647
  recordIfManifest2(manifest, ".claude/settings.json", "hook");
1648
1648
  if (hookResult.added.length > 0) {
1649
- installed.push(platformPrefixed(platform, `.claude/settings.json ${chalk3.dim(`(${hookResult.added.join(" + ")} hooks)`)}`));
1649
+ installed.push(platformPrefixed(platform2, `.claude/settings.json ${chalk3.dim(`(${hookResult.added.join(" + ")} hooks)`)}`));
1650
1650
  }
1651
1651
  if (hookResult.migrated) {
1652
- notes.push(platformPrefixed(platform, `${chalk3.yellow("\u2191")} ${chalk3.dim("Migrated old snapshot hook -> session-start hook")}`));
1652
+ notes.push(platformPrefixed(platform2, `${chalk3.yellow("\u2191")} ${chalk3.dim("Migrated old snapshot hook -> session-start hook")}`));
1653
1653
  }
1654
1654
  if (hookResult.added.length === 0 && !hookResult.migrated) {
1655
- notes.push(platformPrefixed(platform, chalk3.dim("Hooks already present \u2014 skipped")));
1655
+ notes.push(platformPrefixed(platform2, chalk3.dim("Hooks already present \u2014 skipped")));
1656
1656
  }
1657
1657
  const disableNativeMemory = readSetupConfig(projectRoot)?.disableNativeMemory ?? true;
1658
1658
  const memoryChanged = applyClaudeAutoMemory(projectRoot, disableNativeMemory);
1659
1659
  if (memoryChanged) {
1660
- notes.push(platformPrefixed(platform, disableNativeMemory ? chalk3.dim("Disabled Claude native auto-memory (autoMemoryEnabled:false) \u2014 dreamcontext owns memory") : chalk3.dim("Enabled Claude native auto-memory (autoMemoryEnabled:true) per config")));
1660
+ notes.push(platformPrefixed(platform2, disableNativeMemory ? chalk3.dim("Disabled Claude native auto-memory (autoMemoryEnabled:false) \u2014 dreamcontext owns memory") : chalk3.dim("Enabled Claude native auto-memory (autoMemoryEnabled:true) per config")));
1661
1661
  }
1662
1662
  } else {
1663
1663
  const codexResult = ensureCodexConfig(projectRoot);
1664
1664
  recordIfManifest2(manifest, ".codex/config.toml", "hook");
1665
1665
  if (codexResult.updated) {
1666
- installed.push(platformPrefixed(platform, ".codex/config.toml (managed hooks block)"));
1666
+ installed.push(platformPrefixed(platform2, ".codex/config.toml (managed hooks block)"));
1667
1667
  }
1668
1668
  try {
1669
1669
  const result = await installInstructions(projectRoot, "codex", "append");
1670
1670
  if (result.action !== "skipped") {
1671
- notes.push(platformPrefixed(platform, `Root guidance synced: ${result.target}`));
1671
+ notes.push(platformPrefixed(platform2, `Root guidance synced: ${result.target}`));
1672
1672
  }
1673
1673
  } catch (e) {
1674
1674
  const msg = e instanceof Error ? e.message : String(e);
1675
- notes.push(platformPrefixed(platform, `${chalk3.yellow("\u26A0")} AGENTS.md install skipped: ${msg}`));
1675
+ notes.push(platformPrefixed(platform2, `${chalk3.yellow("\u26A0")} AGENTS.md install skipped: ${msg}`));
1676
1676
  }
1677
- notes.push(platformPrefixed(platform, chalk3.dim("Codex gap: SubagentStart + PreCompact hooks are Claude-only.")));
1677
+ notes.push(platformPrefixed(platform2, chalk3.dim("Codex gap: SubagentStart + PreCompact hooks are Claude-only.")));
1678
1678
  }
1679
1679
  return { installed, notes };
1680
1680
  }
@@ -1715,8 +1715,8 @@ function registerInstallSkillCommand(program) {
1715
1715
  const manifest = getOrCreateManifest(projectRoot);
1716
1716
  const installed = [];
1717
1717
  const notes = [];
1718
- for (const platform of platforms) {
1719
- const result = await installCoreForPlatform(platform, projectRoot, manifest);
1718
+ for (const platform2 of platforms) {
1719
+ const result = await installCoreForPlatform(platform2, projectRoot, manifest);
1720
1720
  installed.push(...result.installed);
1721
1721
  notes.push(...result.notes);
1722
1722
  }
@@ -1843,8 +1843,8 @@ async function installPlatformIntegration(projectRoot, opts) {
1843
1843
  for (const p of platforms) recordPlatform(manifest, p);
1844
1844
  const installed = [];
1845
1845
  const notes = [];
1846
- for (const platform of platforms) {
1847
- const result = await installCoreForPlatform(platform, projectRoot, manifest);
1846
+ for (const platform2 of platforms) {
1847
+ const result = await installCoreForPlatform(platform2, projectRoot, manifest);
1848
1848
  installed.push(...result.installed);
1849
1849
  notes.push(...result.notes);
1850
1850
  }
@@ -1853,12 +1853,12 @@ async function installPlatformIntegration(projectRoot, opts) {
1853
1853
  directPackInstall(packs, projectRoot, platforms, manifest);
1854
1854
  }
1855
1855
  info("Installing root instruction file(s)...");
1856
- for (const platform of platforms) {
1856
+ for (const platform2 of platforms) {
1857
1857
  try {
1858
- await installInstructions(projectRoot, platform, "append");
1858
+ await installInstructions(projectRoot, platform2, "append");
1859
1859
  } catch (e) {
1860
1860
  const msg = e instanceof Error ? e.message : String(e);
1861
- info(`${platform} root instructions skipped: ${msg}`);
1861
+ info(`${platform2} root instructions skipped: ${msg}`);
1862
1862
  }
1863
1863
  }
1864
1864
  writeManifest(projectRoot, manifest);
@@ -2804,30 +2804,30 @@ function registerCoreCommand(program) {
2804
2804
  releases.command("show").argument("<version>", "Release version to show").description("Show details of a specific release").action((version) => {
2805
2805
  const root = ensureContextRoot();
2806
2806
  const allReleases = getExistingReleases(root);
2807
- const release = allReleases.find((r) => r.version === version);
2808
- if (!release) {
2807
+ const release2 = allReleases.find((r) => r.version === version);
2808
+ if (!release2) {
2809
2809
  error(`Release not found: ${version}`);
2810
2810
  return;
2811
2811
  }
2812
- console.log(header(`Release ${release.version}`));
2813
- console.log(` Date: ${release.date}`);
2814
- console.log(` Summary: ${release.summary}`);
2815
- console.log(` Breaking: ${release.breaking ? "Yes" : "No"}`);
2816
- console.log(` ID: ${release.id}`);
2817
- if (release.tasks.length > 0) {
2812
+ console.log(header(`Release ${release2.version}`));
2813
+ console.log(` Date: ${release2.date}`);
2814
+ console.log(` Summary: ${release2.summary}`);
2815
+ console.log(` Breaking: ${release2.breaking ? "Yes" : "No"}`);
2816
+ console.log(` ID: ${release2.id}`);
2817
+ if (release2.tasks.length > 0) {
2818
2818
  console.log(`
2819
- Tasks (${release.tasks.length}):`);
2820
- for (const id of release.tasks) console.log(` - ${id}`);
2819
+ Tasks (${release2.tasks.length}):`);
2820
+ for (const id of release2.tasks) console.log(` - ${id}`);
2821
2821
  }
2822
- if (release.features.length > 0) {
2822
+ if (release2.features.length > 0) {
2823
2823
  console.log(`
2824
- Features (${release.features.length}):`);
2825
- for (const id of release.features) console.log(` - ${id}`);
2824
+ Features (${release2.features.length}):`);
2825
+ for (const id of release2.features) console.log(` - ${id}`);
2826
2826
  }
2827
- if (release.changelog.length > 0) {
2827
+ if (release2.changelog.length > 0) {
2828
2828
  console.log(`
2829
- Changelog (${release.changelog.length}):`);
2830
- for (const e of release.changelog) {
2829
+ Changelog (${release2.changelog.length}):`);
2830
+ for (const e of release2.changelog) {
2831
2831
  console.log(` - ${e.date} [${e.type}] ${e.scope}: ${e.description.slice(0, 80)}`);
2832
2832
  }
2833
2833
  }
@@ -2885,10 +2885,10 @@ function readSection(filePath, sectionName) {
2885
2885
  const raw = readFileSync12(filePath, "utf-8");
2886
2886
  const parsed = matter3(raw);
2887
2887
  const sections = parseSections(parsed.content);
2888
- const section = findSection(sections, sectionName);
2889
- if (!section) return null;
2888
+ const section2 = findSection(sections, sectionName);
2889
+ if (!section2) return null;
2890
2890
  const lines = parsed.content.split("\n");
2891
- const bodyLines = lines.slice(section.startLine + 1, section.endLine + 1);
2891
+ const bodyLines = lines.slice(section2.startLine + 1, section2.endLine + 1);
2892
2892
  return bodyLines.join("\n").trim();
2893
2893
  }
2894
2894
  function isPlaceholderLine(line) {
@@ -2907,9 +2907,9 @@ function formatListItems(content, checkbox6) {
2907
2907
  return checkbox6 ? `- [ ] ${t}` : `- ${t}`;
2908
2908
  }).join("\n");
2909
2909
  }
2910
- function stripPlaceholderBody(lines, section) {
2911
- const start = section.startLine + 1;
2912
- const end = section.endLine;
2910
+ function stripPlaceholderBody(lines, section2) {
2911
+ const start = section2.startLine + 1;
2912
+ const end = section2.endLine;
2913
2913
  const meaningful = [];
2914
2914
  for (let i = start; i <= end; i++) {
2915
2915
  const t = lines[i]?.trim() ?? "";
@@ -2941,29 +2941,29 @@ function insertToSection(filePath, sectionName, newContent, position = "top", cr
2941
2941
  const raw = readFileSync12(filePath, "utf-8");
2942
2942
  const parsed = matter3(raw);
2943
2943
  let lines = parsed.content.split("\n");
2944
- let section = findSection(parseSections(lines.join("\n")), sectionName);
2945
- if (!section) {
2944
+ let section2 = findSection(parseSections(lines.join("\n")), sectionName);
2945
+ if (!section2) {
2946
2946
  if (createIfMissing) {
2947
2947
  lines.push("", `## ${sectionName}`);
2948
- section = findSection(parseSections(lines.join("\n")), sectionName);
2948
+ section2 = findSection(parseSections(lines.join("\n")), sectionName);
2949
2949
  } else {
2950
2950
  throw new Error(`Section "${sectionName}" not found in ${filePath}`);
2951
2951
  }
2952
2952
  }
2953
- if (replacePlaceholders && section && stripPlaceholderBody(lines, section) > 0) {
2954
- section = findSection(parseSections(lines.join("\n")), sectionName);
2953
+ if (replacePlaceholders && section2 && stripPlaceholderBody(lines, section2) > 0) {
2954
+ section2 = findSection(parseSections(lines.join("\n")), sectionName);
2955
2955
  }
2956
- if (!section) throw new Error(`Section "${sectionName}" not found in ${filePath}`);
2956
+ if (!section2) throw new Error(`Section "${sectionName}" not found in ${filePath}`);
2957
2957
  const contentLines = newContent.split("\n");
2958
2958
  if (position === "top") {
2959
- let insertAt = section.startLine + 1;
2960
- while (insertAt <= section.endLine && (lines[insertAt]?.trim().startsWith("<!--") || lines[insertAt]?.trim() === "")) {
2959
+ let insertAt = section2.startLine + 1;
2960
+ while (insertAt <= section2.endLine && (lines[insertAt]?.trim().startsWith("<!--") || lines[insertAt]?.trim() === "")) {
2961
2961
  insertAt++;
2962
2962
  }
2963
2963
  lines.splice(insertAt, 0, "", ...contentLines);
2964
2964
  } else {
2965
- let last = section.endLine;
2966
- while (last > section.startLine && (lines[last]?.trim() ?? "") === "") last--;
2965
+ let last = section2.endLine;
2966
+ while (last > section2.startLine && (lines[last]?.trim() ?? "") === "") last--;
2967
2967
  const insertAt = last + 1;
2968
2968
  const block = ["", ...contentLines];
2969
2969
  if (lines[insertAt] !== void 0 && lines[insertAt].trim() !== "") block.push("");
@@ -3311,15 +3311,15 @@ function registerFeaturesCommand(program) {
3311
3311
  features.command("insert").argument("<name>").argument(
3312
3312
  "<section>",
3313
3313
  "Section: changelog, notes, technical_details, constraints, user_stories, acceptance_criteria"
3314
- ).argument("[content...]", "Content to insert").description("Insert content into a feature section").action(async (name, section, contentParts) => {
3314
+ ).argument("[content...]", "Content to insert").description("Insert content into a feature section").action(async (name, section2, contentParts) => {
3315
3315
  const file = findFeatureFile(name);
3316
3316
  if (!file) {
3317
3317
  error(`Feature not found: ${name}`);
3318
3318
  return;
3319
3319
  }
3320
- const sectionKey = section.toLowerCase();
3320
+ const sectionKey = section2.toLowerCase();
3321
3321
  if (!SECTION_MAP[sectionKey]) {
3322
- error(`Unknown section: "${section}". Valid sections: ${Object.keys(SECTION_MAP).join(", ")}`);
3322
+ error(`Unknown section: "${section2}". Valid sections: ${Object.keys(SECTION_MAP).join(", ")}`);
3323
3323
  return;
3324
3324
  }
3325
3325
  const rawContent = contentParts.length > 0 ? contentParts.join(" ") : await promptInput({ message: `Content for ${SECTION_MAP[sectionKey]}:` });
@@ -4526,15 +4526,15 @@ function registerTasksCommand(program) {
4526
4526
  tasks.command("insert").argument("<name>").argument(
4527
4527
  "<section>",
4528
4528
  "Section: why, user_stories, acceptance_criteria, constraints, technical_details, notes, changelog"
4529
- ).argument("[content...]", "Content to insert").description("Insert content into a task section").action(async (name, section, contentParts) => {
4529
+ ).argument("[content...]", "Content to insert").description("Insert content into a task section").action(async (name, section2, contentParts) => {
4530
4530
  const file = findTaskFile(name);
4531
4531
  if (!file) {
4532
4532
  error(`Task not found: ${name}`);
4533
4533
  return;
4534
4534
  }
4535
- const sectionKey = section.toLowerCase();
4535
+ const sectionKey = section2.toLowerCase();
4536
4536
  if (!SECTION_MAP[sectionKey]) {
4537
- error(`Unknown section: "${section}". Valid sections: ${Object.keys(SECTION_MAP).join(", ")}`);
4537
+ error(`Unknown section: "${section2}". Valid sections: ${Object.keys(SECTION_MAP).join(", ")}`);
4538
4538
  return;
4539
4539
  }
4540
4540
  const rawContent = contentParts.length > 0 ? contentParts.join(" ") : await promptInput({ message: `Content for ${SECTION_MAP[sectionKey]}:` });
@@ -4736,8 +4736,8 @@ function detectInstalledPacks(projectRoot, platforms) {
4736
4736
  ...loaded.catalog.standalone.map((s) => s.name)
4737
4737
  ]);
4738
4738
  const found = /* @__PURE__ */ new Set();
4739
- for (const platform of platforms) {
4740
- const root = platformSkillRoot(projectRoot, platform);
4739
+ for (const platform2 of platforms) {
4740
+ const root = platformSkillRoot(projectRoot, platform2);
4741
4741
  if (!existsSync21(root)) continue;
4742
4742
  for (const name of readdirSync6(root)) {
4743
4743
  if (name === "dreamcontext") continue;
@@ -4844,8 +4844,8 @@ function registerUpdateCommand(program) {
4844
4844
  const installed = [];
4845
4845
  const notes = [];
4846
4846
  if (!opts.packsOnly) {
4847
- for (const platform of platforms) {
4848
- const result = await installCoreForPlatform(platform, projectRoot, newManifest);
4847
+ for (const platform2 of platforms) {
4848
+ const result = await installCoreForPlatform(platform2, projectRoot, newManifest);
4849
4849
  installed.push(...result.installed);
4850
4850
  notes.push(...result.notes);
4851
4851
  }
@@ -5131,7 +5131,7 @@ function acquireLock() {
5131
5131
  } finally {
5132
5132
  closeSync(fd);
5133
5133
  }
5134
- return function release() {
5134
+ return function release2() {
5135
5135
  try {
5136
5136
  const heldRaw = readFileSync15(lockPath, "utf8").trim();
5137
5137
  if (Number.parseInt(heldRaw, 10) === process.pid) {
@@ -5142,8 +5142,8 @@ function acquireLock() {
5142
5142
  };
5143
5143
  }
5144
5144
  function withLock(fn) {
5145
- const release = acquireLock();
5146
- return Promise.resolve().then(() => fn()).finally(() => release());
5145
+ const release2 = acquireLock();
5146
+ return Promise.resolve().then(() => fn()).finally(() => release2());
5147
5147
  }
5148
5148
  function isoTs() {
5149
5149
  return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
@@ -5709,6 +5709,110 @@ var init_version_check = __esm({
5709
5709
  }
5710
5710
  });
5711
5711
 
5712
+ // src/lib/snapshot-budget.ts
5713
+ function estimateTokens(s) {
5714
+ return Math.ceil(s.length / 4);
5715
+ }
5716
+ function resolveBudget(env) {
5717
+ if (env === void 0 || env.trim() === "") return DEFAULT_SNAPSHOT_BUDGET_TOKENS;
5718
+ const v = env.trim().toLowerCase();
5719
+ if (v === "0" || v === "off" || v === "false") return null;
5720
+ const n = Number.parseInt(v, 10);
5721
+ if (Number.isNaN(n)) return DEFAULT_SNAPSHOT_BUDGET_TOKENS;
5722
+ return Math.max(2e3, n);
5723
+ }
5724
+ function applyBudget(sections, budgetTokens) {
5725
+ const render = (levels2) => sections.map((s) => {
5726
+ const lvl = levels2.get(s.id) ?? 0;
5727
+ const text2 = lvl === 0 ? s.text : s.demotions[lvl - 1];
5728
+ return text2;
5729
+ }).filter((t) => t.trim() !== "").join("\n");
5730
+ const levels = /* @__PURE__ */ new Map();
5731
+ let text = render(levels);
5732
+ if (budgetTokens === null || estimateTokens(text) <= budgetTokens) {
5733
+ return { text, demoted: [], estimatedTokens: estimateTokens(text), overBudget: false };
5734
+ }
5735
+ const maxLevels = Math.max(0, ...sections.map((s) => s.demotions?.length ?? 0));
5736
+ outer:
5737
+ for (let level = 1; level <= maxLevels; level++) {
5738
+ for (const s of sections) {
5739
+ if (s.neverEvict) continue;
5740
+ if (!s.demotions || s.demotions.length < level) continue;
5741
+ levels.set(s.id, level);
5742
+ text = render(levels);
5743
+ if (estimateTokens(text) <= budgetTokens) break outer;
5744
+ }
5745
+ }
5746
+ const demoted = [...levels.entries()].map(([id, level]) => ({ id, level }));
5747
+ if (demoted.length > 0) {
5748
+ const ids = demoted.map((d) => d.id).join(", ");
5749
+ text += [
5750
+ "\n\n---",
5751
+ `_Budget note: sections demoted to fit the snapshot budget (${ids}).`,
5752
+ "Nothing is lost \u2014 every demoted item keeps its file path above, and",
5753
+ '`dreamcontext memory recall "<keywords>"` surfaces the full content on demand._'
5754
+ ].join("\n");
5755
+ }
5756
+ const finalTokens = estimateTokens(text);
5757
+ return {
5758
+ text,
5759
+ demoted,
5760
+ estimatedTokens: finalTokens,
5761
+ overBudget: finalTokens > budgetTokens
5762
+ };
5763
+ }
5764
+ function demoteMemoryBlock(block, keep) {
5765
+ const marker = /^## Technical Decisions\s*$/m;
5766
+ const m = marker.exec(block);
5767
+ if (!m) return block;
5768
+ const start = m.index + m[0].length;
5769
+ const nextH2 = block.slice(start).search(/^## /m);
5770
+ const end = nextH2 === -1 ? block.length : start + nextH2;
5771
+ const section2 = block.slice(start, end);
5772
+ const lines = section2.split("\n");
5773
+ const preamble = [];
5774
+ const bullets = [];
5775
+ for (const line of lines) {
5776
+ if (/^- /.test(line)) bullets.push([line]);
5777
+ else if (bullets.length === 0) preamble.push(line);
5778
+ else bullets[bullets.length - 1].push(line);
5779
+ }
5780
+ if (bullets.length <= keep) return block;
5781
+ const kept = bullets.slice(0, keep).map((b) => b.join("\n"));
5782
+ const titleOf = (b) => {
5783
+ const head = b[0];
5784
+ const bold = /^- \*\*(.+?)\*\*/.exec(head);
5785
+ if (bold) return bold[1];
5786
+ const plain = head.replace(/^- /, "");
5787
+ return plain.length > 90 ? plain.slice(0, 87) + "..." : plain;
5788
+ };
5789
+ const titles = bullets.slice(keep).map((b) => `- ${titleOf(b)}`);
5790
+ const rebuilt = [
5791
+ ...preamble,
5792
+ ...kept,
5793
+ "",
5794
+ `### Older decisions (${titles.length} \u2014 titles only, \`dreamcontext memory recall\` for detail):`,
5795
+ ...titles,
5796
+ ""
5797
+ ].join("\n");
5798
+ return block.slice(0, start) + "\n" + rebuilt.replace(/^\n+/, "") + block.slice(end);
5799
+ }
5800
+ function demoteTaskList(entries, keep) {
5801
+ if (entries.length <= keep) return entries;
5802
+ const rest = entries.length - keep;
5803
+ return [
5804
+ ...entries.slice(0, keep),
5805
+ `- (+${rest} more active task(s) \u2014 \`dreamcontext tasks list\` or memory recall)`
5806
+ ];
5807
+ }
5808
+ var DEFAULT_SNAPSHOT_BUDGET_TOKENS;
5809
+ var init_snapshot_budget = __esm({
5810
+ "src/lib/snapshot-budget.ts"() {
5811
+ "use strict";
5812
+ DEFAULT_SNAPSHOT_BUDGET_TOKENS = 1e4;
5813
+ }
5814
+ });
5815
+
5712
5816
  // src/cli/commands/snapshot.ts
5713
5817
  import { readFileSync as readFileSync20, existsSync as existsSync28, statSync as statSync3 } from "fs";
5714
5818
  import { join as join27, basename as basename9, dirname as dirname11 } from "path";
@@ -5740,11 +5844,16 @@ function extractFirstParagraph(content) {
5740
5844
  const result = paragraphLines.join(" ");
5741
5845
  return result.length > 300 ? result.slice(0, 297) + "..." : result;
5742
5846
  }
5743
- function getActiveTaskLines(root) {
5847
+ function sortTaskEntriesByActivity(entries) {
5848
+ const statusRank = (s) => s === "in_progress" ? 0 : s === "blocked" ? 1 : 2;
5849
+ const prioRank = (p) => p === "critical" ? 0 : p === "high" ? 1 : p === "medium" ? 2 : 3;
5850
+ return [...entries].sort((a, b) => statusRank(a.status) - statusRank(b.status) || prioRank(a.priority) - prioRank(b.priority) || b.updated.localeCompare(a.updated));
5851
+ }
5852
+ function getActiveTaskEntries(root) {
5744
5853
  const stateDir = join27(root, "state");
5745
5854
  if (!existsSync28(stateDir)) return [];
5746
5855
  const taskFiles = fg8.sync("*.md", { cwd: stateDir, absolute: true });
5747
- const lines = [];
5856
+ const entries = [];
5748
5857
  for (const file of taskFiles) {
5749
5858
  try {
5750
5859
  const { data } = readFrontmatter(file);
@@ -5767,11 +5876,11 @@ function getActiveTaskLines(root) {
5767
5876
  }
5768
5877
  } catch {
5769
5878
  }
5770
- lines.push(line);
5879
+ entries.push({ text: line, status, priority, updated });
5771
5880
  } catch {
5772
5881
  }
5773
5882
  }
5774
- return lines;
5883
+ return entries;
5775
5884
  }
5776
5885
  function resolveActiveTaskPath(root) {
5777
5886
  const stateDir = join27(root, "state");
@@ -5879,7 +5988,14 @@ function getVersionNudge(root) {
5879
5988
  function generateSnapshot() {
5880
5989
  const root = resolveContextRoot();
5881
5990
  if (!root) return "";
5882
- const parts = ["# Agent Context \u2014 Auto-loaded\n"];
5991
+ const sections = [];
5992
+ let parts = ["# Agent Context \u2014 Auto-loaded\n"];
5993
+ const flush = (id, opts = {}) => {
5994
+ if (parts.length > 0) {
5995
+ sections.push({ id, text: parts.join("\n"), ...opts });
5996
+ parts = [];
5997
+ }
5998
+ };
5883
5999
  const soulPath = join27(root, "core", "0.soul.md");
5884
6000
  if (existsSync28(soulPath)) {
5885
6001
  const content = readFileSync20(soulPath, "utf-8").trim();
@@ -5894,6 +6010,7 @@ function generateSnapshot() {
5894
6010
  parts.push(content);
5895
6011
  parts.push("");
5896
6012
  }
6013
+ flush("identity", { neverEvict: true });
5897
6014
  const memoryPath = join27(root, "core", "2.memory.md");
5898
6015
  if (existsSync28(memoryPath)) {
5899
6016
  const content = readFileSync20(memoryPath, "utf-8").trim();
@@ -5901,6 +6018,8 @@ function generateSnapshot() {
5901
6018
  parts.push("## Memory (Technical Decisions, Known Issues, Session Log)\n");
5902
6019
  parts.push(content);
5903
6020
  parts.push("");
6021
+ const full = parts.join("\n");
6022
+ flush("memory", { demotions: [demoteMemoryBlock(full, 8), demoteMemoryBlock(full, 4)] });
5904
6023
  }
5905
6024
  }
5906
6025
  const coreExtras = buildCoreIndex(root);
@@ -5915,11 +6034,15 @@ function generateSnapshot() {
5915
6034
  }
5916
6035
  parts.push("");
5917
6036
  }
5918
- const activeTasks = getActiveTaskLines(root);
6037
+ flush("extended-core", { neverEvict: true });
6038
+ const activeTasks = getActiveTaskEntries(root);
5919
6039
  if (activeTasks.length > 0) {
5920
6040
  parts.push("## Active Tasks\n");
5921
- parts.push(activeTasks.join("\n"));
6041
+ parts.push(activeTasks.map((t) => t.text).join("\n"));
5922
6042
  parts.push("");
6043
+ const sortedTexts = sortTaskEntriesByActivity(activeTasks).map((t) => t.text);
6044
+ const renderTasks = (keep) => ["## Active Tasks\n", demoteTaskList(sortedTexts, keep).join("\n"), ""].join("\n");
6045
+ flush("tasks", { demotions: [renderTasks(12), renderTasks(8)] });
5923
6046
  }
5924
6047
  const productKnowledge = getActiveProductKnowledge(root);
5925
6048
  if (productKnowledge.length > 0) {
@@ -5930,6 +6053,7 @@ function generateSnapshot() {
5930
6053
  parts.push(versionNudge);
5931
6054
  parts.push("");
5932
6055
  }
6056
+ flush("product-and-nudge", { neverEvict: true });
5933
6057
  const sleepState = readSleepState(root);
5934
6058
  if (sleepState.bookmarks.length > 0) {
5935
6059
  const sorted = [...sleepState.bookmarks].sort((a, b) => b.salience - a.salience);
@@ -5976,6 +6100,7 @@ function generateSnapshot() {
5976
6100
  writeSleepState(root, sleepState);
5977
6101
  }
5978
6102
  }
6103
+ flush("awareness", { neverEvict: true });
5979
6104
  const CHANGELOG_TIER1 = 3;
5980
6105
  const CHANGELOG_TIER2 = 10;
5981
6106
  const TIER1_BODY_CHARS = 300;
@@ -5992,36 +6117,53 @@ function generateSnapshot() {
5992
6117
  const entries = readJsonArray(changelogPath);
5993
6118
  const tier1 = entries.slice(0, CHANGELOG_TIER1);
5994
6119
  const tier2 = entries.slice(CHANGELOG_TIER1, CHANGELOG_TIER1 + CHANGELOG_TIER2);
5995
- if (tier1.length > 0) {
5996
- parts.push("## Recent Changelog\n");
6120
+ const headlineOf = (e) => {
6121
+ const date = String(e.date ?? "");
6122
+ const type = String(e.type ?? "");
6123
+ const scope = String(e.scope ?? "");
6124
+ const summary = typeof e.summary === "string" ? e.summary : "";
6125
+ const desc = String(e.description ?? "");
6126
+ const headline = summary || (desc.length > 200 ? desc.slice(0, 197) + "..." : desc);
6127
+ return `- ${date} [${type}] ${scope}: ${headline}${authorSuffix(e)}`;
6128
+ };
6129
+ const tier2LineOf = (e) => {
6130
+ const date = String(e.date ?? "");
6131
+ const type = String(e.type ?? "");
6132
+ const scope = String(e.scope ?? "");
6133
+ const summary = typeof e.summary === "string" ? e.summary : "";
6134
+ const desc = String(e.description ?? "");
6135
+ const raw = summary || desc;
6136
+ const line = raw.length > TIER2_LINE_CHARS ? raw.slice(0, TIER2_LINE_CHARS - 3) + "..." : raw;
6137
+ return `- ${date} [${type}] ${scope}: ${line}${authorSuffix(e)}`;
6138
+ };
6139
+ const renderChangelog = (withBodies, tier2Count) => {
6140
+ const out = ["## Recent Changelog\n"];
5997
6141
  for (const e of tier1) {
5998
- const date = String(e.date ?? "");
5999
- const type = String(e.type ?? "");
6000
- const scope = String(e.scope ?? "");
6142
+ out.push(headlineOf(e));
6001
6143
  const summary = typeof e.summary === "string" ? e.summary : "";
6002
6144
  const desc = String(e.description ?? "");
6003
- const headline = summary || (desc.length > 200 ? desc.slice(0, 197) + "..." : desc);
6004
- parts.push(`- ${date} [${type}] ${scope}: ${headline}${authorSuffix(e)}`);
6005
- if (summary && desc && desc !== summary) {
6145
+ if (withBodies && summary && desc && desc !== summary) {
6006
6146
  const body = desc.length > TIER1_BODY_CHARS ? desc.slice(0, TIER1_BODY_CHARS - 3) + "..." : desc;
6007
- parts.push(` ${body}`);
6147
+ out.push(` ${body}`);
6008
6148
  }
6009
6149
  }
6010
- if (tier2.length > 0) {
6011
- parts.push("");
6012
- parts.push("### Older (titles only \u2014 use `dreamcontext memory recall --types changelog` for detail):");
6013
- for (const e of tier2) {
6014
- const date = String(e.date ?? "");
6015
- const type = String(e.type ?? "");
6016
- const scope = String(e.scope ?? "");
6017
- const summary = typeof e.summary === "string" ? e.summary : "";
6018
- const desc = String(e.description ?? "");
6019
- const raw = summary || desc;
6020
- const line = raw.length > TIER2_LINE_CHARS ? raw.slice(0, TIER2_LINE_CHARS - 3) + "..." : raw;
6021
- parts.push(`- ${date} [${type}] ${scope}: ${line}${authorSuffix(e)}`);
6022
- }
6150
+ const t2 = tier2.slice(0, tier2Count);
6151
+ if (t2.length > 0) {
6152
+ out.push("");
6153
+ out.push("### Older (titles only \u2014 use `dreamcontext memory recall --types changelog` for detail):");
6154
+ for (const e of t2) out.push(tier2LineOf(e));
6023
6155
  }
6024
- parts.push("");
6156
+ out.push("");
6157
+ return out;
6158
+ };
6159
+ if (tier1.length > 0) {
6160
+ parts.push(...renderChangelog(true, CHANGELOG_TIER2));
6161
+ flush("changelog", {
6162
+ demotions: [
6163
+ renderChangelog(false, 5).join("\n"),
6164
+ renderChangelog(false, 0).join("\n")
6165
+ ]
6166
+ });
6025
6167
  }
6026
6168
  } catch {
6027
6169
  }
@@ -6062,10 +6204,12 @@ function generateSnapshot() {
6062
6204
  } catch {
6063
6205
  }
6064
6206
  }
6207
+ flush("releases", { neverEvict: true });
6065
6208
  const featuresDir = join27(root, "core", "features");
6066
6209
  if (existsSync28(featuresDir)) {
6067
6210
  const featureFiles = fg8.sync("*.md", { cwd: featuresDir, absolute: true });
6068
6211
  const features = [];
6212
+ const featureMeta = [];
6069
6213
  for (const file of featureFiles) {
6070
6214
  try {
6071
6215
  const { data } = readFrontmatter(file);
@@ -6119,6 +6263,12 @@ function generateSnapshot() {
6119
6263
  featureLine += "\n" + details.join("\n");
6120
6264
  }
6121
6265
  features.push(featureLine);
6266
+ featureMeta.push({
6267
+ detail: featureLine,
6268
+ nameLine: `- **${name}** (status: ${status}) -> _dream_context/core/features/${name}.md`,
6269
+ status,
6270
+ updated: String(data.updated ?? data.created ?? "")
6271
+ });
6122
6272
  } catch {
6123
6273
  }
6124
6274
  }
@@ -6126,11 +6276,21 @@ function generateSnapshot() {
6126
6276
  parts.push("## Features\n");
6127
6277
  parts.push(features.join("\n"));
6128
6278
  parts.push("");
6279
+ const activeFirst = [...featureMeta].sort((a, b) => {
6280
+ const rank = (s) => s === "in_progress" || s === "active" ? 0 : s === "planned" || s === "todo" ? 1 : 2;
6281
+ return rank(a.status) - rank(b.status) || b.updated.localeCompare(a.updated);
6282
+ });
6283
+ const renderFeatures = (detailCount) => {
6284
+ const lines = activeFirst.map((f, i) => i < detailCount ? f.detail : f.nameLine);
6285
+ return ["## Features\n", lines.join("\n"), ""].join("\n");
6286
+ };
6287
+ flush("features", { demotions: [renderFeatures(8), renderFeatures(0)] });
6129
6288
  }
6130
6289
  }
6131
6290
  const knowledgeEntries = buildKnowledgeIndex(root);
6132
6291
  if (knowledgeEntries.length > 0) {
6133
6292
  const indexLines = [];
6293
+ const compactLines = [];
6134
6294
  const pinnedEntries = [];
6135
6295
  const warmEntries = [];
6136
6296
  const activeTaskTags = [];
@@ -6164,6 +6324,7 @@ function generateSnapshot() {
6164
6324
  }
6165
6325
  }
6166
6326
  indexLines.push(`- **${entry.slug}** (_dream_context/knowledge/${entry.slug}.md): ${entry.description}${tagsStr}${stalenessNote}`);
6327
+ compactLines.push(`- **${entry.slug}**${tagsStr}${stalenessNote ? " (stale)" : ""}`);
6167
6328
  if (entry.pinned) {
6168
6329
  pinnedEntries.push(entry);
6169
6330
  } else if (!stalenessNote) {
@@ -6190,17 +6351,48 @@ function generateSnapshot() {
6190
6351
  parts.push(nonPinnedLines.join("\n"));
6191
6352
  }
6192
6353
  parts.push("");
6193
- if (warmEntries.length > 0) {
6194
- parts.push("## Warm Knowledge (Recently Relevant)\n");
6195
- for (const entry of warmEntries) {
6196
- parts.push(`### ${entry.name}`);
6197
- const firstParagraph = extractFirstParagraph(entry.content);
6198
- if (firstParagraph) {
6199
- parts.push(firstParagraph);
6354
+ {
6355
+ const compactNonPinned = compactLines.filter((_, i) => !pinnedSlugs.has(knowledgeEntries[i]?.slug));
6356
+ const compact = ["## Knowledge Index\n"];
6357
+ if (pinnedEntries.length > 0) {
6358
+ compact.push("> !!! \xC7OK \xD6NEML\u0130 !!! Kullan\u0131c\u0131 bu bilgiyi pinlemi\u015F \u2014 yapaca\u011F\u0131n bir i\u015Fle ili\u015Fkisi varsa MUTLAKA OKU!\n");
6359
+ for (const entry of pinnedEntries) {
6360
+ const tagsStr = entry.tags.length > 0 ? ` [${entry.tags.join(", ")}]` : "";
6361
+ compact.push(`- \u{1F4CC} **${entry.slug}** (_dream_context/knowledge/${entry.slug}.md): ${entry.description}${tagsStr}`);
6200
6362
  }
6201
- parts.push(`-> Read full: _dream_context/knowledge/${entry.slug}.md`);
6202
- parts.push("");
6363
+ compact.push("");
6364
+ compact.push("### Other knowledge:\n");
6203
6365
  }
6366
+ compact.push("(slugs only \u2014 files at _dream_context/knowledge/<slug>.md; descriptions via `dreamcontext knowledge index` or memory recall)");
6367
+ compact.push(compactNonPinned.join("\n"));
6368
+ compact.push("");
6369
+ flush("knowledge-index", { demotions: [compact.join("\n")] });
6370
+ }
6371
+ if (warmEntries.length > 0) {
6372
+ const renderWarm = (cap) => {
6373
+ const out = ["## Warm Knowledge (Recently Relevant)\n"];
6374
+ for (const entry of warmEntries.slice(0, cap)) {
6375
+ out.push(`### ${entry.name}`);
6376
+ const firstParagraph = extractFirstParagraph(entry.content);
6377
+ if (firstParagraph) {
6378
+ out.push(firstParagraph);
6379
+ }
6380
+ out.push(`-> Read full: _dream_context/knowledge/${entry.slug}.md`);
6381
+ out.push("");
6382
+ }
6383
+ if (warmEntries.length > cap) {
6384
+ out.push(`(+${warmEntries.length - cap} more warm file(s) \u2014 listed in the Knowledge Index above)`);
6385
+ out.push("");
6386
+ }
6387
+ return out;
6388
+ };
6389
+ parts.push(...renderWarm(warmEntries.length));
6390
+ flush("warm-knowledge", {
6391
+ demotions: [
6392
+ renderWarm(4).join("\n"),
6393
+ "(Warm knowledge omitted for budget \u2014 the Knowledge Index above lists every file; recall surfaces them on demand.)\n"
6394
+ ]
6395
+ });
6204
6396
  }
6205
6397
  }
6206
6398
  try {
@@ -6211,7 +6403,9 @@ function generateSnapshot() {
6211
6403
  }
6212
6404
  } catch {
6213
6405
  }
6214
- return parts.join("\n").trim();
6406
+ flush("marketing", { neverEvict: true });
6407
+ const budget = resolveBudget(process.env.DREAMCONTEXT_SNAPSHOT_BUDGET);
6408
+ return applyBudget(sections, budget).text.trim();
6215
6409
  }
6216
6410
  function generateSubagentBriefing() {
6217
6411
  const root = resolveContextRoot();
@@ -6339,10 +6533,10 @@ function generateSubagentBriefing() {
6339
6533
  parts.push("");
6340
6534
  }
6341
6535
  }
6342
- const activeTasks = getActiveTaskLines(root);
6536
+ const activeTasks = sortTaskEntriesByActivity(getActiveTaskEntries(root)).map((t) => t.text);
6343
6537
  if (activeTasks.length > 0) {
6344
6538
  parts.push("## Active Tasks\n");
6345
- parts.push(activeTasks.join("\n"));
6539
+ parts.push(demoteTaskList(activeTasks, 12).join("\n"));
6346
6540
  parts.push("");
6347
6541
  }
6348
6542
  parts.push("## Task Awareness\n");
@@ -6389,6 +6583,7 @@ var init_snapshot2 = __esm({
6389
6583
  init_version_check();
6390
6584
  init_manifest();
6391
6585
  init_feature_freshness();
6586
+ init_snapshot_budget();
6392
6587
  }
6393
6588
  });
6394
6589
 
@@ -6648,9 +6843,20 @@ function expandQueryTerms(queryTerms, stem) {
6648
6843
  }
6649
6844
  }
6650
6845
  }
6846
+ for (const [surfaceKey, targets] of Object.entries(DIRECTED_BRIDGES)) {
6847
+ const stemmedKey = stem(surfaceKey);
6848
+ if (!primary.has(stemmedKey)) continue;
6849
+ for (const target of targets) {
6850
+ const stemmedTarget = stem(target);
6851
+ if (primary.has(stemmedTarget)) continue;
6852
+ if (!expansions.has(stemmedTarget)) {
6853
+ expansions.set(stemmedTarget, SYNONYM_WEIGHT);
6854
+ }
6855
+ }
6856
+ }
6651
6857
  return expansions;
6652
6858
  }
6653
- var SYNONYM_GROUPS, SYNONYMS, SYNONYM_WEIGHT;
6859
+ var SYNONYM_GROUPS, DIRECTED_BRIDGES, SYNONYMS, SYNONYM_WEIGHT;
6654
6860
  var init_recall_synonyms = __esm({
6655
6861
  "src/lib/recall-synonyms.ts"() {
6656
6862
  "use strict";
@@ -6669,6 +6875,9 @@ var init_recall_synonyms = __esm({
6669
6875
  ["hook", "hooks"],
6670
6876
  // Memory / remember (core project concept) + TR (hafıza / bellek / beyin)
6671
6877
  ["memory", "remember", "recollection", "haf\u0131za", "bellek", "beyin", "beynini"],
6878
+ // Context (the product's core noun) + TR (bağlam). Bridges natural-TR queries
6879
+ // ("bağlama enjekte eden şey") to the `context-*` doc family.
6880
+ ["context", "ba\u011Flam", "ba\u011Flama", "ba\u011Flam\u0131"],
6672
6881
  // Vector / embeddings / semantic (the path NOT taken — mem0 decision)
6673
6882
  ["vector", "embedding", "embeddings", "semantic"],
6674
6883
  // Keyword / bm25 (the path taken)
@@ -6694,6 +6903,32 @@ var init_recall_synonyms = __esm({
6694
6903
  // Debt / borç (sleep debt)
6695
6904
  ["debt", "bor\xE7"]
6696
6905
  ];
6906
+ DIRECTED_BRIDGES = {
6907
+ // This corpus's own verbs for consolidation ("folds what changed back",
6908
+ // "promotes learnings") — paraphrase queries use them, docs say "consolidate".
6909
+ // All three consolidat* inflection stems listed so the bridge reaches every
6910
+ // form the docs use (consolidation / consolidate / consolidating→consolidat).
6911
+ fold: ["consolidation", "consolidate", "consolidating", "sleep"],
6912
+ promote: ["consolidation", "consolidate", "consolidating", "sleep"],
6913
+ // Brain-as-memory phrasing ("the project's brain") → the memory doc family.
6914
+ brain: ["memory"],
6915
+ // "project folder" / TR klasör/dizin → the vault/registry concept.
6916
+ // `dizini` (accusative) is listed as its own surface form — the conservative
6917
+ // stemmer deliberately does not strip bare-n-buffer accusatives.
6918
+ folder: ["vault", "registry", "multivault"],
6919
+ klas\u00F6r: ["vault", "registry", "multivault"],
6920
+ dizin: ["vault", "registry", "multivault"],
6921
+ dizini: ["vault", "registry", "multivault"],
6922
+ // TR release/publish vocabulary → the npm-shipping doc family.
6923
+ s\u00FCr\u00FCm: ["release", "version", "publish"],
6924
+ yay\u0131n: ["publish", "release"],
6925
+ ad\u0131m: ["step"],
6926
+ // TR sleep-debt phrasing: seviye(level) / eşik(threshold).
6927
+ seviye: ["level"],
6928
+ e\u015Fik: ["threshold"],
6929
+ // TR "oturum başında" (at session start) — `baş` (start/head) → start.
6930
+ ba\u015F: ["start"]
6931
+ };
6697
6932
  SYNONYMS = (() => {
6698
6933
  const map = /* @__PURE__ */ new Map();
6699
6934
  for (const group of SYNONYM_GROUPS) {
@@ -6722,11 +6957,12 @@ function stemEn(token) {
6722
6957
  if (token.length <= 4) return token;
6723
6958
  if (token.endsWith("ing") && token.length > 5) return token.slice(0, -3);
6724
6959
  if (token.endsWith("ed") && token.length > 4) return token.slice(0, -2);
6725
- if (token.endsWith("es") && token.length > 4) return token.slice(0, -2);
6726
- if (token.endsWith("s") && !token.endsWith("ss") && token.length > 4) return token.slice(0, -1);
6727
- return token;
6960
+ let t = token;
6961
+ if (t.endsWith("s") && !t.endsWith("ss") && t.length > 4) t = t.slice(0, -1);
6962
+ if (t.endsWith("e") && t.length > 5) t = t.slice(0, -1);
6963
+ return t;
6728
6964
  }
6729
- function stemTr(token) {
6965
+ function stemTrOnce(token) {
6730
6966
  if (token.length <= 4) return token;
6731
6967
  for (const suf of TR_SUFFIXES) {
6732
6968
  if (token.length - suf.length > 2 && token.endsWith(suf)) {
@@ -6735,8 +6971,15 @@ function stemTr(token) {
6735
6971
  }
6736
6972
  return token;
6737
6973
  }
6974
+ function stemTr(token) {
6975
+ const once = stemTrOnce(token);
6976
+ if (once === token) return token;
6977
+ return stemTrOnce(once);
6978
+ }
6738
6979
  function stemToken(token) {
6739
- return stemTr(stemEn(token));
6980
+ const t = stemTr(stemEn(token));
6981
+ if (t !== token && t.endsWith("e") && t.length > 5) return t.slice(0, -1);
6982
+ return t;
6740
6983
  }
6741
6984
  function tokenize(text) {
6742
6985
  return text.toLowerCase().replace(/[^a-z0-9çğıöşü_\-\s]/g, " ").split(/[\s_\-]+/).filter((t) => t.length > 1 && !STOPWORDS.has(t)).map(stemToken).filter((t) => t.length > 1 && !STOPWORDS.has(t));
@@ -7098,7 +7341,7 @@ function bm25Search(query, corpus, topK = 5, opts = {}) {
7098
7341
  const identityBoost = IDENTITY_BOOST * qCoverage * qCoverage * Math.max(rawScore, 1);
7099
7342
  const rankBase = rawScore + fieldBonus + synonymContrib + identityBoost;
7100
7343
  if (rankBase <= 0) continue;
7101
- const rankScore = rankBase * statusMultiplier(doc.status) * recencyMultiplier(doc.updatedAt, now) * (doc.capture ? CAPTURE_RANK_PENALTY : 1);
7344
+ const rankScore = rankBase * statusMultiplier(doc.status) * recencyMultiplier(doc.updatedAt, now) * (doc.capture ? CAPTURE_RANK_PENALTY : 1) * (doc.type === "changelog" ? CHANGELOG_RANK_FACTOR : 1);
7102
7345
  scored.push({
7103
7346
  hit: { doc, score: rawScore, rankScore, snippet: extractSnippet(doc, queryTerms) },
7104
7347
  rawRank: rankBase
@@ -7119,7 +7362,7 @@ function bm25Search(query, corpus, topK = 5, opts = {}) {
7119
7362
  }
7120
7363
  }
7121
7364
  if (boost > 0) {
7122
- s.hit.rankScore += boost * statusMultiplier(s.hit.doc.status) * recencyMultiplier(s.hit.doc.updatedAt, now) * (s.hit.doc.capture ? CAPTURE_RANK_PENALTY : 1);
7365
+ s.hit.rankScore += boost * statusMultiplier(s.hit.doc.status) * recencyMultiplier(s.hit.doc.updatedAt, now) * (s.hit.doc.capture ? CAPTURE_RANK_PENALTY : 1) * (s.hit.doc.type === "changelog" ? CHANGELOG_RANK_FACTOR : 1);
7123
7366
  }
7124
7367
  }
7125
7368
  }
@@ -7147,7 +7390,7 @@ function extractSnippet(doc, queryTerms) {
7147
7390
  const end = Math.min(lines.length, bestIdx + 2);
7148
7391
  return lines.slice(start, end).join("\n").trim();
7149
7392
  }
7150
- var STOPWORDS, TR_SUFFIXES, FIELD_WEIGHTS, WIKILINK_RE, K1, B, FIELD_WEIGHT_BONUS, IDENTITY_BOOST, CAPTURE_RANK_PENALTY, STATUS_PENALTY, LINK_DECAY;
7393
+ var STOPWORDS, TR_SUFFIXES, FIELD_WEIGHTS, WIKILINK_RE, K1, B, FIELD_WEIGHT_BONUS, IDENTITY_BOOST, CAPTURE_RANK_PENALTY, STATUS_PENALTY, CHANGELOG_RANK_FACTOR, LINK_DECAY;
7151
7394
  var init_recall = __esm({
7152
7395
  "src/lib/recall.ts"() {
7153
7396
  "use strict";
@@ -7243,30 +7486,104 @@ var init_recall = __esm({
7243
7486
  "sen",
7244
7487
  "biz",
7245
7488
  "siz",
7246
- "onlar"
7489
+ "onlar",
7490
+ // Turkish question/filler words — carry no content signal but inflect freely,
7491
+ // so they survive suffix folding as noise terms in natural TR queries
7492
+ // ("güvenlik açıkları NELERDİ", "NASIL hesaplanıyor"). Filtering them keeps
7493
+ // TR query vectors as clean as their EN equivalents (where "what/how" are
7494
+ // already stopwords).
7495
+ "nas\u0131l",
7496
+ "neden",
7497
+ "niye",
7498
+ "nedir",
7499
+ "neler",
7500
+ "nelerdi",
7501
+ "nelerdir",
7502
+ "hangi",
7503
+ "hangisi",
7504
+ "nerede",
7505
+ "nereye",
7506
+ "nereden",
7507
+ "\u015Fey",
7508
+ "\u015Feyi",
7509
+ "eden",
7510
+ "olan",
7511
+ "olarak",
7512
+ "bunu",
7513
+ "bunun",
7514
+ "\u015Funu",
7515
+ "onun",
7516
+ "yapan",
7517
+ "midir",
7518
+ "m\u0131d\u0131r"
7247
7519
  ]);
7248
7520
  TR_SUFFIXES = [
7249
7521
  "lerinden",
7250
7522
  "lar\u0131ndan",
7523
+ "lerinde",
7524
+ "lar\u0131nda",
7251
7525
  "lerine",
7252
7526
  "lar\u0131na",
7253
7527
  "leri",
7254
7528
  "lar\u0131",
7255
7529
  "ler",
7256
7530
  "lar",
7531
+ // locative (+possessive buffer): oturumda / başında / içinde / sunucusunda
7532
+ "\u0131nda",
7533
+ "inde",
7534
+ "unda",
7535
+ "\xFCnde",
7536
+ "nda",
7537
+ "nde",
7538
+ "de",
7539
+ "da",
7540
+ // ablative: sunucudan / sistemden (+ voiceless variants)
7257
7541
  "den",
7258
7542
  "dan",
7543
+ "ten",
7544
+ "tan",
7545
+ // genitive: projenin / sunucunun
7259
7546
  "nin",
7260
7547
  "n\u0131n",
7261
7548
  "nun",
7262
7549
  "n\xFCn",
7263
- "de",
7264
- "da",
7550
+ // 3sg possessive after vowel: sunucusu / kutusu / seviyesi
7551
+ "s\u0131",
7552
+ "si",
7553
+ "su",
7554
+ "s\xFC",
7555
+ // possessive+locative / +genitive / +accusative compounds: sunucusunda /
7556
+ // kutusunun / seviyesini. Listed as compounds because the bare locative
7557
+ // ('unda') would otherwise eat into the possessive and strand an orphan 's'.
7558
+ "s\u0131nda",
7559
+ "sinde",
7560
+ "sunda",
7561
+ "s\xFCnde",
7562
+ "s\u0131n\u0131n",
7563
+ "sinin",
7564
+ "sunun",
7565
+ "s\xFCn\xFCn",
7566
+ "s\u0131n\u0131",
7567
+ "sini",
7568
+ "sunu",
7569
+ "s\xFCn\xFC",
7570
+ // accusative after vowel (y buffer): makaleyi / kapıyı. (Bare-n buffer
7571
+ // variants 'nı/ni/nu/nü' were tried and removed: they mis-segment
7572
+ // consonant-final loanwords — `konsolidasyonu` → `konsolidasyo` — and their
7573
+ // only wins are already covered by synonym surface forms.)
7265
7574
  "yi",
7266
7575
  "y\u0131",
7267
7576
  "yu",
7268
- "y\xFC"
7269
- ];
7577
+ "y\xFC",
7578
+ // relative -ki on locative: oturumdaki / eldeki
7579
+ "daki",
7580
+ "deki",
7581
+ "taki",
7582
+ "teki",
7583
+ // instrumental: hook'la → hookla / sunucuyla
7584
+ "yla",
7585
+ "yle"
7586
+ ].sort((a, b) => b.length - a.length);
7270
7587
  FIELD_WEIGHTS = { title: 3, tags: 2, description: 2, body: 1 };
7271
7588
  WIKILINK_RE = /\[\[([^\]]+)\]\]/g;
7272
7589
  K1 = 1.5;
@@ -7275,6 +7592,7 @@ var init_recall = __esm({
7275
7592
  IDENTITY_BOOST = 1.5;
7276
7593
  CAPTURE_RANK_PENALTY = 0.5;
7277
7594
  STATUS_PENALTY = { completed: 0.85 };
7595
+ CHANGELOG_RANK_FACTOR = 0.85;
7278
7596
  LINK_DECAY = 0.3;
7279
7597
  }
7280
7598
  });
@@ -7349,7 +7667,17 @@ function digestPath(root, sessionId) {
7349
7667
  function digestExists(root, sessionId) {
7350
7668
  return existsSync31(digestPath(root, sessionId));
7351
7669
  }
7352
- function writeDigest(root, sessionId, md) {
7670
+ function digestIsPartial(root, sessionId) {
7671
+ const file = digestPath(root, sessionId);
7672
+ if (!existsSync31(file)) return false;
7673
+ try {
7674
+ const { data } = readFrontmatter(file);
7675
+ return data.partial === true;
7676
+ } catch {
7677
+ return false;
7678
+ }
7679
+ }
7680
+ function writeDigest(root, sessionId, md, opts = {}) {
7353
7681
  const dir = digestsDir(root);
7354
7682
  mkdirSync12(dir, { recursive: true });
7355
7683
  const file = digestPath(root, sessionId);
@@ -7359,6 +7687,7 @@ function writeDigest(root, sessionId, md) {
7359
7687
  "type: session-digest",
7360
7688
  `session_id: ${safeId}`,
7361
7689
  `created_at: ${(/* @__PURE__ */ new Date()).toISOString()}`,
7690
+ ...opts.partial ? ["partial: true"] : [],
7362
7691
  "---",
7363
7692
  ""
7364
7693
  ].join("\n");
@@ -7998,7 +8327,7 @@ function registerHookCommand(program) {
7998
8327
  }
7999
8328
  for (const session of state.sessions) {
8000
8329
  if (!session.transcript_path) continue;
8001
- if (digestExists(root, session.session_id)) continue;
8330
+ if (digestExists(root, session.session_id) && !digestIsPartial(root, session.session_id)) continue;
8002
8331
  try {
8003
8332
  const distilled = distillTranscript(session.transcript_path);
8004
8333
  const md = buildDigest(distilled);
@@ -8267,6 +8596,15 @@ function registerHookCommand(program) {
8267
8596
  state.compaction_log = state.compaction_log.slice(0, 20);
8268
8597
  }
8269
8598
  writeSleepState(root, state);
8599
+ try {
8600
+ const sessionId = input8 && typeof input8.session_id === "string" ? input8.session_id : "";
8601
+ const transcriptPath = input8 && typeof input8.transcript_path === "string" ? input8.transcript_path : "";
8602
+ if (sessionId && transcriptPath && existsSync33(transcriptPath)) {
8603
+ const distilled = distillTranscript(transcriptPath);
8604
+ writeDigest(root, sessionId, buildDigest(distilled), { partial: true });
8605
+ }
8606
+ } catch {
8607
+ }
8270
8608
  });
8271
8609
  hook.command("ensure-dashboard").description("Open the web dashboard if it is not already running (called by Claude Code SessionStart hook)").action(async () => {
8272
8610
  readStdin();
@@ -9263,9 +9601,9 @@ async function handleTasksInsert(req, res, params, contextRoot) {
9263
9601
  sendError(res, 400, "invalid_body", "Request body must be JSON.");
9264
9602
  return;
9265
9603
  }
9266
- const section = body.section;
9604
+ const section2 = body.section;
9267
9605
  let content = body.content;
9268
- if (!section || typeof section !== "string") {
9606
+ if (!section2 || typeof section2 !== "string") {
9269
9607
  sendError(res, 400, "missing_section", "Section name is required.");
9270
9608
  return;
9271
9609
  }
@@ -9282,9 +9620,9 @@ async function handleTasksInsert(req, res, params, contextRoot) {
9282
9620
  acceptance_criteria: "Acceptance Criteria",
9283
9621
  why: "Why"
9284
9622
  };
9285
- const sectionKey = section.toLowerCase();
9623
+ const sectionKey = section2.toLowerCase();
9286
9624
  if (!sectionMap[sectionKey]) {
9287
- sendError(res, 400, "invalid_section", `Unknown section: "${section}". Valid: ${Object.keys(sectionMap).join(", ")}`);
9625
+ sendError(res, 400, "invalid_section", `Unknown section: "${section2}". Valid: ${Object.keys(sectionMap).join(", ")}`);
9288
9626
  return;
9289
9627
  }
9290
9628
  const sectionName = sectionMap[sectionKey];
@@ -9427,10 +9765,10 @@ async function handleCoreGet(_req, res, params, contextRoot) {
9427
9765
  } catch {
9428
9766
  }
9429
9767
  const sectionContents = {};
9430
- for (const section of sections) {
9768
+ for (const section2 of sections) {
9431
9769
  try {
9432
- const sectionContent = readSection(filePath, section);
9433
- if (sectionContent) sectionContents[section] = sectionContent;
9770
+ const sectionContent = readSection(filePath, section2);
9771
+ if (sectionContent) sectionContents[section2] = sectionContent;
9434
9772
  } catch {
9435
9773
  }
9436
9774
  }
@@ -9666,10 +10004,10 @@ async function handleFeaturesGet(_req, res, params, contextRoot) {
9666
10004
  } catch {
9667
10005
  }
9668
10006
  const sectionContents = {};
9669
- for (const section of sections) {
10007
+ for (const section2 of sections) {
9670
10008
  try {
9671
- const sectionContent = readSection(filePath, section);
9672
- if (sectionContent) sectionContents[section] = sectionContent;
10009
+ const sectionContent = readSection(filePath, section2);
10010
+ if (sectionContent) sectionContents[section2] = sectionContent;
9673
10011
  } catch {
9674
10012
  }
9675
10013
  }
@@ -9731,12 +10069,12 @@ async function handleUnreleasedGet(_req, res, _params, contextRoot) {
9731
10069
  }
9732
10070
  async function handleReleaseGet(_req, res, params, contextRoot) {
9733
10071
  const entries = getExistingReleases(contextRoot);
9734
- const release = entries.find((r) => r.version === params.version);
9735
- if (!release) {
10072
+ const release2 = entries.find((r) => r.version === params.version);
10073
+ if (!release2) {
9736
10074
  sendError(res, 404, "not_found", `Release not found: ${params.version}`);
9737
10075
  return;
9738
10076
  }
9739
- sendJson(res, 200, { release });
10077
+ sendJson(res, 200, { release: release2 });
9740
10078
  }
9741
10079
  async function handleReleasesCreate(req, res, _params, contextRoot) {
9742
10080
  const body = await parseJsonBody(req);
@@ -9755,7 +10093,7 @@ async function handleReleasesCreate(req, res, _params, contextRoot) {
9755
10093
  return;
9756
10094
  }
9757
10095
  const status = body.status === "planning" ? "planning" : "released";
9758
- const release = {
10096
+ const release2 = {
9759
10097
  id: generateId("rel"),
9760
10098
  version: version.trim(),
9761
10099
  date: status === "planning" ? "" : today(),
@@ -9767,17 +10105,17 @@ async function handleReleasesCreate(req, res, _params, contextRoot) {
9767
10105
  changelog: Array.isArray(body.changelog) ? body.changelog : []
9768
10106
  };
9769
10107
  const filePath = join38(contextRoot, "core", "RELEASES.json");
9770
- insertToJsonArray(filePath, release);
9771
- if (release.features.length > 0) {
9772
- backPopulateFeatures(contextRoot, release.features, release.version);
10108
+ insertToJsonArray(filePath, release2);
10109
+ if (release2.features.length > 0) {
10110
+ backPopulateFeatures(contextRoot, release2.features, release2.version);
9773
10111
  }
9774
10112
  recordDashboardChange(contextRoot, {
9775
10113
  entity: "core",
9776
10114
  action: "create",
9777
10115
  target: "core/RELEASES.json",
9778
- summary: `Created release ${release.version}`
10116
+ summary: `Created release ${release2.version}`
9779
10117
  });
9780
- sendJson(res, 201, { release });
10118
+ sendJson(res, 201, { release: release2 });
9781
10119
  }
9782
10120
  async function handleReleasesUpdate(req, res, params, contextRoot) {
9783
10121
  const body = await parseJsonBody(req);
@@ -9799,33 +10137,33 @@ async function handleReleasesUpdate(req, res, params, contextRoot) {
9799
10137
  sendError(res, 404, "not_found", `Release not found: ${params.version}`);
9800
10138
  return;
9801
10139
  }
9802
- const release = entries[idx];
10140
+ const release2 = entries[idx];
9803
10141
  if (body.status !== void 0) {
9804
10142
  const s = body.status;
9805
10143
  if (s !== "planning" && s !== "released") {
9806
10144
  sendError(res, 400, "invalid_status", 'Status must be "planning" or "released".');
9807
10145
  return;
9808
10146
  }
9809
- release.status = s;
9810
- if (s === "released" && !release.date) {
9811
- release.date = today();
10147
+ release2.status = s;
10148
+ if (s === "released" && !release2.date) {
10149
+ release2.date = today();
9812
10150
  }
9813
10151
  }
9814
10152
  if (typeof body.summary === "string") {
9815
- release.summary = body.summary.trim();
10153
+ release2.summary = body.summary.trim();
9816
10154
  }
9817
10155
  if (typeof body.date === "string") {
9818
- release.date = body.date.trim();
10156
+ release2.date = body.date.trim();
9819
10157
  }
9820
10158
  const { writeJsonArray: writeJsonArray2 } = await Promise.resolve().then(() => (init_json_file(), json_file_exports));
9821
10159
  writeJsonArray2(filePath, entries);
9822
10160
  recordDashboardChange(contextRoot, {
9823
10161
  entity: "core",
9824
10162
  action: "update",
9825
- target: `core/RELEASES.json#${release.version}`,
9826
- summary: `Updated release ${release.version}`
10163
+ target: `core/RELEASES.json#${release2.version}`,
10164
+ summary: `Updated release ${release2.version}`
9827
10165
  });
9828
- sendJson(res, 200, { release });
10166
+ sendJson(res, 200, { release: release2 });
9829
10167
  }
9830
10168
  var init_changelog = __esm({
9831
10169
  "src/server/routes/changelog.ts"() {
@@ -17620,28 +17958,331 @@ var init_config4 = __esm({
17620
17958
  }
17621
17959
  });
17622
17960
 
17961
+ // src/lib/feedback.ts
17962
+ import { execFileSync as execFileSync8 } from "child_process";
17963
+ import { platform, release, arch } from "os";
17964
+ function isFeedbackCategory(value) {
17965
+ return Object.prototype.hasOwnProperty.call(CATEGORY_META, value);
17966
+ }
17967
+ function parseGhAccount(authOutput) {
17968
+ const match = authOutput.match(/account\s+([^\s(]+)/i);
17969
+ return match ? match[1] : void 0;
17970
+ }
17971
+ function detectGitHubCli(run = defaultRunner) {
17972
+ const version = run("gh", ["--version"]);
17973
+ if (!version.ok) return { installed: false, authenticated: false };
17974
+ const auth = run("gh", ["auth", "status"]);
17975
+ const combined = `${auth.stdout}
17976
+ ${auth.stderr}`;
17977
+ const authenticated = auth.ok || /Logged in to/i.test(combined);
17978
+ return {
17979
+ installed: true,
17980
+ authenticated,
17981
+ account: authenticated ? parseGhAccount(combined) : void 0
17982
+ };
17983
+ }
17984
+ function collectEnvironment() {
17985
+ return {
17986
+ dreamcontextVersion: dreamcontextVersion(),
17987
+ node: process.version,
17988
+ os: `${platform()} ${release()} (${arch()})`
17989
+ };
17990
+ }
17991
+ function section(heading, body, fallback) {
17992
+ const value = body && body.trim().length > 0 ? body.trim() : fallback;
17993
+ return `### ${heading}
17994
+
17995
+ ${value}`;
17996
+ }
17997
+ function buildIssueBody(input8, env) {
17998
+ const todo = "_(not provided)_";
17999
+ const parts = [
18000
+ section("Scenario \u2014 what the agent was doing", input8.scenario, todo),
18001
+ section("Expected \u2014 what dreamcontext should have done", input8.expected, todo),
18002
+ section("Gap \u2014 what was missing, broken, or surprising", input8.gap, todo),
18003
+ section("Reproduction / commands", input8.repro, todo),
18004
+ section("Proposed improvement", input8.proposal, todo),
18005
+ [
18006
+ "### Environment",
18007
+ "",
18008
+ `- dreamcontext: \`${env.dreamcontextVersion}\``,
18009
+ `- node: \`${env.node}\``,
18010
+ `- os: \`${env.os}\``,
18011
+ `- category: \`${input8.category}\` (${CATEGORY_META[input8.category].title})`
18012
+ ].join("\n"),
18013
+ FEEDBACK_MARKER
18014
+ ];
18015
+ return parts.join("\n\n");
18016
+ }
18017
+ function labelsFor(category) {
18018
+ const gh = CATEGORY_META[category].ghLabel;
18019
+ return gh ? [FEEDBACK_LABEL, gh] : [FEEDBACK_LABEL];
18020
+ }
18021
+ function normalizeTitle(title) {
18022
+ return title.toLowerCase().replace(/^(feat|fix|bug|docs|chore)(\([^)]*\))?:\s*/i, "").replace(/[^a-z0-9 ]+/g, " ").replace(/\s+/g, " ").trim();
18023
+ }
18024
+ function titleSimilarity(a, b) {
18025
+ const ta = new Set(normalizeTitle(a).split(" ").filter(Boolean));
18026
+ const tb = new Set(normalizeTitle(b).split(" ").filter(Boolean));
18027
+ if (ta.size === 0 || tb.size === 0) return 0;
18028
+ let inter = 0;
18029
+ for (const t of ta) if (tb.has(t)) inter++;
18030
+ return inter / (ta.size + tb.size - inter);
18031
+ }
18032
+ function findDuplicate(candidateTitle, existing, threshold = 0.6) {
18033
+ let best;
18034
+ for (const ref of existing) {
18035
+ const score = titleSimilarity(candidateTitle, ref.title);
18036
+ if (score >= threshold && (!best || score > best.score)) best = { ref, score };
18037
+ }
18038
+ return best?.ref;
18039
+ }
18040
+ function listFeedbackIssues(run = defaultRunner) {
18041
+ const res = run("gh", [
18042
+ "issue",
18043
+ "list",
18044
+ "--repo",
18045
+ UPSTREAM_REPO,
18046
+ "--state",
18047
+ "open",
18048
+ "--limit",
18049
+ "100",
18050
+ "--json",
18051
+ "number,title,url"
18052
+ ]);
18053
+ if (!res.ok || !res.stdout.trim()) return [];
18054
+ try {
18055
+ const parsed = JSON.parse(res.stdout);
18056
+ return Array.isArray(parsed) ? parsed : [];
18057
+ } catch {
18058
+ return [];
18059
+ }
18060
+ }
18061
+ function ensureFeedbackLabel(run = defaultRunner) {
18062
+ run("gh", [
18063
+ "label",
18064
+ "create",
18065
+ FEEDBACK_LABEL,
18066
+ "--repo",
18067
+ UPSTREAM_REPO,
18068
+ "--color",
18069
+ "5319e7",
18070
+ "--description",
18071
+ "Filed by a dreamcontext agent via the feedback loop",
18072
+ "--force"
18073
+ ]);
18074
+ }
18075
+ function createIssue(input8, body, run = defaultRunner) {
18076
+ const labels = labelsFor(input8.category);
18077
+ const args = [
18078
+ "issue",
18079
+ "create",
18080
+ "--repo",
18081
+ UPSTREAM_REPO,
18082
+ "--title",
18083
+ input8.title,
18084
+ "--body",
18085
+ body
18086
+ ];
18087
+ for (const l of labels) args.push("--label", l);
18088
+ const res = run("gh", args);
18089
+ if (res.ok) {
18090
+ const url = res.stdout.trim().split("\n").filter(Boolean).pop();
18091
+ return { ok: true, url };
18092
+ }
18093
+ const retry = run("gh", ["issue", "create", "--repo", UPSTREAM_REPO, "--title", input8.title, "--body", body]);
18094
+ if (retry.ok) {
18095
+ const url = retry.stdout.trim().split("\n").filter(Boolean).pop();
18096
+ return { ok: true, url };
18097
+ }
18098
+ return { ok: false, error: (res.stderr || retry.stderr || "gh issue create failed").trim() };
18099
+ }
18100
+ var UPSTREAM_REPO, FEEDBACK_LABEL, FEEDBACK_MARKER, CATEGORY_META, FEEDBACK_CATEGORIES, defaultRunner;
18101
+ var init_feedback = __esm({
18102
+ "src/lib/feedback.ts"() {
18103
+ "use strict";
18104
+ init_manifest();
18105
+ UPSTREAM_REPO = "meanllbrl/dreamcontext";
18106
+ FEEDBACK_LABEL = "agent-feedback";
18107
+ FEEDBACK_MARKER = "<!-- filed via `dreamcontext feedback` (agent feedback loop) -->";
18108
+ CATEGORY_META = {
18109
+ bug: { title: "Bug", ghLabel: "bug" },
18110
+ "missing-cli": { title: "Missing CLI command", ghLabel: "enhancement" },
18111
+ "unseen-memory": { title: "Memory not surfaced", ghLabel: "bug" },
18112
+ feature: { title: "Feature request", ghLabel: "enhancement" },
18113
+ docs: { title: "Docs gap", ghLabel: "documentation" },
18114
+ other: { title: "Feedback" }
18115
+ };
18116
+ FEEDBACK_CATEGORIES = Object.keys(CATEGORY_META);
18117
+ defaultRunner = (cmd, args) => {
18118
+ try {
18119
+ const stdout = execFileSync8(cmd, args, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
18120
+ return { ok: true, stdout, stderr: "" };
18121
+ } catch (err) {
18122
+ const e = err;
18123
+ return {
18124
+ ok: false,
18125
+ stdout: e.stdout ? e.stdout.toString() : "",
18126
+ stderr: e.stderr ? e.stderr.toString() : ""
18127
+ };
18128
+ }
18129
+ };
18130
+ }
18131
+ });
18132
+
18133
+ // src/cli/commands/feedback.ts
18134
+ import chalk41 from "chalk";
18135
+ import { confirm as confirm6 } from "@inquirer/prompts";
18136
+ function printAccessGuidance(installed) {
18137
+ console.log(header("GitHub access required to file feedback"));
18138
+ console.log();
18139
+ if (!installed) {
18140
+ console.log("The GitHub CLI (" + chalk41.cyan("gh") + ") is not installed. To file feedback to " + chalk41.cyan(UPSTREAM_REPO) + ":");
18141
+ console.log();
18142
+ console.log(" 1. Install gh: " + chalk41.dim("https://cli.github.com (brew install gh)"));
18143
+ console.log(" 2. Sign in: " + chalk41.cyan("gh auth login"));
18144
+ } else {
18145
+ console.log(chalk41.cyan("gh") + " is installed but you are not signed in.");
18146
+ console.log();
18147
+ console.log(" \u2022 Sign in: " + chalk41.cyan("gh auth login"));
18148
+ }
18149
+ console.log();
18150
+ console.log(chalk41.bold("No GitHub account yet?"));
18151
+ console.log(" dreamcontext files feedback as GitHub issues, so you need a (free) account.");
18152
+ console.log(" Create one at " + chalk41.cyan("https://github.com/signup") + ", then run " + chalk41.cyan("gh auth login") + ".");
18153
+ console.log();
18154
+ info("Re-run " + chalk41.cyan("dreamcontext feedback") + " once you are signed in.");
18155
+ }
18156
+ function renderPreview(input8, body) {
18157
+ console.log(header("Feedback issue preview"));
18158
+ console.log();
18159
+ console.log(miniBox([
18160
+ `repo: ${UPSTREAM_REPO}`,
18161
+ `title: ${input8.title}`,
18162
+ `labels: ${labelsFor(input8.category).join(", ")}`
18163
+ ], { color: "magenta" }));
18164
+ console.log();
18165
+ console.log(chalk41.dim("\u2500\u2500\u2500 body \u2500\u2500\u2500"));
18166
+ console.log(body);
18167
+ console.log(chalk41.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
18168
+ console.log();
18169
+ }
18170
+ function registerFeedbackCommand(program) {
18171
+ program.command("feedback").description(`File a structured feedback issue to ${UPSTREAM_REPO}`).option("-c, --category <category>", `Category: ${FEEDBACK_CATEGORIES.join(" | ")}`).option("-t, --title <title>", "Issue title (concise, specific)").option("-s, --scenario <text>", "What the agent was doing when it hit the gap").option("-e, --expected <text>", "What dreamcontext should have done").option("-g, --gap <text>", "What was missing, broken, or surprising").option("-r, --repro <text>", "Reproduction steps or exact commands").option("-p, --proposal <text>", "Proposed improvement (command, behavior, doc, fix)").option("--dry-run", "Render the issue without filing it (use this to show the user a draft)").option("-y, --yes", "Skip the interactive confirmation and file immediately").option("--no-dedup", "Skip the duplicate-issue check").addHelpText("after", `
18172
+ Examples:
18173
+ ${chalk41.dim("# Render a draft to show the user (no network write):")}
18174
+ dreamcontext feedback --dry-run -c missing-cli -t "Add \`tasks reopen\`" \\
18175
+ -s "User asked to reopen a completed task; no CLI path exists." \\
18176
+ -p "Add a 'tasks reopen <id>' command that flips status back to todo."
18177
+
18178
+ ${chalk41.dim("# File after the user approved the draft:")}
18179
+ dreamcontext feedback --yes -c missing-cli -t "Add \`tasks reopen\`" -s "..." -p "..."
18180
+ `).action(async (opts) => {
18181
+ const category = (opts.category ?? "other").trim();
18182
+ if (!isFeedbackCategory(category)) {
18183
+ error(`Unknown category: ${category}`, `Valid: ${FEEDBACK_CATEGORIES.join(", ")}`);
18184
+ process.exitCode = 1;
18185
+ return;
18186
+ }
18187
+ if (!opts.title || !opts.title.trim()) {
18188
+ error("A --title is required.", 'Keep it concise and specific, e.g. "Add `tasks reopen` command".');
18189
+ process.exitCode = 1;
18190
+ return;
18191
+ }
18192
+ if (!opts.scenario || !opts.scenario.trim()) {
18193
+ error("A --scenario is required.", "Describe what the agent was doing when it hit the gap.");
18194
+ process.exitCode = 1;
18195
+ return;
18196
+ }
18197
+ const input8 = {
18198
+ category,
18199
+ title: opts.title.trim(),
18200
+ scenario: opts.scenario,
18201
+ expected: opts.expected,
18202
+ gap: opts.gap,
18203
+ repro: opts.repro,
18204
+ proposal: opts.proposal
18205
+ };
18206
+ const body = buildIssueBody(input8, collectEnvironment());
18207
+ if (opts.dryRun) {
18208
+ renderPreview(input8, body);
18209
+ info("Dry run \u2014 nothing was filed. Re-run with " + chalk41.cyan("--yes") + " to file after the user approves.");
18210
+ return;
18211
+ }
18212
+ const gh = detectGitHubCli();
18213
+ if (!gh.installed || !gh.authenticated) {
18214
+ printAccessGuidance(gh.installed);
18215
+ process.exitCode = 1;
18216
+ return;
18217
+ }
18218
+ renderPreview(input8, body);
18219
+ if (gh.account) info(`Filing as GitHub user ${chalk41.cyan(gh.account)} \u2192 ${chalk41.cyan(UPSTREAM_REPO)}`);
18220
+ if (opts.dedup !== false) {
18221
+ const existing = listFeedbackIssues();
18222
+ const dup = findDuplicate(input8.title, existing);
18223
+ if (dup) {
18224
+ warn(`A similar open issue already exists: #${dup.number} \u2014 ${dup.title}`);
18225
+ console.log(" " + chalk41.cyan(dup.url));
18226
+ if (!opts.yes) {
18227
+ const proceed = await confirm6({ message: "File anyway?", default: false }).catch(() => false);
18228
+ if (!proceed) {
18229
+ info("Skipped \u2014 consider commenting on the existing issue instead.");
18230
+ return;
18231
+ }
18232
+ }
18233
+ }
18234
+ }
18235
+ if (!opts.yes) {
18236
+ const proceed = await confirm6({
18237
+ message: `File this issue to ${UPSTREAM_REPO}?`,
18238
+ default: true
18239
+ }).catch(() => false);
18240
+ if (!proceed) {
18241
+ info("Cancelled \u2014 nothing was filed.");
18242
+ return;
18243
+ }
18244
+ }
18245
+ ensureFeedbackLabel();
18246
+ const result = createIssue(input8, body);
18247
+ if (result.ok) {
18248
+ success("Feedback filed.");
18249
+ if (result.url) console.log(" " + chalk41.cyan(result.url));
18250
+ } else {
18251
+ error("Failed to file feedback.", result.error);
18252
+ process.exitCode = 1;
18253
+ }
18254
+ });
18255
+ }
18256
+ var init_feedback2 = __esm({
18257
+ "src/cli/commands/feedback.ts"() {
18258
+ "use strict";
18259
+ init_feedback();
18260
+ init_format();
18261
+ }
18262
+ });
18263
+
17623
18264
  // src/cli/interactive.ts
17624
18265
  import { select as select3, input as input7, checkbox as checkbox5 } from "@inquirer/prompts";
17625
- import chalk41 from "chalk";
18266
+ import chalk42 from "chalk";
17626
18267
  function outlinedRow(emoji, label, colorFn) {
17627
18268
  const contentWidth = 2 + 2 + 2 + label.length;
17628
18269
  const pad = Math.max(1, BW - contentWidth);
17629
- return `${chalk41.dim("\u2502")} ${emoji} ${colorFn(label)}${" ".repeat(pad)}${chalk41.dim("\u2502")}`;
18270
+ return `${chalk42.dim("\u2502")} ${emoji} ${colorFn(label)}${" ".repeat(pad)}${chalk42.dim("\u2502")}`;
17630
18271
  }
17631
18272
  function solidRow(emoji, label) {
17632
18273
  const contentWidth = 2 + 2 + 2 + label.length;
17633
18274
  const pad = Math.max(1, BW - contentWidth);
17634
- return `${chalk41.magentaBright("\u2503")} ${emoji} ${chalk41.white.bold(label)}${" ".repeat(pad)}${chalk41.magentaBright("\u2503")}`;
18275
+ return `${chalk42.magentaBright("\u2503")} ${emoji} ${chalk42.white.bold(label)}${" ".repeat(pad)}${chalk42.magentaBright("\u2503")}`;
17635
18276
  }
17636
18277
  function outlinedBackRow() {
17637
18278
  const contentWidth = 2 + 1 + 3 + 4;
17638
18279
  const pad = Math.max(1, BW - contentWidth);
17639
- return `${chalk41.dim("\u2502")} \u2190 ${chalk41.dim("Back")}${" ".repeat(pad)}${chalk41.dim("\u2502")}`;
18280
+ return `${chalk42.dim("\u2502")} \u2190 ${chalk42.dim("Back")}${" ".repeat(pad)}${chalk42.dim("\u2502")}`;
17640
18281
  }
17641
18282
  function solidBackRow() {
17642
18283
  const contentWidth = 2 + 1 + 3 + 4;
17643
18284
  const pad = Math.max(1, BW - contentWidth);
17644
- return `${chalk41.magentaBright("\u2503")} ${chalk41.white("\u2190")} ${chalk41.white.bold("Back")}${" ".repeat(pad)}${chalk41.magentaBright("\u2503")}`;
18285
+ return `${chalk42.magentaBright("\u2503")} ${chalk42.white("\u2190")} ${chalk42.white.bold("Back")}${" ".repeat(pad)}${chalk42.magentaBright("\u2503")}`;
17645
18286
  }
17646
18287
  function buildTopLevelMenu() {
17647
18288
  const solidMap = /* @__PURE__ */ new Map();
@@ -17657,7 +18298,7 @@ function buildTopLevelMenu() {
17657
18298
  description: cat.description
17658
18299
  });
17659
18300
  }
17660
- const exitOutlined = outlinedRow("\u{1F6AA}", "Exit", chalk41.dim);
18301
+ const exitOutlined = outlinedRow("\u{1F6AA}", "Exit", chalk42.dim);
17661
18302
  const exitSolid = solidRow("\u{1F6AA}", "Exit");
17662
18303
  solidMap.set(exitOutlined, exitSolid);
17663
18304
  choices.push({
@@ -17695,16 +18336,16 @@ function buildSubmenuMenu(cat) {
17695
18336
  }
17696
18337
  function makeTheme(solidMap) {
17697
18338
  return {
17698
- prefix: { idle: chalk41.magentaBright("\u25C6"), done: chalk41.green("\u2714") },
18339
+ prefix: { idle: chalk42.magentaBright("\u25C6"), done: chalk42.green("\u2714") },
17699
18340
  icon: { cursor: " " },
17700
18341
  style: {
17701
18342
  highlight: (text) => {
17702
18343
  const name = text.slice(2);
17703
18344
  const solid = solidMap.get(name);
17704
- if (solid) return chalk41.bgHex("#581C87")(" " + solid);
17705
- return chalk41.bgHex("#581C87")(text);
18345
+ if (solid) return chalk42.bgHex("#581C87")(" " + solid);
18346
+ return chalk42.bgHex("#581C87")(text);
17706
18347
  },
17707
- description: (text) => chalk41.dim(text)
18348
+ description: (text) => chalk42.dim(text)
17708
18349
  }
17709
18350
  };
17710
18351
  }
@@ -17754,12 +18395,12 @@ async function executeCommand(command) {
17754
18395
  try {
17755
18396
  const result = await collectArgs(command.args);
17756
18397
  if (result === null) {
17757
- console.log(chalk41.dim(" Cancelled.\n"));
18398
+ console.log(chalk42.dim(" Cancelled.\n"));
17758
18399
  return;
17759
18400
  }
17760
18401
  collectedArgs = result;
17761
18402
  } catch {
17762
- console.log(chalk41.dim(" Cancelled.\n"));
18403
+ console.log(chalk42.dim(" Cancelled.\n"));
17763
18404
  return;
17764
18405
  }
17765
18406
  }
@@ -17780,14 +18421,14 @@ async function executeCommand(command) {
17780
18421
  } catch (err) {
17781
18422
  if (err.code === "commander.helpDisplayed" || err.code === "commander.version") {
17782
18423
  } else {
17783
- console.error(chalk41.red(` \u2717 ${err.message}`));
18424
+ console.error(chalk42.red(` \u2717 ${err.message}`));
17784
18425
  }
17785
18426
  }
17786
18427
  }
17787
18428
  async function startInteractive(_program) {
17788
18429
  const totalCommands = CATEGORIES.reduce((sum, cat) => sum + cat.commands.length, 0);
17789
- console.log(chalk41.dim(` v0.1.0 \xB7 ${totalCommands} commands in ${CATEGORIES.length} categories`));
17790
- console.log(chalk41.dim(` Use \u2191\u2193 to navigate, Enter to select.
18430
+ console.log(chalk42.dim(` v0.1.0 \xB7 ${totalCommands} commands in ${CATEGORIES.length} categories`));
18431
+ console.log(chalk42.dim(` Use \u2191\u2193 to navigate, Enter to select.
17791
18432
  `));
17792
18433
  const { choices: topChoices, solidMap: topSolid } = buildTopLevelMenu();
17793
18434
  while (true) {
@@ -17801,11 +18442,11 @@ async function startInteractive(_program) {
17801
18442
  theme: makeTheme(topSolid)
17802
18443
  });
17803
18444
  } catch {
17804
- console.log(chalk41.dim("\n Until next session.\n"));
18445
+ console.log(chalk42.dim("\n Until next session.\n"));
17805
18446
  process.exit(0);
17806
18447
  }
17807
18448
  if (categoryId === EXIT_SENTINEL) {
17808
- console.log(chalk41.dim("\n Until next session.\n"));
18449
+ console.log(chalk42.dim("\n Until next session.\n"));
17809
18450
  process.exit(0);
17810
18451
  }
17811
18452
  const category = CATEGORIES.find((c) => c.id === categoryId);
@@ -17865,8 +18506,8 @@ var init_interactive = __esm({
17865
18506
  emoji: "\u{1F680}",
17866
18507
  label: "Setup",
17867
18508
  description: "Initialize project and install skills",
17868
- color: chalk41.cyan,
17869
- colorBright: chalk41.cyanBright,
18509
+ color: chalk42.cyan,
18510
+ colorBright: chalk42.cyanBright,
17870
18511
  commands: [
17871
18512
  {
17872
18513
  emoji: "\u{1F680}",
@@ -17964,8 +18605,8 @@ var init_interactive = __esm({
17964
18605
  emoji: "\u{1F4CB}",
17965
18606
  label: "Tasks",
17966
18607
  description: "Create tasks, log progress, mark complete",
17967
- color: chalk41.green,
17968
- colorBright: chalk41.greenBright,
18608
+ color: chalk42.green,
18609
+ colorBright: chalk42.greenBright,
17969
18610
  commands: [
17970
18611
  {
17971
18612
  emoji: "\u2795",
@@ -17995,8 +18636,8 @@ var init_interactive = __esm({
17995
18636
  emoji: "\u{1F9E9}",
17996
18637
  label: "Features",
17997
18638
  description: "Create features and add content to sections",
17998
- color: chalk41.yellow,
17999
- colorBright: chalk41.yellowBright,
18639
+ color: chalk42.yellow,
18640
+ colorBright: chalk42.yellowBright,
18000
18641
  commands: [
18001
18642
  {
18002
18643
  emoji: "\u2728",
@@ -18022,8 +18663,8 @@ var init_interactive = __esm({
18022
18663
  emoji: "\u{1F4DA}",
18023
18664
  label: "Knowledge",
18024
18665
  description: "Create and browse knowledge documents",
18025
- color: chalk41.blue,
18026
- colorBright: chalk41.blueBright,
18666
+ color: chalk42.blue,
18667
+ colorBright: chalk42.blueBright,
18027
18668
  commands: [
18028
18669
  {
18029
18670
  emoji: "\u{1F4C4}",
@@ -18051,8 +18692,8 @@ var init_interactive = __esm({
18051
18692
  emoji: "\u{1F4DD}",
18052
18693
  label: "Changelog",
18053
18694
  description: "Record changelog entries and releases",
18054
- color: chalk41.magenta,
18055
- colorBright: chalk41.magentaBright,
18695
+ color: chalk42.magenta,
18696
+ colorBright: chalk42.magentaBright,
18056
18697
  commands: [
18057
18698
  {
18058
18699
  emoji: "\u{1F4AC}",
@@ -18079,8 +18720,8 @@ var init_interactive = __esm({
18079
18720
  emoji: "\u{1F527}",
18080
18721
  label: "System",
18081
18722
  description: "Sleep tracking, diagnostics, snapshots",
18082
- color: chalk41.whiteBright,
18083
- colorBright: (s) => chalk41.whiteBright.bold(s),
18723
+ color: chalk42.whiteBright,
18724
+ colorBright: (s) => chalk42.whiteBright.bold(s),
18084
18725
  commands: [
18085
18726
  {
18086
18727
  emoji: "\u{1F4CA}",
@@ -18163,8 +18804,8 @@ var init_interactive = __esm({
18163
18804
  emoji: "\u{1F5A5}\uFE0F",
18164
18805
  label: "Dashboard",
18165
18806
  description: "Open the web dashboard in your browser",
18166
- color: chalk41.magentaBright,
18167
- colorBright: (s) => chalk41.magentaBright.bold(s),
18807
+ color: chalk42.magentaBright,
18808
+ colorBright: (s) => chalk42.magentaBright.bold(s),
18168
18809
  commands: [
18169
18810
  {
18170
18811
  emoji: "\u{1F310}",
@@ -18180,7 +18821,7 @@ var init_interactive = __esm({
18180
18821
  });
18181
18822
 
18182
18823
  // src/lib/pixel-banner.ts
18183
- import chalk42 from "chalk";
18824
+ import chalk43 from "chalk";
18184
18825
  function decodeIdx(c) {
18185
18826
  return c === "." ? -1 : IDX[c];
18186
18827
  }
@@ -18197,17 +18838,17 @@ function renderBanner() {
18197
18838
  line += " ";
18198
18839
  } else if (ti >= 0 && bi === -1) {
18199
18840
  const [r, g, b] = P[ti];
18200
- line += chalk42.rgb(r, g, b)("\u2580");
18841
+ line += chalk43.rgb(r, g, b)("\u2580");
18201
18842
  } else if (ti === -1 && bi >= 0) {
18202
18843
  const [r, g, b] = P[bi];
18203
- line += chalk42.rgb(r, g, b)("\u2584");
18844
+ line += chalk43.rgb(r, g, b)("\u2584");
18204
18845
  } else {
18205
18846
  const [tr, tg, tb] = P[ti];
18206
18847
  const [br, bg, bb] = P[bi];
18207
18848
  if (tr === br && tg === bg && tb === bb) {
18208
- line += chalk42.rgb(tr, tg, tb)("\u2588");
18849
+ line += chalk43.rgb(tr, tg, tb)("\u2588");
18209
18850
  } else {
18210
- line += chalk42.rgb(tr, tg, tb).bgRgb(br, bg, bb)("\u2580");
18851
+ line += chalk43.rgb(tr, tg, tb).bgRgb(br, bg, bb)("\u2580");
18211
18852
  }
18212
18853
  }
18213
18854
  }
@@ -18273,12 +18914,12 @@ __export(index_exports, {
18273
18914
  createProgram: () => createProgram
18274
18915
  });
18275
18916
  import { Command as Command2 } from "commander";
18276
- import chalk43 from "chalk";
18917
+ import chalk44 from "chalk";
18277
18918
  function getBanner() {
18278
18919
  const logo = renderBanner();
18279
- const title = `${chalk43.bold.cyan("D R E A M")}${chalk43.bold.cyanBright(" C O N T E X T")}`;
18280
- const sep7 = chalk43.dim("\u2501".repeat(25));
18281
- const tagline = chalk43.dim("persistent memory for AI agents");
18920
+ const title = `${chalk44.bold.cyan("D R E A M")}${chalk44.bold.cyanBright(" C O N T E X T")}`;
18921
+ const sep7 = chalk44.dim("\u2501".repeat(25));
18922
+ const tagline = chalk44.dim("persistent memory for AI agents");
18282
18923
  const text = [
18283
18924
  "",
18284
18925
  ` ${title}`,
@@ -18318,6 +18959,7 @@ function createProgram() {
18318
18959
  registerMemoryCommand(program);
18319
18960
  registerVaultsCommand(program);
18320
18961
  registerConfigCommand(program);
18962
+ registerFeedbackCommand(program);
18321
18963
  return program;
18322
18964
  }
18323
18965
  async function main() {
@@ -18361,46 +19003,48 @@ var init_index = __esm({
18361
19003
  init_upgrade();
18362
19004
  init_vaults2();
18363
19005
  init_config4();
19006
+ init_feedback2();
18364
19007
  init_interactive();
18365
19008
  init_pixel_banner();
18366
19009
  init_manifest();
18367
19010
  HELP_GROUPS = `
18368
- ${chalk43.bold("Setup")}
18369
- ${chalk43.magentaBright("setup")} One-shot: init + install-skill + install-instructions
18370
- ${chalk43.magentaBright("init")} ${chalk43.dim("(deprecated)")} Initialize _dream_context/ in your project
18371
- ${chalk43.magentaBright("install-skill")} ${chalk43.dim("(deprecated)")} Install skill + agents + optional packs
18372
- ${chalk43.magentaBright("install-instructions")} ${chalk43.dim("(deprecated)")} Install managed root instruction files
18373
- ${chalk43.magentaBright("install-claude-md")} ${chalk43.dim("(deprecated)")} Legacy alias for CLAUDE.md install
18374
- ${chalk43.magentaBright("update")} Refresh installed skill, agents, hooks, packs, and root instructions
18375
- ${chalk43.magentaBright("upgrade")} Upgrade the dreamcontext CLI itself to the latest version
19011
+ ${chalk44.bold("Setup")}
19012
+ ${chalk44.magentaBright("setup")} One-shot: init + install-skill + install-instructions
19013
+ ${chalk44.magentaBright("init")} ${chalk44.dim("(deprecated)")} Initialize _dream_context/ in your project
19014
+ ${chalk44.magentaBright("install-skill")} ${chalk44.dim("(deprecated)")} Install skill + agents + optional packs
19015
+ ${chalk44.magentaBright("install-instructions")} ${chalk44.dim("(deprecated)")} Install managed root instruction files
19016
+ ${chalk44.magentaBright("install-claude-md")} ${chalk44.dim("(deprecated)")} Legacy alias for CLAUDE.md install
19017
+ ${chalk44.magentaBright("update")} Refresh installed skill, agents, hooks, packs, and root instructions
19018
+ ${chalk44.magentaBright("upgrade")} Upgrade the dreamcontext CLI itself to the latest version
18376
19019
 
18377
- ${chalk43.bold("Content")}
18378
- ${chalk43.magentaBright("core")} Add changelog and release entries
18379
- ${chalk43.magentaBright("features")} Create features and insert into sections
18380
- ${chalk43.magentaBright("knowledge")} Create and index knowledge files
18381
- ${chalk43.magentaBright("memory")} Recall facts via BM25 search over the project corpus
18382
- ${chalk43.magentaBright("tasks")} Create tasks, log progress, and mark complete
18383
- ${chalk43.magentaBright("bookmark")} Tag important moments for consolidation
18384
- ${chalk43.magentaBright("trigger")} Manage contextual reminders (prospective memory)
18385
- ${chalk43.magentaBright("council")} Run structured multi-agent debates on decisions
19020
+ ${chalk44.bold("Content")}
19021
+ ${chalk44.magentaBright("core")} Add changelog and release entries
19022
+ ${chalk44.magentaBright("features")} Create features and insert into sections
19023
+ ${chalk44.magentaBright("knowledge")} Create and index knowledge files
19024
+ ${chalk44.magentaBright("memory")} Recall facts via BM25 search over the project corpus
19025
+ ${chalk44.magentaBright("tasks")} Create tasks, log progress, and mark complete
19026
+ ${chalk44.magentaBright("bookmark")} Tag important moments for consolidation
19027
+ ${chalk44.magentaBright("trigger")} Manage contextual reminders (prospective memory)
19028
+ ${chalk44.magentaBright("council")} Run structured multi-agent debates on decisions
18386
19029
 
18387
- ${chalk43.bold("System")}
18388
- ${chalk43.magentaBright("snapshot")} Output context snapshot (used by SessionStart hook)
18389
- ${chalk43.magentaBright("sleep")} Track sleep debt and consolidation state
18390
- ${chalk43.magentaBright("hook")} Hook handlers used by platform integrations
18391
- ${chalk43.magentaBright("transcript")} Process session transcripts
18392
- ${chalk43.magentaBright("doctor")} Validate _dream_context/ structure and report issues
19030
+ ${chalk44.bold("System")}
19031
+ ${chalk44.magentaBright("snapshot")} Output context snapshot (used by SessionStart hook)
19032
+ ${chalk44.magentaBright("sleep")} Track sleep debt and consolidation state
19033
+ ${chalk44.magentaBright("hook")} Hook handlers used by platform integrations
19034
+ ${chalk44.magentaBright("transcript")} Process session transcripts
19035
+ ${chalk44.magentaBright("doctor")} Validate _dream_context/ structure and report issues
19036
+ ${chalk44.magentaBright("feedback")} File a gap/bug as a GitHub issue to the dreamcontext project
18393
19037
 
18394
- ${chalk43.bold("Dashboard")}
18395
- ${chalk43.magentaBright("dashboard")} Open the web dashboard in your browser
19038
+ ${chalk44.bold("Dashboard")}
19039
+ ${chalk44.magentaBright("dashboard")} Open the web dashboard in your browser
18396
19040
 
18397
- ${chalk43.bold("Vaults")}
18398
- ${chalk43.magentaBright("vaults")} Manage the global vault registry (multi-project)
19041
+ ${chalk44.bold("Vaults")}
19042
+ ${chalk44.magentaBright("vaults")} Manage the global vault registry (multi-project)
18399
19043
 
18400
- ${chalk43.dim("Run")} dreamcontext ${chalk43.dim("<command> --help")} ${chalk43.dim("for details on a specific command.")}
19044
+ ${chalk44.dim("Run")} dreamcontext ${chalk44.dim("<command> --help")} ${chalk44.dim("for details on a specific command.")}
18401
19045
  `;
18402
19046
  main().catch((err) => {
18403
- console.error(chalk43.red("\u2717") + " " + err.message);
19047
+ console.error(chalk44.red("\u2717") + " " + err.message);
18404
19048
  process.exit(1);
18405
19049
  });
18406
19050
  }