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
@@ -0,0 +1,99 @@
1
+ // atomic_check.js — the regression guard for the kit's core promise:
2
+ // every chart type is a plug-in adaptor, drivable from ONE spec element with DATA only.
3
+ //
4
+ // Run: node examples/atomic_check.js
5
+ // Each type below gets a single spec element and nothing else — no coordinates, no layout, no JS
6
+ // helpers. If it draws elements with a clean audit, it is genuinely atomic. If someone adds a chart
7
+ // to charts.js but forgets to register it in COMPOSITES, or breaks it on minimal input, this fails.
8
+ const path = require('path');
9
+ const os = require('os');
10
+ const { buildExcalidraw } = require(path.resolve(__dirname, '../scripts/build_excalidraw.js'));
11
+
12
+ // Minimal-but-real input per type. Deliberately sparse: a chart must degrade sanely, not assume
13
+ // the author passed every option.
14
+ const CASES = {
15
+ lineChart: { type: 'lineChart', w: 400, h: 240, xLabels: ['1', '2', '3'], series: [{ label: 'DAU', points: [10, 30, 20] }] },
16
+ barChart: { type: 'barChart', w: 400, h: 240, bars: [{ label: 'US', value: 266 }, { label: 'TR', value: 22 }] },
17
+ barCompare: { type: 'barCompare', w: 400, h: 240, seriesLabels: ['W1', 'W2'], groups: [{ label: 'CPM', values: [139, 169] }] },
18
+ stackedBar: { type: 'stackedBar', w: 400, h: 240, seriesLabels: ['a', 'b'], groups: [{ label: 'X', values: [3, 7] }] },
19
+ gantt: { type: 'gantt', w: 600, tasks: [{ label: 'iş', start: '2026-07-16', end: '2026-07-20', done: 0.4 }] },
20
+ quadrant: { type: 'quadrant', w: 400, h: 400, items: [{ label: 'A', x: 0.8, y: 0.8 }, { label: 'B', x: 0.2, y: 0.3 }] },
21
+ donut: { type: 'donut', r: 80, slices: [{ label: 'a', value: 70 }, { label: 'b', value: 30 }] },
22
+ pie: { type: 'pie', r: 80, slices: [{ label: 'a', value: 60 }, { label: 'b', value: 40 }] },
23
+ sparkline: { type: 'sparkline', w: 160, h: 40, points: [5, 9, 4, 8] },
24
+ heatmap: { type: 'heatmap', rows: ['r1', 'r2'], cols: ['D0', 'D1'], values: [[100, 11], [100, 9]] },
25
+ table: { type: 'table', headers: ['Plan', 'Churn'], rows: [['Pro', '3.4%']] },
26
+ timeline: { type: 'timeline', w: 800, events: [{ label: 'başladı', at: '2026-07-03' }, { label: 'review', at: '2026-07-16' }] },
27
+ kpi: { type: 'kpi', w: 260, label: 'DAU', value: '32', delta: '−%57' },
28
+ callout: { type: 'callout', w: 600, title: 'not', text: 'metin hep ölçüde kalır.' },
29
+ funnel: { type: 'funnel', w: 300, stages: [{ label: 'Landing' }, { label: 'Sub' }] },
30
+ // device + product-UI kit
31
+ 'device(iphone)': { type: 'device', kind: 'iphone', x: 0, y: 0 },
32
+ 'device(ipad)': { type: 'device', kind: 'ipad', x: 0, y: 0 },
33
+ 'device(mac)': { type: 'device', kind: 'mac', x: 0, y: 0 },
34
+ appBar: { type: 'appBar', w: 340, title: 'Ayarlar', back: true, actions: ['more-v'] },
35
+ tabBar: { type: 'tabBar', w: 340, items: [{ icon: 'home', label: 'Akış' }, { icon: 'user', label: 'Profil' }], active: 0 },
36
+ icon: { type: 'icon', name: 'search', size: 24 },
37
+ iconButton: { type: 'iconButton', icon: 'plus', shape: 'circle', variant: 'solid', color: 'blue' },
38
+ listRow: { type: 'listRow', w: 340, title: 'Bildirimler', trailing: 'toggle' },
39
+ toggle: { type: 'toggle', on: true },
40
+ segmented: { type: 'segmented', w: 300, items: ['Hepsi', 'Yeni'], active: 0 },
41
+ slider: { type: 'slider', w: 260, value: 0.4 },
42
+ searchField:{ type: 'searchField', w: 300, placeholder: 'Ara' },
43
+ windowFrame:{ type: 'windowFrame', w: 400, h: 260, kind: 'browser', url: 'acme.app' },
44
+ button: { type: 'button', w: 140, text: 'Kaydet' },
45
+ input: { type: 'input', w: 240, label: 'Slug', placeholder: 'chart-kit' },
46
+ imagePlaceholder: { type: 'imagePlaceholder', w: 200, h: 140 },
47
+ };
48
+
49
+ // Degenerate input must not throw or divide by zero — empty series, single point, all-equal values.
50
+ const EDGE = {
51
+ 'lineChart (boş seri)': { type: 'lineChart', w: 300, h: 200, series: [] },
52
+ 'lineChart (tek nokta)': { type: 'lineChart', w: 300, h: 200, xLabels: ['1'], series: [{ label: 'a', points: [5] }] },
53
+ 'barChart (hepsi eşit)': { type: 'barChart', w: 300, h: 200, bars: [{ label: 'a', value: 7 }, { label: 'b', value: 7 }] },
54
+ 'donut (tek dilim)': { type: 'donut', r: 60, slices: [{ label: 'a', value: 1 }] },
55
+ 'sparkline (boş)': { type: 'sparkline', w: 100, h: 30, points: [] },
56
+ 'table (satır yok)': { type: 'table', headers: ['a', 'b'], rows: [] },
57
+ 'tabBar (boş)': { type: 'tabBar', w: 300, items: [] },
58
+ 'segmented (tek)': { type: 'segmented', w: 200, items: ['A'], active: 0 },
59
+ 'icon (bilinmeyen ad)': { type: 'icon', name: 'yok-boyle-bir-sey', size: 20 },
60
+ 'listRow (başlıksız)': { type: 'listRow', w: 300, title: '' },
61
+ };
62
+
63
+ const tmp = path.join(os.tmpdir(), 'excalidraw-atomic-check');
64
+ let pass = 0, fail = 0;
65
+
66
+ function check(label, el, requireElements = true) {
67
+ try {
68
+ const r = buildExcalidraw({ out: path.join(tmp, `${label.replace(/\W+/g, '-')}.excalidraw.md`), elements: [el] });
69
+ const bad = r.overlaps + r.buriedText + r.longLines;
70
+ const ok = bad === 0 && (!requireElements || r.elements > 0);
71
+ if (ok) { pass++; console.log(` ✓ ${label.padEnd(22)} ${String(r.elements).padStart(3)} element`); }
72
+ else { fail++; console.log(` ✗ ${label.padEnd(22)} elements=${r.elements} audit=${bad}`); }
73
+ } catch (e) {
74
+ fail++; console.log(` ✗ ${label.padEnd(22)} THREW: ${e.message.slice(0, 60)}`);
75
+ }
76
+ }
77
+
78
+ console.log('\nEvery type from ONE spec element (data only, no JS):');
79
+ for (const [name, el] of Object.entries(CASES)) check(name, el);
80
+
81
+ console.log('\nDegenerate input must not throw:');
82
+ for (const [name, el] of Object.entries(EDGE)) check(name, el, false);
83
+
84
+ // dreamcontext contract: a board destined for knowledge/ must carry name + description, or it cannot
85
+ // be recalled. This is the integration that used to require hand-patching every generated file.
86
+ console.log('\nFrontmatter (dreamcontext recall contract):');
87
+ try {
88
+ const out = path.join(tmp, 'frontmatter.excalidraw.md');
89
+ buildExcalidraw({ out, name: 'demo-board', description: 'What this board shows.', tags: ['x', 'excalidraw'],
90
+ elements: [{ type: 'kpi', x: 0, y: 0, label: 'A', value: '1' }] });
91
+ const fm = require('fs').readFileSync(out, 'utf8').split('---')[1] || '';
92
+ const ok = /(^|\n)name: demo-board/.test(fm) && /(^|\n)description: >-/.test(fm)
93
+ && /(^|\n)tags: \[x, excalidraw\]/.test(fm) && /excalidraw-plugin: parsed/.test(fm);
94
+ if (ok) { pass++; console.log(' ✓ name + description + tags emitted'); }
95
+ else { fail++; console.log(' ✗ frontmatter wrong:', JSON.stringify(fm.trim())); }
96
+ } catch (e) { fail++; console.log(' ✗ THREW:', e.message.slice(0, 60)); }
97
+
98
+ console.log(`\n ${pass} passed / ${fail} failed`);
99
+ process.exit(fail ? 1 : 0);
@@ -0,0 +1,122 @@
1
+ {
2
+ "out": "./examples/Chart Spec.excalidraw.md",
3
+ "background": "#ffffff",
4
+ "elements": [
5
+ {
6
+ "type": "stack",
7
+ "x": 40,
8
+ "y": 40,
9
+ "gap": 40,
10
+ "items": [
11
+ {
12
+ "type": "sectionTitle",
13
+ "text": "Declarative charts — pure JSON, no generator script",
14
+ "fontSize": 34
15
+ },
16
+ {
17
+ "type": "row",
18
+ "gap": 24,
19
+ "items": [
20
+ {
21
+ "type": "kpi",
22
+ "w": 260,
23
+ "label": "D0 ROAS",
24
+ "value": "0.25",
25
+ "delta": "W1: 0.25 — değişmedi",
26
+ "color": "red"
27
+ },
28
+ {
29
+ "type": "kpi",
30
+ "w": 260,
31
+ "label": "CPM",
32
+ "value": "$169",
33
+ "delta": "+%22",
34
+ "color": "red",
35
+ "spark": [
36
+ 139,
37
+ 144,
38
+ 151,
39
+ 158,
40
+ 169
41
+ ]
42
+ },
43
+ {
44
+ "type": "callout",
45
+ "w": 640,
46
+ "color": "gray",
47
+ "title": "tak diye",
48
+ "text": "Bu board tek bir JSON. Agent hiç JS yazmadan lineChart/barCompare/gantt çizebiliyor."
49
+ }
50
+ ]
51
+ },
52
+ {
53
+ "type": "row",
54
+ "gap": 50,
55
+ "items": [
56
+ {
57
+ "type": "lineChart",
58
+ "w": 620,
59
+ "h": 300,
60
+ "title": "lineChart — DAU",
61
+ "xLabels": [
62
+ "3",
63
+ "5",
64
+ "7",
65
+ "9",
66
+ "11",
67
+ "13",
68
+ "15"
69
+ ],
70
+ "area": true,
71
+ "series": [
72
+ {
73
+ "label": "DAU",
74
+ "color": "blue",
75
+ "points": [
76
+ 58,
77
+ 69,
78
+ 55,
79
+ 44,
80
+ 38,
81
+ 35,
82
+ 32
83
+ ]
84
+ }
85
+ ]
86
+ },
87
+ {
88
+ "type": "barCompare",
89
+ "w": 560,
90
+ "h": 300,
91
+ "title": "barCompare — W1 ↔ W2",
92
+ "seriesLabels": [
93
+ "W1",
94
+ "W2"
95
+ ],
96
+ "colors": [
97
+ "gray",
98
+ "red"
99
+ ],
100
+ "groups": [
101
+ {
102
+ "label": "CPM",
103
+ "values": [
104
+ 139,
105
+ 169
106
+ ]
107
+ },
108
+ {
109
+ "label": "Trans %",
110
+ "values": [
111
+ 67.2,
112
+ 46.77
113
+ ]
114
+ }
115
+ ]
116
+ }
117
+ ]
118
+ }
119
+ ]
120
+ }
121
+ ]
122
+ }
@@ -0,0 +1,173 @@
1
+ // chart_board.js — every chart in the kit, on one board.
2
+ // Data is FICTIONAL (a made-up product, "Acme"): this file ships to npm, so it demos the kit and
3
+ // must never carry real customer metrics.
4
+ // Run: node examples/chart_board.js → examples/Chart Kit.excalidraw.md (expects a clean audit)
5
+ //
6
+ // This doubles as the kit's smoke test: it drives every builder, and the build must report
7
+ // overlaps=0 buriedText=0 longLines=0. If a chart's geometry drifts, this board says so.
8
+ const path = require('path');
9
+ const { buildExcalidraw } = require(path.resolve(__dirname, '../scripts/build_excalidraw.js'));
10
+ const { sectionTitle, prose, stack, row, funnel, READ_W } = require(path.resolve(__dirname, '../scripts/lib/style.js'));
11
+ const {
12
+ lineChart, barChart, barCompare, stackedBar, gantt, quadrant,
13
+ donut, sparkline, heatmap, table, timeline, kpi, callout,
14
+ } = require(path.resolve(__dirname, '../scripts/lib/charts.js'));
15
+
16
+ const DAYS = ['3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15'];
17
+ const DAU = [58, 74, 69, 64, 55, 47, 44, 41, 38, 36, 35, 33, 32];
18
+ const NEW = [44, 56, 51, 47, 40, 33, 30, 28, 26, 24, 23, 21, 20];
19
+ const PREM = [30, 35, 36, 38, 33, 27, 24, 21, 18, 15, 14, 12, 11];
20
+
21
+ const board = stack({
22
+ x: 60, y: 60, gap: 64, items: [
23
+ (x, y) => stack({
24
+ x, y, gap: 12, items: [
25
+ (x, y) => sectionTitle({ x, y, text: 'Excalidraw chart kit — every builder, one board', fontSize: 42 }),
26
+ (x, y) => prose({ x, y, width: READ_W, fontSize: 15, text: 'Each chart below is one call with DATA only — no coordinates, no hand-placed labels. Geometry, axes, wrapping and collision-avoidance belong to the builder.' }),
27
+ ],
28
+ }),
29
+
30
+ // KPI tiles (with sparklines) + a callout
31
+ (x, y) => row({
32
+ x, y, gap: 24, items: [
33
+ (x, y) => kpi({ x, y, w: 300, label: 'DAU', value: '32', delta: 'peak 74 → -57%', color: 'red', spark: DAU }),
34
+ (x, y) => kpi({ x, y, w: 300, label: 'NEW USERS / DAY', value: '20', delta: '425 over 13 days', color: 'red', spark: NEW }),
35
+ (x, y) => kpi({ x, y, w: 300, label: 'D0 ROAS', value: '0.34', delta: 'W1: 0.31 — +10%', color: 'yellow' }),
36
+ (x, y) => callout({ x, y, w: 700, color: 'gray', title: 'callout()', text: 'Body copy is always bounded to the reading measure. A wide band puts its heading beside the text instead of stretching one line edge-to-edge.' }),
37
+ ],
38
+ }),
39
+
40
+ // lineChart + barCompare
41
+ (x, y) => row({
42
+ x, y, gap: 60, items: [
43
+ (x, y) => lineChart({
44
+ x, y, w: 760, h: 340, title: 'lineChart() — app health, days 1–13',
45
+ xLabels: DAYS, area: true,
46
+ series: [
47
+ { label: 'DAU', color: 'blue', points: DAU },
48
+ { label: 'new users', color: 'green', points: NEW },
49
+ { label: 'paid actives', color: 'red', points: PREM },
50
+ ],
51
+ }),
52
+ (x, y) => barCompare({
53
+ x, y, w: 700, h: 340, title: 'barCompare() — week 1 vs week 2',
54
+ seriesLabels: ['Week 1', 'Week 2'], colors: ['gray', 'red'],
55
+ groups: [
56
+ { label: 'ROAS x100', values: [31, 34] },
57
+ { label: 'CPM $', values: [120, 145] },
58
+ { label: 'Checkout %', values: [72.0, 58.4] },
59
+ { label: 'Refund x10', values: [18.0, 26.5] },
60
+ ],
61
+ }),
62
+ ],
63
+ }),
64
+
65
+ // funnel + barChart(horizontal) + donut
66
+ (x, y) => row({
67
+ x, y, gap: 60, valign: 'top', items: [
68
+ (x, y) => funnel({
69
+ x, y, w: 420, topW: 420, botW: 120, stageH: 74, fontSize: 15, notes: false,
70
+ stages: [
71
+ { label: 'Landing 4,000', color: 'blue' }, { label: 'Signup 1,900', color: 'red' },
72
+ { label: 'Onboard 1,700', color: 'green' }, { label: 'Trial 1,200', color: 'red' },
73
+ { label: 'Checkout 1,150', color: 'yellow' }, { label: 'Paid 140', color: 'red' },
74
+ ],
75
+ }),
76
+ (x, y) => barChart({
77
+ x, y, w: 620, h: 320, horizontal: true, title: 'barChart({horizontal}) — signups by country',
78
+ bars: [
79
+ { label: 'US', value: 310, color: 'blue' }, { label: 'DE', value: 64, color: 'yellow' },
80
+ { label: 'UK', value: 52, color: 'gray' }, { label: 'CA', value: 41, color: 'gray' },
81
+ { label: 'AU', value: 23, color: 'gray' },
82
+ ],
83
+ }),
84
+ (x, y) => donut({
85
+ x, y, r: 120, title: 'donut() — error breakdown',
86
+ slices: [
87
+ { label: 'timeout', value: 240, color: 'red' },
88
+ { label: 'other', value: 60, color: 'gray' },
89
+ { label: 'rate limited', value: 30, color: 'yellow' },
90
+ ],
91
+ }),
92
+ ],
93
+ }),
94
+
95
+ // stackedBar + quadrant
96
+ (x, y) => row({
97
+ x, y, gap: 60, valign: 'top', items: [
98
+ (x, y) => stackedBar({
99
+ x, y, w: 680, h: 340, title: 'stackedBar() — D1 cohort split',
100
+ seriesLabels: ['paid returned', 'free returned', 'churned'], colors: ['green', 'blue', 'gray'],
101
+ groups: [
102
+ { label: 'week 1', values: [22, 14, 90] }, { label: 'week 2', values: [19, 12, 84] },
103
+ { label: 'week 3', values: [17, 11, 96] },
104
+ ],
105
+ }),
106
+ (x, y) => quadrant({
107
+ x, y, w: 620, h: 460, title: 'quadrant() — roadmap: impact x effort',
108
+ xAxis: { left: 'high effort', right: 'low effort' }, yAxis: { bottom: 'low impact', top: 'high impact' },
109
+ quadrantLabels: { tr: 'DO FIRST', tl: 'plan', br: 'quick win', bl: 'later' },
110
+ items: [
111
+ { label: 'signup provisioning', x: 0.42, y: 0.95, color: 'red' },
112
+ { label: 'checkout rate', x: 0.55, y: 0.88, color: 'red' },
113
+ { label: 'landing A/B', x: 0.78, y: 0.66, color: 'yellow' },
114
+ { label: 'churn-save', x: 0.35, y: 0.5, color: 'blue' },
115
+ { label: 'refund monitor', x: 0.85, y: 0.28, color: 'gray' },
116
+ ],
117
+ }),
118
+ ],
119
+ }),
120
+
121
+ // gantt + timeline
122
+ (x, y) => gantt({
123
+ x, y, w: 1400, title: 'gantt() — fix plan', today: '2026-03-02',
124
+ tasks: [
125
+ { label: 'backend cross-check', start: '2026-03-02', end: '2026-03-05', color: 'red', done: 0.3 },
126
+ { label: 'payment triage', start: '2026-03-03', end: '2026-03-09', color: 'red' },
127
+ { label: 'landing A/B', start: '2026-03-06', end: '2026-03-16', color: 'yellow' },
128
+ { label: 'churn-save flow', start: '2026-03-10', end: '2026-03-22', color: 'blue' },
129
+ { label: 'review', start: '2026-03-09', milestone: true, color: 'purple' },
130
+ ],
131
+ }),
132
+ (x, y) => timeline({
133
+ x, y, w: 1400, title: 'timeline() — campaign events',
134
+ events: [
135
+ { label: 'Campaign start', at: '2026-02-17', color: 'blue' },
136
+ { label: 'Pricing change', at: '2026-02-22', color: 'yellow' },
137
+ { label: 'Budget cut 67%', at: '2026-02-23', color: 'red' },
138
+ { label: 'Checkout dropped', at: '2026-02-26', color: 'red' },
139
+ { label: 'Review', at: '2026-03-02', color: 'purple' },
140
+ ],
141
+ }),
142
+
143
+ // heatmap + table
144
+ (x, y) => row({
145
+ x, y, gap: 60, valign: 'top', items: [
146
+ (x, y) => heatmap({
147
+ x, y, title: 'heatmap() — retention, cohort x day', cell: 40,
148
+ rows: ['week 1', 'week 2', 'week 3', 'week 4', 'week 5'],
149
+ cols: ['D0', 'D1', 'D2', 'D3', 'D4'],
150
+ values: [
151
+ [100, 11, 7, 5, 4], [100, 9, 6, 4, 3], [100, 13, 8, 6, 4],
152
+ [100, 8, 5, 4, null], [100, 27, 12, null, null],
153
+ ],
154
+ fmt: (v) => (v == null ? '' : v + '%'),
155
+ }),
156
+ (x, y) => table({
157
+ x, y, title: 'table() — plan comparison',
158
+ headers: ['Plan', 'Churn', 'MRR', 'Seats'],
159
+ align: ['left', 'right', 'right', 'right'],
160
+ rows: [
161
+ ['Free', { text: '9.1%', color: 'red' }, '$0', '1,240'],
162
+ ['Pro', { text: '3.4%', color: 'yellow' }, '$18,400', '460'],
163
+ ['Team', { text: '1.8%', color: 'green' }, '$42,900', '210'],
164
+ ['Enterprise', { text: '0.9%', color: 'green' }, '$96,000', '48'],
165
+ ],
166
+ }),
167
+ ],
168
+ }),
169
+ ],
170
+ });
171
+
172
+ const res = buildExcalidraw({ out: path.resolve(__dirname, 'Chart Kit.excalidraw.md'), elements: board });
173
+ console.log(`elements=${res.elements} texts=${res.texts} overlaps=${res.overlaps} buriedText=${res.buriedText} longLines=${res.longLines}`);
@@ -2,13 +2,83 @@
2
2
  "out": "examples/Hello Excalidraw.excalidraw.md",
