dreamcontext 0.17.1 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +321 -565
  2. package/agents/sleep-product.md +21 -2
  3. package/agents/sleep-state.md +24 -0
  4. package/agents/sleep-tasks.md +16 -0
  5. package/dist/agents/sleep-product.md +21 -2
  6. package/dist/agents/sleep-state.md +24 -0
  7. package/dist/agents/sleep-tasks.md +16 -0
  8. package/dist/dashboard/announcements/dashboard-highlights-0-17-0-18.excalidraw.md +1531 -0
  9. package/dist/dashboard/announcements/goal-skill-v2.excalidraw.md +1490 -0
  10. package/dist/dashboard/announcements/task-manager.excalidraw.md +1217 -0
  11. package/dist/dashboard/announcements/visual-announcements.excalidraw.md +1373 -0
  12. package/dist/dashboard/announcements.json +38 -0
  13. package/dist/dashboard/assets/{BrainCanvas3D-DyF_3yYD.js → BrainCanvas3D-D9G3dOLf.js} +1 -1
  14. package/dist/dashboard/assets/{_baseUniq-Do8VMBA0.js → _baseUniq-Cyshlz4Y.js} +1 -1
  15. package/dist/dashboard/assets/{ar-SA-G6X2FPQ2-DmbXDb2R.js → ar-SA-G6X2FPQ2-qj-2Cbgo.js} +1 -1
  16. package/dist/dashboard/assets/{arc-CwtUBQfU.js → arc-0OnX5WDs.js} +1 -1
  17. package/dist/dashboard/assets/{architectureDiagram-Q4EWVU46-O9bOog_f.js → architectureDiagram-Q4EWVU46-Cx3c0nUi.js} +1 -1
  18. package/dist/dashboard/assets/{az-AZ-76LH7QW2-c9Zk10vG.js → az-AZ-76LH7QW2-CBuoh6M3.js} +1 -1
  19. package/dist/dashboard/assets/{bg-BG-XCXSNQG7-uMTg84lX.js → bg-BG-XCXSNQG7-X5QYyZWx.js} +1 -1
  20. package/dist/dashboard/assets/{blockDiagram-DXYQGD6D-BTENXCSO.js → blockDiagram-DXYQGD6D-BwESAg1j.js} +1 -1
  21. package/dist/dashboard/assets/{bn-BD-2XOGV67Q-DUFKHcua.js → bn-BD-2XOGV67Q-DlodQLNR.js} +1 -1
  22. package/dist/dashboard/assets/{c4Diagram-AHTNJAMY-DMXPWRiQ.js → c4Diagram-AHTNJAMY-CopL0lbP.js} +1 -1
  23. package/dist/dashboard/assets/{ca-ES-6MX7JW3Y-BuYX1q89.js → ca-ES-6MX7JW3Y-DfqF6Yhy.js} +1 -1
  24. package/dist/dashboard/assets/channel-BLisRbYb.js +1 -0
  25. package/dist/dashboard/assets/{chunk-4BX2VUAB-DgefvnWS.js → chunk-4BX2VUAB-CRwifLK3.js} +1 -1
  26. package/dist/dashboard/assets/{chunk-4TB4RGXK-BnFO5G1t.js → chunk-4TB4RGXK-uxJYY_64.js} +1 -1
  27. package/dist/dashboard/assets/{chunk-55IACEB6-COm2TYEM.js → chunk-55IACEB6-DhYIp7Oc.js} +1 -1
  28. package/dist/dashboard/assets/{chunk-EDXVE4YY-CtsGCwZp.js → chunk-EDXVE4YY-CCxfcirt.js} +1 -1
  29. package/dist/dashboard/assets/{chunk-FMBD7UC4-cfSvx35j.js → chunk-FMBD7UC4-D7OC8QFC.js} +1 -1
  30. package/dist/dashboard/assets/{chunk-OYMX7WX6-DAhDKteL.js → chunk-OYMX7WX6-CwHgaUQo.js} +1 -1
  31. package/dist/dashboard/assets/{chunk-QZHKN3VN-B5h4qML3.js → chunk-QZHKN3VN-7Idpf6YJ.js} +1 -1
  32. package/dist/dashboard/assets/{chunk-YZCP3GAM-CGp_NiRg.js → chunk-YZCP3GAM-D4Lh0fgr.js} +1 -1
  33. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-CgqeQiHi.js +1 -0
  34. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-CgqeQiHi.js +1 -0
  35. package/dist/dashboard/assets/clone-CQXNMCV5.js +1 -0
  36. package/dist/dashboard/assets/{cose-bilkent-S5V4N54A-Dk7CMFA4.js → cose-bilkent-S5V4N54A-BYcMtJTF.js} +1 -1
  37. package/dist/dashboard/assets/{cs-CZ-2BRQDIVT-zfUTiS_d.js → cs-CZ-2BRQDIVT-rnrpKdSJ.js} +1 -1
  38. package/dist/dashboard/assets/{da-DK-5WZEPLOC-CU14f8NA.js → da-DK-5WZEPLOC-D5OGAvk7.js} +1 -1
  39. package/dist/dashboard/assets/{dagre-KV5264BT-BiMVxC4Q.js → dagre-KV5264BT-V0f1_b4R.js} +1 -1
  40. package/dist/dashboard/assets/{de-DE-XR44H4JA-CDOHAJGo.js → de-DE-XR44H4JA-CDyb8YfL.js} +1 -1
  41. package/dist/dashboard/assets/{diagram-5BDNPKRD-DfJEsVTA.js → diagram-5BDNPKRD-BmpizoaS.js} +1 -1
  42. package/dist/dashboard/assets/{diagram-G4DWMVQ6-CztLHIcY.js → diagram-G4DWMVQ6-ClQg-LTu.js} +1 -1
  43. package/dist/dashboard/assets/{diagram-MMDJMWI5-DqoQLlWK.js → diagram-MMDJMWI5-BkXcDMIV.js} +1 -1
  44. package/dist/dashboard/assets/{diagram-TYMM5635-DvyvQBCc.js → diagram-TYMM5635-BbFiiCM2.js} +1 -1
  45. package/dist/dashboard/assets/{el-GR-BZB4AONW-ChUphbcv.js → el-GR-BZB4AONW-Y1YnKZL0.js} +1 -1
  46. package/dist/dashboard/assets/{erDiagram-SMLLAGMA-D_uSs2_2.js → erDiagram-SMLLAGMA-Dzdv7_l5.js} +1 -1
  47. package/dist/dashboard/assets/{es-ES-U4NZUMDT-BNalBEhb.js → es-ES-U4NZUMDT-D0T536hs.js} +1 -1
  48. package/dist/dashboard/assets/{eu-ES-A7QVB2H4-BMiQyA2y.js → eu-ES-A7QVB2H4-Bfrya0et.js} +1 -1
  49. package/dist/dashboard/assets/{fa-IR-HGAKTJCU-Bd6ZnTSo.js → fa-IR-HGAKTJCU-pYE_hG-L.js} +1 -1
  50. package/dist/dashboard/assets/{fi-FI-Z5N7JZ37-BWAfJadC.js → fi-FI-Z5N7JZ37-D3C-fNyk.js} +1 -1
  51. package/dist/dashboard/assets/{flowDiagram-DWJPFMVM-Bmsp6kyU.js → flowDiagram-DWJPFMVM-CFhyjwKY.js} +1 -1
  52. package/dist/dashboard/assets/{fr-FR-RHASNOE6-CspbYzOW.js → fr-FR-RHASNOE6-CgwnG5JW.js} +1 -1
  53. package/dist/dashboard/assets/{ganttDiagram-T4ZO3ILL-wEdysXo_.js → ganttDiagram-T4ZO3ILL-BRKRiSzf.js} +1 -1
  54. package/dist/dashboard/assets/{gitGraphDiagram-UUTBAWPF-BEiGpPBj.js → gitGraphDiagram-UUTBAWPF-CTqCK49d.js} +1 -1
  55. package/dist/dashboard/assets/{gl-ES-HMX3MZ6V-CV76vsWr.js → gl-ES-HMX3MZ6V-DjJTqTm3.js} +1 -1
  56. package/dist/dashboard/assets/{graph-CZFIeNHZ.js → graph-D429kSbY.js} +1 -1
  57. package/dist/dashboard/assets/{he-IL-6SHJWFNN-Y1VoXJ_H.js → he-IL-6SHJWFNN-C84FlH6r.js} +1 -1
  58. package/dist/dashboard/assets/{hi-IN-IWLTKZ5I-Crh5S49o.js → hi-IN-IWLTKZ5I-Blhkfum2.js} +1 -1
  59. package/dist/dashboard/assets/{hu-HU-A5ZG7DT2-D4I3gCbp.js → hu-HU-A5ZG7DT2-DLC1JfN-.js} +1 -1
  60. package/dist/dashboard/assets/{id-ID-SAP4L64H-Chvzkuvi.js → id-ID-SAP4L64H-C3pB_IWB.js} +1 -1
  61. package/dist/dashboard/assets/image-FgR93jdt.js +1 -0
  62. package/dist/dashboard/assets/index-2m8ueOUn.js +1 -0
  63. package/dist/dashboard/assets/index-CWwjuihq.css +32 -0
  64. package/dist/dashboard/assets/{index-C7Bo5AQH.js → index-CbOXCDms.js} +1 -1
  65. package/dist/dashboard/assets/index-SJ64pf-4.js +551 -0
  66. package/dist/dashboard/assets/{infoDiagram-42DDH7IO-BzfuDHl4.js → infoDiagram-42DDH7IO-CIzDShDw.js} +1 -1
  67. package/dist/dashboard/assets/{ishikawaDiagram-UXIWVN3A-BVoNJ9VS.js → ishikawaDiagram-UXIWVN3A-CuasYzdX.js} +1 -1
  68. package/dist/dashboard/assets/{it-IT-JPQ66NNP-BH_gN5es.js → it-IT-JPQ66NNP-DGGEoNPu.js} +1 -1
  69. package/dist/dashboard/assets/{ja-JP-DBVTYXUO-DU_WmLVa.js → ja-JP-DBVTYXUO-CEqP9aps.js} +1 -1
  70. package/dist/dashboard/assets/{journeyDiagram-VCZTEJTY-DbwICa_a.js → journeyDiagram-VCZTEJTY-DHiq2OTQ.js} +1 -1
  71. package/dist/dashboard/assets/{kaa-6HZHGXH3-KYU9qowM.js → kaa-6HZHGXH3-GOFmTAXq.js} +1 -1
  72. package/dist/dashboard/assets/{kab-KAB-ZGHBKWFO-bjhyiUq5.js → kab-KAB-ZGHBKWFO-B865Wwzu.js} +1 -1
  73. package/dist/dashboard/assets/{kanban-definition-6JOO6SKY-D9XucLs4.js → kanban-definition-6JOO6SKY-BhlTKFbL.js} +1 -1
  74. package/dist/dashboard/assets/{kk-KZ-P5N5QNE5-CYTx_dAZ.js → kk-KZ-P5N5QNE5-CNfuE6b6.js} +1 -1
  75. package/dist/dashboard/assets/{km-KH-HSX4SM5Z-DqsuY4Lf.js → km-KH-HSX4SM5Z-CsmgRWxu.js} +1 -1
  76. package/dist/dashboard/assets/{ko-KR-MTYHY66A-BZe7NywF.js → ko-KR-MTYHY66A-B_02RgEz.js} +1 -1
  77. package/dist/dashboard/assets/{ku-TR-6OUDTVRD-F5d6HFWt.js → ku-TR-6OUDTVRD-JfQA5u05.js} +1 -1
  78. package/dist/dashboard/assets/{layout-CotqU0S9.js → layout-DvrQSvOI.js} +1 -1
  79. package/dist/dashboard/assets/{linear-Dqv87Scf.js → linear-6r0qttLs.js} +1 -1
  80. package/dist/dashboard/assets/{lt-LT-XHIRWOB4-BCCuaPbS.js → lt-LT-XHIRWOB4-DWFUXEdf.js} +1 -1
  81. package/dist/dashboard/assets/{lv-LV-5QDEKY6T-NLGi-vJ6.js → lv-LV-5QDEKY6T-C5yAd0n_.js} +1 -1
  82. package/dist/dashboard/assets/{min-BbJdnc3h.js → min-D_EP9dBf.js} +1 -1
  83. package/dist/dashboard/assets/{mindmap-definition-QFDTVHPH-Dk4QySu7.js → mindmap-definition-QFDTVHPH-Col3ao9B.js} +1 -1
  84. package/dist/dashboard/assets/{mr-IN-CRQNXWMA-BnGDIgVN.js → mr-IN-CRQNXWMA-Dwjz0Xdm.js} +1 -1
  85. package/dist/dashboard/assets/{my-MM-5M5IBNSE-CspgYE9_.js → my-MM-5M5IBNSE-EXJDNyjA.js} +1 -1
  86. package/dist/dashboard/assets/{nb-NO-T6EIAALU-BeRPw3hu.js → nb-NO-T6EIAALU-BWm2bgLd.js} +1 -1
  87. package/dist/dashboard/assets/{nl-NL-IS3SIHDZ-C-G-bljM.js → nl-NL-IS3SIHDZ-f8nP-yp-.js} +1 -1
  88. package/dist/dashboard/assets/{nn-NO-6E72VCQL-Ct7VZY8D.js → nn-NO-6E72VCQL-B0c_gCNR.js} +1 -1
  89. package/dist/dashboard/assets/{oc-FR-POXYY2M6-Cv5-C4Qq.js → oc-FR-POXYY2M6-C40PSwAh.js} +1 -1
  90. package/dist/dashboard/assets/{pa-IN-N4M65BXN-DAgkIThL.js → pa-IN-N4M65BXN-DDcgXFkB.js} +1 -1
  91. package/dist/dashboard/assets/{percentages-BXMCSKIN-vidRYabK.js → percentages-BXMCSKIN-MHBQP8nI.js} +7 -7
  92. package/dist/dashboard/assets/{pica-Cy-Xl-mi.js → pica-C5CFA09W.js} +1 -1
  93. package/dist/dashboard/assets/{pieDiagram-DEJITSTG-BnP4-zwd.js → pieDiagram-DEJITSTG-DFHmB0fL.js} +1 -1
  94. package/dist/dashboard/assets/{pl-PL-T2D74RX3-BuJQ3HD-.js → pl-PL-T2D74RX3-yFTBt0Xu.js} +1 -1
  95. package/dist/dashboard/assets/{pt-BR-5N22H2LF-BbAqsvD6.js → pt-BR-5N22H2LF-ilAW3Fdv.js} +1 -1
  96. package/dist/dashboard/assets/{pt-PT-UZXXM6DQ-DzFJedU3.js → pt-PT-UZXXM6DQ-CXHFN95K.js} +1 -1
  97. package/dist/dashboard/assets/{quadrantDiagram-34T5L4WZ-BXN88cHy.js → quadrantDiagram-34T5L4WZ-CR732_oP.js} +1 -1
  98. package/dist/dashboard/assets/{requirementDiagram-MS252O5E-D34hL42a.js → requirementDiagram-MS252O5E-mKoVG52Z.js} +1 -1
  99. package/dist/dashboard/assets/{ro-RO-JPDTUUEW-BV2-sOiv.js → ro-RO-JPDTUUEW-BKlWpyF4.js} +1 -1
  100. package/dist/dashboard/assets/{ru-RU-B4JR7IUQ-BCL4N9Ej.js → ru-RU-B4JR7IUQ-BGoxlhJm.js} +1 -1
  101. package/dist/dashboard/assets/{sankeyDiagram-XADWPNL6-0mFeok-3.js → sankeyDiagram-XADWPNL6-DXipts7M.js} +1 -1
  102. package/dist/dashboard/assets/{sequenceDiagram-FGHM5R23-C-5nW5j6.js → sequenceDiagram-FGHM5R23-DFQhU8q7.js} +1 -1
  103. package/dist/dashboard/assets/{si-LK-N5RQ5JYF-CNhaw4jx.js → si-LK-N5RQ5JYF-yDbJWFTH.js} +1 -1
  104. package/dist/dashboard/assets/{sk-SK-C5VTKIMK-mHCphOXu.js → sk-SK-C5VTKIMK-DglyhbNB.js} +1 -1
  105. package/dist/dashboard/assets/{sl-SI-NN7IZMDC--lzgHthQ.js → sl-SI-NN7IZMDC-DPfq0s4I.js} +1 -1
  106. package/dist/dashboard/assets/{stateDiagram-FHFEXIEX-C50iDFqe.js → stateDiagram-FHFEXIEX-Dm50jiEh.js} +1 -1
  107. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-CoSm11sD.js +1 -0
  108. package/dist/dashboard/assets/{subset-shared.chunk-DNsjL37s.js → subset-shared.chunk-OHz6M6ct.js} +1 -1
  109. package/dist/dashboard/assets/{subset-worker.chunk-BaV3r-bl.js → subset-worker.chunk-BzwrOBtO.js} +1 -1
  110. package/dist/dashboard/assets/{sv-SE-XGPEYMSR-ckw8jfGN.js → sv-SE-XGPEYMSR-BLHNwr4k.js} +1 -1
  111. package/dist/dashboard/assets/{ta-IN-2NMHFXQM-CSeNmVhS.js → ta-IN-2NMHFXQM-Dw-6hUpN.js} +1 -1
  112. package/dist/dashboard/assets/{th-TH-HPSO5L25-Cvn1sg_3.js → th-TH-HPSO5L25-DPkcM_k9.js} +1 -1
  113. package/dist/dashboard/assets/{timeline-definition-GMOUNBTQ-DRYfuqHT.js → timeline-definition-GMOUNBTQ-BKFNQ_7e.js} +1 -1
  114. package/dist/dashboard/assets/{tr-TR-DEFEU3FU-CyhY22TB.js → tr-TR-DEFEU3FU-rBVsY5RS.js} +1 -1
  115. package/dist/dashboard/assets/{uk-UA-QMV73CPH-BvvAEO6U.js → uk-UA-QMV73CPH-CV6_yTZs.js} +1 -1
  116. package/dist/dashboard/assets/{vennDiagram-DHZGUBPP-Crril7Cj.js → vennDiagram-DHZGUBPP-BZb_r5tY.js} +1 -1
  117. package/dist/dashboard/assets/{vi-VN-M7AON7JQ-c7AwSUZ8.js → vi-VN-M7AON7JQ-CJMgSsLz.js} +1 -1
  118. package/dist/dashboard/assets/{wardley-RL74JXVD-Da5AhSWU.js → wardley-RL74JXVD-DgqjmWyN.js} +1 -1
  119. package/dist/dashboard/assets/{wardleyDiagram-NUSXRM2D-C4GeB_Df.js → wardleyDiagram-NUSXRM2D-BDpniS9m.js} +1 -1
  120. package/dist/dashboard/assets/webviewWindow-Bwv2421L.js +1 -0
  121. package/dist/dashboard/assets/window-BObcHN8e.js +1 -0
  122. package/dist/dashboard/assets/{xychartDiagram-5P7HB3ND-BPCFKXqR.js → xychartDiagram-5P7HB3ND-CCyPcx2A.js} +1 -1
  123. package/dist/dashboard/assets/{zh-CN-LNUGB5OW-BvNiZwKU.js → zh-CN-LNUGB5OW-9LJLF_AC.js} +1 -1
  124. package/dist/dashboard/assets/{zh-HK-E62DVLB3-CCFtoCWb.js → zh-HK-E62DVLB3-IefAiePp.js} +1 -1
  125. package/dist/dashboard/assets/{zh-TW-RAJ6MFWO-bYBr-stu.js → zh-TW-RAJ6MFWO-CHeY9rNZ.js} +1 -1
  126. package/dist/dashboard/index.html +2 -2
  127. package/dist/index.js +4099 -1538
  128. package/dist/skill-packs/agents/goal-implementer.md +42 -1
  129. package/dist/skill-packs/agents/goal-plan-reviewer.md +7 -0
  130. package/dist/skill-packs/agents/goal-planner.md +34 -0
  131. package/dist/skill-packs/catalog.json +31 -21
  132. package/dist/skill-packs/excalidraw/SKILL.md +244 -13
  133. package/dist/skill-packs/excalidraw/examples/Chart Kit.excalidraw.md +15740 -0
  134. package/dist/skill-packs/excalidraw/examples/Wireframe Kit.excalidraw.md +16860 -0
  135. package/dist/skill-packs/excalidraw/examples/atomic_check.js +99 -0
  136. package/dist/skill-packs/excalidraw/examples/chart.spec.json +122 -0
  137. package/dist/skill-packs/excalidraw/examples/chart_board.js +173 -0
  138. package/dist/skill-packs/excalidraw/examples/hello.spec.json +79 -9
  139. package/dist/skill-packs/excalidraw/examples/visual_board.js +82 -0
  140. package/dist/skill-packs/excalidraw/examples/wireframe_board.js +161 -0
  141. package/dist/skill-packs/excalidraw/scripts/build_excalidraw.js +292 -27
  142. package/dist/skill-packs/excalidraw/scripts/lib/charts.js +771 -0
  143. package/dist/skill-packs/excalidraw/scripts/lib/style.js +369 -35
  144. package/dist/skill-packs/excalidraw/scripts/lib/wireframe.js +406 -0
  145. package/dist/skill-packs/goal-skill/SKILL.md +369 -100
  146. package/dist/skill-packs/goal-skill/assets/goal-skill-demo.cjs +51 -0
  147. package/dist/skill-packs/goal-skill/assets/goal-skill-viewer.cjs +181 -0
  148. package/package.json +2 -1
  149. package/skill/references/integrations.md +54 -0
  150. package/skill/references/knowledge-and-recall.md +3 -1
  151. package/skill/references/sleep.md +4 -4
  152. package/skill-packs/agents/goal-implementer.md +42 -1
  153. package/skill-packs/agents/goal-plan-reviewer.md +7 -0
  154. package/skill-packs/agents/goal-planner.md +34 -0
  155. package/skill-packs/catalog.json +31 -21
  156. package/skill-packs/excalidraw/SKILL.md +244 -13
  157. package/skill-packs/excalidraw/examples/Chart Kit.excalidraw.md +15740 -0
  158. package/skill-packs/excalidraw/examples/Wireframe Kit.excalidraw.md +16860 -0
  159. package/skill-packs/excalidraw/examples/atomic_check.js +99 -0
  160. package/skill-packs/excalidraw/examples/chart.spec.json +122 -0
  161. package/skill-packs/excalidraw/examples/chart_board.js +173 -0
  162. package/skill-packs/excalidraw/examples/hello.spec.json +79 -9
  163. package/skill-packs/excalidraw/examples/visual_board.js +82 -0
  164. package/skill-packs/excalidraw/examples/wireframe_board.js +161 -0
  165. package/skill-packs/excalidraw/scripts/build_excalidraw.js +292 -27
  166. package/skill-packs/excalidraw/scripts/lib/charts.js +771 -0
  167. package/skill-packs/excalidraw/scripts/lib/style.js +369 -35
  168. package/skill-packs/excalidraw/scripts/lib/wireframe.js +406 -0
  169. package/skill-packs/goal-skill/SKILL.md +369 -100
  170. package/skill-packs/goal-skill/assets/goal-skill-demo.cjs +51 -0
  171. package/skill-packs/goal-skill/assets/goal-skill-viewer.cjs +181 -0
  172. package/skill-task-manager/SKILL.md +93 -0
  173. package/dist/dashboard/assets/channel-2YfRjala.js +0 -1
  174. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-DB_UnN1h.js +0 -1
  175. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-DB_UnN1h.js +0 -1
  176. package/dist/dashboard/assets/clone-DaDvB3N6.js +0 -1
  177. package/dist/dashboard/assets/index-BIfrbaFS.js +0 -516
  178. package/dist/dashboard/assets/index-BdZ3tppu.css +0 -32
  179. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-eW9-s0Sm.js +0 -1
  180. package/dist/dashboard/assets/webviewWindow-BbG9Cr7f.js +0 -1
  181. package/dist/dashboard/assets/window-DmNpeJAL.js +0 -1
