@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
package/dist/index.js CHANGED
@@ -1,13 +1,31 @@
1
1
  import { Command } from 'commander';
2
- import { writeFileSync } from 'node:fs';
3
- import { encode as toToon } from '@toon-format/toon';
4
2
  import { start } from './commands/start.js';
5
- import { connectToCanvas, generateId } from './lib/ws-client.js';
3
+ import { load, defaultDeps as loadDeps } from './commands/load.js';
4
+ import { addImage, defaultDeps as addImageDeps } from './commands/add-image.js';
5
+ import { addShape, defaultDeps as addShapeDeps } from './commands/add-shape.js';
6
+ import { addText, defaultDeps as addTextDeps } from './commands/add-text.js';
7
+ import { addLine, defaultDeps as addLineDeps } from './commands/add-line.js';
8
+ import { addArrow, defaultDeps as addArrowDeps } from './commands/add-arrow.js';
9
+ import { addPolygon, defaultDeps as addPolygonDeps } from './commands/add-polygon.js';
10
+ import { resizeElements, defaultDeps as resizeElementsDeps } from './commands/resize-elements.js';
11
+ import { groupElements, defaultDeps as groupElementsDeps } from './commands/group-elements.js';
12
+ import { ungroupElement, defaultDeps as ungroupElementDeps } from './commands/ungroup-element.js';
13
+ import { deleteElements, defaultDeps as deleteElementsDeps } from './commands/delete-elements.js';
14
+ import { rotateElements, defaultDeps as rotateElementsDeps } from './commands/rotate-elements.js';
15
+ import { moveElements, defaultDeps as moveElementsDeps } from './commands/move-elements.js';
16
+ import { read, defaultDeps as readDeps } from './commands/read.js';
17
+ import { save, defaultDeps as saveDeps } from './commands/save.js';
18
+ import { exportImage, defaultDeps as exportDeps } from './commands/export.js';
19
+ import { clear, defaultDeps as clearDeps } from './commands/clear.js';
20
+ import { list, defaultDeps as listDeps } from './commands/list.js';
21
+ import { newCanvas, defaultDeps as newCanvasDeps } from './commands/new-canvas.js';
22
+ import { useCanvas, defaultDeps as useCanvasDeps } from './commands/use-canvas.js';
23
+ import { renameCanvas, defaultDeps as renameCanvasDeps } from './commands/rename-canvas.js';
6
24
  const program = new Command();
7
25
  program
8
26
  .name('agent-canvas')
9
27
  .description('CLI for Agent Canvas - Excalidraw interface for AI agents')
10
- .version('0.8.0');
28
+ .version('0.9.0');
11
29
  program
12
30
  .command('start')
13
31
  .description('Start the canvas server and open in browser')
@@ -18,8 +36,7 @@ program
18
36
  .command('load [filepath]')
19
37
  .description('Load an .excalidraw file into the current canvas')
20
38
  .action(async (filepath) => {
21
- const { loadFile } = await import('./commands/start.js');
22
- await loadFile(filepath);
39
+ await load(filepath, loadDeps);
23
40
  });
24
41
  // ============================================================================
25
42
  // Add Shape
@@ -41,8 +58,7 @@ program
41
58
  .option('--label-font-size <number>', 'Label font size', parseFloat)
42
59
  .option('-n, --note <text>', 'Note for this element (stored in customData)')
43
60
  .action(async (options) => {
44
- const client = await connectToCanvas();
45
- const params = {
61
+ await addShape({
46
62
  type: options.type,
47
63
  x: options.x,
48
64
  y: options.y,
@@ -53,23 +69,10 @@ program
53
69
  strokeWidth: options.strokeWidth,
54
70
  strokeStyle: options.strokeStyle,
55
71
  fillStyle: options.fillStyle,
56
- customData: options.note ? { note: options.note } : undefined,
57
- };
58
- if (options.label) {
59
- params.label = { text: options.label, fontSize: options.labelFontSize };
60
- }
61
- const result = await client.send({ type: 'addShape', id: generateId(), params });
62
- if (result.success) {
63
- const dims = result.width !== undefined && result.height !== undefined
64
- ? ` x=${result.x} y=${result.y} w=${result.width} h=${result.height}`
65
- : '';
66
- console.log(`Shape created (id: ${result.elementId}${dims})`);
67
- }
68
- else {
69
- console.error(`Failed: ${result.error}`);
70
- process.exit(1);
71
- }
72
- client.close();
72
+ label: options.label,
73
+ labelFontSize: options.labelFontSize,
74
+ note: options.note,
75
+ }, addShapeDeps);
73
76
  });