3
3
  "background": "#ffffff",
4
4
  "elements": [
5
- { "type": "text", "x": 0, "y": -70, "text": "excalidraw skill — portable smoke test", "fontSize": 28, "color": "#1971c2" },
6
- { "type": "text", "x": 0, "y": -28, "text": "Give a text a width and it wraps to that width (no overlap). The image embeds via sha1 wikilink — no base64. Only skill-relative paths, so this runs in any project.", "fontSize": 15, "color": "#868e96", "width": 540 },
7
- { "type": "rectangle", "x": 0, "y": 40, "width": 260, "height": 140, "strokeColor": "#1e1e1e", "backgroundColor": "#a5d8ff", "fillStyle": "solid", "strokeWidth": 2, "roundness": true },
8
- { "type": "text", "x": 24, "y": 96, "text": "rounded rect\n+ fill", "fontSize": 20, "color": "#1e1e1e" },
9
- { "type": "ellipse", "x": 340, "y": 40, "width": 160, "height": 140, "strokeColor": "#2f9e44", "backgroundColor": "#b2f2bb", "fillStyle": "hachure" },
10
- { "type": "arrow", "points": [[260, 110], [340, 110]], "strokeColor": "#e8590c", "strokeWidth": 3 },
11
- { "type": "text", "x": 0, "y": 220, "text": "embedded image (resolved from vault by sha1 wikilink):", "fontSize": 16, "color": "#555", "width": 420 },
12
- { "type": "image", "x": 0, "y": 250, "path": "examples/sample.png", "width": 320 }
5
+ {
6
+ "type": "text",
7
+ "x": 0,
8
+ "y": -70,
9
+ "text": "excalidraw skill portable smoke test",
10
+ "fontSize": 28,
11
+ "color": "#1971c2"
12
+ },
13
+ {
14
+ "type": "text",
15
+ "x": 0,
16
+ "y": -28,
17
+ "text": "Give a text a width and it wraps to that width (no overlap). The image embeds via sha1 wikilink — no base64. Only skill-relative paths, so this runs in any project.",
18
+ "fontSize": 15,
19
+ "color": "#868e96",
20
+ "width": 540
21
+ },
22
+ {
23
+ "type": "rectangle",
24
+ "x": 0,
25
+ "y": 40,
26
+ "width": 260,
27
+ "height": 140,
28
+ "strokeColor": "#1e1e1e",
29
+ "backgroundColor": "#a5d8ff",
30
+ "fillStyle": "solid",
31
+ "strokeWidth": 2,
32
+ "roundness": true
33
+ },
34
+ {
35
+ "type": "text",
36
+ "x": 24,
37
+ "y": 96,
38
+ "text": "rounded rect\n+ fill",
39
+ "fontSize": 20,
40
+ "color": "#1e1e1e"
41
+ },
42
+ {
43
+ "type": "ellipse",
44
+ "x": 340,
45
+ "y": 40,
46
+ "width": 160,
47
+ "height": 140,
48
+ "strokeColor": "#2f9e44",
49
+ "backgroundColor": "#b2f2bb",
50
+ "fillStyle": "hachure"
51
+ },
52
+ {
53
+ "type": "arrow",
54
+ "points": [
55
+ [
56
+ 260,
57
+ 110
58
+ ],
59
+ [
60
+ 340,
61
+ 110
62
+ ]
63
+ ],
64
+ "strokeColor": "#e8590c",
65
+ "strokeWidth": 3
66
+ },
67
+ {
68
+ "type": "text",
69
+ "x": 0,
70
+ "y": 220,
71
+ "text": "embedded image (resolved from vault by sha1 wikilink):",
72
+ "fontSize": 16,
73
+ "color": "#555",
74
+ "width": 540
75
+ },
76
+ {
77
+ "type": "image",
78
+ "x": 0,
79
+ "y": 250,
80
+ "path": "examples/sample.png",
81
+ "width": 320
82
+ }
13
83
  ]
