agent-whiteboard 1.0.3 → 1.1.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 (198) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +13 -2
  3. package/dist/client/assets/abnfDiagram-VCTEODGH-CcuBIZ5h.js +1 -0
  4. package/dist/client/assets/{arc-4691b008.js → arc-Aq92EeUK.js} +1 -1
  5. package/dist/client/assets/architectureDiagram-5GKGNRK7-CpMRoWIY.js +36 -0
  6. package/dist/client/assets/blockDiagram-I7D4REHJ-Dee0m4lz.js +129 -0
  7. package/dist/client/assets/{bootstrap.min-21652813.js → bootstrap.min-UtnB-TxT.js} +1 -2
  8. package/dist/client/assets/c4Diagram-7LVT6UL2-D_qs3YTM.js +38 -0
  9. package/dist/client/assets/channel-9qggtmY_.js +1 -0
  10. package/dist/client/assets/{chunk-QZHKN3VN-0f554985.js → chunk-2Q5K7J3B-CBwQ-uNF.js} +1 -1
  11. package/dist/client/assets/{chunk-FMBD7UC4-23d48b24.js → chunk-5VM5RSS4-yGvVHapR.js} +1 -1
  12. package/dist/client/assets/{chunk-ND2GUHAM-1104c326.js → chunk-F27PBJKO-BzFUf98n.js} +1 -1
  13. package/dist/client/assets/chunk-IMKFNOWR-D-Zj1GaL.js +231 -0
  14. package/dist/client/assets/{chunk-4BX2VUAB-3c93511d.js → chunk-JWPE2WC7-C8Aj4MVR.js} +1 -1
  15. package/dist/client/assets/chunk-POPQ4Y6H-DZP2a-yV.js +1 -0
  16. package/dist/client/assets/chunk-SVP7TREG-COihS1MQ.js +88 -0
  17. package/dist/client/assets/chunk-TICWLB2K-DNZTRqyJ.js +206 -0
  18. package/dist/client/assets/{chunk-55IACEB6-0243aefd.js → chunk-XXDRQBXY-BC_9L4PF.js} +1 -1
  19. package/dist/client/assets/classDiagram-ZZMXUADV-BUnGzX-0.js +1 -0
  20. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BUnGzX-0.js +1 -0
  21. package/dist/client/assets/cose-bilkent-JH36ORCC-DrJ8c1cV.js +1 -0
  22. package/dist/client/assets/cynefin-OW5HDTMX-CMVAR4fd.js +178 -0
  23. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CdAQ0Lst.js +62 -0
  24. package/dist/client/assets/cytoscape.esm-C5JX3QLV.js +331 -0
  25. package/dist/client/assets/dagre-GXQ25YYZ-CybK0L_u.js +4 -0
  26. package/dist/client/assets/diagram-S7CK7UJ4-CHjTv5Sr.js +30 -0
  27. package/dist/client/assets/diagram-UQ7AKVKN-DfypPsGR.js +41 -0
  28. package/dist/client/assets/{diagram-KO2AKTUF-81f42eeb.js → diagram-VSXAHHWV-DHsmmCug.js} +3 -3
  29. package/dist/client/assets/diagram-VX7I27RA-CHZoTi9k.js +24 -0
  30. package/dist/client/assets/diagram-Z3DM3KII-Ceb2h13y.js +24 -0
  31. package/dist/client/assets/ebnfDiagram-PWID7BFC-BlZ247wB.js +1 -0
  32. package/dist/client/assets/embed-DcNeILcO.js +211 -0
  33. package/dist/client/assets/erDiagram-RLTQ6QDP-BQdw-U-S.js +99 -0
  34. package/dist/client/assets/flowDiagram-HODETNUW-DjUWHA94.js +168 -0
  35. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CXu2s5vq.js +292 -0
  36. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-CwlsB28k.js +106 -0
  37. package/dist/client/assets/index-CFelVSRu.js +19 -0
  38. package/dist/client/assets/index-GF8Uj64S.css +1 -0
  39. package/dist/client/assets/infoDiagram-27XIBGKW-C7nvTbsQ.js +2 -0
  40. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-50b43d03.js → ishikawaDiagram-5VMMS53U-DGFXG874.js} +2 -2
  41. package/dist/client/assets/{journeyDiagram-JHISSGLW-dce41bdf.js → journeyDiagram-3NMN7TZE-BDdRMcmq.js} +4 -4
  42. package/dist/client/assets/{kanban-definition-UN3LZRKU-92401a86.js → kanban-definition-UXKFOSKX-C3fnvfeO.js} +1 -1
  43. package/dist/client/assets/{katex-4c9ea27f.js → katex-BTI-AXqd.js} +3 -3
  44. package/dist/client/assets/{katex-0cba7652.js → katex-C5jXJg4s.js} +3 -3
  45. package/dist/client/assets/layout-BfegUiqt.js +1 -0
  46. package/dist/client/assets/linear-D1EL1Azg.js +1 -0
  47. package/dist/client/assets/mermaid.core-DioArgDk.js +310 -0
  48. package/dist/client/assets/{mindmap-definition-RKZ34NQL-66fe4544.js → mindmap-definition-YA3MSWOX-CFCbAUC0.js} +12 -12
  49. package/dist/client/assets/{ordinal-db88ae6f.js → ordinal-BeghXfj9.js} +1 -1
  50. package/dist/client/assets/pegDiagram-XKGWAZYB-B1ULJH6S.js +1 -0
  51. package/dist/client/assets/pieDiagram-E7YTZNPT-B9H3HosU.js +39 -0
  52. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-f64a7ed7.js → quadrantDiagram-AXDQQJYC-eWc3HHkM.js} +4 -4
  53. package/dist/client/assets/railroadDiagram-O6MQD6OU-DT7c-KwW.js +1 -0
  54. package/dist/client/assets/requirementDiagram-BXWQKSXE-Dk1yVWV5.js +84 -0
  55. package/dist/client/assets/sankeyDiagram-P5KCCOFB-B5a__hiX.js +40 -0
  56. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-CkCIByRS.js +162 -0
  57. package/dist/client/assets/sizeCapture-INFHLROL-CnZIW94r.js +1 -0
  58. package/dist/client/assets/stateDiagram-D77RDMKH-89Sfaoz9.js +1 -0
  59. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CP--cdl-.js +1 -0
  60. package/dist/client/assets/step-BEQzeS8V.js +1 -0
  61. package/dist/client/assets/swimlanes-42K2YHIH-C7m88XIh.js +1 -0
  62. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DmG2scPu.js +8 -0
  63. package/dist/client/assets/{time-043b3464.js → time-BaoZouO5.js} +1 -1
  64. package/dist/client/assets/{timeline-definition-PNZ67QCA-b0c81243.js → timeline-definition-24CTP7MA-BHKHgHq9.js} +10 -10
  65. package/dist/client/assets/vennDiagram-4TSXK5OY-BqKaRdWu.js +34 -0
  66. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-8d4d7626.js → wardleyDiagram-VM6X3IG4-XiDVRZV5.js} +3 -3
  67. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CxP4dIVd.js +7 -0
  68. package/dist/client/index.html +2 -3
  69. package/dist/server/app.js +29 -397
  70. package/dist/server/channel.js +5 -3
  71. package/dist/server/export-html.js +26 -60
  72. package/dist/server/export-zip.js +83 -0
  73. package/dist/server/import-zip.js +196 -0
  74. package/dist/server/index.js +2 -1
  75. package/dist/server/mcp.js +9 -9
  76. package/dist/server/port.js +18 -0
  77. package/dist/server/render-core.js +5 -5
  78. package/dist/server/routes/export.js +95 -0
  79. package/dist/server/routes/import.js +24 -0
  80. package/dist/server/routes/render.js +184 -0
  81. package/dist/server/routes/slideshow.js +52 -0
  82. package/dist/server/routes/snapshots.js +119 -0
  83. package/dist/server/snapshot-reader.js +58 -20
  84. package/dist/server/snapshot-writer.js +18 -16
  85. package/dist/server/viewport-cache.js +97 -25
  86. package/package.json +13 -7
  87. package/dist/client/assets/architecture-7EHR7CIX-1221aa61.js +0 -1
  88. package/dist/client/assets/architectureDiagram-3BPJPVTR-1eef4d3c.js +0 -36
  89. package/dist/client/assets/blockDiagram-GPEHLZMM-313fb06c.js +0 -132
  90. package/dist/client/assets/c4Diagram-AAUBKEIU-92b023ad.js +0 -10
  91. package/dist/client/assets/channel-5ee4a8a7.js +0 -1
  92. package/dist/client/assets/chunk-2J33WTMH-fb021fdc.js +0 -1
  93. package/dist/client/assets/chunk-727SXJPM-8e0e0228.js +0 -206
  94. package/dist/client/assets/chunk-AQP2D5EJ-2ccc13c2.js +0 -231
  95. package/dist/client/assets/classDiagram-4FO5ZUOK-42ffecb6.js +0 -1
  96. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-42ffecb6.js +0 -1
  97. package/dist/client/assets/cose-bilkent-S5V4N54A-45ec2e52.js +0 -1
  98. package/dist/client/assets/cytoscape.esm-1491e259.js +0 -331
  99. package/dist/client/assets/dagre-BM42HDAG-ed748885.js +0 -4
  100. package/dist/client/assets/diagram-2AECGRRQ-ccc0ddec.js +0 -43
  101. package/dist/client/assets/diagram-5GNKFQAL-342efdea.js +0 -10
  102. package/dist/client/assets/diagram-LMA3HP47-39e66739.js +0 -24
  103. package/dist/client/assets/diagram-OG6HWLK6-b3e61903.js +0 -24
  104. package/dist/client/assets/embed-2b4adf34.js +0 -201
  105. package/dist/client/assets/erDiagram-TEJ5UH35-281f5cc7.js +0 -85
  106. package/dist/client/assets/eventmodeling-FCH6USID-6508120e.js +0 -1
  107. package/dist/client/assets/flowDiagram-I6XJVG4X-c3a4269e.js +0 -162
  108. package/dist/client/assets/ganttDiagram-6RSMTGT7-013b07ec.js +0 -292
  109. package/dist/client/assets/gitGraph-WXDBUCRP-02827359.js +0 -1
  110. package/dist/client/assets/gitGraphDiagram-PVQCEYII-de184acb.js +0 -106
  111. package/dist/client/assets/graph-f3dfaf53.js +0 -1
  112. package/dist/client/assets/index-d674a6a4.css +0 -1
  113. package/dist/client/assets/index-ffc5af4b.js +0 -5
  114. package/dist/client/assets/info-J43DQDTF-81e32294.js +0 -1
  115. package/dist/client/assets/infoDiagram-5YYISTIA-196101ee.js +0 -2
  116. package/dist/client/assets/layout-3a4eff80.js +0 -1
  117. package/dist/client/assets/linear-fed00341.js +0 -1
  118. package/dist/client/assets/mermaid-parser.core-52f9cd92.js +0 -173
  119. package/dist/client/assets/mermaid.core-7dfc221a.js +0 -306
  120. package/dist/client/assets/packet-YPE3B663-278a272a.js +0 -1
  121. package/dist/client/assets/pie-LRSECV5Y-2e55d9ae.js +0 -1
  122. package/dist/client/assets/pieDiagram-4H26LBE5-65b1bcbd.js +0 -30
  123. package/dist/client/assets/radar-GUYGQ44K-608e459f.js +0 -1
  124. package/dist/client/assets/requirementDiagram-4Y6WPE33-90ebf889.js +0 -84
  125. package/dist/client/assets/sankeyDiagram-5OEKKPKP-2d1a83b3.js +0 -40
  126. package/dist/client/assets/sequenceDiagram-3UESZ5HK-aece3633.js +0 -162
  127. package/dist/client/assets/stateDiagram-AJRCARHV-9bd5b5f4.js +0 -1
  128. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-7c16c251.js +0 -1
  129. package/dist/client/assets/step-171ad54a.js +0 -1
  130. package/dist/client/assets/treeView-BLDUP644-e54b9ddb.js +0 -1
  131. package/dist/client/assets/treemap-LRROVOQU-6a81775b.js +0 -1
  132. package/dist/client/assets/vennDiagram-CIIHVFJN-8eaf0464.js +0 -34
  133. package/dist/client/assets/wardley-L42UT6IY-7abd921f.js +0 -1
  134. package/dist/client/assets/xychartDiagram-2RQKCTM6-450f333c.js +0 -7
  135. /package/dist/client/assets/{KaTeX_AMS-Regular-0cdd387c.woff2 → KaTeX_AMS-Regular-BQhdFMY1.woff2} +0 -0
  136. /package/dist/client/assets/{KaTeX_AMS-Regular-30da91e8.woff → KaTeX_AMS-Regular-DMm9YOAa.woff} +0 -0
  137. /package/dist/client/assets/{KaTeX_AMS-Regular-68534840.ttf → KaTeX_AMS-Regular-DRggAlZN.ttf} +0 -0
  138. /package/dist/client/assets/{KaTeX_Caligraphic-Bold-07d8e303.ttf → KaTeX_Caligraphic-Bold-ATXxdsX0.ttf} +0 -0
  139. /package/dist/client/assets/{KaTeX_Caligraphic-Bold-1ae6bd74.woff → KaTeX_Caligraphic-Bold-BEiXGLvX.woff} +0 -0
  140. /package/dist/client/assets/{KaTeX_Caligraphic-Bold-de7701e4.woff2 → KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2} +0 -0
  141. /package/dist/client/assets/{KaTeX_Caligraphic-Regular-3398dd02.woff → KaTeX_Caligraphic-Regular-CTRA-rTL.woff} +0 -0
  142. /package/dist/client/assets/{KaTeX_Caligraphic-Regular-5d53e70a.woff2 → KaTeX_Caligraphic-Regular-Di6jR-x-.woff2} +0 -0
  143. /package/dist/client/assets/{KaTeX_Caligraphic-Regular-ed0b7437.ttf → KaTeX_Caligraphic-Regular-wX97UBjC.ttf} +0 -0
  144. /package/dist/client/assets/{KaTeX_Fraktur-Bold-9163df9c.ttf → KaTeX_Fraktur-Bold-BdnERNNW.ttf} +0 -0
  145. /package/dist/client/assets/{KaTeX_Fraktur-Bold-9be7ceb8.woff → KaTeX_Fraktur-Bold-BsDP51OF.woff} +0 -0
  146. /package/dist/client/assets/{KaTeX_Fraktur-Bold-74444efd.woff2 → KaTeX_Fraktur-Bold-CL6g_b3V.woff2} +0 -0
  147. /package/dist/client/assets/{KaTeX_Fraktur-Regular-1e6f9579.ttf → KaTeX_Fraktur-Regular-CB_wures.ttf} +0 -0
  148. /package/dist/client/assets/{KaTeX_Fraktur-Regular-51814d27.woff2 → KaTeX_Fraktur-Regular-CTYiF6lA.woff2} +0 -0
  149. /package/dist/client/assets/{KaTeX_Fraktur-Regular-5e28753b.woff → KaTeX_Fraktur-Regular-Dxdc4cR9.woff} +0 -0
  150. /package/dist/client/assets/{KaTeX_Main-Bold-0f60d1b8.woff2 → KaTeX_Main-Bold-Cx986IdX.woff2} +0 -0
  151. /package/dist/client/assets/{KaTeX_Main-Bold-c76c5d69.woff → KaTeX_Main-Bold-Jm3AIy58.woff} +0 -0
  152. /package/dist/client/assets/{KaTeX_Main-Bold-138ac28d.ttf → KaTeX_Main-Bold-waoOVXN0.ttf} +0 -0
  153. /package/dist/client/assets/{KaTeX_Main-BoldItalic-99cd42a3.woff2 → KaTeX_Main-BoldItalic-DxDJ3AOS.woff2} +0 -0
  154. /package/dist/client/assets/{KaTeX_Main-BoldItalic-70ee1f64.ttf → KaTeX_Main-BoldItalic-DzxPMmG6.ttf} +0 -0
  155. /package/dist/client/assets/{KaTeX_Main-BoldItalic-a6f7ec0d.woff → KaTeX_Main-BoldItalic-SpSLRI95.woff} +0 -0
  156. /package/dist/client/assets/{KaTeX_Main-Italic-0d85ae7c.ttf → KaTeX_Main-Italic-3WenGoN9.ttf} +0 -0
  157. /package/dist/client/assets/{KaTeX_Main-Italic-f1d6ef86.woff → KaTeX_Main-Italic-BMLOBm91.woff} +0 -0
  158. /package/dist/client/assets/{KaTeX_Main-Italic-97479ca6.woff2 → KaTeX_Main-Italic-NWA7e6Wa.woff2} +0 -0
  159. /package/dist/client/assets/{KaTeX_Main-Regular-c2342cd8.woff2 → KaTeX_Main-Regular-B22Nviop.woff2} +0 -0
  160. /package/dist/client/assets/{KaTeX_Main-Regular-c6368d87.woff → KaTeX_Main-Regular-Dr94JaBh.woff} +0 -0
  161. /package/dist/client/assets/{KaTeX_Main-Regular-d0332f52.ttf → KaTeX_Main-Regular-ypZvNtVU.ttf} +0 -0
  162. /package/dist/client/assets/{KaTeX_Math-BoldItalic-f9377ab0.ttf → KaTeX_Math-BoldItalic-B3XSjfu4.ttf} +0 -0
  163. /package/dist/client/assets/{KaTeX_Math-BoldItalic-dc47344d.woff2 → KaTeX_Math-BoldItalic-CZnvNsCZ.woff2} +0 -0
  164. /package/dist/client/assets/{KaTeX_Math-BoldItalic-850c0af5.woff → KaTeX_Math-BoldItalic-iY-2wyZ7.woff} +0 -0
  165. /package/dist/client/assets/{KaTeX_Math-Italic-8a8d2445.woff → KaTeX_Math-Italic-DA0__PXp.woff} +0 -0
  166. /package/dist/client/assets/{KaTeX_Math-Italic-08ce98e5.ttf → KaTeX_Math-Italic-flOr_0UB.ttf} +0 -0
  167. /package/dist/client/assets/{KaTeX_Math-Italic-7af58c5e.woff2 → KaTeX_Math-Italic-t53AETM-.woff2} +0 -0
  168. /package/dist/client/assets/{KaTeX_SansSerif-Bold-1ece03f7.ttf → KaTeX_SansSerif-Bold-CFMepnvq.ttf} +0 -0
  169. /package/dist/client/assets/{KaTeX_SansSerif-Bold-e99ae511.woff2 → KaTeX_SansSerif-Bold-D1sUS0GD.woff2} +0 -0
  170. /package/dist/client/assets/{KaTeX_SansSerif-Bold-ece03cfd.woff → KaTeX_SansSerif-Bold-DbIhKOiC.woff} +0 -0
  171. /package/dist/client/assets/{KaTeX_SansSerif-Italic-00b26ac8.woff2 → KaTeX_SansSerif-Italic-C3H0VqGB.woff2} +0 -0
  172. /package/dist/client/assets/{KaTeX_SansSerif-Italic-91ee6750.woff → KaTeX_SansSerif-Italic-DN2j7dab.woff} +0 -0
  173. /package/dist/client/assets/{KaTeX_SansSerif-Italic-3931dd81.ttf → KaTeX_SansSerif-Italic-YYjJ1zSn.ttf} +0 -0
  174. /package/dist/client/assets/{KaTeX_SansSerif-Regular-f36ea897.ttf → KaTeX_SansSerif-Regular-BNo7hRIc.ttf} +0 -0
  175. /package/dist/client/assets/{KaTeX_SansSerif-Regular-11e4dc8a.woff → KaTeX_SansSerif-Regular-CS6fqUqJ.woff} +0 -0
  176. /package/dist/client/assets/{KaTeX_SansSerif-Regular-68e8c73e.woff2 → KaTeX_SansSerif-Regular-DDBCnlJ7.woff2} +0 -0
  177. /package/dist/client/assets/{KaTeX_Script-Regular-1c67f068.ttf → KaTeX_Script-Regular-C5JkGWo-.ttf} +0 -0
  178. /package/dist/client/assets/{KaTeX_Script-Regular-036d4e95.woff2 → KaTeX_Script-Regular-D3wIWfF6.woff2} +0 -0
  179. /package/dist/client/assets/{KaTeX_Script-Regular-d96cdf2b.woff → KaTeX_Script-Regular-D5yQViql.woff} +0 -0
  180. /package/dist/client/assets/{KaTeX_Size1-Regular-c943cc98.woff → KaTeX_Size1-Regular-C195tn64.woff} +0 -0
  181. /package/dist/client/assets/{KaTeX_Size1-Regular-95b6d2f1.ttf → KaTeX_Size1-Regular-Dbsnue_I.ttf} +0 -0
  182. /package/dist/client/assets/{KaTeX_Size1-Regular-6b47c401.woff2 → KaTeX_Size1-Regular-mCD8mA8B.woff2} +0 -0
  183. /package/dist/client/assets/{KaTeX_Size2-Regular-a6b2099f.ttf → KaTeX_Size2-Regular-B7gKUWhC.ttf} +0 -0
  184. /package/dist/client/assets/{KaTeX_Size2-Regular-d04c5421.woff2 → KaTeX_Size2-Regular-Dy4dx90m.woff2} +0 -0
  185. /package/dist/client/assets/{KaTeX_Size2-Regular-2014c523.woff → KaTeX_Size2-Regular-oD1tc_U0.woff} +0 -0
  186. /package/dist/client/assets/{KaTeX_Size3-Regular-6ab6b62e.woff → KaTeX_Size3-Regular-CTq5MqoE.woff} +0 -0
  187. /package/dist/client/assets/{KaTeX_Size3-Regular-500e04d5.ttf → KaTeX_Size3-Regular-DgpXs0kz.ttf} +0 -0
  188. /package/dist/client/assets/{KaTeX_Size4-Regular-99f9c675.woff → KaTeX_Size4-Regular-BF-4gkZK.woff} +0 -0
  189. /package/dist/client/assets/{KaTeX_Size4-Regular-c647367d.ttf → KaTeX_Size4-Regular-DWFBv043.ttf} +0 -0
  190. /package/dist/client/assets/{KaTeX_Size4-Regular-a4af7d41.woff2 → KaTeX_Size4-Regular-Dl5lxZxV.woff2} +0 -0
  191. /package/dist/client/assets/{KaTeX_Typewriter-Regular-e14fed02.woff → KaTeX_Typewriter-Regular-C0xS9mPB.woff} +0 -0
  192. /package/dist/client/assets/{KaTeX_Typewriter-Regular-71d517d6.woff2 → KaTeX_Typewriter-Regular-CO6r4hn1.woff2} +0 -0
  193. /package/dist/client/assets/{KaTeX_Typewriter-Regular-f01f3e87.ttf → KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf} +0 -0
  194. /package/dist/client/assets/{colors-98f238a0.js → colors-Cc3OSVma.js} +0 -0
  195. /package/dist/client/assets/{defaultLocale-a8476f12.js → defaultLocale-CzDG__Ur.js} +0 -0
  196. /package/dist/client/assets/{index-a1656aec.js → index-Bi7T_FA4.js} +0 -0
  197. /package/dist/client/assets/{init-a5b10ee5.js → init-Dmth1JHB.js} +0 -0
  198. /package/dist/client/assets/{range-6bc2a9a0.js → range-OtVwhkKS.js} +0 -0