74
77
  // ============================================================================
75
78
  // Add Text
@@ -86,29 +89,16 @@ program
86
89
  .option('--stroke-color <color>', 'Text color (hex)')
87
90
  .option('-n, --note <text>', 'Note for this element (stored in customData)')
88
91
  .action(async (options) => {
89
- const client = await connectToCanvas();
90
- const result = await client.send({
91
- type: 'addText',
92
- id: generateId(),
93
- params: {
94
- text: options.text,
95
- x: options.ax,
96
- y: options.ay,
97
- fontSize: options.fontSize,
98
- textAlign: options.textAlign,
99
- anchor: options.anchor,
100
- strokeColor: options.strokeColor,
101
- customData: options.note ? { note: options.note } : undefined,
102
- },
103
- });
104
- if (result.success) {
105
- console.log(`Text created (id: ${result.elementId}, x: ${result.x}, y: ${result.y}, ${result.width}x${result.height})`);
106
- }
107
- else {
108
- console.error(`Failed: ${result.error}`);
109
- process.exit(1);
110
- }
111
- client.close();
92
+ await addText({
93
+ text: options.text,
94
+ x: options.ax,
95
+ y: options.ay,
96
+ fontSize: options.fontSize,
97
+ textAlign: options.textAlign,
98
+ anchor: options.anchor,
99
+ strokeColor: options.strokeColor,
100
+ note: options.note,
101
+ }, addTextDeps);
112
102
  });
113
103
  // ============================================================================
114
104
  // Add Line
@@ -125,29 +115,16 @@ program
125
115
  .option('--stroke-style <style>', 'Line style: solid, dashed, or dotted')
126
116
  .option('-n, --note <text>', 'Note for this element (stored in customData)')
127
117
  .action(async (options) => {
128
- const client = await connectToCanvas();
129
- const result = await client.send({
130
- type: 'addLine',
131
- id: generateId(),
132
- params: {
133
- x: options.x,
134
- y: options.y,
135
- endX: options.endX,
136
- endY: options.endY,
137
- strokeColor: options.strokeColor,
138
- strokeWidth: options.strokeWidth,
139
- strokeStyle: options.strokeStyle,
140
- customData: options.note ? { note: options.note } : undefined,
141
- },
142
- });
143
- if (result.success) {
144
- console.log(`Line created (id: ${result.elementId})`);
145
- }
146
- else {
147
- console.error(`Failed: ${result.error}`);
148
- process.exit(1);
149
- }
150
- client.close();
118
+ await addLine({
119
+ x: options.x,
120
+ y: options.y,
121
+ endX: options.endX,
122
+ endY: options.endY,
123
+ strokeColor: options.strokeColor,
124
+ strokeWidth: options.strokeWidth,
125
+ strokeStyle: options.strokeStyle,
126
+ note: options.note,
127
+ }, addLineDeps);
151
128
  });
152
129
  // ============================================================================
153
130
  // Add Arrow
@@ -168,41 +145,20 @@ program
168
145
  .option('--via <points>', 'Intermediate points as "x1,y1;x2,y2;..." (absolute coordinates). For round: 1 control point. For elbow: multiple turn points.')
169
146
  .option('-n, --note <text>', 'Note for this element (stored in customData)')