@@ -1,13 +1,22 @@
1
1
  ---
2
2
  name: excalidraw
3
3
  description: >-
4
- Generate or extend Obsidian Excalidraw (.excalidraw.md) boards in this vault — lay out
5
- images/screenshots, text labels, shapes, arrows, frames, lanes and grids — by writing a small
6
- JSON spec and letting a deterministic script emit valid plugin markup (so it costs ~no tokens and
7
- always renders). Embeds local images via the plugin's sha1 wikilink trick (no base64). Triggers:
8
- '/excalidraw', 'draw this in excalidraw', 'make an excalidraw board', 'excalidraw diagram',
9
- 'funnel map board', 'embed screenshots into excalidraw', 'add images to an excalidraw file',
10
- 'excalidraw çiz', 'excalidraw board oluştur', 'ekran görüntülerini excalidraw a ekle'.
4
+ Generate or extend Obsidian Excalidraw (.excalidraw.md) boards in this vault — visual-first diagrams,
5
+ charts (line/bar/comparison/stacked/gantt/quadrant/donut/heatmap/table/timeline/KPI/sparkline),
6
+ funnels, device mockups (iPhone/iPad/Mac) and wireframes/prototypes, flowcharts, image/screenshot
7
+ layouts, shapes, arrows, frames, lanes and grids by passing DATA to ~44 ready-made deterministic
8
+ builders and letting a script emit valid plugin markup (so it costs ~no tokens and always renders).
9
+ Every builder works from JS or straight from a JSON spec. Text wraps to a readable measure; the build
10
+ audits the scene for overlaps, buried labels and over-long lines. Embeds local images via the plugin's
11
+ sha1 wikilink trick (no base64). Triggers: '/excalidraw', 'draw this in excalidraw', 'make an
12
+ excalidraw board', 'excalidraw diagram', 'chart', 'line chart', 'bar chart', 'compare before/after',
13
+ 'gantt', 'timeline', 'quadrant', 'impact effort matrix', 'heatmap', 'KPI tiles', 'dashboard board',
14
+ 'funnel', 'conversion funnel', 'wireframe', 'prototype', 'mockup', 'app/web screen mockup', 'iphone
15
+ mockup', 'ipad mockup', 'mac app mockup', 'ui kit', 'icon button', 'funnel map board', 'embed
16
+ screenshots into excalidraw', 'add images to an excalidraw file', 'excalidraw çiz', 'excalidraw board
17
+ oluştur', 'grafik çiz', 'çizgi grafik', 'bar grafik', 'karşılaştırma grafiği', 'zaman çizelgesi',
18
+ 'funnel çiz', 'wireframe çiz', 'prototip çiz', 'iphone ekranı çiz', 'ekran tasarımı çiz', 'ekran
19
+ görüntülerini excalidraw a ekle'.
11
20
  ---
