@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,117 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { moveElements } from '../move-elements';
3
+ function createMockClient(sendFn) {
4
+ return {
5
+ send: sendFn ?? vi.fn(() => Promise.resolve({ success: true, movedCount: 2 })),
6
+ close: vi.fn(),
7
+ };
8
+ }
9
+ function createMockDeps(overrides) {
10
+ return {
11
+ connectToCanvas: vi.fn(() => Promise.resolve(createMockClient())),
12
+ generateId: vi.fn(() => 'test-id'),
13
+ log: vi.fn(),
14
+ error: vi.fn(),
15
+ exit: vi.fn(),
16
+ ...overrides,
17
+ };
18
+ }
19
+ describe('moveElements', () => {
20
+ // ==================== Parameter Assembly Tests ====================
21
+ describe('parameter assembly', () => {
22
+ it('should parse comma-separated element IDs correctly', async () => {
23
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, movedCount: 2 }));
24
+ const mockClient = createMockClient(mockSend);
25
+ const deps = createMockDeps({
26
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
27
+ });
28
+ await moveElements({ elementIds: 'id1, id2', deltaX: 100, deltaY: 50 }, deps);
29
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({
30
+ type: 'moveElements',
31
+ id: 'test-id',
32
+ params: {
33
+ elementIds: ['id1', 'id2'],
34
+ deltaX: 100,
35
+ deltaY: 50,
36
+ },
37
+ }));
38
+ });
39
+ it('should pass deltaX and deltaY correctly', async () => {
40
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, movedCount: 1 }));
41
+ const mockClient = createMockClient(mockSend);
42
+ const deps = createMockDeps({
43
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
44
+ });
45
+ await moveElements({ elementIds: 'id1', deltaX: 200, deltaY: -100 }, deps);
46
+ const callParams = mockSend.mock.calls[0][0].params;
47
+ expect(callParams.deltaX).toBe(200);
48
+ expect(callParams.deltaY).toBe(-100);
49
+ });
50
+ it('should handle negative deltas', async () => {
51
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, movedCount: 1 }));
52
+ const mockClient = createMockClient(mockSend);
53
+ const deps = createMockDeps({
54
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
55
+ });
56
+ await moveElements({ elementIds: 'id1', deltaX: -50, deltaY: -75 }, deps);
57
+ const callParams = mockSend.mock.calls[0][0].params;
58
+ expect(callParams.deltaX).toBe(-50);
59
+ expect(callParams.deltaY).toBe(-75);
60
+ });
61
+ it('should trim whitespace from element IDs', async () => {
62
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, movedCount: 3 }));
63
+ const mockClient = createMockClient(mockSend);
64
+ const deps = createMockDeps({
65
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
66
+ });
67
+ await moveElements({ elementIds: ' id1 , id2 , id3 ', deltaX: 10, deltaY: 20 }, deps);
68
+ const callParams = mockSend.mock.calls[0][0].params;
69
+ expect(callParams.elementIds).toEqual(['id1', 'id2', 'id3']);
70
+ });
71
+ });
72
+ // ==================== Response Handling Tests ====================
73
+ describe('response handling', () => {
74
+ it('should log success message with moved count', async () => {
75
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, movedCount: 4 }));
76
+ const mockClient = createMockClient(mockSend);
77
+ const deps = createMockDeps({
78
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
79
+ });
80
+ await moveElements({ elementIds: 'id1,id2,id3,id4', deltaX: 50, deltaY: 50 }, deps);
81
+ expect(deps.log).toHaveBeenCalledWith('Moved 4 element(s)');
82
+ });
83
+ it('should error and exit on failure response', async () => {
84
+ const mockSend = vi.fn(() => Promise.resolve({
85
+ success: false,
86
+ error: 'Element not found',
87
+ }));
88
+ const mockClient = createMockClient(mockSend);
89
+ const deps = createMockDeps({
90
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
91
+ });
92
+ await moveElements({ elementIds: 'invalid-id', deltaX: 10, deltaY: 10 }, deps);
93
+ expect(deps.error).toHaveBeenCalledWith('Failed: Element not found');
94
+ expect(deps.exit).toHaveBeenCalledWith(1);
95
+ });
96
+ it('should close client after success', async () => {
97
+ const mockClose = vi.fn();
98
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, movedCount: 1 }));
99
+ const mockClient = { send: mockSend, close: mockClose };
100
+ const deps = createMockDeps({
101
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
102
+ });
103
+ await moveElements({ elementIds: 'id1', deltaX: 10, deltaY: 20 }, deps);
104
+ expect(mockClose).toHaveBeenCalled();
105
+ });
106
+ it('should close client after failure', async () => {
107
+ const mockClose = vi.fn();
108
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
109
+ const mockClient = { send: mockSend, close: mockClose };
110
+ const deps = createMockDeps({
111
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
112
+ });
113
+ await moveElements({ elementIds: 'id1', deltaX: 0, deltaY: 0 }, deps);
114
+ expect(mockClose).toHaveBeenCalled();
115
+ });
116
+ });
117
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,113 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { newCanvas } from '../new-canvas';
3
+ function createMockClient(sendFn) {
4
+ return {
5
+ send: sendFn ?? vi.fn(() => Promise.resolve({ success: true, canvas: { name: 'Test' } })),
6
+ close: vi.fn(),
7
+ };
8
+ }
9
+ function createMockDeps(overrides) {
10
+ return {
11
+ connectToCanvas: vi.fn(() => Promise.resolve(createMockClient())),
12
+ generateId: vi.fn(() => 'test-id'),
13
+ log: vi.fn(),
14
+ error: vi.fn(),
15
+ exit: vi.fn(),
16
+ ...overrides,
17
+ };
18
+ }
19
+ describe('newCanvas', () => {
20
+ // ==================== Parameter Assembly Tests ====================
21
+ describe('parameter assembly', () => {
22
+ it('should send correct params with name and switchTo=false', async () => {
23
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, canvas: { name: 'My Canvas' } }));
24
+ const mockClient = createMockClient(mockSend);
25
+ const deps = createMockDeps({
26
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
27
+ });
28
+ await newCanvas({ name: 'My Canvas' }, deps);
29
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({
30
+ type: 'createCanvas',
31
+ id: 'test-id',
32
+ params: {
33
+ name: 'My Canvas',
34
+ switchTo: false,
35
+ },
36
+ }));
37
+ });
38
+ it('should send switchTo=true when use is true', async () => {
39
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, canvas: { name: 'My Canvas' } }));
40
+ const mockClient = createMockClient(mockSend);
41
+ const deps = createMockDeps({
42
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
43
+ });
44
+ await newCanvas({ name: 'My Canvas', use: true }, deps);
45
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({
46
+ params: {
47
+ name: 'My Canvas',
48
+ switchTo: true,
49
+ },
50
+ }));
51
+ });
52
+ });
53
+ // ==================== Response Handling Tests ====================
54
+ describe('response handling', () => {
55
+ it('should log success message without switch text when use=false', async () => {
56
+ const mockSend = vi.fn(() => Promise.resolve({
57
+ success: true,
58
+ canvas: { name: 'New Canvas' },
59
+ }));
60
+ const mockClient = createMockClient(mockSend);
61
+ const deps = createMockDeps({
62
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
63
+ });
64
+ await newCanvas({ name: 'New Canvas', use: false }, deps);
65
+ expect(deps.log).toHaveBeenCalledWith('Canvas "New Canvas" created');
66
+ });
67
+ it('should log success message with switch text when use=true', async () => {
68
+ const mockSend = vi.fn(() => Promise.resolve({
69
+ success: true,
70
+ canvas: { name: 'New Canvas' },
71
+ }));
72
+ const mockClient = createMockClient(mockSend);
73
+ const deps = createMockDeps({
74
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
75
+ });
76
+ await newCanvas({ name: 'New Canvas', use: true }, deps);
77
+ expect(deps.log).toHaveBeenCalledWith('Canvas "New Canvas" created and switched to it');
78
+ });
79
+ it('should error and exit on failure response', async () => {
80
+ const mockSend = vi.fn(() => Promise.resolve({
81
+ success: false,
82
+ error: 'Canvas name already exists',
83
+ }));
84
+ const mockClient = createMockClient(mockSend);
85
+ const deps = createMockDeps({
86
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
87
+ });
88
+ await newCanvas({ name: 'Test' }, deps);
89
+ expect(deps.error).toHaveBeenCalledWith('Failed: Canvas name already exists');
90
+ expect(deps.exit).toHaveBeenCalledWith(1);
91
+ });
92
+ it('should close client after success', async () => {
93
+ const mockClose = vi.fn();
94
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, canvas: { name: 'Test' } }));
95
+ const mockClient = { send: mockSend, close: mockClose };
96
+ const deps = createMockDeps({
97
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
98
+ });
99
+ await newCanvas({ name: 'Test' }, deps);
100
+ expect(mockClose).toHaveBeenCalled();
101
+ });
102
+ it('should close client after failure', async () => {
103
+ const mockClose = vi.fn();
104
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
105
+ const mockClient = { send: mockSend, close: mockClose };
106
+ const deps = createMockDeps({
107
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
108
+ });
109
+ await newCanvas({ name: 'Test' }, deps);
110
+ expect(mockClose).toHaveBeenCalled();
111
+ });
112
+ });
113
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,247 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { read } from '../read';
3
+ function createMockClient(sendFn) {
4
+ return {
5
+ send: sendFn ?? vi.fn(() => Promise.resolve({ success: true, elements: [] })),
6
+ close: vi.fn(),
7
+ };
8
+ }
9
+ function createMockDeps(overrides) {
10
+ return {
11
+ connectToCanvas: vi.fn(() => Promise.resolve(createMockClient())),
12
+ generateId: vi.fn(() => 'test-id'),
13
+ toToon: vi.fn((data) => JSON.stringify(data)),
14
+ log: vi.fn(),
15
+ error: vi.fn(),
16
+ exit: vi.fn(),
17
+ ...overrides,
18
+ };
19
+ }
20
+ describe('read', () => {
21
+ // ==================== JSON Mode Tests ====================
22
+ describe('json mode', () => {
23
+ it('should call saveScene when --json is specified', async () => {
24
+ const mockSend = vi.fn(() => Promise.resolve({
25
+ success: true,
26
+ data: { elements: [], appState: {} },
27
+ }));
28
+ const mockClient = createMockClient(mockSend);
29
+ const deps = createMockDeps({
30
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
31
+ });
32
+ await read({ json: true }, deps);
33
+ expect(mockSend).toHaveBeenCalledWith({
34
+ type: 'saveScene',
35
+ id: 'test-id',
36
+ });
37
+ });
38
+ it('should output JSON data on success', async () => {
39
+ const sceneData = { elements: [{ id: 'el-1' }], appState: {} };
40
+ const mockSend = vi.fn(() => Promise.resolve({
41
+ success: true,
42
+ data: sceneData,
43
+ }));
44
+ const mockClient = createMockClient(mockSend);
45
+ const deps = createMockDeps({
46
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
47
+ });
48
+ await read({ json: true }, deps);
49
+ expect(deps.log).toHaveBeenCalledWith(JSON.stringify(sceneData, null, 2));
50
+ });
51
+ it('should error and exit on json mode failure', async () => {
52
+ const mockSend = vi.fn(() => Promise.resolve({
53
+ success: false,
54
+ error: 'Connection lost',
55
+ }));
56
+ const mockClient = createMockClient(mockSend);
57
+ const deps = createMockDeps({
58
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
59
+ });
60
+ await read({ json: true }, deps);
61
+ expect(deps.error).toHaveBeenCalledWith('Failed: Connection lost');
62
+ expect(deps.exit).toHaveBeenCalledWith(1);
63
+ });
64
+ });
65
+ // ==================== TOON Mode Tests ====================
66
+ describe('toon mode (default)', () => {
67
+ it('should call readScene in default mode', async () => {
68
+ const mockSend = vi.fn(() => Promise.resolve({
69
+ success: true,
70
+ elements: [],
71
+ }));
72
+ const mockClient = createMockClient(mockSend);
73
+ const deps = createMockDeps({
74
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
75
+ });
76
+ await read({}, deps);
77
+ expect(mockSend).toHaveBeenCalledWith({
78
+ type: 'readScene',
79
+ id: 'test-id',
80
+ });
81
+ });
82
+ it('should call toToon with converted data', async () => {
83
+ const mockToToon = vi.fn(() => 'toon-output');
84
+ const mockSend = vi.fn(() => Promise.resolve({
85
+ success: true,
86
+ elements: [
87
+ { id: 'rect-1', type: 'rectangle', x: 100, y: 200, width: 150, height: 80 },
88
+ ],
89
+ }));
90
+ const mockClient = createMockClient(mockSend);
91
+ const deps = createMockDeps({
92
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
93
+ toToon: mockToToon,
94
+ });
95
+ await read({}, deps);
96
+ expect(mockToToon).toHaveBeenCalled();
97
+ const calls = mockToToon.mock.calls;
98
+ const callArg = calls[0]?.[0];
99
+ expect(callArg).toBeDefined();
100
+ expect(callArg).toHaveProperty('shapes');
101
+ expect(callArg).toHaveProperty('lines');
102
+ expect(callArg).toHaveProperty('labels');
103
+ expect(callArg).toHaveProperty('texts');
104
+ expect(callArg).toHaveProperty('images');
105
+ expect(callArg).toHaveProperty('groups');
106
+ });
107
+ it('should output TOON format on success', async () => {
108
+ const mockToToon = vi.fn(() => 'formatted-toon-output');
109
+ const mockSend = vi.fn(() => Promise.resolve({
110
+ success: true,
111
+ elements: [],
112
+ }));
113
+ const mockClient = createMockClient(mockSend);
114
+ const deps = createMockDeps({
115
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
116
+ toToon: mockToToon,
117
+ });
118
+ await read({}, deps);
119
+ expect(deps.log).toHaveBeenCalledWith('formatted-toon-output');
120
+ });
121
+ it('should output selected elements when present', async () => {
122
+ const mockSend = vi.fn(() => Promise.resolve({
123
+ success: true,
124
+ elements: [],
125
+ selectedElementIds: ['el-1', 'el-2'],
126
+ }));
127
+ const mockClient = createMockClient(mockSend);
128
+ const deps = createMockDeps({
129
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
130
+ });
131
+ await read({}, deps);
132
+ expect(deps.log).toHaveBeenCalledWith('\nSelected: el-1, el-2');
133
+ });
134
+ it('should not output selected elements when empty', async () => {
135
+ const mockSend = vi.fn(() => Promise.resolve({
136
+ success: true,
137
+ elements: [],
138
+ selectedElementIds: [],
139
+ }));
140
+ const mockClient = createMockClient(mockSend);
141
+ const deps = createMockDeps({
142
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
143
+ });
144
+ await read({}, deps);
145
+ // Should only be called once (for the TOON output)
146
+ expect(deps.log).toHaveBeenCalledTimes(1);
147
+ });
148
+ it('should error and exit on failure', async () => {
149
+ const mockSend = vi.fn(() => Promise.resolve({
150
+ success: false,
151
+ error: 'Read failed',
152
+ }));
153
+ const mockClient = createMockClient(mockSend);
154
+ const deps = createMockDeps({
155
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
156
+ });
157
+ await read({}, deps);
158
+ expect(deps.error).toHaveBeenCalledWith('Failed: Read failed');
159
+ expect(deps.exit).toHaveBeenCalledWith(1);
160
+ });
161
+ });
162
+ // ==================== withStyle Tests ====================
163
+ describe('withStyle option', () => {
164
+ it('should pass withStyle=false by default', async () => {
165
+ const mockToToon = vi.fn(() => 'output');
166
+ const mockSend = vi.fn(() => Promise.resolve({
167
+ success: true,
168
+ elements: [
169
+ { id: 'rect-1', type: 'rectangle', x: 0, y: 0, strokeColor: '#ff0000' },
170
+ ],
171
+ }));
172
+ const mockClient = createMockClient(mockSend);
173
+ const deps = createMockDeps({
174
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
175
+ toToon: mockToToon,
176
+ });
177
+ await read({}, deps);
178
+ const calls = mockToToon.mock.calls;
179
+ const callArg = calls[0]?.[0];
180
+ expect(callArg).toBeDefined();
181
+ expect(callArg.shapes[0]).not.toHaveProperty('stroke');
182
+ });
183
+ it('should include style when withStyle=true', async () => {
184
+ const mockToToon = vi.fn(() => 'output');
185
+ const mockSend = vi.fn(() => Promise.resolve({
186
+ success: true,
187
+ elements: [
188
+ { id: 'rect-1', type: 'rectangle', x: 0, y: 0, strokeColor: '#ff0000', backgroundColor: '#00ff00' },
189
+ ],
190
+ }));
191
+ const mockClient = createMockClient(mockSend);
192
+ const deps = createMockDeps({
193
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
194
+ toToon: mockToToon,
195
+ });
196
+ await read({ withStyle: true }, deps);
197
+ const calls = mockToToon.mock.calls;
198
+ const callArg = calls[0]?.[0];
199
+ expect(callArg).toBeDefined();
200
+ expect(callArg.shapes[0].stroke).toBe('#ff0000');
201
+ expect(callArg.shapes[0].bg).toBe('#00ff00');
202
+ });
203
+ });
204
+ // ==================== Client Lifecycle Tests ====================
205
+ describe('client lifecycle', () => {
206
+ it('should close client after json mode success', async () => {
207
+ const mockClose = vi.fn();
208
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, data: {} }));
209
+ const mockClient = { send: mockSend, close: mockClose };
210
+ const deps = createMockDeps({
211
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
212
+ });
213
+ await read({ json: true }, deps);
214
+ expect(mockClose).toHaveBeenCalled();
215
+ });
216
+ it('should close client after json mode failure', async () => {
217
+ const mockClose = vi.fn();
218
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
219
+ const mockClient = { send: mockSend, close: mockClose };
220
+ const deps = createMockDeps({
221
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
222
+ });
223
+ await read({ json: true }, deps);
224
+ expect(mockClose).toHaveBeenCalled();
225
+ });
226
+ it('should close client after toon mode success', async () => {
227
+ const mockClose = vi.fn();
228
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elements: [] }));
229
+ const mockClient = { send: mockSend, close: mockClose };
230
+ const deps = createMockDeps({
231
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
232
+ });
233
+ await read({}, deps);
234
+ expect(mockClose).toHaveBeenCalled();
235
+ });
236
+ it('should close client after toon mode failure', async () => {
237
+ const mockClose = vi.fn();
238
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
239
+ const mockClient = { send: mockSend, close: mockClose };
240
+ const deps = createMockDeps({
241
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
242
+ });
243
+ await read({}, deps);
244
+ expect(mockClose).toHaveBeenCalled();
245
+ });
246
+ });
247
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,86 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { renameCanvas } from '../rename-canvas';
3
+ function createMockClient(sendFn) {
4
+ return {
5
+ send: sendFn ?? vi.fn(() => Promise.resolve({ success: true, canvas: { name: 'Test' } })),
6
+ close: vi.fn(),
7
+ };
8
+ }
9
+ function createMockDeps(overrides) {
10
+ return {
11
+ connectToCanvas: vi.fn(() => Promise.resolve(createMockClient())),
12
+ generateId: vi.fn(() => 'test-id'),
13
+ log: vi.fn(),
14
+ error: vi.fn(),
15
+ exit: vi.fn(),
16
+ ...overrides,
17
+ };
18
+ }
19
+ describe('renameCanvas', () => {
20
+ // ==================== Parameter Assembly Tests ====================
21
+ describe('parameter assembly', () => {
22
+ it('should send correct params with newName', async () => {
23
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, canvas: { name: 'New Name' } }));
24
+ const mockClient = createMockClient(mockSend);
25
+ const deps = createMockDeps({
26
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
27
+ });
28
+ await renameCanvas({ newName: 'New Name' }, deps);
29
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({
30
+ type: 'renameCanvas',
31
+ id: 'test-id',
32
+ params: {
33
+ newName: 'New Name',
34
+ },
35
+ }));
36
+ });
37
+ });
38
+ // ==================== Response Handling Tests ====================
39
+ describe('response handling', () => {
40
+ it('should log success message with new canvas name', async () => {
41
+ const mockSend = vi.fn(() => Promise.resolve({
42
+ success: true,
43
+ canvas: { name: 'Renamed Canvas' },
44
+ }));
45
+ const mockClient = createMockClient(mockSend);
46
+ const deps = createMockDeps({
47
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
48
+ });
49
+ await renameCanvas({ newName: 'Renamed Canvas' }, deps);
50
+ expect(deps.log).toHaveBeenCalledWith('Canvas renamed to "Renamed Canvas"');
51
+ });
52
+ it('should error and exit on failure response', async () => {
53
+ const mockSend = vi.fn(() => Promise.resolve({
54
+ success: false,
55
+ error: 'Name already in use',
56
+ }));
57
+ const mockClient = createMockClient(mockSend);
58
+ const deps = createMockDeps({
59
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
60
+ });
61
+ await renameCanvas({ newName: 'Duplicate' }, deps);
62
+ expect(deps.error).toHaveBeenCalledWith('Failed: Name already in use');
63
+ expect(deps.exit).toHaveBeenCalledWith(1);
64
+ });
65
+ it('should close client after success', async () => {
66
+ const mockClose = vi.fn();
67
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, canvas: { name: 'Test' } }));
68
+ const mockClient = { send: mockSend, close: mockClose };
69
+ const deps = createMockDeps({
70
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
71
+ });
72
+ await renameCanvas({ newName: 'Test' }, deps);
73
+ expect(mockClose).toHaveBeenCalled();
74
+ });
75
+ it('should close client after failure', async () => {
76
+ const mockClose = vi.fn();
77
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
78
+ const mockClient = { send: mockSend, close: mockClose };
79
+ const deps = createMockDeps({
80
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
81
+ });
82
+ await renameCanvas({ newName: 'Test' }, deps);
83
+ expect(mockClose).toHaveBeenCalled();
84
+ });
85
+ });
86
+ });
@@ -0,0 +1 @@
1
+ export {};