170
147
  .action(async (options) => {
171
- // Parse --via option into midpoints array
172
- let midpoints;
173
- if (options.via) {
174
- midpoints = options.via.split(';').map((pt) => {
175
- const [x, y] = pt.split(',').map(Number);
176
- return { x, y };
177
- });
178
- }
179
- const client = await connectToCanvas();
180
- const result = await client.send({
181
- type: 'addArrow',
182
- id: generateId(),
183
- params: {
184
- x: options.x,
185
- y: options.y,
186
- endX: options.endX,
187
- endY: options.endY,
188
- strokeColor: options.strokeColor,
189
- strokeWidth: options.strokeWidth,
190
- strokeStyle: options.strokeStyle,
191
- startArrowhead: options.startArrowhead,
192
- endArrowhead: options.endArrowhead,
193
- arrowType: options.arrowType,
194
- midpoints,
195
- customData: options.note ? { note: options.note } : undefined,
196
- },
197
- });
198
- if (result.success) {
199
- console.log(`Arrow created (id: ${result.elementId})`);
200
- }
201
- else {
202
- console.error(`Failed: ${result.error}`);
203
- process.exit(1);
204
- }
205
- client.close();
148
+ await addArrow({
149
+ x: options.x,
150
+ y: options.y,
151
+ endX: options.endX,
152
+ endY: options.endY,
153
+ strokeColor: options.strokeColor,
154
+ strokeWidth: options.strokeWidth,
155
+ strokeStyle: options.strokeStyle,
156
+ startArrowhead: options.startArrowhead,
157
+ endArrowhead: options.endArrowhead,
158
+ arrowType: options.arrowType,
159
+ via: options.via,
160
+ note: options.note,
161
+ }, addArrowDeps);
206
162
  });
207
163
  // ============================================================================
208
164
  // Add Polygon
@@ -218,36 +174,37 @@ program
218
174
  .option('--fill-style <style>', 'Fill style: hachure, cross-hatch, solid, or zigzag')
219
175
  .option('-n, --note <text>', 'Note for this element (stored in customData)')
220
176
  .action(async (options) => {
221
- let points;
222
- try {
223
- points = JSON.parse(options.points);
224
- }
225
- catch {
226
- console.error('Invalid points JSON');
227
- process.exit(1);
228
- }
229
- const client = await connectToCanvas();
230
- const result = await client.send({
231
- type: 'addPolygon',
232
- id: generateId(),
233
- params: {
234
- points,
235
- strokeColor: options.strokeColor,
236
- backgroundColor: options.backgroundColor,
237
- strokeWidth: options.strokeWidth,
238
- strokeStyle: options.strokeStyle,
239
- fillStyle: options.fillStyle,
240
- customData: options.note ? { note: options.note } : undefined,
241
- },
242
- });
243
- if (result.success) {
244
- console.log(`Polygon created (id: ${result.elementId})`);
245
- }
246
- else {
247
- console.error(`Failed: ${result.error}`);
248
- process.exit(1);
249
- }
250
- client.close();
177
+ await addPolygon({
178
+ points: options.points,
179
+ strokeColor: options.strokeColor,
180
+ backgroundColor: options.backgroundColor,
181
+ strokeWidth: options.strokeWidth,
182
+ strokeStyle: options.strokeStyle,
183
+ fillStyle: options.fillStyle,
184
+ note: options.note,
185
+ }, addPolygonDeps);
186
+ });
187
+ // ============================================================================
188
+ // Add Image
189
+ // ============================================================================
190
+ program
191
+ .command('add-image')
192
+ .description('Add an image to the canvas')
193
+ .requiredOption('-f, --file <path>', 'Path to image file (PNG, JPEG, GIF, SVG, WebP)')
194
+ .requiredOption('-x, --x <number>', 'X coordinate', parseFloat)
195
+ .requiredOption('-y, --y <number>', 'Y coordinate', parseFloat)
196
+ .option('-w, --width <number>', 'Width (default: original image width)', parseFloat)
197
+ .option('-h, --height <number>', 'Height (default: original image height)', parseFloat)
198
+ .option('-n, --note <text>', 'Note for this element (stored in customData)')
199
+ .action(async (options) => {
200
+ await addImage({
201
+ file: options.file,
202
+ x: options.x,
203
+ y: options.y,
204
+ width: options.width,
205
+ height: options.height,
206
+ note: options.note,
207
+ }, addImageDeps);
251
208
  });