12
21
 
13
22
  # Excalidraw board generator (Obsidian)
@@ -17,6 +26,37 @@ Write `.excalidraw.md` files that render natively in this vault's Obsidian Excal
17
26
  frontmatter, `## Text Elements`, `## Embedded Files`, and the `%% ## Drawing … %%` JSON, with
18
27
  correct sha1 image links, fractional z-indices, and deterministic seeds (clean git diffs).
19
28
 
29
+ ## Design principles (read first)
30
+
31
+ Excalidraw's strength is **pictures, not paragraphs**. Four rules keep a board clean, readable, and
32
+ visually rich — the primitives below enforce them, so lean on them instead of placing raw text/shapes:
33
+
34
+ 1. **Use a primitive; don't hand-roll one.** There are ~44 ready builders (charts, house style,
35
+ devices/UI) covering most of what a board needs — pass DATA, get correct geometry. This is the rule
36
+ the other three depend on: hand-rolled composites are where boards break. Reach for `charts.js` /
37
+ `wireframe.js` / `style.js` **before** writing rects + text yourself, and only drop to raw elements
38
+ when nothing fits. Every builder is also a spec JSON `type`, so a whole board can be pure JSON.
39
+ 2. **Visual-first.** Explain complex things with *structure you can see*: a `funnel()` of trapezoid
40
+ bands, a `device()` of the actual screen, a `lineChart()` of the trend, a `hub()`/flow of `card()`s.
41
+ Reach for a picture before a sentence. When you must write, keep it to labels and short notes.
42
+ 3. **Readable measure — text never runs edge-to-edge.** Every text primitive wraps to a bounded width
43
+ (`READ_W ≈ 620px`, ~60 chars). Use `prose()` for body copy, `bullets()` for lists, `callout()` for
44
+ titled notes, `sectionTitle()` for headers — they cap + wrap for you. A raw `text` element **must**
45
+ carry a `width` (it then wraps and the newlines are baked in, so it renders at that measure). Long
46
+ unbounded text is the #1 readability killer, and the build now **enforces** this (`longLines`).
47
+ 4. **No overlap — flow the layout, don't hand-place.** Build with `stack()` (top-to-bottom) and `row()`
48
+ (left-to-right): each block is placed after the previous one's *measured* size, so boxes can't
49
+ collide. Every build audits the finished scene and reports
50
+ `overlaps=N buriedText=N longLines=N` — any non-zero count is a real defect (see **Layout rules**).
51
+
52
+ Everything downstream (the primitives, the auditors, the wrap-baking) exists to make these four cheap.
53
+
54
+ > **A clean audit is necessary, not sufficient — render the board and LOOK at it.** This is not a
55
+ > platitude: in practice most defects that reach a finished board are ones the audit cannot see —
56
+ > a mis-scaled axis, an axis caption wrapping one glyph per line, a sentence torn across a gap,
57
+ > content escaping a device bezel, a row label silently truncated. The audit catches geometry it can
58
+ > measure; your eyes catch the rest. See **Verify** for the headless render command.
59
+
20
60
  ## The one trick that makes images work
