@agent-canvas/cli 0.8.0 → 0.9.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 (199) hide show
  1. package/dist/commands/__tests__/add-arrow.test.d.ts +1 -0
  2. package/dist/commands/__tests__/add-arrow.test.js +186 -0
  3. package/dist/commands/__tests__/add-image.test.d.ts +1 -0
  4. package/dist/commands/__tests__/add-image.test.js +170 -0
  5. package/dist/commands/__tests__/add-line.test.d.ts +1 -0
  6. package/dist/commands/__tests__/add-line.test.js +138 -0
  7. package/dist/commands/__tests__/add-polygon.test.d.ts +1 -0
  8. package/dist/commands/__tests__/add-polygon.test.js +147 -0
  9. package/dist/commands/__tests__/add-shape.test.d.ts +1 -0
  10. package/dist/commands/__tests__/add-shape.test.js +193 -0
  11. package/dist/commands/__tests__/add-text.test.d.ts +1 -0
  12. package/dist/commands/__tests__/add-text.test.js +144 -0
  13. package/dist/commands/__tests__/clear.test.d.ts +1 -0
  14. package/dist/commands/__tests__/clear.test.js +65 -0
  15. package/dist/commands/__tests__/delete-elements.test.d.ts +1 -0
  16. package/dist/commands/__tests__/delete-elements.test.js +103 -0
  17. package/dist/commands/__tests__/export.test.d.ts +1 -0
  18. package/dist/commands/__tests__/export.test.js +187 -0
  19. package/dist/commands/__tests__/group-elements.test.d.ts +1 -0
  20. package/dist/commands/__tests__/group-elements.test.js +93 -0
  21. package/dist/commands/__tests__/list.test.d.ts +1 -0
  22. package/dist/commands/__tests__/list.test.js +134 -0
  23. package/dist/commands/__tests__/load.test.d.ts +1 -0
  24. package/dist/commands/__tests__/load.test.js +158 -0
  25. package/dist/commands/__tests__/move-elements.test.d.ts +1 -0
  26. package/dist/commands/__tests__/move-elements.test.js +117 -0
  27. package/dist/commands/__tests__/new-canvas.test.d.ts +1 -0
  28. package/dist/commands/__tests__/new-canvas.test.js +113 -0
  29. package/dist/commands/__tests__/read.test.d.ts +1 -0
  30. package/dist/commands/__tests__/read.test.js +247 -0
  31. package/dist/commands/__tests__/rename-canvas.test.d.ts +1 -0
  32. package/dist/commands/__tests__/rename-canvas.test.js +86 -0
  33. package/dist/commands/__tests__/resize-elements.test.d.ts +1 -0
  34. package/dist/commands/__tests__/resize-elements.test.js +150 -0
  35. package/dist/commands/__tests__/rotate-elements.test.d.ts +1 -0
  36. package/dist/commands/__tests__/rotate-elements.test.js +114 -0
  37. package/dist/commands/__tests__/save.test.d.ts +1 -0
  38. package/dist/commands/__tests__/save.test.js +105 -0
  39. package/dist/commands/__tests__/ungroup-element.test.d.ts +1 -0
  40. package/dist/commands/__tests__/ungroup-element.test.js +93 -0
  41. package/dist/commands/__tests__/use-canvas.test.d.ts +1 -0
  42. package/dist/commands/__tests__/use-canvas.test.js +86 -0
  43. package/dist/commands/add-arrow.d.ts +40 -0
  44. package/dist/commands/add-arrow.js +52 -0
  45. package/dist/commands/add-image.d.ts +26 -0
  46. package/dist/commands/add-image.js +66 -0
  47. package/dist/commands/add-line.d.ts +27 -0
  48. package/dist/commands/add-line.js +35 -0
  49. package/dist/commands/add-polygon.d.ts +26 -0
  50. package/dist/commands/add-polygon.js +44 -0
  51. package/dist/commands/add-shape.d.ts +32 -0
  52. package/dist/commands/add-shape.js +41 -0
  53. package/dist/commands/add-text.d.ts +28 -0
  54. package/dist/commands/add-text.js +35 -0
  55. package/dist/commands/clear.d.ts +17 -0
  56. package/dist/commands/clear.js +23 -0
  57. package/dist/commands/delete-elements.d.ts +20 -0
  58. package/dist/commands/delete-elements.js +26 -0
  59. package/dist/commands/export.d.ts +26 -0
  60. package/dist/commands/export.js +45 -0
  61. package/dist/commands/group-elements.d.ts +20 -0
  62. package/dist/commands/group-elements.js +28 -0
  63. package/dist/commands/list.d.ts +23 -0
  64. package/dist/commands/list.js +50 -0
  65. package/dist/commands/load.d.ts +20 -0
  66. package/dist/commands/load.js +67 -0
  67. package/dist/commands/move-elements.d.ts +22 -0
  68. package/dist/commands/move-elements.js +26 -0
  69. package/dist/commands/new-canvas.d.ts +21 -0
  70. package/dist/commands/new-canvas.js +29 -0
  71. package/dist/commands/read.d.ts +23 -0
  72. package/dist/commands/read.js +49 -0
  73. package/dist/commands/rename-canvas.d.ts +20 -0
  74. package/dist/commands/rename-canvas.js +27 -0
  75. package/dist/commands/resize-elements.d.ts +24 -0
  76. package/dist/commands/resize-elements.js +41 -0
  77. package/dist/commands/rotate-elements.d.ts +21 -0
  78. package/dist/commands/rotate-elements.js +26 -0
  79. package/dist/commands/save.d.ts +18 -0
  80. package/dist/commands/save.js +27 -0
  81. package/dist/commands/start.d.ts +0 -1
  82. package/dist/commands/start.js +0 -41
  83. package/dist/commands/ungroup-element.d.ts +20 -0
  84. package/dist/commands/ungroup-element.js +28 -0
  85. package/dist/commands/use-canvas.d.ts +20 -0
  86. package/dist/commands/use-canvas.js +27 -0
  87. package/dist/index.js +124 -518
  88. package/dist/lib/__tests__/image-utils.test.d.ts +1 -0
  89. package/dist/lib/__tests__/image-utils.test.js +123 -0
  90. package/dist/lib/__tests__/toon-converter.test.d.ts +1 -0
  91. package/dist/lib/__tests__/toon-converter.test.js +586 -0
  92. package/dist/lib/__tests__/ws-client.test.d.ts +1 -0
  93. package/dist/lib/__tests__/ws-client.test.js +22 -0
  94. package/dist/lib/image-utils.d.ts +3 -0
  95. package/dist/lib/image-utils.js +21 -0
  96. package/dist/lib/protocol.d.ts +24 -0
  97. package/dist/lib/toon-converter.d.ts +104 -0
  98. package/dist/lib/toon-converter.js +221 -0
  99. package/dist/static/assets/{ar-SA-G6X2FPQ2-DrFZc17I.js → ar-SA-G6X2FPQ2-DBOnFzSe.js} +1 -1
  100. package/dist/static/assets/{arc-BE4RRWho.js → arc-bbUtBUEI.js} +1 -1
  101. package/dist/static/assets/{az-AZ-76LH7QW2-DgHo0c8x.js → az-AZ-76LH7QW2-Cc10aZ9u.js} +1 -1
  102. package/dist/static/assets/{bg-BG-XCXSNQG7-D6Qfq7sN.js → bg-BG-XCXSNQG7-Ccf7m1dz.js} +1 -1
  103. package/dist/static/assets/{blockDiagram-38ab4fdb-j4QCKNBJ.js → blockDiagram-38ab4fdb-fpHXuuqC.js} +1 -1
  104. package/dist/static/assets/{bn-BD-2XOGV67Q-DtD_GeTA.js → bn-BD-2XOGV67Q-DUsn1OkS.js} +1 -1
  105. package/dist/static/assets/{c4Diagram-3d4e48cf-BmQ9mE4L.js → c4Diagram-3d4e48cf-R8YUsP4D.js} +1 -1
  106. package/dist/static/assets/{ca-ES-6MX7JW3Y-pqblEVH2.js → ca-ES-6MX7JW3Y-hu4EsJg6.js} +1 -1
  107. package/dist/static/assets/channel-DOejQ6Zr.js +1 -0
  108. package/dist/static/assets/{classDiagram-70f12bd4-CUF5vm_X.js → classDiagram-70f12bd4-Bd-nCoOe.js} +1 -1
  109. package/dist/static/assets/{classDiagram-v2-f2320105-Cpj_A_lB.js → classDiagram-v2-f2320105-BSqlF2Ya.js} +1 -1
  110. package/dist/static/assets/clone-BACvnIVb.js +1 -0
  111. package/dist/static/assets/{createText-2e5e7dd3-pnM7Sebc.js → createText-2e5e7dd3-DDxcRLmM.js} +1 -1
  112. package/dist/static/assets/{cs-CZ-2BRQDIVT-CybzkHZt.js → cs-CZ-2BRQDIVT-CvZtKTE7.js} +1 -1
  113. package/dist/static/assets/{da-DK-5WZEPLOC-pqELhXiQ.js → da-DK-5WZEPLOC-Bo6-ltfA.js} +1 -1
  114. package/dist/static/assets/{de-DE-XR44H4JA-ZL76WiIL.js → de-DE-XR44H4JA-Rki2qM_x.js} +1 -1
  115. package/dist/static/assets/{edges-e0da2a9e-B9extNmC.js → edges-e0da2a9e-DWJxCouB.js} +1 -1
  116. package/dist/static/assets/{el-GR-BZB4AONW-rKEdKItN.js → el-GR-BZB4AONW-BRy2rrt9.js} +1 -1
  117. package/dist/static/assets/{erDiagram-9861fffd-Bf-1lr9-.js → erDiagram-9861fffd-DXldiM4J.js} +1 -1
  118. package/dist/static/assets/{es-ES-U4NZUMDT-BB6riLIk.js → es-ES-U4NZUMDT-hCKbxwHs.js} +1 -1
  119. package/dist/static/assets/{eu-ES-A7QVB2H4-ChqJNrpA.js → eu-ES-A7QVB2H4-CmZGwoa5.js} +1 -1
  120. package/dist/static/assets/{fa-IR-HGAKTJCU--KEd62Xu.js → fa-IR-HGAKTJCU-C6DRPcaF.js} +1 -1
  121. package/dist/static/assets/{fi-FI-Z5N7JZ37-CdB0adCJ.js → fi-FI-Z5N7JZ37-DBaspnIB.js} +1 -1
  122. package/dist/static/assets/{flowDb-956e92f1-Dbca38tY.js → flowDb-956e92f1-C48Cmgvd.js} +1 -1
  123. package/dist/static/assets/{flowDiagram-66a62f08-DpQc0ZQB.js → flowDiagram-66a62f08-DV7f8TtG.js} +1 -1
  124. package/dist/static/assets/flowDiagram-v2-96b9c2cf-MnAxlKb6.js +1 -0
  125. package/dist/static/assets/{flowchart-elk-definition-4a651766-CAxl2EAj.js → flowchart-elk-definition-4a651766-C2muEpzy.js} +1 -1
  126. package/dist/static/assets/{fr-FR-RHASNOE6-LEJbMD3b.js → fr-FR-RHASNOE6-D1dEEEfS.js} +1 -1
  127. package/dist/static/assets/{ganttDiagram-c361ad54-BsKueDb1.js → ganttDiagram-c361ad54-CrooqCzc.js} +1 -1
  128. package/dist/static/assets/{gitGraphDiagram-72cf32ee-BySoTKcT.js → gitGraphDiagram-72cf32ee-x7BVIo_3.js} +1 -1
  129. package/dist/static/assets/{gl-ES-HMX3MZ6V-Bi3P3M7W.js → gl-ES-HMX3MZ6V-Czkw2ahx.js} +1 -1
  130. package/dist/static/assets/{graph-B_0qOa-k.js → graph-Bv0C_szp.js} +1 -1
  131. package/dist/static/assets/{he-IL-6SHJWFNN-DE7_aRwg.js → he-IL-6SHJWFNN-BLwbN3CV.js} +1 -1
  132. package/dist/static/assets/{hi-IN-IWLTKZ5I-CjARmJ8i.js → hi-IN-IWLTKZ5I-BJh3HrXc.js} +1 -1
  133. package/dist/static/assets/{hu-HU-A5ZG7DT2-d79urL5L.js → hu-HU-A5ZG7DT2-D00s-8EN.js} +1 -1
  134. package/dist/static/assets/{id-ID-SAP4L64H-bxo8Q0Jv.js → id-ID-SAP4L64H-BmyuzwXV.js} +1 -1
  135. package/dist/static/assets/{index-3862675e-BLm8h60G.js → index-3862675e-mZlepZqF.js} +1 -1
  136. package/dist/static/assets/{index-BkW4NM9R.js → index-Bnmyv9TE.js} +4 -4
  137. package/dist/static/assets/index-jjzEa4oB.js +316 -0
  138. package/dist/static/assets/{infoDiagram-f8f76790-CZ4J5sjk.js → infoDiagram-f8f76790-w7FUTsVV.js} +1 -1
  139. package/dist/static/assets/{it-IT-JPQ66NNP-D41R3uEK.js → it-IT-JPQ66NNP-CeVq0l8v.js} +1 -1
  140. package/dist/static/assets/{ja-JP-DBVTYXUO-zK8NUJnS.js → ja-JP-DBVTYXUO-BUNKxxGA.js} +1 -1
  141. package/dist/static/assets/{journeyDiagram-49397b02-DtFcZaIk.js → journeyDiagram-49397b02-DYjDqkQG.js} +1 -1
  142. package/dist/static/assets/{kaa-6HZHGXH3-CbGIc6V6.js → kaa-6HZHGXH3-BIKwULqb.js} +1 -1
  143. package/dist/static/assets/{kab-KAB-ZGHBKWFO-BweHPuX1.js → kab-KAB-ZGHBKWFO-BDpRo7IX.js} +1 -1
  144. package/dist/static/assets/{kk-KZ-P5N5QNE5-DSokMm7h.js → kk-KZ-P5N5QNE5-bI2LN3W0.js} +1 -1
  145. package/dist/static/assets/{km-KH-HSX4SM5Z-LYiEs3ge.js → km-KH-HSX4SM5Z-gtwrLJn5.js} +1 -1
  146. package/dist/static/assets/{ko-KR-MTYHY66A-BzgMEtcU.js → ko-KR-MTYHY66A-BVcwVELq.js} +1 -1
  147. package/dist/static/assets/{ku-TR-6OUDTVRD-D1FtjbSs.js → ku-TR-6OUDTVRD-COvDJH7d.js} +1 -1
  148. package/dist/static/assets/{layout-CQWIZrii.js → layout-HBWJ9_zM.js} +1 -1
  149. package/dist/static/assets/{line-BryEd-Ku.js → line-DxrK6d-_.js} +1 -1
  150. package/dist/static/assets/{linear-SXhM57Mz.js → linear-TwnxNDQ0.js} +1 -1
  151. package/dist/static/assets/{lt-LT-XHIRWOB4-BPrhIUrC.js → lt-LT-XHIRWOB4-BxYB7tM6.js} +1 -1
  152. package/dist/static/assets/{lv-LV-5QDEKY6T-CXJse_rs.js → lv-LV-5QDEKY6T-CGURbwyW.js} +1 -1
  153. package/dist/static/assets/{mindmap-definition-fc14e90a-C8giDsiX.js → mindmap-definition-fc14e90a-CWJfWF5a.js} +1 -1
  154. package/dist/static/assets/{mr-IN-CRQNXWMA-Clab-bAO.js → mr-IN-CRQNXWMA-65brZPyQ.js} +1 -1
  155. package/dist/static/assets/{my-MM-5M5IBNSE-Dp08JzEw.js → my-MM-5M5IBNSE-DaCAmQNv.js} +1 -1
  156. package/dist/static/assets/{nb-NO-T6EIAALU-CiaXJA-W.js → nb-NO-T6EIAALU-BiSJhu0W.js} +1 -1
  157. package/dist/static/assets/{nl-NL-IS3SIHDZ-D-9KUTnx.js → nl-NL-IS3SIHDZ-D3rj4Vme.js} +1 -1
  158. package/dist/static/assets/{nn-NO-6E72VCQL-Bg5gsQ4h.js → nn-NO-6E72VCQL-rxxP7Cwf.js} +1 -1
  159. package/dist/static/assets/{oc-FR-POXYY2M6-G4iqllhL.js → oc-FR-POXYY2M6-6emd2NQX.js} +1 -1
  160. package/dist/static/assets/{pa-IN-N4M65BXN-l6Lk41uX.js → pa-IN-N4M65BXN-CXwT_z_m.js} +1 -1
  161. package/dist/static/assets/{pica-CtkejCRD.js → pica-CtyIOuSv.js} +1 -1
  162. package/dist/static/assets/{pieDiagram-8a3498a8-CG6gQ14H.js → pieDiagram-8a3498a8-Ccff4vHz.js} +1 -1
  163. package/dist/static/assets/{pl-PL-T2D74RX3-BZPbB8S3.js → pl-PL-T2D74RX3-DMx_ZmIC.js} +1 -1
  164. package/dist/static/assets/{pt-BR-5N22H2LF-CIC4vRyd.js → pt-BR-5N22H2LF-D9nz7afr.js} +1 -1
  165. package/dist/static/assets/{pt-PT-UZXXM6DQ-rkGTBEI0.js → pt-PT-UZXXM6DQ-DeFH3geX.js} +1 -1
  166. package/dist/static/assets/{quadrantDiagram-120e2f19-BL9eFu4M.js → quadrantDiagram-120e2f19-RF2ZGF1U.js} +1 -1
  167. package/dist/static/assets/{requirementDiagram-deff3bca-crxdUpVK.js → requirementDiagram-deff3bca-CvnD9QLg.js} +1 -1
  168. package/dist/static/assets/{ro-RO-JPDTUUEW-GDhpTKBO.js → ro-RO-JPDTUUEW-Cy22QAjW.js} +1 -1
  169. package/dist/static/assets/{ru-RU-B4JR7IUQ-BzHvMwjC.js → ru-RU-B4JR7IUQ-Cw2rH2nW.js} +1 -1
  170. package/dist/static/assets/{sankeyDiagram-04a897e0-bM05WQw3.js → sankeyDiagram-04a897e0-CWfRjMv0.js} +1 -1
  171. package/dist/static/assets/{sequenceDiagram-704730f1-DjknV0Qp.js → sequenceDiagram-704730f1-pAE8N_Ym.js} +1 -1
  172. package/dist/static/assets/{si-LK-N5RQ5JYF-D3P3TNDH.js → si-LK-N5RQ5JYF-DmXIZ3i0.js} +1 -1
  173. package/dist/static/assets/{sk-SK-C5VTKIMK-CM8yTXlZ.js → sk-SK-C5VTKIMK-CboHDpHd.js} +1 -1
  174. package/dist/static/assets/{sl-SI-NN7IZMDC-CxoGm3aM.js → sl-SI-NN7IZMDC-8XnCHmN4.js} +1 -1
  175. package/dist/static/assets/{stateDiagram-587899a1-CmWqIdF5.js → stateDiagram-587899a1-B4nuLay6.js} +1 -1
  176. package/dist/static/assets/{stateDiagram-v2-d93cdb3a-CgzNTiHW.js → stateDiagram-v2-d93cdb3a-9cMNxr_8.js} +1 -1
  177. package/dist/static/assets/{styles-6aaf32cf-CI4s6NIA.js → styles-6aaf32cf-CynMMkPq.js} +1 -1
  178. package/dist/static/assets/{styles-9a916d00-ZcdN6rtW.js → styles-9a916d00-BTmAnC2j.js} +1 -1
  179. package/dist/static/assets/{styles-c10674c1-ZFkD6ta7.js → styles-c10674c1-DQ_pTuGr.js} +1 -1
  180. package/dist/static/assets/{subset-shared.chunk-B4F4dEPr.js → subset-shared.chunk-DPGuz0R6.js} +1 -1
  181. package/dist/static/assets/{subset-worker.chunk-CmgaOgn3.js → subset-worker.chunk-CMiOYLER.js} +1 -1
  182. package/dist/static/assets/{sv-SE-XGPEYMSR-CnVZlafq.js → sv-SE-XGPEYMSR-ATPKfqXs.js} +1 -1
  183. package/dist/static/assets/{svgDrawCommon-08f97a94-DbN3OiBf.js → svgDrawCommon-08f97a94-qY4BnSWc.js} +1 -1
  184. package/dist/static/assets/{ta-IN-2NMHFXQM-Bl-eCjzL.js → ta-IN-2NMHFXQM-Ct5-Fher.js} +1 -1
  185. package/dist/static/assets/{th-TH-HPSO5L25-CNIGPjSR.js → th-TH-HPSO5L25-5a6bUzcv.js} +1 -1
  186. package/dist/static/assets/{timeline-definition-85554ec2-Cmr82Iq1.js → timeline-definition-85554ec2-Bgexbl3C.js} +1 -1
  187. package/dist/static/assets/{tr-TR-DEFEU3FU-Cx7HbGIA.js → tr-TR-DEFEU3FU-WsK7dnwA.js} +1 -1
  188. package/dist/static/assets/{uk-UA-QMV73CPH-BxcA50Ze.js → uk-UA-QMV73CPH-B_P61mnc.js} +1 -1
  189. package/dist/static/assets/{vi-VN-M7AON7JQ-BvGuRh0c.js → vi-VN-M7AON7JQ-qdiQcney.js} +1 -1
  190. package/dist/static/assets/{xychartDiagram-e933f94c-BcWLDEHu.js → xychartDiagram-e933f94c-vkQjFADD.js} +1 -1
  191. package/dist/static/assets/{zh-CN-LNUGB5OW-SQH8i3l5.js → zh-CN-LNUGB5OW-DQ3BQjPe.js} +1 -1
  192. package/dist/static/assets/{zh-HK-E62DVLB3-COWoLNur.js → zh-HK-E62DVLB3-Ynj07W9J.js} +1 -1
  193. package/dist/static/assets/{zh-TW-RAJ6MFWO-Cm5B69ig.js → zh-TW-RAJ6MFWO-DNkcasuo.js} +1 -1
  194. package/dist/static/index.html +1 -1
  195. package/package.json +5 -2
  196. package/dist/static/assets/channel-DjiT9qJ0.js +0 -1
  197. package/dist/static/assets/clone-nkJpLn4s.js +0 -1
  198. package/dist/static/assets/flowDiagram-v2-96b9c2cf-Dlfh8z7R.js +0 -1
  199. package/dist/static/assets/index-B6CTdFKu.js +0 -311