252
209
  // ============================================================================
253
210
  // Delete Elements
@@ -257,21 +214,7 @@ program
257
214
  .description('Delete elements from the canvas')
258
215
  .requiredOption('-i, --element-ids <ids>', 'Comma-separated element IDs to delete')
259
216
  .action(async (options) => {
260
- const elementIds = options.elementIds.split(',').map((s) => s.trim());
261
- const client = await connectToCanvas();
262
- const result = await client.send({
263
- type: 'deleteElements',
264
- id: generateId(),
265
- params: { elementIds },
266
- });
267
- if (result.success) {
268
- console.log(`Deleted ${result.deletedCount} element(s)`);
269
- }
270
- else {
271
- console.error(`Failed: ${result.error}`);
272
- process.exit(1);
273
- }
274
- client.close();
217
+ await deleteElements({ elementIds: options.elementIds }, deleteElementsDeps);
275
218
  });
276
219
  // ============================================================================
277
220
  // Rotate Elements
@@ -282,21 +225,7 @@ program
282
225
  .requiredOption('-i, --element-ids <ids>', 'Comma-separated element IDs to rotate')
283
226
  .requiredOption('-a, --angle <degrees>', 'Rotation angle in degrees', parseFloat)
284
227
  .action(async (options) => {
285
- const elementIds = options.elementIds.split(',').map((s) => s.trim());
286
- const client = await connectToCanvas();
287
- const result = await client.send({
288
- type: 'rotateElements',
289
- id: generateId(),
290
- params: { elementIds, angle: options.angle },
291
- });
292
- if (result.success) {
293
- console.log(`Rotated ${result.rotatedCount} element(s)`);
294
- }
295
- else {
296
- console.error(`Failed: ${result.error}`);
297
- process.exit(1);
298
- }
299
- client.close();
228
+ await rotateElements({ elementIds: options.elementIds, angle: options.angle }, rotateElementsDeps);
300
229
  });
301
230
  // ============================================================================
302
231
  // Group Elements
@@ -307,20 +236,7 @@ program
307
236
  .requiredOption('-i, --element-ids <ids>', 'Comma-separated element IDs')
308
237
  .action(async (options) => {
309
238
  const elementIds = options.elementIds.split(',').map((s) => s.trim());
310
- const client = await connectToCanvas();
311
- const result = await client.send({
312
- type: 'groupElements',
313
- id: generateId(),
314
- params: { elementIds },
315
- });
316
- if (result.success) {
317
- console.log(`Group created (id: ${result.groupId})`);
318
- }
319
- else {
320
- console.error(`Failed: ${result.error}`);
321
- process.exit(1);
322
- }
323
- client.close();
239
+ await groupElements({ elementIds }, groupElementsDeps);
324
240
  });
325
241
  // ============================================================================
326
242
  // Ungroup Element
@@ -330,20 +246,7 @@ program
330
246
  .description('Remove an element from its group')
331
247
  .requiredOption('-i, --element-id <id>', 'Element ID to ungroup')
332
248
  .action(async (options) => {
333
- const client = await connectToCanvas();
334
- const result = await client.send({
335
- type: 'ungroupElement',
336
- id: generateId(),
337
- params: { elementId: options.elementId },
338
- });
339
- if (result.success) {
340
- console.log('Element ungrouped');
341
- }
342
- else {
343
- console.error(`Failed: ${result.error}`);
344
- process.exit(1);
345
- }
346
- client.close();
249
+ await ungroupElement({ elementId: options.elementId }, ungroupElementDeps);
347
250
  });
348
251
  // ============================================================================
349
252
  // Move Elements
@@ -355,28 +258,18 @@ program
355
258
  .requiredOption('--delta-x <number>', 'Horizontal offset (positive = right)', parseFloat)
356
259
  .requiredOption('--delta-y <number>', 'Vertical offset (positive = down)', parseFloat)