21
61
  An image element references `fileId` = **sha1 of the image file**. The `## Embedded Files` section
22
62
  maps `<sha1>: [[image.png]]`. The plugin resolves the picture from the vault via that wikilink —
@@ -28,7 +68,10 @@ maps `<sha1>: [[image.png]]`. The plugin resolves the picture from the vault via
28
68
  ```bash
29
69
  node .claude/skills/excalidraw/scripts/build_excalidraw.js <spec.json> [--out <path.excalidraw.md>]
30
70
  ```
31
- Write a spec JSON, then run it. The script prints `elements/images/texts` counts on success.
71
+ Write a spec JSON, then run it. On success it prints
72
+ `elements=… images=… texts=… overlaps=… buriedText=… longLines=…` — the last three must all be **0**.
73
+ A spec element's `type` may be a primitive OR any of the ~44 composites (charts, house style, devices,
74
+ `stack`/`row`), so a whole board can be pure JSON with no generator script.
32
75
 
33
76
  ### JS API (for pipelines that generate many boards)
34
77
  ```js
@@ -120,6 +163,14 @@ Key conventions:
120
163
  "attachDir": "Attachments", // external images get copied here (relative to board dir)
121
164
  "wikilinkMode": "basename", // "basename" (default) or "path" (vault-relative)
122
165
  "background": "#ffffff",
166
+
167
+ // frontmatter — REQUIRED for a board that lives in knowledge/ (dreamcontext indexes name +
168
+ // description + tags; without them the board is effectively unrecallable). Omit for scratch boards.
169
+ "name": "recall-engine-v2",
170
+ "description": "One paragraph on what this board visualises. Long prose is fine — it is emitted as a folded YAML block.",
171
+ "tags": ["architecture", "excalidraw"],
172
+ "frontmatter": { "any-extra-key": "value" }, // optional passthrough
173
+
123
174
  "elements": [ /* ElementSpec… */ ]
124
175
  }
125
176
  ```