@@ -4,19 +4,37 @@
4
4
  // step-frames sequence persists its own manual viewport independently, consistent
5
5
  // with each frame now getting its own auto-fit trigger (was a bare `id` key,
6
6
  // shared across a whole sequence, pre-v0.26.1).
7
- import { mkdirSync, readFileSync, writeFileSync } from "fs";
7
+ //
8
+ // NF49 (v1.4): reads/writes go through fs/promises instead of blocking the event
9
+ // loop, and the on-disk file is treated as a write-back cache — kept in memory
10
+ // after the first load and flushed to disk on a coalesced delay (see
11
+ // `scheduleFlush()`) instead of a full synchronous read-modify-write per
12
+ // zoom/pan event.
13
+ import { mkdir, readFile, writeFile } from "fs/promises";
8
14
  import { join } from "path";
9
15
  import { getSnapshotsRoot } from "./paths.js";
10
16
  function cachePath() {
11
17
  return join(getSnapshotsRoot(), "viewport-cache.json");
12
18
  }
13
- function readCache() {
19
+ function cacheKey(id, frameIndex) {
20
+ return `${id}:${frameIndex}`;
21
+ }
22
+ // In-memory cache, lazily loaded on first access. `cachedForPath` guards
23
+ // against a stale in-memory cache surviving a change to the underlying
24
+ // snapshots root (WHITEBOARD_SNAPSHOTS_DIR) — reloads transparently if the
25
+ // resolved cache path differs from the one currently held in memory.
26
+ let cache;
27
+ let cachedForPath;
28
+ async function loadCache() {
29
+ const path = cachePath();
30
+ if (cache !== undefined && cachedForPath === path)
31
+ return cache;
14
32
  try {
15
- const raw = readFileSync(cachePath(), "utf-8");
33
+ const raw = await readFile(path, "utf-8");
16
34
  const parsed = JSON.parse(raw);
17
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
18
- return {};
19
- return parsed;
35
+ cache = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)
36
+ ? parsed
37
+ : {};
20
38
  }
21
39
  catch (err) {
22
40
  // ENOENT (no cache file yet, e.g. first run) is expected and not logged.
@@ -25,45 +43,99 @@ function readCache() {
25
43
  if (err?.code !== "ENOENT") {
26
44
  console.error("[agent-whiteboard] viewport-cache read failed, resetting cache:", err instanceof Error ? err.message : String(err));
27
45
  }
28
- return {};
46
+ cache = {};
29
47
  }
48
+ cachedForPath = path;
49
+ return cache;
30
50
  }
31
- function writeCache(cache) {
51
+ async function flushCache() {
52
+ if (cache === undefined)
53
+ return;
32
54
  try {
33
- mkdirSync(getSnapshotsRoot(), { recursive: true });
34
- writeFileSync(cachePath(), JSON.stringify(cache, null, 2), "utf-8");
55
+ await mkdir(getSnapshotsRoot(), { recursive: true });
56
+ await writeFile(cachePath(), JSON.stringify(cache, null, 2), "utf-8");
35
57
  }
36
58
  catch (err) {
37
59
  console.error("[agent-whiteboard] viewport-cache write failed:", err instanceof Error ? err.message : String(err));
38
60
  }
39
61
  }
40
- function cacheKey(id, frameIndex) {
41
- return `${id}:${frameIndex}`;
62
+ /**
63
+ * Delay before a scheduled flush fires. Exported so tests can advance fake
64
+ * timers by exactly this amount instead of hardcoding a duplicate constant.
65
+ */
66
+ export const VIEWPORT_CACHE_FLUSH_DELAY_MS = 250;
67
+ let flushTimer;
68
+ /**
69
+ * Coalesces bursts of writes (continuous zoom/pan produces many `setViewport`
70
+ * calls in quick succession) into a single disk write roughly
71
+ * `VIEWPORT_CACHE_FLUSH_DELAY_MS` after the first update in a burst, instead
72
+ * of a full synchronous rewrite per update. A timer already pending absorbs
73
+ * every subsequent call in the same burst — it is not reset per call, so a
74
+ * sustained stream of updates still flushes periodically rather than being
75
+ * postponed indefinitely.
76
+ */
77
+ function scheduleFlush() {
78
+ if (flushTimer !== undefined)
79
+ return;
80
+ flushTimer = setTimeout(() => {
81
+ flushTimer = undefined;
82
+ void flushCache();
83
+ }, VIEWPORT_CACHE_FLUSH_DELAY_MS);
84
+ }
85
+ export async function getViewport(id, frameIndex) {
86
+ const c = await loadCache();
87
+ return c[cacheKey(id, frameIndex)];
42
88
  }
43
- export function getViewport(id, frameIndex) {
44
- return readCache()[cacheKey(id, frameIndex)];
89
+ export async function setViewport(id, frameIndex, viewport) {
90
+ const c = await loadCache();
91
+ c[cacheKey(id, frameIndex)] = viewport;
92
+ scheduleFlush();
45
93
  }
46
- export function setViewport(id, frameIndex, viewport) {
47
- const cache = readCache();
48
- cache[cacheKey(id, frameIndex)] = viewport;
49
- writeCache(cache);
94
+ /**
95
+ * Immediately flushes the in-memory cache to disk, bypassing (and cancelling)
96
+ * any pending debounced flush. Not needed in production — `setViewport`'s
97
+ * own scheduled flush is sufficient — but lets tests assert on-disk state
98
+ * deterministically without waiting on the real debounce delay or racing
99
+ * fake timers against real fs/promises I/O.
100
+ */
101
+ export async function flushViewportCacheNow() {
102
+ if (flushTimer !== undefined) {
103
+ clearTimeout(flushTimer);
104
+ flushTimer = undefined;
105
+ }
106
+ await flushCache();
107
+ }
108
+ /**
109
+ * Drops the in-memory cache and cancels any pending flush, forcing the next
110
+ * call to reload from disk. Not needed in production (the snapshots root
111
+ * doesn't change at runtime); exists for tests whose fixtures recreate the
112
+ * snapshots directory on the same path between cases (`cachedForPath`'s
113
+ * path-based invalidation can't detect that on its own).
114
+ */
115
+ export function resetViewportCacheForTest() {
116
+ cache = undefined;
117
+ cachedForPath = undefined;
118
+ if (flushTimer !== undefined) {
119
+ clearTimeout(flushTimer);
120
+ flushTimer = undefined;
121
+ }
50
122
  }
51
- export function deleteViewport(id) {
52
- deleteViewports([id]);
123
+ export async function deleteViewport(id) {
124
+ await deleteViewports([id]);
53
125
  }
54
126
  /** Removes every per-frame entry for each given snapshot id (prefix match on "<id>:"). */
55
- export function deleteViewports(ids) {
127
+ export async function deleteViewports(ids) {
56
128
  if (ids.length === 0)
57
129
  return;
58
- const cache = readCache();
130
+ const c = await loadCache();
59
131
  const prefixes = ids.map((id) => `${id}:`);
60
132
  let changed = false;
61
- for (const key of Object.keys(cache)) {
133
+ for (const key of Object.keys(c)) {
62
134
  if (prefixes.some((prefix) => key.startsWith(prefix))) {
63
- delete cache[key];
135
+ delete c[key];
64
136
  changed = true;
65
137
  }
66
138
  }
67
139
  if (changed)
68
- writeCache(cache);
140
+ scheduleFlush();
69
141
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-whiteboard",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "A domain-agnostic interactive whiteboard for AI teacher agents — render diagrams, math, charts, and HTML to a local browser tab via MCP tools.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -48,16 +48,21 @@
48
48
  "test": "vitest run",
49
49
  "test:e2e": "playwright test",
50
50
  "lint": "eslint .",
51
- "lint:fix": "eslint . --fix"
51
+ "lint:fix": "eslint . --fix",
52
+ "prepublishOnly": "npm run build"
52
53
  },
53
54
  "dependencies": {
54
55
  "@hono/node-server": "^1.13.7",
55
56
  "@modelcontextprotocol/sdk": "^1.12.1",
57
+ "@types/archiver": "^7.0.0",
56
58
  "@types/dompurify": "^3.2.0",
59
+ "archiver": "^7.0.1",
57
60
  "bootstrap": "^5.3.8",
58
- "dompurify": "^3.4.7",
59
- "happy-dom": "^20.10.6",
61
+ "dompurify": "^3.4.15",
62
+ "extract-zip": "^2.0.1",
60
63
  "hono": "^4.7.11",
64
+ "jsdom": "^26.1.0",
65
+ "jszip": "^3.10.1",
61
66
  "katex": "^0.17.0",
62
67
  "mermaid": "^11.15.0",
63
68
  "open": "^10.1.2",
@@ -69,10 +74,11 @@
69
74
  "devDependencies": {
70
75
  "@eslint/js": "^10.0.1",
71
76
  "@playwright/test": "^1.60.0",
72
- "@sveltejs/vite-plugin-svelte": "^2.4.6",
77
+ "@sveltejs/vite-plugin-svelte": "^3.1.2",
73
78
  "@testing-library/jest-dom": "^6.9.1",
74
79
  "@testing-library/svelte": "^4.2.3",
75
80
  "@tsconfig/svelte": "^5.0.4",
81
+ "@types/jsdom": "^30.0.0",
76
82
  "@types/node": "^20.17.57",
77
83
  "@types/ws": "^8.18.1",
78
84
  "concurrently": "^9.1.2",
@@ -85,8 +91,8 @@
85
91
  "tsx": "^3.14.0",
86
92
  "typescript": "^5.8.3",
87
93
  "typescript-eslint": "^8.62.1",
88
- "vite": "^4.5.10",
89
- "vitest": "^0.34.6",
94
+ "vite": "^5.4.21",
95
+ "vitest": "^3.2.7",
90
96
  "wait-on": "^8.0.3"
91
97
  }
92
98
  }
@@ -1 +0,0 @@
1
- import{A as c,f as i}from"./mermaid-parser.core-52f9cd92.js";import"./index-ffc5af4b.js";export{c as ArchitectureModule,i as createArchitectureServices};