357
260
  .action(async (options) => {
358
- const elementIds = options.elementIds.split(',').map((s) => s.trim());
359
- const client = await connectToCanvas();
360
- const result = await client.send({
361
- type: 'moveElements',
362
- id: generateId(),
363
- params: { elementIds, deltaX: options.deltaX, deltaY: options.deltaY },
364
- });
365
- if (result.success) {
366
- console.log(`Moved ${result.movedCount} element(s)`);
367
- }
368
- else {
369
- console.error(`Failed: ${result.error}`);
370
- process.exit(1);
371
- }
372
- client.close();
261
+ await moveElements({
262
+ elementIds: options.elementIds,
263
+ deltaX: options.deltaX,
264
+ deltaY: options.deltaY,
265
+ }, moveElementsDeps);
373
266
  });
374
267
  // ============================================================================
375
268
  // Resize Elements
376
269
  // ============================================================================
377
270
  program
378
271
  .command('resize-elements')
379
- .description('Resize shape elements by expanding/contracting edges')
272
+ .description('Resize elements (shapes and images) by expanding/contracting edges')
380
273
  .requiredOption('-i, --element-ids <ids>', 'Comma-separated element IDs')
381
274
  .option('--top <number>', 'Expand top edge (positive = upward, negative = contract)', parseFloat)
382
275
  .option('--bottom <number>', 'Expand bottom edge (positive = downward, negative = contract)', parseFloat)
@@ -384,28 +277,13 @@ program
384
277
  .option('--right <number>', 'Expand right edge (positive = rightward, negative = contract)', parseFloat)
385
278
  .action(async (options) => {
386
279
  const elementIds = options.elementIds.split(',').map((s) => s.trim());
387
- const top = options.top ?? 0;
388
- const bottom = options.bottom ?? 0;
389
- const left = options.left ?? 0;
390
- const right = options.right ?? 0;
391
- if (top === 0 && bottom === 0 && left === 0 && right === 0) {
392
- console.error('At least one of --top, --bottom, --left, --right must be specified');
393
- process.exit(1);
394
- }
395
- const client = await connectToCanvas();
396
- const result = await client.send({
397
- type: 'resizeElements',
398
- id: generateId(),
399
- params: { elementIds, top, bottom, left, right },
400
- });
401
- if (result.success) {
402
- console.log(`Resized ${result.resizedCount} element(s)`);
403
- }
404
- else {
405
- console.error(`Failed: ${result.error}`);
406
- process.exit(1);
407
- }
408
- client.close();
280
+ await resizeElements({
281
+ elementIds,
282
+ top: options.top,
283
+ bottom: options.bottom,
284
+ left: options.left,
285
+ right: options.right,
286
+ }, resizeElementsDeps);
409
287
  });
410
288
  // ============================================================================
411
289
  // Read Scene
@@ -416,173 +294,7 @@ program
416
294
  .option('--json', 'Output raw Excalidraw scene JSON')
417
295
  .option('--with-style', 'Include style info (stroke, bg) in TOON output')