@@ -128,6 +179,11 @@ Key conventions:
128
179
  hardcode absolute paths. This keeps the generator portable: move the folder and it still runs.
129
180
 
130
181
  ### Element types
182
+ A `type` is either a **primitive** (below) or any **composite** — every chart (`lineChart`, `barCompare`,
183
+ `gantt`, `quadrant`, `heatmap`, `table`, `kpi`, `callout`, …), house-style widget (`card`, `funnel`,
184
+ `windowFrame`, `chip`, …) or layout (`stack`, `row`, which nest via `items`). Composites expand to
185
+ primitives before the build, so the JSON surface is as capable as the JS API. See **Charts** below.
186
+
131
187
  - `text` — `{ x, y, text, fontSize?, color?, width?, align?, fontFamily? }` (fontFamily 1=hand, 2=normal, 3=code). **Set `width` for any caption/label that must stay inside a column or card** → the text WRAPS to that width (autoResize off) and its height is computed from the wrapped line count. Omit `width` only for short single-line text you want sized to content (it renders on one line and will overlap neighbours if long).
132
188
  - `image` — `{ x, y, path, width? , height? }` — give ONE of width/height; the other is derived from aspect. `path` is an absolute file path.
133
189
  - `rectangle`/`ellipse`/`diamond` — `{ x, y, width, height, strokeColor?, backgroundColor?, fillStyle?(solid|hachure|cross-hatch), strokeWidth?, roundness?(true=rounded) }`