14
- }
84
+ }
@@ -0,0 +1,82 @@
1
+ // visual_board.js — the visual-first kit demo. Run from anywhere: node examples/visual_board.js
2
+ // Shows the three rules in action: a trapezoid FUNNEL, a browser PROTOTYPE assembled purely with
3
+ // stack()/row() flow layout (no hand-computed coordinates → no overlap), and READABLE prose/bullets
4
+ // that wrap to a bounded measure instead of stretching across the whole board.
5
+ const path = require('path');
6
+ const { buildExcalidraw } = require(path.join(__dirname, '..', 'scripts', 'build_excalidraw.js'));
7
+ const {
8
+ sectionTitle, prose, bullets, funnel,
9
+ windowFrame, navbar, button, textRows, imagePlaceholder,
10
+ stack, row,
11
+ } = require(path.join(__dirname, '..', 'scripts', 'lib', 'style.js'));
12
+
13
+ const els = [];
14
+ const P = (...a) => els.push(...a.flat());
15
+
16
+ P(sectionTitle({ x: 60, y: 40, text: 'Visual-first kit — funnel · prototype · readable text', fontSize: 32 }));
17
+
18
+ // ── FUNNEL (left) — filled trapezoid bands, each with a right-margin metric note ──
19
+ P(sectionTitle({ x: 60, y: 118, text: 'Conversion funnel', fontSize: 20, color: '#868e96' }));
20
+ P(funnel({
21
+ x: 60, y: 168, w: 440, stageH: 80,
22
+ stages: [
23
+ { label: 'Visitors', note: '100% · 48,200 sessions', color: 'blue' },
24
+ { label: 'Signups', note: '32% · quality-gated', color: 'purple' },
25
+ { label: 'Activated', note: '18% · reached first value', color: 'yellow' },
26
+ { label: 'Paying', note: '6% · $29 / mo', color: 'mint' },
27
+ ],
28
+ }));
29
+
30
+ // ── PROTOTYPE (right) — a browser wireframe; every child placed by flow layout ──
31
+ const win = windowFrame({ x: 900, y: 118, w: 680, h: 560, kind: 'browser', url: 'https://acme.app/pricing' });
32
+ P(win);
33
+ const I = win.inner;
34
+ P(navbar({ x: I.x, y: I.y, w: I.w, brand: 'Acme', items: ['Product', 'Pricing', 'Docs'], cta: 'Sign up' }));
35
+
36
+ // hero: copy column + image, flowed side by side (row can't let them overlap)
37
+ const hero = row({
38
+ x: I.x, y: I.y + 74, gap: 28, valign: 'top',
39
+ items: [
40
+ (x, y) => stack({
41
+ x, y, gap: 14, items: [
42
+ (hx, hy) => prose({ x: hx, y: hy, text: 'The persistent brain for your agents', fontSize: 24, width: 320 }),
43
+ (hx, hy) => textRows({ x: hx, y: hy, w: 320, rows: 3 }),
44
+ (hx, hy) => button({ x: hx, y: hy, w: 160, h: 42, text: 'Get started', color: 'blue' }),
45
+ ],
46
+ }),
47
+ (x, y) => imagePlaceholder({ x, y, w: 236, h: 158, label: 'product shot' }),
48
+ ],
49
+ });
50
+ P(hero);
51
+
52
+ // three feature tiles, flowed left→right
53
+ const tiles = row({
54
+ x: I.x, y: hero.nextY + 28, gap: 18,
55
+ items: [['Remember', 'green'], ['Recall', 'purple'], ['Act', 'mint']].map(([t]) => (x, y) => stack({
56
+ x, y, gap: 8, items: [
57
+ (ax, ay) => imagePlaceholder({ x: ax, y: ay, w: 190, h: 72 }),
58
+ (ax, ay) => prose({ x: ax, y: ay, text: t, fontSize: 16, width: 190 }),
59
+ (ax, ay) => textRows({ x: ax, y: ay, w: 190, rows: 2 }),
60
+ ],
61
+ })),
62
+ });
63
+ P(tiles);
64
+
65
+ // ── READABLE MEASURE (bottom-left) — text that wraps to a column, not the canvas ──
66
+ P(sectionTitle({ x: 60, y: 600, text: 'Readable measure', fontSize: 20, color: '#868e96' }));
67
+ P(prose({
68
+ x: 60, y: 646, width: 620, fontSize: 18,
69
+ text: 'Body text wraps to a bounded reading width (~60 characters) instead of stretching across the whole board. Long passages stay in a comfortable column, so the eye never has to travel the full width of a wide canvas to find the start of the next line — that is what keeps a text block legible.',
70
+ }));
71
+ P(bullets({
72
+ x: 60, y: 792, width: 620, fontSize: 18,
73
+ items: [
74
+ 'Prefer pictures — funnels, wireframes, placeholders — over paragraphs.',
75
+ 'When you do write, cap the measure with prose() / bullets() so nothing runs edge to edge.',
76
+ 'Lay out with stack() / row() so boxes flow and never overlap; the build step also audits and warns.',
77
+ ],
78
+ }));
79
+
80
+ const out = path.join(__dirname, 'Visual Kit.excalidraw.md');
81
+ const res = buildExcalidraw({ out, elements: els, background: '#ffffff' });
82
+ console.log('visual demo →', out, '| overlaps:', res.overlaps);