418
296
  .action(async (options) => {
419
- const client = await connectToCanvas();
420
- if (options.json) {
421
- // Return raw Excalidraw scene data
422
- const result = await client.send({
423
- type: 'saveScene',
424
- id: generateId(),
425
- });
426
- if (result.success && result.data) {
427
- console.log(JSON.stringify(result.data, null, 2));
428
- }
429
- else {
430
- console.error(`Failed: ${result.error}`);
431
- process.exit(1);
432
- }
433
- client.close();
434
- return;
435
- }
436
- const result = await client.send({
437
- type: 'readScene',
438
- id: generateId(),
439
- });
440
- if (result.success && result.elements) {
441
- const withStyle = options.withStyle;
442
- // Separate elements into shapes, lines, labels (bound text), texts (standalone text), and groups
443
- const shapes = [];
444
- const lines = [];
445
- const labels = [];
446
- const texts = [];
447
- const groupsMap = new Map(); // groupId -> elementIds
448
- for (const el of result.elements) {
449
- const angle = el.angle ? Math.round(el.angle * 180 / Math.PI) : 0; // Convert radians to degrees
450
- // Collect group memberships
451
- if (el.groupIds?.length) {
452
- for (const groupId of el.groupIds) {
453
- if (!groupsMap.has(groupId)) {
454
- groupsMap.set(groupId, []);
455
- }
456
- groupsMap.get(groupId).push(el.id);
457
- }
458
- }
459
- if (el.type === 'text') {
460
- if (el.containerId) {
461
- // Bound text (label)
462
- labels.push({
463
- id: el.id,
464
- containerId: el.containerId,
465
- content: el.text ?? '',
466
- x: Math.round(el.x),
467
- y: Math.round(el.y),
468
- w: el.width !== undefined ? Math.round(el.width) : null,
469
- h: el.height !== undefined ? Math.round(el.height) : null,
470
- });
471
- }
472
- else {
473
- // Standalone text
474
- const text = {
475
- id: el.id,
476
- content: el.text ?? '',
477
- x: Math.round(el.x),
478
- y: Math.round(el.y),
479
- w: el.width !== undefined ? Math.round(el.width) : null,
480
- h: el.height !== undefined ? Math.round(el.height) : null,
481
- angle,
482
- note: el.customData?.note ?? null,
483
- };
484
- if (withStyle) {
485
- text.stroke = el.strokeColor ?? null;
486
- }
487
- texts.push(text);
488
- }
489
- }
490
- else if (el.type === 'line' || el.type === 'arrow') {
491
- const pts = el.points ?? [];
492
- // Check if it's a closed polygon (first and last point within 8px threshold)
493
- const isPolygon = el.type === 'line' && pts.length >= 3 && (() => {
494
- const first = pts[0];
495
- const last = pts[pts.length - 1];
496
- const distance = Math.sqrt((last[0] - first[0]) ** 2 + (last[1] - first[1]) ** 2);
497
- return distance <= 8;
498
- })();
499
- if (isPolygon) {
500
- // Polygon - treat as shape
501
- // Calculate bounding box from points
502
- const xs = pts.map(p => p[0]);
503
- const ys = pts.map(p => p[1]);
504
- const minX = Math.min(...xs);
505
- const maxX = Math.max(...xs);
506
- const minY = Math.min(...ys);
507
- const maxY = Math.max(...ys);
508
- const shape = {
509
- id: el.id,
510
- type: 'polygon',
511
- x: Math.round(el.x + minX),
512
- y: Math.round(el.y + minY),
513
- w: Math.round(maxX - minX),
514
- h: Math.round(maxY - minY),
515
- angle,
516
- labelId: null,
517
- note: el.customData?.note ?? null,
518
- };
519
- if (withStyle) {
520
- shape.stroke = el.strokeColor ?? null;
521
- shape.bg = el.backgroundColor ?? null;
522
- }
523
- shapes.push(shape);
524
- }
525
- else {
526
- // Line/Arrow element
527
- const lastPt = pts.length > 0 ? pts[pts.length - 1] : [0, 0];
528
- const line = {
529
- id: el.id,
530
- type: el.type,
531
- x: Math.round(el.x),
532
- y: Math.round(el.y),
533
- endX: Math.round(el.x + lastPt[0]),
534
- endY: Math.round(el.y + lastPt[1]),
535
- // Show intermediate points (via) in the same format as --via input
536
- via: pts.length > 2
537
- ? pts.slice(1, -1).map(pt => `${Math.round(el.x + pt[0])},${Math.round(el.y + pt[1])}`).join(';')
538
- : null,
539
- angle,
540
- note: el.customData?.note ?? null,
541
- };
542
- if (withStyle) {
543
- line.stroke = el.strokeColor ?? null;
544
- }
545
- lines.push(line);
546
- }
547
- }
548
- else {
549
- // Shape element (rectangle, ellipse, diamond, etc.)
550
- const boundText = el.boundElements?.find(b => b.type === 'text');
551
- const shape = {
552
- id: el.id,
553
- type: el.type,
554
- x: Math.round(el.x),
555
- y: Math.round(el.y),
556
- w: el.width !== undefined ? Math.round(el.width) : null,
557
- h: el.height !== undefined ? Math.round(el.height) : null,
558
- angle,
559
- labelId: boundText?.id ?? null,
560
- note: el.customData?.note ?? null,
561
- };
562
- if (withStyle) {
563
- shape.stroke = el.strokeColor ?? null;
564
- shape.bg = el.backgroundColor ?? null;
565
- }
566
- shapes.push(shape);
567
- }
568
- }
569
- // Build groups array
570
- const groups = Array.from(groupsMap.entries()).map(([id, elementIds]) => ({
571
- id,
572
- elementIds: elementIds.join(','),
573
- }));
574
- console.log(toToon({ shapes, lines, labels, texts, groups }));
575
- // Output selected elements
576
- const selectedIds = result.selectedElementIds ?? [];
577
- if (selectedIds.length > 0) {
578
- console.log(`\nSelected: ${selectedIds.join(', ')}`);
579
- }
580
- }
581
- else {
582
- console.error(`Failed: ${result.error}`);
583
- process.exit(1);
584
- }
585
- client.close();
297
+ await read({ json: options.json, withStyle: options.withStyle }, readDeps);
586
298
  });