@@ -179,11 +235,162 @@ Match the team's look by default. The builder now defaults text to **Excalifont
179
235
  - **`bullets({x,y,items})`** → one left-aligned bulleted text block (their spec-list pattern).
180
236
  - Edge helpers `center/rightOf/leftOf/topOf/bottomOf(x,y,w,h)` to wire connectors to card edges.
181
237
 
182
- Compose these into a `buildExcalidraw({ out, elements })` call. Runnable example: `examples/style_board.js`.
238
+ ### Readable text + flow layout (use these, don't hand-place)
239
+ Every builder below returns an `ElementSpec[]` that also carries `.x/.y/.w/.h/.nextX/.nextY`, so the
240
+ layout helpers can measure and place blocks for you — no coordinate math, no overlap.
241
+ - **`prose({x,y,text,fontSize,width})`** → a wrapped paragraph. `width` defaults to `READ_W` (~60 chars);
242
+ text can never exceed it. This is THE body-copy primitive. Height is derived from the wrapped lines.
243
+ - **`bullets({x,y,items,width})`** → left-aligned list; each item wraps to `width` with a hanging indent.
244
+ - **`sectionTitle({x,y,text,fontSize,maxWidth})`** → big header; long titles wrap to `maxWidth`.
245
+ - **`stack({x,y,gap,items})`** → flow blocks TOP-TO-BOTTOM. Each item is a factory `(x,y)=>els` (draws
246
+ itself at the running cursor) or a pre-built `els` array (gets shifted down). Returns `.nextY`.
247
+ - **`row({x,y,gap,valign,items})`** → flow blocks LEFT-TO-RIGHT (same contract). Returns `.nextX`.
248
+ - `READ_W` / `NOTE_W` are the exported reading measures; `translate(els,dx,dy)` / `bbox(els)` are the
249
+ low-level helpers the layout uses.
250
+
251
+ ## Charts (`scripts/lib/charts.js`) — data in, correct geometry out
252
+
253
+ **Never hand-roll a chart from rects + text.** These builders own the axes, scales, wrapping, label
254
+ thinning and collision-avoidance; you supply DATA only. Same contract as `style.js` (return an
255
+ `ElementSpec[]` carrying `.x/.y/.w/.h/.nextY`), so they drop straight into `stack()`/`row()`. Nothing
256
+ is random or time-dependent — same input ⇒ same bytes. Each chart is **grouped**, so it moves as one
257
+ unit and the auditors treat its internals as intentional.
258
+
259
+ | builder | use it for |
260
+ |---|---|
261
+ | **`lineChart({series,xLabels,area,markers})`** | trend over time — DAU, spend, error rate. `series[].points` is a `number[]` aligned to `xLabels` (or `[{x,y}]` for irregular spacing) |
262
+ | **`barChart({bars,horizontal})`** | one value per category. `horizontal:true` when labels are long — they get their own gutter instead of being crammed under vertical bars |
263
+ | **`barCompare({groups,seriesLabels})`** | the "did it move?" chart — same categories across 2+ scenarios (W1↔W2, before/after, plan/actual) |
264
+ | **`stackedBar({groups,seriesLabels})`** | composition per category (revenue by plan, traffic by source); segments stack to each group's total |
265
+ | **`gantt({tasks,today})`** | timeline bars over a date axis. `start`/`end` take `'YYYY-MM-DD'`; `done:0..1` overlays progress; `milestone:true` draws a diamond |
266
+ | **`quadrant({items,xAxis,yAxis,quadrantLabels})`** | 2×2 positioning map (impact×effort, RICE). `items[]` carry `{label,x,y}` in 0..1; top-right is tinted as the "go" quadrant |
267
+ | **`donut({slices,inner})`** / **`pie`** | composition of a whole. Keep to ≤ ~6 slices — beyond that `barChart` reads better |
268
+ | **`sparkline({points})`** | a tiny trend with no axes, for inside a KPI tile or table cell. A glyph, not a chart |
269
+ | **`heatmap({rows,cols,values})`** | matrix of intensities (cohort×day retention). Cell tint interpolates, and the label flips to white on dark cells |
270
+ | **`table({headers,rows,align})`** | a real grid — column widths derive from content, so cells never spill. A cell may be `{text,color}` |
271
+ | **`timeline({events})`** | milestones on a track; labels alternate above/below so they can't collide |
272
+ | **`kpi({label,value,delta,spark})`** | the metric tile: three type sizes for hierarchy, optional sparkline footer |
273
+ | **`callout({title,text,sideTitle})`** | a titled note band. Body copy is **always** bounded to `READ_W`; a wide band puts its heading *beside* the text rather than stretching one line |
274
+
275
+ **`w` is a MAXIMUM, not a target.** `callout()` sizes itself to its own wrapped text — hand it 1080px for
276
+ 620px of copy and it returns ~780px, not a band with 27% dead space. The title gutter hugs the title too.
277
+ That is what makes a primitive atomic: the caller says *at most this wide*, the builder works out the rest.
278
+ Pin `titleW` only to align the gutters of several stacked callouts; pass `fit: false` for a deliberate
279
+ full-width band. `prose()` already hugs the same way. (`card()`/`kpi()` stay caller-sized on purpose —
280
+ a row of tiles should be uniform.)
281
+
282
+ Helpers for custom charts: `linScale`, `niceScale`, `fmtNum`, `plotFrame`, `chartHead`, `xTickLabels`.
283
+
284
+ **Never split short copy into newspaper columns.** A 1–2 line "column" reads as a sentence torn across
285
+ a gap — worse than a long line. `callout()` handles this for you.
286
+
287
+ ### Declarative charts — any composite works as a spec `type`
288
+ Every chart and house-style widget is also a **spec JSON element type**, expanded to primitives before
289
+ the build. An agent can draw a whole board without writing a generator — `stack`/`row` nest as JSON too:
290
+ ```jsonc
291
+ { "out": "./Board.excalidraw.md", "elements": [
292
+ { "type": "stack", "x": 40, "y": 40, "gap": 40, "items": [
293
+ { "type": "sectionTitle", "text": "Weekly review", "fontSize": 34 },
294
+ { "type": "row", "gap": 24, "items": [
295
+ { "type": "kpi", "w": 260, "label": "D0 ROAS", "value": "0.25", "delta": "flat", "color": "red" },
296
+ { "type": "lineChart", "w": 620, "h": 300, "xLabels": ["3","5","7"],
297
+ "series": [{ "label": "DAU", "color": "blue", "points": [58, 69, 32] }] }
298
+ ]}
299
+ ]}
300
+ ]}
301
+ ```
302
+ Reach for the JS API instead when you need loops, data mapping, or many boards from one data set.
303
+ Runnable: `node examples/chart_board.js` (every builder) · `node scripts/build_excalidraw.js examples/chart.spec.json` (pure JSON).
304
+
305
+ ### Funnel
306
+ - **`funnel({x,y,w,stageH,stages,topW,botW})`** → a conversion/marketing funnel: filled trapezoid bands
307
+ narrowing top→bottom, one per `stages[]` entry `{ label, note?, color? }`. Labels auto-fit; an optional
308
+ `note` (a metric / drop-off) is placed in the right margin with a short non-crossing connector. Colors
309
+ cycle through the semantic palette unless you set `color`. Returns `.nextY`.
310
+
311
+ ## Devices + product UI (`scripts/lib/wireframe.js`) — sketch a real screen
312
+
313
+ For **app/product** wireframes. One require gives the whole UI kit (it re-exports style.js's wireframe
314
+ bits too). Every builder is also a spec JSON `type`.
315
+
316
+ - **`device({kind,x,y,w?,label?,dark?,content?})`** → a device shell at **real proportions**
317
+ (`iphone` 393×852 · `ipad` 834×1194 · `mac` 1440×900), with status bar, dynamic island / camera /
318
+ notch, home indicator, Mac menu bar + laptop foot. Returns **`.inner`** — the safe content region
319
+ (inside the bezel, below the island, above the home indicator) — and `.screen`.
320
+ **Pass `content: (inner) => els`**: it's the only place overflow can be caught. The build audit is
321
+ blind here — a device shell is a filled polygon and `isOpaqueBox()` only knows rect/ellipse/diamond/
322
+ image — so a hardcoded child width silently renders *outside the bezel*. `content` warns instead.
323
+ - **`appBar({title,back,actions})`** · **`tabBar({items,active})`** — mobile top/bottom chrome.
324
+ - **`icon({name,size})`** — 31 line-drawn glyphs. `iconNames()` lists them; an unknown name draws a
325
+ box so a typo is visible rather than silently absent.
326
+ - **`iconButton({icon,shape,variant,color})`** — `shape`: circle/square/rounded · `variant`: solid/outline/ghost.
327
+ - **`listRow({title,subtitle,leading,trailing})`** — `leading` an icon name or `'avatar'`; `trailing`
328
+ an icon name, `'toggle'`, or text.
329
+ - **`toggle({on})`** · **`segmented({items,active})`** · **`slider({value})`** · **`searchField({placeholder})`**
330
+ - Plus the generic bits: `windowFrame` (browser/app chrome), `navbar`, `button`, `input`, `textRows`,
331
+ `imagePlaceholder`, `avatar`, `chip`, `divider`.
332
+
333
+ ```js
334
+ const { device, appBar, tabBar, listRow } = require('.../lib/wireframe.js');
335
+ P(device({ kind: 'iphone', x: 60, y: 80, label: 'Ayarlar', content: (inner) => stack({
336
+ x: inner.x, y: inner.y, gap: 0, items: [
337
+ (x, y) => appBar({ x, y, w: inner.w, title: 'Ayarlar', back: true }),
338
+ (x, y) => listRow({ x, y, w: inner.w, leading: 'bell', title: 'Bildirimler', trailing: 'toggle' }),
339
+ ],
340
+ })}));
341
+ ```
342
+ Runnable: `node examples/wireframe_board.js` — three devices, every control, the full icon set.
343
+
344
+ **Corner radius gotcha**: `roundness:true` maps to Excalidraw's ADAPTIVE_RADIUS, capped at ~32px —
345
+ too tight for a phone (an iPhone's is ~14% of its width). Device shells are therefore filled
346
+ **polygons** with exact arc corners (`roundRect()` is exported if you need the same trick).
347
+
348
+ ### Generic UI bits (grayscale — sketch a UI, not decoration)
349
+ These live in `style.js` and are re-exported by `wireframe.js`, so `require` either one. Use them
350
+ inside a `device()` for an app screen, or a `windowFrame()` for a web page.
351
+ - **`windowFrame({x,y,w,h,kind,url,title})`** → a browser (`kind:'browser'`, draws a URL bar) or app
352
+ (`kind:'app'`, centered title) window with traffic-light chrome. **Returns `.inner = {x,y,w,h}`** — the
353
+ safe content region; place children there (via `stack`/`row`) and they won't hit the chrome.
354
+ For an **iPhone/iPad/Mac** shell with real proportions, use `device()` above instead.
355
+ - **`navbar({x,y,w,brand,items,cta})`** → top nav: brand left, links right, optional CTA button.
356
+ - **`button({x,y,w,h,text,color,variant})`** → solid CTA (default) or `variant:'outline'`.
357
+ - **`input({x,y,w,h,placeholder,label})`** → a form field with a muted placeholder + optional label.
358
+ - **`textRows({x,y,w,rows})`** → grey bars standing in for body copy — VISUAL filler, no real text. Use
359
+ these instead of lorem ipsum so a wireframe never becomes a wall of text.
360
+ - **`imagePlaceholder({x,y,w,h,label})`** → the universal box-with-an-X where a screenshot would go.
361
+ - **`avatar({cx,cy,r})`** → round user placeholder. **`chip({x,y,text,color})`** → a pill/tag/badge.
362
+ **`divider({x,y,w})`** → a thin rule.
363
+
183
364
  Conventions: color nodes by ROLE, label every arrow, put specs in side-annotations, use big plain
184
- section titles to break the board into "slides", keep one idea per card.
365
+ section titles to break the board into "slides", keep one idea per card, and **prefer a picture to a
366
+ paragraph**.
367
+
368
+ ### Which lib?
369
+ | file | owns | reach for it when |
370
+ |---|---|---|
371
+ | `lib/style.js` | house style + layout: `card`, `node`, `connector`, `hub`, `column`, `funnel`, `prose`, `bullets`, `sectionTitle`, `chip`, `divider`, **`stack`/`row`**, `READ_W`, `measureText`, `wrapToWidth`, `fitText` | diagrams, flows, any board's skeleton |
372
+ | `lib/charts.js` | data viz + copy: `lineChart`, `barChart`, `barCompare`, `stackedBar`, `gantt`, `quadrant`, `donut`/`pie`, `sparkline`, `heatmap`, `table`, `timeline`, `kpi`, `callout` | anything with numbers |
373
+ | `lib/wireframe.js` | product UI: `device`, `appBar`, `tabBar`, `icon`, `iconButton`, `listRow`, `toggle`, `segmented`, `slider`, `searchField` (+ re-exports style.js's UI bits) | app/screen mockups |
374
+
375
+ All three share one contract — an `ElementSpec[]` carrying `.x/.y/.w/.h/.nextX/.nextY` — so anything
376
+ composes inside `stack()`/`row()`, and everything is also a spec JSON `type`.
185
377
 
186
378
  ### Layout rules that keep boards clean
379
+ - **Flow the layout with `stack()` / `row()`; never eyeball coordinates for a column or a grid.** They
380
+ place each block after the previous one's measured size, so nothing overlaps by construction. Reserve
381
+ hand-picked `x/y` for a handful of top-level anchors (where a funnel goes vs where a window goes).
382
+ - **Heed the audit — all three checks.** Every build reports `overlaps=N buriedText=N longLines=N`, and
383
+ prints a `[excalidraw]` warning naming the offenders. Any non-zero count is a real defect:
384
+ - `overlaps` — two filled boxes collide (intentional nesting like a button inside a window is ignored).
385
+ - `buriedText` — a text LINE is >30% swallowed by a box it isn't grouped with, i.e. an unreadable
386
+ label. Box-vs-box cannot see this: a section title eaten by a card is text-vs-box.
387
+ - `longLines` — body copy past the reading measure (`READ_W`, +10% tolerance; display type ≥28px is
388
+ exempt). This is the skill's headline rule, and it is now enforced rather than merely documented.
389
+
390
+ Fix by flowing that region through `stack()`/`row()`, or by using the primitives that cap the measure
391
+ (`prose`/`bullets`/`callout`). Opt out with `spec.audit === false` only if you *know* it's deliberate.
392
+ **A clean audit is necessary, not sufficient — always render the board and LOOK at it.** The audit
393
+ cannot see a chart with a mis-scaled axis, a torn sentence, or a layout that is merely ugly.
187
394
  - **Size boxes for their text.** A card guarantees the label stays *inside*, but it does so by shrinking
188
395
  the font — a long label in a small box ends up tiny. Give wide/long labels a wider `w` (or more `h`),
189
396
  or split the idea across two cards. Watch for `[excalidraw]` fit warnings on the console.
@@ -214,8 +421,24 @@ so they work in any project):
214
421
  cd .claude/skills/excalidraw
215
422
  node scripts/build_excalidraw.js examples/hello.spec.json # spec-driven: text/shapes/image → examples/Hello Excalidraw.excalidraw.md
216
423
  node examples/style_board.js # JS API: card/connector/lane house style → examples/Style Demo.excalidraw.md
424
+ node examples/visual_board.js # visual-first kit: funnel + browser prototype + readable prose
425
+ node examples/chart_board.js # every chart in the kit, one board (smoke test)
426
+ node scripts/build_excalidraw.js examples/chart.spec.json # charts declaratively, pure JSON, no generator
427
+ node examples/atomic_check.js # every type from ONE spec element + degenerate input
428
+ node examples/wireframe_board.js # devices (iPhone/iPad/Mac) + every UI control + icon set
429
+ ```
430
+ `atomic_check.js` is the guard on the kit's core promise: each type must draw from a **single spec
431
+ element with data only**, and must not throw on degenerate input (empty series, one point, all-equal
432
+ values). Add a chart to `charts.js` but forget to register it in `COMPOSITES` and this fails. It exits
433
+ non-zero, so it can be wired into CI.
434
+ Each build prints `overlaps=N buriedText=N longLines=N` — a clean board reports **0 for all three**.
435
+
436
+ **Then LOOK at the board.** A clean audit is necessary, not sufficient: it cannot see a mis-scaled
437
+ axis, a sentence torn across a gap, or a layout that is simply ugly. Either open it in Obsidian
438
+ (Excalidraw view), or render it headlessly and inspect the PNG:
439
+ ```bash
440
+ node scripts/diagrams/render-excalidraw.mjs <board.excalidraw.md> /tmp/out.png 1 # (in this repo)
217
441
  ```
218
- Then open the resulting board in Obsidian (Excalidraw view) to confirm it renders.
219
442
 
220
443
  See `reference/format.md` for the exact `.excalidraw.md` anatomy reverse-engineered from this vault.
221
444
 
@@ -233,8 +456,16 @@ JSON).
233
456
 
234
457
  ### Required frontmatter
235
458
 
236
- Every board MUST have `name:` and `description:`. Boards with no `## Text Elements` content rely
237
- entirely on description for recall make it descriptive.
459
+ Every board MUST have `name:` and `description:` **pass them to `buildExcalidraw`** and it emits
460
+ them for you (long descriptions become a folded YAML block; `tags` defaults to `[excalidraw]`).
461
+ Do NOT hand-patch the generated file afterwards.
462
+
463
+ ```js
464
+ buildExcalidraw({ out, elements, name: 'recall-engine-v2', tags: ['architecture', 'excalidraw'],
465
+ description: 'How recall ranks and merges hits across the vault and consenting peers…' });
466
+ ```
467
+ Memory indexes frontmatter + `## Text Elements` and never the scene JSON, so a board with few labels
468
+ leans entirely on `description` for recall — make it descriptive.
238
469
 
239
470
  ```yaml
240
471
  ---