@@ -0,0 +1,26 @@
1
+ export interface AddImageOptions {
2
+ file: string;
3
+ x: number;
4
+ y: number;
5
+ width?: number;
6
+ height?: number;
7
+ note?: string;
8
+ }
9
+ export interface ImageClient {
10
+ send: <T>(request: {
11
+ type: string;
12
+ id: string;
13
+ params?: unknown;
14
+ }) => Promise<T>;
15
+ close: () => void;
16
+ }
17
+ export interface AddImageDeps {
18
+ readFile: (path: string) => Buffer;
19
+ connectToCanvas: () => Promise<ImageClient>;
20
+ generateId: () => string;
21
+ log: (msg: string) => void;
22
+ error: (msg: string) => void;
23
+ exit: (code: number) => never | void;
24
+ }
25
+ export declare const defaultDeps: AddImageDeps;
26
+ export declare function addImage(options: AddImageOptions, deps?: AddImageDeps): Promise<void>;
@@ -0,0 +1,66 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
3
+ import { getMimeType, generateFileId, MAX_IMAGE_SIZE } from '../lib/image-utils.js';
4
+ export const defaultDeps = {
5
+ readFile: readFileSync,
6
+ connectToCanvas,
7
+ generateId,
8
+ log: console.log,
9
+ error: console.error,
10
+ exit: process.exit,
11
+ };
12
+ export async function addImage(options, deps = defaultDeps) {
13
+ // 1. Validate file extension
14
+ const mimeType = getMimeType(options.file);
15
+ if (!mimeType) {
16
+ deps.error('Unsupported image format. Supported: PNG, JPEG, GIF, SVG, WebP');
17
+ deps.exit(1);
18
+ return;
19
+ }
20
+ // 2. Read file
21
+ let buffer;
22
+ try {
23
+ buffer = deps.readFile(options.file);
24
+ }
25
+ catch {
26
+ deps.error(`Failed to read file: ${options.file}`);
27
+ deps.exit(1);
28
+ return;
29
+ }
30
+ // 3. Check file size
31
+ if (buffer.length > MAX_IMAGE_SIZE) {
32
+ const sizeMB = (buffer.length / 1024 / 1024).toFixed(2);
33
+ deps.error(`Image too large: ${sizeMB}MB (max: 2MB)`);
34
+ deps.exit(1);
35
+ return;
36
+ }
37
+ // 4. Convert to base64 and generate fileId
38
+ const base64 = buffer.toString('base64');
39
+ const dataUrl = `data:${mimeType};base64,${base64}`;
40
+ const fileId = generateFileId(buffer);
41
+ // 5. Send WebSocket message
42
+ const client = await deps.connectToCanvas();
43
+ const result = await client.send({
44
+ type: 'addImage',
45
+ id: deps.generateId(),
46
+ params: {
47
+ x: options.x,
48
+ y: options.y,
49
+ width: options.width,
50
+ height: options.height,
51
+ dataUrl,
52
+ mimeType,
53
+ fileId,
54
+ customData: options.note ? { note: options.note } : undefined,
55
+ },
56
+ });
57
+ // 6. Handle response
58
+ if (result.success) {
59
+ deps.log(`Image added (id: ${result.elementId}, fileId: ${result.fileId} x=${result.x} y=${result.y} w=${result.width} h=${result.height})`);
60
+ }
61
+ else {
62
+ deps.error(`Failed: ${result.error}`);
63
+ deps.exit(1);
64
+ }
65
+ client.close();
66
+ }
@@ -0,0 +1,27 @@
1
+ export interface AddLineOptions {
2
+ x: number;
3
+ y: number;
4
+ endX: number;
5
+ endY: number;
6
+ strokeColor?: string;
7
+ strokeWidth?: number;
8
+ strokeStyle?: 'solid' | 'dashed' | 'dotted';
9
+ note?: string;
10
+ }
11
+ export interface LineClient {
12
+ send: <T>(request: {
13
+ type: string;
14
+ id: string;
15
+ params?: unknown;
16
+ }) => Promise<T>;
17
+ close: () => void;
18
+ }
19
+ export interface AddLineDeps {
20
+ connectToCanvas: () => Promise<LineClient>;
21
+ generateId: () => string;
22
+ log: (msg: string) => void;
23
+ error: (msg: string) => void;
24
+ exit: (code: number) => never | void;
25
+ }
26
+ export declare const defaultDeps: AddLineDeps;
27
+ export declare function addLine(options: AddLineOptions, deps?: AddLineDeps): Promise<void>;
@@ -0,0 +1,35 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ export const defaultDeps = {
3
+ connectToCanvas,
4
+ generateId,
5
+ log: console.log,
6
+ error: console.error,
7
+ exit: process.exit,
8
+ };
9
+ export async function addLine(options, deps = defaultDeps) {
10
+ const client = await deps.connectToCanvas();
11
+ // Build params
12
+ const params = {
13
+ x: options.x,
14
+ y: options.y,
15
+ endX: options.endX,
16
+ endY: options.endY,
17
+ strokeColor: options.strokeColor,
18
+ strokeWidth: options.strokeWidth,
19
+ strokeStyle: options.strokeStyle,
20
+ customData: options.note ? { note: options.note } : undefined,
21
+ };
22
+ const result = await client.send({
23
+ type: 'addLine',
24
+ id: deps.generateId(),
25
+ params,
26
+ });
27
+ if (result.success) {
28
+ deps.log(`Line created (id: ${result.elementId})`);
29
+ }
30
+ else {
31
+ deps.error(`Failed: ${result.error}`);
32
+ deps.exit(1);
33
+ }
34
+ client.close();
35
+ }
@@ -0,0 +1,26 @@
1
+ export interface AddPolygonOptions {
2
+ points: string;
3
+ strokeColor?: string;
4
+ backgroundColor?: string;
5
+ strokeWidth?: number;
6
+ strokeStyle?: 'solid' | 'dashed' | 'dotted';
7
+ fillStyle?: 'hachure' | 'cross-hatch' | 'solid' | 'zigzag';
8
+ note?: string;
9
+ }
10
+ export interface PolygonClient {
11
+ send: <T>(request: {
12
+ type: string;
13
+ id: string;
14
+ params?: unknown;
15
+ }) => Promise<T>;
16
+ close: () => void;
17
+ }
18
+ export interface AddPolygonDeps {
19
+ connectToCanvas: () => Promise<PolygonClient>;
20
+ generateId: () => string;
21
+ log: (msg: string) => void;
22
+ error: (msg: string) => void;
23
+ exit: (code: number) => never | void;
24
+ }
25
+ export declare const defaultDeps: AddPolygonDeps;
26
+ export declare function addPolygon(options: AddPolygonOptions, deps?: AddPolygonDeps): Promise<void>;
@@ -0,0 +1,44 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ export const defaultDeps = {
3
+ connectToCanvas,
4
+ generateId,
5
+ log: console.log,
6
+ error: console.error,
7
+ exit: process.exit,
8
+ };
9
+ export async function addPolygon(options, deps = defaultDeps) {
10
+ // Parse and validate points JSON
11
+ let points;
12
+ try {
13
+ points = JSON.parse(options.points);
14
+ }
15
+ catch {
16
+ deps.error('Invalid points JSON');
17
+ deps.exit(1);
18
+ return;
19
+ }
20
+ const client = await deps.connectToCanvas();
21
+ // Build params
22
+ const params = {
23
+ points,
24
+ strokeColor: options.strokeColor,
25
+ backgroundColor: options.backgroundColor,
26
+ strokeWidth: options.strokeWidth,
27
+ strokeStyle: options.strokeStyle,
28
+ fillStyle: options.fillStyle,
29
+ customData: options.note ? { note: options.note } : undefined,
30
+ };
31
+ const result = await client.send({
32
+ type: 'addPolygon',
33
+ id: deps.generateId(),
34
+ params,
35
+ });
36
+ if (result.success) {
37
+ deps.log(`Polygon created (id: ${result.elementId})`);
38
+ }
39
+ else {
40
+ deps.error(`Failed: ${result.error}`);
41
+ deps.exit(1);
42
+ }
43
+ client.close();
44
+ }
@@ -0,0 +1,32 @@
1
+ export interface AddShapeOptions {
2
+ type: 'rectangle' | 'ellipse' | 'diamond';
3
+ x: number;
4
+ y: number;
5
+ width?: number;
6
+ height?: number;
7
+ strokeColor?: string;
8
+ backgroundColor?: string;
9
+ strokeWidth?: number;
10
+ strokeStyle?: 'solid' | 'dashed' | 'dotted';
11
+ fillStyle?: 'hachure' | 'cross-hatch' | 'solid' | 'zigzag';
12
+ label?: string;
13
+ labelFontSize?: number;
14
+ note?: string;
15
+ }
16
+ export interface ShapeClient {
17
+ send: <T>(request: {
18
+ type: string;
19
+ id: string;
20
+ params?: unknown;
21
+ }) => Promise<T>;
22
+ close: () => void;
23
+ }
24
+ export interface AddShapeDeps {
25
+ connectToCanvas: () => Promise<ShapeClient>;
26
+ generateId: () => string;
27
+ log: (msg: string) => void;
28
+ error: (msg: string) => void;
29
+ exit: (code: number) => never | void;
30
+ }
31
+ export declare const defaultDeps: AddShapeDeps;
32
+ export declare function addShape(options: AddShapeOptions, deps?: AddShapeDeps): Promise<void>;
@@ -0,0 +1,41 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ export const defaultDeps = {
3
+ connectToCanvas,
4
+ generateId,
5
+ log: console.log,
6
+ error: console.error,
7
+ exit: process.exit,
8
+ };
9
+ export async function addShape(options, deps = defaultDeps) {
10
+ const client = await deps.connectToCanvas();
11
+ // Build params
12
+ const params = {
13
+ type: options.type,
14
+ x: options.x,
15
+ y: options.y,
16
+ width: options.width,
17
+ height: options.height,
18
+ strokeColor: options.strokeColor,
19
+ backgroundColor: options.backgroundColor,
20
+ strokeWidth: options.strokeWidth,
21
+ strokeStyle: options.strokeStyle,
22
+ fillStyle: options.fillStyle,
23
+ customData: options.note ? { note: options.note } : undefined,
24
+ };
25
+ if (options.label) {
26
+ params.label = { text: options.label, fontSize: options.labelFontSize };
27
+ }
28
+ const result = await client.send({
29
+ type: 'addShape',
30
+ id: deps.generateId(),
31
+ params,
32
+ });
33
+ if (result.success) {
34
+ deps.log(`Shape created (id: ${result.elementId} x=${result.x} y=${result.y} w=${result.width} h=${result.height})`);
35
+ }
36
+ else {
37
+ deps.error(`Failed: ${result.error}`);
38
+ deps.exit(1);
39
+ }
40
+ client.close();
41
+ }
@@ -0,0 +1,28 @@
1
+ import type { TextAnchor } from '../lib/protocol.js';
2
+ export interface AddTextOptions {
3
+ text: string;
4
+ x: number;
5
+ y: number;
6
+ fontSize?: number;
7
+ textAlign?: 'left' | 'center' | 'right';
8
+ anchor?: TextAnchor;
9
+ strokeColor?: string;
10
+ note?: string;
11
+ }
12
+ export interface TextClient {
13
+ send: <T>(request: {
14
+ type: string;
15
+ id: string;
16
+ params?: unknown;
17
+ }) => Promise<T>;
18
+ close: () => void;
19
+ }
20
+ export interface AddTextDeps {
21
+ connectToCanvas: () => Promise<TextClient>;
22
+ generateId: () => string;
23
+ log: (msg: string) => void;
24
+ error: (msg: string) => void;
25
+ exit: (code: number) => never | void;
26
+ }
27
+ export declare const defaultDeps: AddTextDeps;
28
+ export declare function addText(options: AddTextOptions, deps?: AddTextDeps): Promise<void>;
@@ -0,0 +1,35 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ export const defaultDeps = {
3
+ connectToCanvas,
4
+ generateId,
5
+ log: console.log,
6
+ error: console.error,
7
+ exit: process.exit,
8
+ };
9
+ export async function addText(options, deps = defaultDeps) {
10
+ const client = await deps.connectToCanvas();
11
+ // Build params
12
+ const params = {
13
+ text: options.text,
14
+ x: options.x,
15
+ y: options.y,
16
+ fontSize: options.fontSize,
17
+ textAlign: options.textAlign,
18
+ anchor: options.anchor,
19
+ strokeColor: options.strokeColor,
20
+ customData: options.note ? { note: options.note } : undefined,
21
+ };
22
+ const result = await client.send({
23
+ type: 'addText',
24
+ id: deps.generateId(),
25
+ params,
26
+ });
27
+ if (result.success) {
28
+ deps.log(`Text created (id: ${result.elementId}, x: ${result.x}, y: ${result.y}, ${result.width}x${result.height})`);
29
+ }
30
+ else {
31
+ deps.error(`Failed: ${result.error}`);
32
+ deps.exit(1);
33
+ }
34
+ client.close();
35
+ }
@@ -0,0 +1,17 @@
1
+ export interface ClearClient {
2
+ send: <T>(request: {
3
+ type: string;
4
+ id: string;
5
+ params?: unknown;
6
+ }) => Promise<T>;
7
+ close: () => void;
8
+ }
9
+ export interface ClearDeps {
10
+ connectToCanvas: () => Promise<ClearClient>;
11
+ generateId: () => string;
12
+ log: (msg: string) => void;
13
+ error: (msg: string) => void;
14
+ exit: (code: number) => never | void;
15
+ }
16
+ export declare const defaultDeps: ClearDeps;
17
+ export declare function clear(deps?: ClearDeps): Promise<void>;
@@ -0,0 +1,23 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ export const defaultDeps = {
3
+ connectToCanvas,
4
+ generateId,
5
+ log: console.log,
6
+ error: console.error,
7
+ exit: process.exit,
8
+ };
9
+ export async function clear(deps = defaultDeps) {
10
+ const client = await deps.connectToCanvas();
11
+ const result = await client.send({
12
+ type: 'clearCanvas',
13
+ id: deps.generateId(),
14
+ });
15
+ if (result.success) {
16
+ deps.log('Canvas cleared');
17
+ }
18
+ else {
19
+ deps.error(`Failed: ${result.error}`);
20
+ deps.exit(1);
21
+ }
22
+ client.close();
23
+ }
@@ -0,0 +1,20 @@
1
+ export interface DeleteElementsOptions {
2
+ elementIds: string;
3
+ }
4
+ export interface DeleteElementsClient {
5
+ send: <T>(request: {
6
+ type: string;
7
+ id: string;
8
+ params?: unknown;
9
+ }) => Promise<T>;
10
+ close: () => void;
11
+ }
12
+ export interface DeleteElementsDeps {
13
+ connectToCanvas: () => Promise<DeleteElementsClient>;
14
+ generateId: () => string;
15
+ log: (msg: string) => void;
16
+ error: (msg: string) => void;
17
+ exit: (code: number) => never | void;
18
+ }
19
+ export declare const defaultDeps: DeleteElementsDeps;
20
+ export declare function deleteElements(options: DeleteElementsOptions, deps?: DeleteElementsDeps): Promise<void>;
@@ -0,0 +1,26 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ export const defaultDeps = {
3
+ connectToCanvas,
4
+ generateId,
5
+ log: console.log,
6
+ error: console.error,
7
+ exit: process.exit,
8
+ };
9
+ export async function deleteElements(options, deps = defaultDeps) {
10
+ const client = await deps.connectToCanvas();
11
+ // Parse comma-separated element IDs
12
+ const elementIds = options.elementIds.split(',').map((s) => s.trim());
13
+ const result = await client.send({
14
+ type: 'deleteElements',
15
+ id: deps.generateId(),
16
+ params: { elementIds },
17
+ });
18
+ if (result.success) {
19
+ deps.log(`Deleted ${result.deletedCount} element(s)`);
20
+ }
21
+ else {
22
+ deps.error(`Failed: ${result.error}`);
23
+ deps.exit(1);
24
+ }
25
+ client.close();
26
+ }
@@ -0,0 +1,26 @@
1
+ export interface ExportOptions {
2
+ output?: string;
3
+ background?: boolean;
4
+ dark?: boolean;
5
+ embedScene?: boolean;
6
+ scale?: number;
7
+ }
8
+ export interface ExportClient {
9
+ send: <T>(request: {
10
+ type: string;
11
+ id: string;
12
+ params?: unknown;
13
+ }) => Promise<T>;
14
+ close: () => void;
15
+ }
16
+ export interface ExportDeps {
17
+ connectToCanvas: () => Promise<ExportClient>;
18
+ generateId: () => string;
19
+ writeFile: (path: string, data: Buffer) => void;
20
+ now: () => number;
21
+ log: (msg: string) => void;
22
+ error: (msg: string) => void;
23
+ exit: (code: number) => never | void;
24
+ }
25
+ export declare const defaultDeps: ExportDeps;
26
+ export declare function exportImage(options: ExportOptions, deps?: ExportDeps): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ import { writeFileSync } from 'node:fs';
3
+ export const defaultDeps = {
4
+ connectToCanvas,
5
+ generateId,
6
+ writeFile: writeFileSync,
7
+ now: Date.now,
8
+ log: console.log,
9
+ error: console.error,
10
+ exit: process.exit,
11
+ };
12
+ export async function exportImage(options, deps = defaultDeps) {
13
+ // Validate scale
14
+ const scale = options.scale ?? 1;
15
+ if (![1, 2, 3].includes(scale)) {
16
+ deps.error('Scale must be 1, 2, or 3');
17
+ deps.exit(1);
18
+ return;
19
+ }
20
+ const client = await deps.connectToCanvas();
21
+ const result = await client.send({
22
+ type: 'exportImage',
23
+ id: deps.generateId(),
24
+ params: {
25
+ background: options.background ?? true,
26
+ dark: options.dark ?? false,
27
+ embedScene: options.embedScene ?? false,
28
+ scale: scale,
29
+ },
30
+ });
31
+ if (result.success && result.dataUrl) {
32
+ // Extract base64 data from data URL
33
+ const base64Data = result.dataUrl.replace(/^data:image\/png;base64,/, '');
34
+ const buffer = Buffer.from(base64Data, 'base64');
35
+ // Generate output path if not specified
36
+ const outputPath = options.output ?? `canvas-${deps.now()}.png`;
37
+ deps.writeFile(outputPath, buffer);
38
+ deps.log(`Exported to ${outputPath}`);
39
+ }
40
+ else {
41
+ deps.error(`Failed: ${result.error}`);
42
+ deps.exit(1);
43
+ }
44
+ client.close();
45
+ }
@@ -0,0 +1,20 @@
1
+ export interface GroupElementsOptions {
2
+ elementIds: string[];
3
+ }
4
+ export interface GroupClient {
5
+ send: <T>(request: {
6
+ type: string;
7
+ id: string;
8
+ params?: unknown;
9
+ }) => Promise<T>;
10
+ close: () => void;
11
+ }
12
+ export interface GroupElementsDeps {
13
+ connectToCanvas: () => Promise<GroupClient>;
14
+ generateId: () => string;
15
+ log: (msg: string) => void;
16
+ error: (msg: string) => void;
17
+ exit: (code: number) => never | void;
18
+ }
19
+ export declare const defaultDeps: GroupElementsDeps;
20
+ export declare function groupElements(options: GroupElementsOptions, deps?: GroupElementsDeps): Promise<void>;
@@ -0,0 +1,28 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ export const defaultDeps = {
3
+ connectToCanvas,
4
+ generateId,
5
+ log: console.log,
6
+ error: console.error,
7
+ exit: process.exit,
8
+ };
9
+ export async function groupElements(options, deps = defaultDeps) {
10
+ const client = await deps.connectToCanvas();
11
+ // Build params
12
+ const params = {
13
+ elementIds: options.elementIds,
14
+ };
15
+ const result = await client.send({
16
+ type: 'groupElements',
17
+ id: deps.generateId(),
18
+ params,
19
+ });
20
+ if (result.success) {
21
+ deps.log(`Group created (id: ${result.groupId})`);
22
+ }
23
+ else {
24
+ deps.error(`Failed: ${result.error}`);
25
+ deps.exit(1);
26
+ }
27
+ client.close();
28
+ }
@@ -0,0 +1,23 @@
1
+ import type { CanvasMetadata } from '../lib/protocol.js';
2
+ export interface ListClient {
3
+ send: <T>(request: {
4
+ type: string;
5
+ id: string;
6
+ }) => Promise<T>;
7
+ close: () => void;
8
+ }
9
+ export interface ListDeps {
10
+ connectToCanvas: () => Promise<ListClient>;
11
+ generateId: () => string;
12
+ log: (msg: string) => void;
13
+ error: (msg: string) => void;
14
+ exit: (code: number) => never | void;
15
+ }
16
+ export declare const defaultDeps: ListDeps;
17
+ export interface ListResult {
18
+ activeCanvasId?: string;
19
+ agentActiveCanvasId?: string;
20
+ canvases: CanvasMetadata[];
21
+ }
22
+ export declare function formatCanvasList(result: ListResult): string[];
23
+ export declare function list(deps?: ListDeps): Promise<void>;
@@ -0,0 +1,50 @@
1
+ import { connectToCanvas, generateId } from '../lib/ws-client.js';
2
+ export const defaultDeps = {
3
+ connectToCanvas,
4
+ generateId,
5
+ log: console.log,
6
+ error: console.error,
7
+ exit: process.exit,
8
+ };
9
+ export function formatCanvasList(result) {
10
+ const lines = ['Canvases: ([U]=User [A]=Agent)'];
11
+ for (const canvas of result.canvases) {
12
+ const isUser = canvas.id === result.activeCanvasId;
13
+ const isAgent = canvas.id === result.agentActiveCanvasId;
14
+ let marker = ' ';
15
+ if (isUser && isAgent) {
16
+ marker = '[UA]';
17
+ }
18
+ else if (isUser) {
19
+ marker = '[U] ';
20
+ }
21
+ else if (isAgent) {
22
+ marker = '[A] ';
23
+ }
24
+ const date = new Date(canvas.updatedAt).toLocaleString();
25
+ lines.push(`${marker} ${canvas.name} (updated: ${date})`);
26
+ }
27
+ return lines;
28
+ }
29
+ export async function list(deps = defaultDeps) {
30
+ const client = await deps.connectToCanvas();
31
+ const result = await client.send({
32
+ type: 'listCanvases',
33
+ id: deps.generateId(),
34
+ });
35
+ if (result.success && result.canvases) {
36
+ const lines = formatCanvasList({
37
+ activeCanvasId: result.activeCanvasId,
38
+ agentActiveCanvasId: result.agentActiveCanvasId,
39
+ canvases: result.canvases,
40
+ });
41
+ for (const line of lines) {
42
+ deps.log(line);
43
+ }
44
+ }
45
+ else {
46
+ deps.error(`Failed: ${result.error}`);
47
+ deps.exit(1);
48
+ }
49
+ client.close();
50
+ }
@@ -0,0 +1,20 @@
1
+ export interface LoadClient {
2
+ send: <T>(request: {
3
+ type: string;
4
+ id: string;
5
+ params?: unknown;
6
+ }) => Promise<T>;
7
+ close: () => void;
8
+ }
9
+ export interface LoadDeps {
10
+ connectToCanvas: () => Promise<LoadClient>;
11
+ generateId: () => string;
12
+ readFile: (path: string, encoding: 'utf-8') => string;
13
+ existsSync: (path: string) => boolean;
14
+ resolvePath: (path: string) => string;
15
+ log: (msg: string) => void;
16
+ error: (msg: string) => void;
17
+ exit: (code: number) => never | void;
18
+ }
19
+ export declare const defaultDeps: LoadDeps;
20
+ export declare function load(filepath: string | undefined, deps?: LoadDeps): Promise<void>;