587
299
  // ============================================================================
588
300
  // Export Image
@@ -596,36 +308,13 @@ program
596
308
  .option('--embed-scene', 'Embed scene data in PNG')
597
309
  .option('--scale <scale>', 'Export scale (1, 2, or 3)', '1')
598
310
  .action(async (options) => {
599
- const scale = parseInt(options.scale, 10);
600
- if (![1, 2, 3].includes(scale)) {
601
- console.error('Scale must be 1, 2, or 3');
602
- process.exit(1);
603
- }
604
- const client = await connectToCanvas();
605
- const result = await client.send({
606
- type: 'exportImage',
607
- id: generateId(),
608
- params: {
609
- background: options.background,
610
- dark: options.dark ?? false,
611
- embedScene: options.embedScene ?? false,
612
- scale: scale,
613
- },
614
- });
615
- if (result.success && result.dataUrl) {
616
- // Extract base64 data from data URL
617
- const base64Data = result.dataUrl.replace(/^data:image\/png;base64,/, '');
618
- const buffer = Buffer.from(base64Data, 'base64');
619
- // Generate output path if not specified
620
- const outputPath = options.output || `canvas-${Date.now()}.png`;
621
- writeFileSync(outputPath, buffer);
622
- console.log(`Exported to ${outputPath}`);
623
- }
624
- else {
625
- console.error(`Failed: ${result.error}`);
626
- process.exit(1);
627
- }
628
- client.close();
311
+ await exportImage({
312
+ output: options.output,
313
+ background: options.background,
314
+ dark: options.dark,
315
+ embedScene: options.embedScene,
316
+ scale: parseInt(options.scale, 10),
317
+ }, exportDeps);
629
318
  });
630
319
  // ============================================================================
631
320
  // Save Scene
@@ -635,21 +324,7 @@ program
635
324
  .description('Save canvas to an .excalidraw file')
636
325
  .argument('<filepath>', 'Output file path (.excalidraw)')
637
326
  .action(async (filepath) => {
638
- const client = await connectToCanvas();
639
- const result = await client.send({
640
- type: 'saveScene',
641
- id: generateId(),
642
- });
643
- if (result.success && result.data) {
644
- const outputPath = filepath.endsWith('.excalidraw') ? filepath : `${filepath}.excalidraw`;
645
- writeFileSync(outputPath, JSON.stringify(result.data, null, 2));
646
- console.log(`Saved to ${outputPath}`);
647
- }
648
- else {
649
- console.error(`Failed: ${result.error}`);
650
- process.exit(1);
651
- }
652
- client.close();
327
+ await save(filepath, saveDeps);
653
328
  });
654
329
  // ============================================================================
655
330
  // Clear Canvas
@@ -658,19 +333,7 @@ program
658
333
  .command('clear')
659
334
  .description('Clear all elements from the canvas')
660
335
  .action(async () => {
661
- const client = await connectToCanvas();
662
- const result = await client.send({
663
- type: 'clearCanvas',
664
- id: generateId(),
665
- });
666
- if (result.success) {
667
- console.log('Canvas cleared');
668
- }
669
- else {
670
- console.error(`Failed: ${result.error}`);
671
- process.exit(1);
672
- }
673
- client.close();
336
+ await clear(clearDeps);
674
337
  });
675
338
  // ============================================================================
676
339
  // List Canvases
@@ -679,24 +342,7 @@ program
679
342
  .command('list')
680
343
  .description('List all canvases')
681
344
  .action(async () => {
682
- const client = await connectToCanvas();
683
- const result = await client.send({
684
- type: 'listCanvases',
685
- id: generateId(),
686
- });
687
- if (result.success && result.canvases) {
688
- console.log('Canvases:');
689
- for (const canvas of result.canvases) {
690
- const marker = canvas.id === result.activeCanvasId ? ' *' : ' ';
691
- const date = new Date(canvas.updatedAt).toLocaleString();
692
- console.log(`${marker} ${canvas.name} (updated: ${date})`);
693
- }
694
- }
695
- else {
696
- console.error(`Failed: ${result.error}`);
697
- process.exit(1);
698
- }
699
- client.close();
345
+ await list(listDeps);
700
346
  });
701
347
  // ============================================================================
702
348
  // Create Canvas
@@ -707,21 +353,7 @@ program
707
353
  .requiredOption('-n, --name <name>', 'Name for the new canvas')
708
354
  .option('--use', 'Switch to the new canvas after creation')
709
355
  .action(async (options) => {
710
- const client = await connectToCanvas();
711
- const result = await client.send({
712
- type: 'createCanvas',
713
- id: generateId(),
714
- params: { name: options.name, switchTo: options.use ?? false },
715
- });
716
- if (result.success && result.canvas) {
717
- const switched = options.use ? ' and switched to it' : '';
718
- console.log(`Canvas "${result.canvas.name}" created${switched}`);
719
- }
720
- else {
721
- console.error(`Failed: ${result.error}`);
722
- process.exit(1);
723
- }
724
- client.close();
356
+ await newCanvas({ name: options.name, use: options.use }, newCanvasDeps);
725
357
  });
726
358
  // ============================================================================
727
359
  // Switch Canvas
@@ -731,20 +363,7 @@ program
731
363
  .description('Switch to a canvas by name')
732
364
  .argument('<name>', 'Canvas name to switch to')
733
365
  .action(async (name) => {
734
- const client = await connectToCanvas();
735
- const result = await client.send({
736
- type: 'switchCanvas',
737
- id: generateId(),
738
- params: { name },
739
- });
740
- if (result.success && result.canvas) {
741
- console.log(`Switched to canvas "${result.canvas.name}"`);
742
- }
743
- else {
744
- console.error(`Failed: ${result.error}`);
745
- process.exit(1);
746
- }
747
- client.close();
366
+ await useCanvas({ name }, useCanvasDeps);
748
367
  });
749
368
  // ============================================================================
750
369
  // Rename Canvas
@@ -754,19 +373,6 @@ program
754
373
  .description('Rename the current canvas')
755
374
  .argument('<name>', 'New name for the canvas')
756
375
  .action(async (name) => {
757
- const client = await connectToCanvas();
758
- const result = await client.send({
759
- type: 'renameCanvas',
760
- id: generateId(),
761
- params: { newName: name },
762
- });
763
- if (result.success && result.canvas) {
764
- console.log(`Canvas renamed to "${result.canvas.name}"`);
765
- }
766
- else {
767
- console.error(`Failed: ${result.error}`);
768
- process.exit(1);
769
- }
770
- client.close();
376
+ await renameCanvas({ newName: name }, renameCanvasDeps);
771
377
  });
772
378
  program.parse();