velloo 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/BUN-LICENSE.md +91 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +9 -0
  4. package/README.md +262 -2
  5. package/THIRD-PARTY-NOTICES.md +467 -0
  6. package/assets/elsewhere-alps-9fqhv029.jpg +0 -0
  7. package/assets/elsewhere-bali-vp60g115.jpg +0 -0
  8. package/assets/elsewhere-forest-xgn23zrj.jpg +0 -0
  9. package/assets/elsewhere-japan-qs7qkbr2.jpg +0 -0
  10. package/assets/elsewhere-kyoto-map-n2bvkrya.svg +1 -0
  11. package/assets/elsewhere-kyoto-qemtn6nk.jpg +0 -0
  12. package/assets/elsewhere-room-g1gaw7cs.jpg +0 -0
  13. package/canvas/apple-touch-icon.png +0 -0
  14. package/canvas/assets/index-BCvDZiBo.css +2 -0
  15. package/canvas/assets/index-BcBJ11d2.js +28 -0
  16. package/canvas/assets/lucide-all-BdEyryfF.js +1 -0
  17. package/canvas/assets/radix-C3HaOB-d.js +41 -0
  18. package/canvas/assets/react-D0Ec-185.js +9 -0
  19. package/canvas/assets/rolldown-runtime-hePW80VL.js +1 -0
  20. package/canvas/assets/vendor-CKmQ-Zst.js +53 -0
  21. package/canvas/favicon.ico +0 -0
  22. package/canvas/favicon.svg +12 -0
  23. package/canvas/fonts/OFL-1.1.txt +93 -0
  24. package/canvas/fonts/poppins-700.woff2 +0 -0
  25. package/canvas/icon-192.png +0 -0
  26. package/canvas/icon-512.png +0 -0
  27. package/canvas/index.html +22 -0
  28. package/canvas/site.webmanifest +11 -0
  29. package/chunk-0t68szgr.js +3 -0
  30. package/chunk-1bywxgc5.js +4 -0
  31. package/chunk-1gx45384.js +41 -0
  32. package/chunk-1y50g9vp.js +2 -0
  33. package/chunk-1yhc252b.js +3 -0
  34. package/chunk-2mv65qxs.js +5 -0
  35. package/chunk-2smsg2ct.js +7 -0
  36. package/chunk-2vx420g2.js +442 -0
  37. package/chunk-2z0k59hz.js +3 -0
  38. package/chunk-329e3phg.js +451 -0
  39. package/chunk-40657ggd.js +10 -0
  40. package/chunk-56vqqr8s.js +3 -0
  41. package/chunk-582y60bv.js +2 -0
  42. package/chunk-5js0qw32.js +2 -0
  43. package/chunk-5x173xay.js +2 -0
  44. package/chunk-65wb0g7d.js +3 -0
  45. package/chunk-6tx68d90.js +3 -0
  46. package/chunk-74skmg76.js +2 -0
  47. package/chunk-75wbh438.js +2 -0
  48. package/chunk-79ykzywe.js +4 -0
  49. package/chunk-7dggmqwq.js +53 -0
  50. package/chunk-7e39xe21.js +18 -0
  51. package/chunk-7p7ha0qk.js +3 -0
  52. package/chunk-8ssr8a8w.js +89 -0
  53. package/chunk-946pcnt5.js +5 -0
  54. package/chunk-9vg3yafz.js +3 -0
  55. package/chunk-aapybh30.js +6 -0
  56. package/chunk-b2ebm1t3.js +303 -0
  57. package/chunk-b7j86xq7.js +4 -0
  58. package/chunk-bjnhhsak.js +2 -0
  59. package/chunk-bk8b7f9a.js +62 -0
  60. package/chunk-cep3ktr3.js +4 -0
  61. package/chunk-cxe6jjwj.js +3 -0
  62. package/chunk-d385435m.js +8 -0
  63. package/chunk-dt03awr1.js +2 -0
  64. package/chunk-e2ag33vd.js +226 -0
  65. package/chunk-erwfk47h.js +3 -0
  66. package/chunk-fgw3hp2v.js +3 -0
  67. package/chunk-fjbzk4sw.js +3 -0
  68. package/chunk-g02nd9hn.js +4 -0
  69. package/chunk-h0c36khx.js +2 -0
  70. package/chunk-h6gchare.js +3 -0
  71. package/chunk-hggap8fq.js +3 -0
  72. package/chunk-hs2j6s1v.js +75 -0
  73. package/chunk-jnsfgtn9.js +3 -0
  74. package/chunk-jrsknzjt.js +3 -0
  75. package/chunk-k6ferbam.js +4 -0
  76. package/chunk-k784090q.js +6 -0
  77. package/chunk-kxk5x7g6.js +3 -0
  78. package/chunk-mq4znqv2.js +2 -0
  79. package/chunk-mzhdrawd.js +3 -0
  80. package/chunk-n5007jcz.js +2 -0
  81. package/chunk-nfr3q7mg.js +5 -0
  82. package/chunk-nsqs1bqf.js +2 -0
  83. package/chunk-nwx5700b.js +3 -0
  84. package/chunk-pphgrsxa.js +2 -0
  85. package/chunk-qpvj6kzq.js +6 -0
  86. package/chunk-qwv7xkms.js +2 -0
  87. package/chunk-rksq3w72.js +244 -0
  88. package/chunk-s23gtejf.js +3 -0
  89. package/chunk-t2ttkxe9.js +85 -0
  90. package/chunk-tmtzxcs5.js +2 -0
  91. package/chunk-vbk1qhdz.js +3 -0
  92. package/chunk-w5rzk6ms.js +1229 -0
  93. package/chunk-xr6f94rj.js +2 -0
  94. package/chunk-y0zxzefg.js +5 -0
  95. package/chunk-zf3xc1wz.js +2 -0
  96. package/cli.js +3 -0
  97. package/launcher.cjs +97 -0
  98. package/package.json +58 -5
  99. package/pkgs/helpers/src/box.tsx +21 -0
  100. package/pkgs/helpers/src/cn.ts +32 -0
  101. package/pkgs/helpers/src/descriptors.ts +270 -0
  102. package/pkgs/helpers/src/divider.tsx +123 -0
  103. package/pkgs/helpers/src/gradient.tsx +90 -0
  104. package/pkgs/helpers/src/heading.tsx +20 -0
  105. package/pkgs/helpers/src/icon-data.ts +8009 -0
  106. package/pkgs/helpers/src/icon.tsx +53 -0
  107. package/pkgs/helpers/src/image.tsx +111 -0
  108. package/pkgs/helpers/src/index.ts +29 -0
  109. package/pkgs/helpers/src/layer.tsx +61 -0
  110. package/pkgs/helpers/src/lowering.ts +53 -0
  111. package/pkgs/helpers/src/paths.ts +47 -0
  112. package/pkgs/helpers/src/placeholder.tsx +88 -0
  113. package/pkgs/helpers/src/prose.tsx +42 -0
  114. package/pkgs/helpers/src/registry.ts +41 -0
  115. package/pkgs/helpers/src/svg.tsx +62 -0
  116. package/pkgs/helpers/src/text.tsx +16 -0
  117. package/pkgs/provider-antd/src/index.ts +78 -0
  118. package/pkgs/provider-antd/src/intro.ts +14 -0
  119. package/pkgs/provider-antd/src/manifest.ts +439 -0
  120. package/pkgs/provider-antd/src/overlays.ts +176 -0
  121. package/pkgs/provider-antd/src/registry.ts +104 -0
  122. package/pkgs/provider-antd/src/render-pass.ts +43 -0
  123. package/pkgs/provider-antd/src/tailwind-entry.css +21 -0
  124. package/pkgs/provider-antd/src/theme.ts +132 -0
  125. package/pkgs/provider-antd/src/version.ts +8 -0
  126. package/pkgs/provider-chakra/src/index.ts +80 -0
  127. package/pkgs/provider-chakra/src/intro.ts +14 -0
  128. package/pkgs/provider-chakra/src/manifest.ts +421 -0
  129. package/pkgs/provider-chakra/src/overlays.ts +246 -0
  130. package/pkgs/provider-chakra/src/registry.ts +227 -0
  131. package/pkgs/provider-chakra/src/render-pass.ts +55 -0
  132. package/pkgs/provider-chakra/src/tailwind-entry.css +21 -0
  133. package/pkgs/provider-chakra/src/theme.ts +180 -0
  134. package/pkgs/provider-chakra/src/version.ts +8 -0
  135. package/pkgs/provider-mui/src/index.ts +117 -0
  136. package/pkgs/provider-mui/src/intro.ts +12 -0
  137. package/pkgs/provider-mui/src/manifest.ts +263 -0
  138. package/pkgs/provider-mui/src/overlays.ts +124 -0
  139. package/pkgs/provider-mui/src/registry.ts +120 -0
  140. package/pkgs/provider-mui/src/render-pass.ts +36 -0
  141. package/pkgs/provider-mui/src/tailwind-entry.css +21 -0
  142. package/pkgs/provider-mui/src/theme.ts +129 -0
  143. package/pkgs/provider-mui/src/version.ts +8 -0
  144. package/pkgs/provider-none/src/components-inline.tsx +204 -0
  145. package/pkgs/provider-none/src/components.tsx +155 -0
  146. package/pkgs/provider-none/src/index.ts +57 -0
  147. package/pkgs/provider-none/src/intro.ts +18 -0
  148. package/pkgs/provider-none/src/manifest.ts +163 -0
  149. package/pkgs/provider-none/src/registry-inline.ts +36 -0
  150. package/pkgs/provider-none/src/registry.ts +39 -0
  151. package/pkgs/provider-none/src/tailwind-entry.css +57 -0
  152. package/pkgs/provider-none/src/version.ts +10 -0
  153. package/pkgs/schema/src/annotation.ts +120 -0
  154. package/pkgs/schema/src/asset.ts +66 -0
  155. package/pkgs/schema/src/board.ts +71 -0
  156. package/pkgs/schema/src/comment.ts +107 -0
  157. package/pkgs/schema/src/config.ts +178 -0
  158. package/pkgs/schema/src/css-sanitize.ts +56 -0
  159. package/pkgs/schema/src/extension.ts +105 -0
  160. package/pkgs/schema/src/fonts.ts +690 -0
  161. package/pkgs/schema/src/frame.ts +40 -0
  162. package/pkgs/schema/src/icon-name.ts +21 -0
  163. package/pkgs/schema/src/ids.ts +14 -0
  164. package/pkgs/schema/src/index.ts +161 -0
  165. package/pkgs/schema/src/migrate.ts +244 -0
  166. package/pkgs/schema/src/node.ts +229 -0
  167. package/pkgs/schema/src/paths.ts +28 -0
  168. package/pkgs/schema/src/repo.ts +52 -0
  169. package/pkgs/schema/src/screen.ts +30 -0
  170. package/pkgs/schema/src/snippet-resolve.ts +193 -0
  171. package/pkgs/schema/src/snippet.ts +104 -0
  172. package/pkgs/schema/src/svg-sanitize.ts +74 -0
  173. package/pkgs/schema/src/theme.ts +218 -0
  174. package/pkgs/schema/src/typeset.ts +693 -0
  175. package/pkgs/schema/src/validate-ids.ts +46 -0
  176. package/pkgs/schema/src/viewport.ts +8 -0
  177. package/pkgs/shadcn-snapshot/dist/manifest.json +8109 -0
  178. package/pkgs/shadcn-snapshot/src/components/canvas-portal.tsx +55 -0
  179. package/pkgs/shadcn-snapshot/src/components/ui/accordion.tsx +122 -0
  180. package/pkgs/shadcn-snapshot/src/components/ui/alert-dialog.tsx +164 -0
  181. package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +74 -0
  182. package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +13 -0
  183. package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +197 -0
  184. package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +100 -0
  185. package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +50 -0
  186. package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +109 -0
  187. package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +130 -0
  188. package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +82 -0
  189. package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +72 -0
  190. package/pkgs/shadcn-snapshot/src/components/ui/calendar.tsx +229 -0
  191. package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +92 -0
  192. package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +235 -0
  193. package/pkgs/shadcn-snapshot/src/components/ui/chart-option.ts +250 -0
  194. package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +177 -0
  195. package/pkgs/shadcn-snapshot/src/components/ui/checkbox.tsx +41 -0
  196. package/pkgs/shadcn-snapshot/src/components/ui/collapsible.tsx +32 -0
  197. package/pkgs/shadcn-snapshot/src/components/ui/combobox.tsx +196 -0
  198. package/pkgs/shadcn-snapshot/src/components/ui/context-menu.tsx +227 -0
  199. package/pkgs/shadcn-snapshot/src/components/ui/dialog.tsx +131 -0
  200. package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +24 -0
  201. package/pkgs/shadcn-snapshot/src/components/ui/drawer.tsx +112 -0
  202. package/pkgs/shadcn-snapshot/src/components/ui/dropdown-menu.tsx +205 -0
  203. package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +98 -0
  204. package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +228 -0
  205. package/pkgs/shadcn-snapshot/src/components/ui/hover-card.tsx +51 -0
  206. package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +148 -0
  207. package/pkgs/shadcn-snapshot/src/components/ui/input.tsx +43 -0
  208. package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +187 -0
  209. package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +30 -0
  210. package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +25 -0
  211. package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +71 -0
  212. package/pkgs/shadcn-snapshot/src/components/ui/menubar.tsx +243 -0
  213. package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +89 -0
  214. package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +60 -0
  215. package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +165 -0
  216. package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +117 -0
  217. package/pkgs/shadcn-snapshot/src/components/ui/popover.tsx +66 -0
  218. package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +35 -0
  219. package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +48 -0
  220. package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +59 -0
  221. package/pkgs/shadcn-snapshot/src/components/ui/select.tsx +180 -0
  222. package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +32 -0
  223. package/pkgs/shadcn-snapshot/src/components/ui/sheet.tsx +107 -0
  224. package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +17 -0
  225. package/pkgs/shadcn-snapshot/src/components/ui/slider.tsx +68 -0
  226. package/pkgs/shadcn-snapshot/src/components/ui/sonner.tsx +91 -0
  227. package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +21 -0
  228. package/pkgs/shadcn-snapshot/src/components/ui/switch.tsx +41 -0
  229. package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +93 -0
  230. package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +84 -0
  231. package/pkgs/shadcn-snapshot/src/components/ui/textarea.tsx +24 -0
  232. package/pkgs/shadcn-snapshot/src/components/ui/toggle-group.tsx +94 -0
  233. package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +50 -0
  234. package/pkgs/shadcn-snapshot/src/components/ui/tooltip.tsx +47 -0
  235. package/pkgs/shadcn-snapshot/src/examples.ts +36 -0
  236. package/pkgs/shadcn-snapshot/src/groups.ts +87 -0
  237. package/pkgs/shadcn-snapshot/src/index.ts +43 -0
  238. package/pkgs/shadcn-snapshot/src/lib/utils.ts +4 -0
  239. package/pkgs/shadcn-snapshot/src/manifest.ts +12 -0
  240. package/pkgs/shadcn-snapshot/src/notes.ts +97 -0
  241. package/pkgs/shadcn-snapshot/src/paths.ts +47 -0
  242. package/pkgs/shadcn-snapshot/src/registry-files.ts +293 -0
  243. package/pkgs/shadcn-snapshot/src/registry.ts +631 -0
  244. package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +632 -0
  245. package/pkgs/shadcn-snapshot/src/tailwind-entry.css +159 -0
  246. package/pkgs/shadcn-snapshot/src/version.ts +8 -0
  247. package/plugins/claude/velloo/.claude-plugin/plugin.json +6 -0
  248. package/plugins/claude/velloo/agents/velloo-design-reviewer.md +33 -0
  249. package/plugins/claude/velloo/agents/velloo-designer.md +39 -0
  250. package/plugins/claude/velloo/commands/design.md +11 -0
  251. package/plugins/claude/velloo/commands/implement.md +10 -0
  252. package/plugins/claude/velloo/commands/review.md +8 -0
  253. package/plugins/gemini/GEMINI.md +31 -0
  254. package/plugins/gemini/commands/velloo/design.toml +10 -0
  255. package/plugins/gemini/commands/velloo/implement.toml +9 -0
  256. package/plugins/gemini/gemini-extension.json +9 -0
  257. package/skills/velloo-brand/SKILL.md +124 -0
  258. package/skills/velloo-design/SKILL.md +144 -0
  259. package/skills/velloo-design-system/SKILL.md +90 -0
  260. package/skills/velloo-implement/SKILL.md +101 -0
  261. package/skills/velloo-logo/SKILL.md +93 -0
  262. package/skills/velloo-setup/SKILL.md +156 -0
@@ -0,0 +1,93 @@
1
+ Copyright 2020 The Poppins Project Authors (https://github.com/itfoundry/Poppins)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created using
78
+ the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file
Binary file
Binary file
@@ -0,0 +1,22 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
+ <link rel="alternate icon" href="/favicon.ico" sizes="16x16 32x32 48x48" />
8
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
9
+ <link rel="manifest" href="/site.webmanifest" />
10
+ <meta name="theme-color" content="#0d0c0a" />
11
+ <title>velloo</title>
12
+ <script type="module" crossorigin src="/assets/index-BcBJ11d2.js"></script>
13
+ <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-hePW80VL.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/react-D0Ec-185.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/vendor-CKmQ-Zst.js">
16
+ <link rel="modulepreload" crossorigin href="/assets/radix-C3HaOB-d.js">
17
+ <link rel="stylesheet" crossorigin href="/assets/index-BCvDZiBo.css">
18
+ </head>
19
+ <body>
20
+ <div id="root"></div>
21
+ </body>
22
+ </html>
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "Velloo",
3
+ "short_name": "Velloo",
4
+ "icons": [
5
+ { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
6
+ { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
7
+ ],
8
+ "theme_color": "#0d0c0a",
9
+ "background_color": "#0d0c0a",
10
+ "display": "standalone"
11
+ }
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ var ANTD_VERSION="5";
3
+ export{ANTD_VERSION};
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import{RepoManifestSchema}from"./chunk-bk8b7f9a.js";import{writeJsonAtomic,localDesignsAt,localDesignOf,writeLocalDesign}from"./chunk-329e3phg.js";import{existsSync,realpathSync}from"fs";import{readdir,readFile,rm,stat,writeFile}from"fs/promises";import{homedir}from"os";import{basename,dirname,isAbsolute,join,relative,resolve,sep}from"path";var MANIFEST_FILE="velloo.json",DEFAULT_FOLDER_NAME="velloo",PROJECT_NAME=/^[a-z0-9][a-z0-9._-]*$/i,ManifestSchema=RepoManifestSchema;async function findManifest(startDir){let dir=resolve(startDir);while(!0){let path=join(dir,MANIFEST_FILE),raw=null;try{raw=await readFile(path,"utf8")}catch(err){if(err.code!=="ENOENT")throw err}if(raw!==null){let parsed;try{parsed=JSON.parse(raw)}catch(err){throw Error(`${path} is not valid JSON: ${err.message}`)}let projects=parsed?.projects;for(let[name,entry]of Object.entries(projects&&typeof projects==="object"?projects:{}))if(entry&&typeof entry==="object"&&"managed"in entry)throw Error(`${path}: project "${name}" is a managed design locator, which velloo.json no longer holds \u2014 a design outside the repository is recorded only on the machine that has it. Remove the entry, then run \`velloo folder bind <design folder>\` from this checkout.`);let result=ManifestSchema.safeParse(parsed);if(!result.success){let issues=result.error.issues.map((i)=>`${i.path.join(".")||"(root)"}: ${i.message}`).join("; ");throw Error(`${path} is not a valid velloo manifest: ${issues}`)}let folders=new Map(Object.entries(result.data.projects).map(([name,rel])=>[name,resolve(dir,rel.replace(/\\/g,"/"))]));return{path,dir,manifest:result.data,folders}}let parent=dirname(dir);if(parent===dir)return null;dir=parent}}async function findProjects(cwd){let repo=await findManifest(cwd),local=localDesignsAt(cwd);if(!repo&&local.length===0)return null;let folders=new Map(repo?.folders??[]);for(let design of local){let clash=folders.get(design.projectName);if(clash!==void 0)throw Error(`Project "${design.projectName}" names both ${clash} (in ${repo?.path??"another local design"}) and the local design ${design.designRoot}. Remove one with \`velloo folder remove\`, or rename the velloo.json entry.`);folders.set(design.projectName,design.designRoot)}return{repo,local,folders,defaultProject:repo?.manifest.defaultProject}}function pickProject(projects,cwd){let entries=[...projects.folders],appMatches=projects.local.filter((design)=>resolve(design.appRoot)!==resolve(design.root)&&isWithin(resolve(design.appRoot),cwd));if(appMatches.length===1&&appMatches[0])return appMatches[0].projectName;let containing=entries.find(([,folder])=>cwd===folder||cwd.startsWith(folder+sep));if(containing)return containing[0];let under=entries.filter(([,folder])=>folder.startsWith(cwd+sep));if(under.length===1&&under[0])return under[0][0];if(entries.length===1&&entries[0])return entries[0][0];return projects.defaultProject??null}async function projectLabel(folder){let abs=resolve(folder),local=localDesignOf(abs);if(local)return`${local.projectName} \u2014 ${abs} (local, for ${local.root})`;let found;try{found=await findManifest(abs)}catch{return null}if(!found)return null;let entry=[...found.folders].find(([,path])=>path===abs||existsSync(path)&&existsSync(abs)&&realpathSync(path)===realpathSync(abs));if(!entry)return null;let rel=relative(found.dir,abs)||".";return`${entry[0]} \u2014 ${rel} (in ${found.dir})`}async function unregisterProject(folder,appRoot){let abs=resolve(folder),found=await findManifest(appRoot);if(!found)return{name:null,path:null,removedManifest:!1};let name=null;for(let[candidate,target]of found.folders)if(target===abs||existsSync(target)&&existsSync(abs)&&realpathSync(target)===realpathSync(abs))name=candidate;if(!name)return{name:null,path:found.path,removedManifest:!1};let{[name]:_dropped,...projects}=found.manifest.projects;if(Object.keys(projects).length===0)return await rm(found.path,{force:!0}),{name,path:found.path,removedManifest:!0};let manifest={...found.manifest,projects,...found.manifest.defaultProject===name?{defaultProject:void 0}:{}};if(manifest.defaultProject===void 0)delete manifest.defaultProject;return await writeFile(found.path,`${JSON.stringify(manifest,null,2)}
3
+ `,"utf8"),{name,path:found.path,removedManifest:!1}}async function manifestDirFor(folder,appRoot){let git=await findGitRoot(appRoot);if(git)return git;let dir=resolve(appRoot);while(!isWithin(dir,folder)&&dirname(dir)!==dir)dir=dirname(dir);return dir}async function checkoutRoot(appRoot,launchRoot){let found=await findManifest(launchRoot).catch(()=>null);if(found)return found.dir;let git=await findGitRoot(appRoot);if(git)return git;return isWithin(resolve(launchRoot),resolve(appRoot))?resolve(launchRoot):resolve(appRoot)}function isWithin(parent,child){let rel=relative(parent,child);return rel===""||!rel.startsWith("..")&&!isAbsolute(rel)}async function findGitRoot(start){let home=homedir(),dir=resolve(start);while(dir!==home){try{return await stat(join(dir,".git")),dir}catch{}let parent=dirname(dir);if(parent===dir)return null;dir=parent}return null}var SCAN_SKIP=new Set(["node_modules",".git","dist","build",".next",".turbo","coverage",".velloo"]);async function discoverDesignFolders(root,maxDepth=3){let out=[],walk=async(dir,depth)=>{let entries;try{entries=await readdir(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){if(!entry.isDirectory()||entry.name.startsWith(".")||SCAN_SKIP.has(entry.name))continue;let child=join(dir,entry.name);try{await stat(join(child,".design","config.json")),out.push(child);continue}catch{}if(depth<maxDepth)await walk(child,depth+1)}};return await walk(resolve(root),1),out.sort()}function deriveName(folder){let base=basename(folder);return(base==="velloo"||base==="."?basename(dirname(folder)):base).toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/^[^a-z0-9]+/,"")||"app"}async function registerProject(folder,appRoot,requestedName){checkProjectName(requestedName);let abs=resolve(folder),found=await findManifest(abs),dir=found?found.dir:await manifestDirFor(abs,appRoot),path=found?found.path:join(dir,MANIFEST_FILE),localNames=new Set(localDesignsAt(dir).map((design)=>design.projectName)),projects={...found?.manifest.projects??{}};for(let[existing,target]of found?.folders??[])if(target===abs||existsSync(target)&&existsSync(abs)&&realpathSync(target)===realpathSync(abs))return{name:existing,path,created:!1};let add=(folder,wanted)=>{let name=wanted??deriveName(folder);for(let n=2;name in projects||localNames.has(name);n++)name=`${wanted??deriveName(folder)}-${n}`;return projects[name]=relative(dir,folder)||".",name},defaultProject=found?.manifest.defaultProject;if(!found)for(let sibling of await discoverDesignFolders(dir)){if(sibling===abs)continue;let name=add(sibling);if(sibling===join(dir,DEFAULT_FOLDER_NAME))defaultProject=name}let outsideApp=!isWithin(resolve(appRoot),abs),name=add(abs,requestedName??(outsideApp?deriveName(appRoot):void 0)),manifest={...found?.manifest??{},projects,...defaultProject?{defaultProject}:{}};return await writeJsonAtomic(path,manifest),{name,path,created:!0}}function checkProjectName(name){if(name&&!PROJECT_NAME.test(name))throw Error(`invalid --project ${JSON.stringify(name)} \u2014 names are letters/digits plus . _ -`)}async function registerLocalDesign(opts){checkProjectName(opts.requestedName);let existing=localDesignsAt(opts.root).find((design)=>design.id===opts.id),taken=new Set((await findProjects(opts.root))?.folders.keys()??[]);if(existing)taken.delete(existing.projectName);let base=opts.requestedName??existing?.projectName??deriveName(opts.appRoot);if(opts.requestedName&&taken.has(base))throw Error(`project "${base}" already exists for ${opts.root} \u2014 pick another --project.`);let name=base;for(let n=2;taken.has(name);n++)name=`${base}-${n}`;return await writeLocalDesign(opts.id,{root:opts.root,appRoot:opts.appRoot,projectName:name,...opts.designPath?{designPath:opts.designPath}:{}}),name}
4
+ export{findManifest,findProjects,pickProject,projectLabel,unregisterProject,checkoutRoot,isWithin,findGitRoot,discoverDesignFolders,registerProject,registerLocalDesign};
@@ -0,0 +1,41 @@
1
+ // @bun
2
+ import{localDesignOf}from"./chunk-329e3phg.js";import{TOOL_VERSION}from"./chunk-65wb0g7d.js";import{isCancel,multiselect,log,select}from"./chunk-8ssr8a8w.js";import{findManifest}from"./chunk-1bywxgc5.js";import{require_picocolors}from"./chunk-jrsknzjt.js";import{__toESM}from"./chunk-2smsg2ct.js";import{existsSync}from"fs";import{homedir}from"os";import{dirname,join}from"path";var claudeEntry=(conn)=>conn.transport==="http"?{type:"http",url:conn.url}:{command:conn.command,args:conn.args},cursorEntry=(conn)=>conn.transport==="http"?{url:conn.url}:{command:conn.command,args:conn.args},codexEntry=cursorEntry,continueEntry=(conn)=>conn.transport==="http"?{name:"velloo",type:"streamable-http",url:conn.url}:{name:"velloo",type:"stdio",command:conn.command,args:conn.args},droidEntry=(conn)=>conn.transport==="http"?{type:"http",url:conn.url}:{type:"stdio",command:conn.command,args:conn.args,disabled:!1},geminiEntry=(conn)=>conn.transport==="http"?{httpUrl:conn.url}:{command:conn.command,args:conn.args},opencodeEntry=(conn)=>conn.transport==="http"?{type:"remote",url:conn.url,enabled:!0}:{type:"local",command:[conn.command,...conn.args],enabled:!0},vscodeEntry=(conn)=>conn.transport==="http"?{type:"http",url:conn.url}:{type:"stdio",command:conn.command,args:conn.args};function claudeDesktopConfigPath(homeDir){if(process.platform==="win32")return join(homeDir,"AppData","Roaming","Claude","claude_desktop_config.json");if(process.platform==="darwin")return join(homeDir,"Library","Application Support","Claude","claude_desktop_config.json");return join(homeDir,".config","Claude","claude_desktop_config.json")}var AGENTS={"claude-code":{id:"claude-code",label:"Claude Code (project)",scope:"project",format:"json",family:"claude-code",path:(root)=>join(root,".mcp.json"),entry:claudeEntry},cursor:{id:"cursor",label:"Cursor (project)",scope:"project",format:"json",family:"cursor",path:(root)=>join(root,".cursor","mcp.json"),entry:cursorEntry},codex:{id:"codex",label:"Codex CLI (project)",scope:"project",format:"codex-toml",path:(root)=>join(root,".codex","config.toml"),entry:codexEntry},continue:{id:"continue",label:"Continue (project)",scope:"project",format:"continue-block",path:(root)=>join(root,".continue","mcpServers","velloo.yaml"),entry:continueEntry},"claude-code-global":{id:"claude-code-global",label:"Claude Code (global)",scope:"global",format:"json",family:"claude-code",path:(_root,home)=>join(home,".claude.json"),entry:claudeEntry},"cursor-global":{id:"cursor-global",label:"Cursor (global)",scope:"global",format:"json",family:"cursor",path:(_root,home)=>join(home,".cursor","mcp.json"),entry:cursorEntry},"codex-global":{id:"codex-global",label:"Codex CLI (global)",scope:"global",format:"codex-toml",path:(_root,home)=>join(home,".codex","config.toml"),entry:codexEntry},"continue-global":{id:"continue-global",label:"Continue (global)",scope:"global",format:"continue-config",path:(_root,home)=>join(home,".continue","config.yaml"),entry:continueEntry},"claude-desktop":{id:"claude-desktop",label:"Claude Desktop",scope:"global",format:"json",gui:!0,path:(_root,home)=>claudeDesktopConfigPath(home),entry:claudeEntry},opencode:{id:"opencode",label:"opencode (project)",scope:"project",format:"opencode-json",path:(root)=>join(root,"opencode.json"),entry:opencodeEntry},"opencode-global":{id:"opencode-global",label:"opencode (global)",scope:"global",format:"opencode-json",path:(_root,home)=>join(home,".config","opencode","opencode.json"),entry:opencodeEntry},"droid-global":{id:"droid-global",label:"Droid (global)",scope:"global",format:"json",path:(_root,home)=>join(home,".factory","mcp.json"),entry:droidEntry},"cline-global":{id:"cline-global",label:"Cline (global)",scope:"global",format:"json",path:(_root,home)=>join(home,".cline","data","settings","cline_mcp_settings.json"),entry:cursorEntry},gemini:{id:"gemini",label:"Gemini CLI (project)",scope:"project",format:"json",path:(root)=>join(root,".gemini","settings.json"),entry:geminiEntry},"gemini-global":{id:"gemini-global",label:"Gemini CLI (global)",scope:"global",format:"json",path:(_root,home)=>join(home,".gemini","settings.json"),entry:geminiEntry},"windsurf-global":{id:"windsurf-global",label:"Windsurf (global)",scope:"global",format:"json",path:(_root,home)=>join(home,".codeium","windsurf","mcp_config.json"),entry:cursorEntry},vscode:{id:"vscode",label:"VS Code / Copilot (project)",scope:"project",format:"vscode-json",path:(root)=>join(root,".vscode","mcp.json"),entry:vscodeEntry}},AGENT_IDS=Object.keys(AGENTS),PROJECT_AGENT_IDS=["claude-code","cursor"],GLOBAL_AGENT_IDS=["claude-code-global","cursor-global"];function detectInstalledAgents(homeDir=homedir()){let has=(rel)=>existsSync(join(homeDir,rel)),found=[];if(Bun.which("claude")||has(".claude.json")||has(".claude"))found.push("claude-code-global");if(Bun.which("cursor-agent")||Bun.which("cursor")||has(".cursor"))found.push("cursor-global");if(Bun.which("codex")||has(".codex"))found.push("codex-global");if(has(".continue"))found.push("continue-global");if(existsSync(dirname(claudeDesktopConfigPath(homeDir))))found.push("claude-desktop");if(Bun.which("opencode")||has(join(".config","opencode")))found.push("opencode-global");if(Bun.which("droid")||has(".factory"))found.push("droid-global");if(Bun.which("cline")||has(".cline"))found.push("cline-global");if(Bun.which("gemini")||has(join(".gemini","settings.json")))found.push("gemini-global");if(has(join(".codeium","windsurf")))found.push("windsurf-global");return found}import{existsSync as existsSync2,realpathSync}from"fs";import{access}from"fs/promises";import{dirname as dirname2,join as join2,parse,relative,resolve}from"path";async function resolveProjectRoot(designFolder,override){if(override)return override;let local=localDesignOf(designFolder);if(local)return local.root;let registered=await registeringManifest(designFolder);if(registered)return registered.found.dir;return nearestPackageRoot(designFolder)}async function designFolderReference(projectRoot,designFolder){let local=localDesignOf(designFolder);if(local)return local.projectName;let registered=await registeringManifest(designFolder);if(registered&&isUnder(registered.found.dir,resolve(projectRoot)))return registered.name;return relative(projectRoot,designFolder)||"."}async function agentRootCandidates(designFolder){if(localDesignOf(designFolder))return[];let roots=[await resolveProjectRoot(designFolder)];return roots.push(await nearestPackageRoot(designFolder)),[...new Set(roots)]}async function registeringManifest(designFolder){let abs=resolve(designFolder),found;try{found=await findManifest(abs)}catch{return null}if(!found)return null;let real=existsSync2(abs)?realpathSync(abs):abs;for(let[name,folder]of found.folders)if(folder===abs||existsSync2(folder)&&realpathSync(folder)===real)return{found,name};return null}async function nearestPackageRoot(designFolder){let fallback=dirname2(designFolder),dir=fallback,fsRoot=parse(dir).root;for(let i=0;i<8;i++){try{return await access(join2(dir,"package.json")),dir}catch{}if(dir===fsRoot)break;dir=dirname2(dir)}return fallback}function isUnder(parent,child){let rel=relative(parent,child);return rel===""||!rel.startsWith("..")&&!parse(rel).root}import{existsSync as existsSync5}from"fs";import{homedir as homedir3}from"os";import{join as join6}from"path";import{mkdir,writeFile}from"fs/promises";import{dirname as dirname3,join as join3}from"path";async function installCursorRules(projectRoot,designFolder){let designRel=await designFolderReference(projectRoot,designFolder),body=`---
3
+ description: Drive UI design through the Velloo MCP server (a local design canvas backed by this project's shadcn components).
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Velloo design
8
+
9
+ Velloo is a local, code-shaped design canvas exposed over MCP. The design folder
10
+ for this project is \`${designRel}\`.
11
+
12
+ - Cursor starts the velloo MCP server itself (wired as \`velloo mcp\`), so the
13
+ tools are available once the MCP config is loaded \u2014 nothing to start first. If
14
+ they're missing, ask the user to run \`velloo connect ${designRel}\` and
15
+ restart Cursor. To watch the canvas, the user runs \`velloo run ${designRel}\`
16
+ (stays in the foreground; \`b\` background, \`s\` stop, \`o\` open). If you start
17
+ it yourself, pass \`--background\` so you aren't stuck in that session. It
18
+ prints the canvas URL (defaults to \`:7300\`, or a free port if that's taken,
19
+ so don't assume 7300). When a canvas is already up, the server's
20
+ \`initialize\` instructions hand you its live URL.
21
+ - You are the designer: compose screens from the project's shadcn components via
22
+ the velloo MCP tools, verify visually with \`screenshot\`, then \`emit_code\` to
23
+ turn a design into real code in this project's conventions.
24
+ - Read the server's \`initialize\` instructions \u2014 they are the authoritative tool
25
+ reference; this rule is just the pointer.
26
+ - Designs are static on the canvas (no handlers, routing, or data fetching);
27
+ write those when you implement.
28
+ `,dest=join3(projectRoot,".cursor","rules","velloo.mdc");return await mkdir(dirname3(dest),{recursive:!0}),await writeFile(dest,body,"utf8"),{installed:!0,path:dest}}import{existsSync as existsSync4}from"fs";import{cp as cp2,mkdir as mkdir3,readFile,rm,writeFile as writeFile2}from"fs/promises";import{homedir as homedir2}from"os";import{dirname as dirname5,join as join5}from"path";import{fileURLToPath as fileURLToPath2}from"url";import{existsSync as existsSync3}from"fs";import{access as access2,cp,mkdir as mkdir2,readdir}from"fs/promises";import{dirname as dirname4,join as join4}from"path";import{fileURLToPath}from"url";var here=dirname4(fileURLToPath(import.meta.url));function resolveSkillsRoot(){let dev=join4(here,"..","..","..","..","skills");return[process.env.VELLOO_SKILLS_SRC,join4(here,"skills"),dev].filter((p)=>Boolean(p)).find((p)=>existsSync3(p))??dev}var SKILLS_ROOT=resolveSkillsRoot();async function installSkills(projectRoot,baseDir=".agents"){let entries;try{entries=await readdir(SKILLS_ROOT,{withFileTypes:!0})}catch{return[]}let results=[];for(let entry of entries){if(!entry.isDirectory())continue;let name=entry.name,srcDir=join4(SKILLS_ROOT,name);try{await access2(join4(srcDir,"SKILL.md"))}catch{continue}let destDir=join4(projectRoot,baseDir,"skills",name);await mkdir2(dirname4(destDir),{recursive:!0}),await cp(srcDir,destDir,{recursive:!0}),results.push({name,installed:!0,path:join4(destDir,"SKILL.md")})}return results}var here2=dirname5(fileURLToPath2(import.meta.url));function resolvePluginsRoot(){let dev=join5(here2,"..","..","..","..","plugins");return[process.env.VELLOO_PLUGINS_SRC,join5(here2,"plugins"),dev].filter((p)=>Boolean(p)).find((p)=>existsSync4(p))??dev}var PLUGINS_ROOT=resolvePluginsRoot(),bareVersion=()=>TOOL_VERSION.split(" ")[0]??"0.0.0";async function patchVersion(manifestPath){let manifest=JSON.parse(await readFile(manifestPath,"utf8"));return manifest.version=bareVersion(),await writeFile2(manifestPath,`${JSON.stringify(manifest,null,2)}
29
+ `),bareVersion()}async function installClaudePlugin(homeDir=homedir2()){let src=join5(PLUGINS_ROOT,"claude","velloo");if(!existsSync4(src))return null;let marketplaceDir=join5(homeDir,".velloo","claude-plugins"),pluginDir=join5(marketplaceDir,"plugins","velloo");if(await rm(pluginDir,{recursive:!0,force:!0}),await mkdir3(join5(marketplaceDir,".claude-plugin"),{recursive:!0}),await cp2(src,pluginDir,{recursive:!0}),existsSync4(SKILLS_ROOT))await cp2(SKILLS_ROOT,join5(pluginDir,"skills"),{recursive:!0});let version=await patchVersion(join5(pluginDir,".claude-plugin","plugin.json"));await writeFile2(join5(marketplaceDir,".claude-plugin","marketplace.json"),`${JSON.stringify({name:"velloo",owner:{name:"Velloo",url:"https://velloo.design"},plugins:[{name:"velloo",source:"./plugins/velloo",description:"Design and implement UI on the Velloo canvas \u2014 skills, slash commands, and subagents.",version}]},null,2)}
30
+ `);let settingsPath=join5(homeDir,".claude","settings.json"),settings={};try{settings=JSON.parse(await readFile(settingsPath,"utf8"))}catch(err){if(err.code!=="ENOENT")throw Error(`${settingsPath} exists but isn't valid JSON \u2014 fix or remove it, then re-run connect.`)}let marketplaces=settings.extraKnownMarketplaces&&typeof settings.extraKnownMarketplaces==="object"?settings.extraKnownMarketplaces:{},enabled=settings.enabledPlugins&&typeof settings.enabledPlugins==="object"?settings.enabledPlugins:{},merged={...settings,extraKnownMarketplaces:{...marketplaces,velloo:{source:{source:"directory",path:marketplaceDir}}},enabledPlugins:{...enabled,"velloo@velloo":!0}};return await mkdir3(dirname5(settingsPath),{recursive:!0}),await writeFile2(settingsPath,`${JSON.stringify(merged,null,2)}
31
+ `),{marketplaceDir,settingsPath,version}}async function installGeminiExtension(homeDir=homedir2()){let src=join5(PLUGINS_ROOT,"gemini");if(!existsSync4(src))return null;let dir=join5(homeDir,".velloo","gemini-extension");if(await rm(dir,{recursive:!0,force:!0}),await cp2(src,dir,{recursive:!0}),existsSync4(SKILLS_ROOT))await cp2(SKILLS_ROOT,join5(dir,"skills"),{recursive:!0});await patchVersion(join5(dir,"gemini-extension.json"));let linked=!1;if(homeDir===homedir2()&&Bun.which("gemini"))try{let proc=Bun.spawn(["gemini","extensions","link",dir],{stdin:"ignore",stdout:"ignore",stderr:"ignore"}),timeout=setTimeout(()=>proc.kill(),15000);linked=await proc.exited===0,clearTimeout(timeout)}catch{linked=!1}return{dir,linked}}async function refreshAgentArtifacts(opts){let homeDir=opts.homeDir??homedir3(),refreshed=[];if(existsSync5(join6(homeDir,".velloo","claude-plugins","plugins","velloo"))){let plugin=await installClaudePlugin(homeDir);if(plugin)refreshed.push(`claude plugin (${plugin.marketplaceDir})`)}for(let projectRoot of opts.projectRoots){let skillsDir=join6(projectRoot,".agents","skills");if(existsSync5(skillsDir)){let skills=await installSkills(projectRoot);if(skills.length>0)refreshed.push(`${skills.length} skills (${skillsDir})`)}}if(existsSync5(join6(homeDir,".velloo","gemini-extension"))){let ext=await installGeminiExtension(homeDir);if(ext)refreshed.push(`gemini extension (${ext.dir})`)}for(let projectRoot of opts.projectRoots){let cursorRule=join6(projectRoot,".cursor","rules","velloo.mdc");if(existsSync5(cursorRule)){let rules=await installCursorRules(projectRoot,opts.designFolder);if(rules.installed&&rules.path)refreshed.push(`cursor rule (${rules.path})`)}}return{refreshed}}import{readFile as readFile3}from"fs/promises";import{homedir as homedir4}from"os";import{resolve as resolve2}from"path";var import_picocolors=__toESM(require_picocolors(),1);import{mkdir as mkdir4,readFile as readFile2,writeFile as writeFile3}from"fs/promises";import{dirname as dirname6}from"path";async function writeAgentConfig(projectRoot,agent,conn,homeDir){let path=agent.path(projectRoot,homeDir),entry=agent.entry(conn),existing=null;try{existing=await readFile2(path,"utf8")}catch(err){if(err.code!=="ENOENT")throw err}let content;switch(agent.format){case"json":content=mergeJson(existing,entry,path);break;case"codex-toml":content=mergeCodexToml(existing,entry,path);break;case"continue-block":content=continueBlockFile(entry);break;case"continue-config":content=mergeContinueConfig(existing,entry,path);break;case"opencode-json":content=mergeOpencodeJson(existing,entry,path);break;case"vscode-json":content=mergeVscodeJson(existing,entry,path);break}return await mkdir4(dirname6(path),{recursive:!0}),await writeFile3(path,content,"utf8"),{agent:agent.id,path,action:existing===null?"created":"updated"}}function invalidConfig(path,format,err){let msg=err instanceof Error?err.message:String(err);return Error(`${path} exists but isn't valid ${format} (${msg}) \u2014 fix or remove it, then re-run connect.`)}function mergeJson(existing,entry,path){let parsed={};if(existing!==null)try{parsed=JSON.parse(existing)}catch(err){throw invalidConfig(path,"JSON",err)}let servers=parsed.mcpServers&&typeof parsed.mcpServers==="object"?parsed.mcpServers:{},merged={...parsed,mcpServers:{...servers,velloo:entry}};return`${JSON.stringify(merged,null,2)}
32
+ `}function mergeOpencodeJson(existing,entry,path){let parsed={$schema:"https://opencode.ai/config.json"};if(existing!==null)try{parsed=JSON.parse(existing)}catch(err){throw invalidConfig(path,"JSON",err)}let mcp=parsed.mcp&&typeof parsed.mcp==="object"?parsed.mcp:{},merged={...parsed,mcp:{...mcp,velloo:entry}};return`${JSON.stringify(merged,null,2)}
33
+ `}function mergeVscodeJson(existing,entry,path){let parsed={};if(existing!==null)try{parsed=JSON.parse(existing)}catch(err){throw invalidConfig(path,"JSON",err)}let servers=parsed.servers&&typeof parsed.servers==="object"?parsed.servers:{},merged={...parsed,servers:{...servers,velloo:entry}};return`${JSON.stringify(merged,null,2)}
34
+ `}function tomlValue(v){if(typeof v==="string")return JSON.stringify(v);if(Array.isArray(v))return`[${v.map(tomlValue).join(", ")}]`;return String(v)}var VELLOO_TABLE=/^\s*\[\s*mcp_servers\s*\.\s*(?:"velloo"|velloo)\s*(?:\]|\.)/,ANY_TABLE=/^\s*\[/;function mergeCodexToml(existing,entry,path){if(existing!==null&&existing.trim()!=="")try{Bun.TOML.parse(existing)}catch(err){throw invalidConfig(path,"TOML",err)}let lines=existing===null?[]:existing.split(`
35
+ `);while(lines.length>0&&lines[lines.length-1]?.trim()==="")lines.pop();let keep=[],insertAt=-1,i=0;while(i<lines.length){let line=lines[i];if(VELLOO_TABLE.test(line)){if(insertAt===-1)insertAt=keep.length;i++;while(i<lines.length&&!ANY_TABLE.test(lines[i]))i++;continue}keep.push(line),i++}let block=["[mcp_servers.velloo]",...Object.entries(entry).map(([k,v])=>`${k} = ${tomlValue(v)}`)];if(insertAt===-1){if(keep.length>0&&keep[keep.length-1]?.trim()!=="")keep.push("");keep.push(...block)}else keep.splice(insertAt,0,...block);let content=`${keep.join(`
36
+ `)}
37
+ `;return Bun.TOML.parse(content),content}function toYaml(value){let yaml=Bun.YAML.stringify(value,null,2).replace(/[ \t]+$/gm,"");return yaml.endsWith(`
38
+ `)?yaml:`${yaml}
39
+ `}function continueBlockFile(entry){let version=TOOL_VERSION.split(" ")[0]??"0.0.0";return toYaml({name:"velloo",version,schema:"v1",mcpServers:[entry]})}function mergeContinueConfig(existing,entry,path){let doc={name:"Local Assistant",version:"1.0.0",schema:"v1"};if(existing!==null&&existing.trim()!==""){let parsed;try{parsed=Bun.YAML.parse(existing)}catch(err){throw invalidConfig(path,"YAML",err)}if(parsed===null||typeof parsed!=="object"||Array.isArray(parsed))throw invalidConfig(path,"YAML",Error("expected a top-level mapping"));doc=parsed}let others=(Array.isArray(doc.mcpServers)?doc.mcpServers:[]).filter((s)=>!(s!==null&&typeof s==="object"&&s.name==="velloo"));return toYaml({...doc,mcpServers:[...others,entry]})}var DEFAULT_MCP_URL="http://127.0.0.1:7301/mcp",MANUAL_AGENT_ID="manual";function manualSetupText(){return["velloo speaks MCP over stdio (recommended) or HTTP \u2014 any MCP-capable agent can connect.","","stdio \u2014 the agent spawns the server itself:",' command: "velloo" args: ["mcp"]',` (resolves the design folder from the agent's cwd; pin one with ["mcp", "path/to/velloo"])`,""," Most agents take the JSON convention:",' { "mcpServers": { "velloo": { "command": "velloo", "args": ["mcp"] } } }',"","HTTP \u2014 for agents that dial a URL: start `velloo mcp --http <folder>` (it prints the",`MCP URL, default ${DEFAULT_MCP_URL}), then point the agent at it:`,` { "mcpServers": { "velloo": { "type": "http", "url": "${DEFAULT_MCP_URL}" } } }`].join(`
40
+ `)}function baseLabel(id){return(AGENTS[id]?.label??id).replace(/\s*\((?:project|global)\)$/,"")}function projectVariantOf(id){let agent=AGENTS[id];if(!agent)return;if(agent.scope==="project")return id;let candidate=id.replace(/-global$/,"");return candidate!==id&&AGENTS[candidate]?candidate:void 0}async function askAgentWiring(opts){let preWired=await globallyWiredAgents(),projectWired=opts?.projectRoot&&!opts.globalOnly?await projectWiredAgents(opts.projectRoot):[],detected=detectInstalledAgents(),fallback=detected.length===0,wanted=fallback?GLOBAL_AGENT_IDS:detected,missing=wanted.filter((id)=>!preWired.includes(id));if(projectWired.length>0)log.info(`Already wired for this project: ${projectWired.map(baseLabel).join(", ")} ${import_picocolors.default.dim("(re-wiring is a no-op merge)")}`);if(preWired.length>0){let labels=preWired.map(baseLabel).join(", ");if(opts?.skipWhenCovered&&missing.length===0)return log.success(`velloo is already wired globally \u2014 ${labels} ${import_picocolors.default.dim("(covers this project; skipping agent setup)")}`),{agents:[],manual:!1,preWired};log.info(`Already wired globally: ${labels} ${import_picocolors.default.dim("(covers this project)")}`)}log.info(fallback?`No coding agents detected on this machine \u2014 offering the defaults (${wanted.map(baseLabel).join(", ")}).`:`Coding agents detected: ${detected.map(baseLabel).join(", ")}`);let targets=missing.length>0?missing:wanted,names=targets.map(baseLabel).join(", "),projectTargets=opts?.globalOnly?[]:targets.map(projectVariantOf).filter((id)=>Boolean(id));if(opts?.globalOnly)log.info(import_picocolors.default.dim("This design lives outside the repository, so only global agent configs are offered \u2014 nothing is written into the checkout."));let mode=await select({message:"Wire the velloo MCP into your coding agents?",options:[{value:"global",label:`Install globally \u2014 ${names}`,hint:"recommended \u2014 one config covers every project"},...projectTargets.length>0?[{value:"project",label:"Install for this project only",hint:projectTargets.map(baseLabel).join(", ")}]:[],{value:"choose",label:"Let me pick agents",hint:"the full list"},{value:"manual",label:"Manual MCP setup instructions",hint:"prints the config to paste into any agent"},{value:"skip",label:"Don't install now",hint:"wire later with `velloo connect`"}],initialValue:"global"});if(isCancel(mode))return null;if(mode==="skip")return{agents:[],manual:!1,preWired};if(mode==="manual")return{agents:[],manual:!0,preWired};if(mode==="global")return{agents:targets,manual:!1,preWired};if(mode==="project")return{agents:projectTargets,manual:!1,preWired};let picked=await pickAgents({exclude:[...opts?.skipWhenCovered?preWired:[],...opts?.globalOnly?Object.values(AGENTS).filter((agent)=>agent.scope==="project").map((agent)=>agent.id):[]],initial:[...new Set([...targets,...preWired,...projectWired])],wired:[...new Set([...preWired,...projectWired])]});if(picked===null)return null;return{agents:picked.filter((id)=>id!==MANUAL_AGENT_ID),manual:picked.includes(MANUAL_AGENT_ID),preWired}}async function pickAgents(opts){let exclude=new Set(opts?.exclude??[]),wired=new Set(opts?.wired??[]),agents=Object.values(AGENTS).filter((a)=>!exclude.has(a.id)).sort((a,b)=>a.scope===b.scope?0:a.scope==="global"?-1:1),detected=detectInstalledAgents(),initial=(opts?.initial??(detected.length>0?detected:GLOBAL_AGENT_IDS)).filter((id)=>!exclude.has(id)),picked=await multiselect({message:"Wire the velloo MCP into which agents?",options:[...agents.map((a)=>({value:a.id,label:a.label,hint:wired.has(a.id)?`already wired \u2014 ${a.path(".","~")}`:a.path(".","~")})),{value:MANUAL_AGENT_ID,label:"Manual / other agent",hint:"prints the MCP config to paste anywhere"}],initialValues:initial,required:!1});return isCancel(picked)?null:picked}function hasVellooEntry(content,format){try{switch(format){case"json":{let parsed=JSON.parse(content);return Boolean(parsed.mcpServers&&"velloo"in parsed.mcpServers)}case"codex-toml":return/^\s*\[\s*mcp_servers\s*\.\s*(?:"velloo"|velloo)\s*(?:\]|\.)/m.test(content);case"continue-block":return!0;case"continue-config":{let doc=Bun.YAML.parse(content);return Array.isArray(doc?.mcpServers)&&doc.mcpServers.some((s)=>s!==null&&typeof s==="object"&&s.name==="velloo")}case"opencode-json":{let parsed=JSON.parse(content);return Boolean(parsed.mcp&&"velloo"in parsed.mcp)}case"vscode-json":{let parsed=JSON.parse(content);return Boolean(parsed.servers&&"velloo"in parsed.servers)}}}catch{return!1}}async function projectWiredAgents(projectRoot){let out=[];for(let agent of Object.values(AGENTS)){if(agent.scope!=="project")continue;let content;try{content=await readFile3(agent.path(projectRoot,homedir4()),"utf8")}catch{continue}if(hasVellooEntry(content,agent.format))out.push(agent.id)}return out}async function globallyWiredAgents(homeDir=homedir4()){let out=[];for(let agent of Object.values(AGENTS)){if(agent.scope!=="global")continue;let content;try{content=await readFile3(agent.path(".",homeDir),"utf8")}catch{continue}if(hasVellooEntry(content,agent.format))out.push(agent.id)}return out}function localDesignScopeProblem(folder,agents){if(!localDesignOf(folder))return null;let refused=agents.filter((id)=>AGENTS[id]?.scope==="project");if(refused.length===0)return null;let globals=refused.map((id)=>`${id}-global`).filter((id)=>AGENTS[id]).join(", ");return`${refused.join(", ")} ${refused.length===1?"writes":"write"} into the checkout, and ${folder} is a local design outside it \u2014 only global configs are allowed${globals?` (use ${globals})`:""}.`}async function connect(opts){let transport=opts.transport??"stdio",homeDir=opts.homeDir??homedir4(),projectRoot=await resolveProjectRoot(opts.designFolder,opts.projectRoot),local=localDesignOf(opts.designFolder)!==null,designRel=await designFolderReference(projectRoot,opts.designFolder),connectionFor=(agent)=>{if(transport==="http")return{transport:"http",url:opts.mcpUrl??DEFAULT_MCP_URL};if(agent.gui){let script=process.argv[1]?resolve2(process.argv[1]):Bun.which("velloo");return script?{transport:"stdio",command:process.execPath,args:[script,"mcp",resolve2(opts.designFolder)]}:{transport:"stdio",command:"velloo",args:["mcp",resolve2(opts.designFolder)]}}return{transport:"stdio",command:"velloo",args:agent.scope==="project"?["mcp",designRel]:["mcp"]}},configs=[],unknownAgents=[],projectScoped=[];for(let id of opts.agents){let agent=AGENTS[id];if(!agent){unknownAgents.push(id);continue}if(local&&agent.scope==="project"){projectScoped.push(id);continue}configs.push(await writeAgentConfig(projectRoot,agent,connectionFor(agent),homeDir))}let hasFamily=(family)=>opts.agents.some((id)=>AGENTS[id]?.family===family),hasAny=(...ids)=>opts.agents.some((id)=>ids.includes(id)),plugin=opts.installSkill&&hasFamily("claude-code")?await installClaudePlugin(homeDir)??void 0:void 0,skills=opts.installSkill&&!local&&hasAny("opencode","opencode-global","droid-global","cline-global","gemini","gemini-global","codex","codex-global")?await installSkills(projectRoot):void 0,geminiExtension=opts.installSkill&&hasAny("gemini","gemini-global")?await installGeminiExtension(homeDir)??void 0:void 0,cursorRules=opts.installSkill&&!local&&hasFamily("cursor")?await installCursorRules(projectRoot,opts.designFolder):void 0;return{projectRoot,transport,configs,skills,plugin,geminiExtension,cursorRules,unknownAgents,projectScoped}}
41
+ export{AGENT_IDS,PROJECT_AGENT_IDS,GLOBAL_AGENT_IDS,resolveProjectRoot,agentRootCandidates,refreshAgentArtifacts,DEFAULT_MCP_URL,MANUAL_AGENT_ID,manualSetupText,askAgentWiring,globallyWiredAgents,localDesignScopeProblem,connect};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./chunk-65wb0g7d.js";import{refreshUpdateCache}from"./chunk-cep3ktr3.js";import{defineCommand}from"./chunk-2smsg2ct.js";var update_check_default=defineCommand({meta:{name:"__update_check",description:"Internal release check"},async run(){await refreshUpdateCache()}});export{update_check_default as default};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ import{failWithError}from"./chunk-s23gtejf.js";import{traceEnabled}from"./chunk-6tx68d90.js";var LOADERS={init:()=>import("./chunk-qwv7xkms.js").then((m)=>m.default),login:()=>import("./chunk-7p7ha0qk.js").then((m)=>m.default),logout:()=>import("./chunk-74skmg76.js").then((m)=>m.default),connect:()=>import("./chunk-erwfk47h.js").then((m)=>m.default),run:()=>import("./chunk-nsqs1bqf.js").then((m)=>m.default),folder:()=>import("./chunk-qpvj6kzq.js").then((m)=>m.default),mcp:()=>import("./chunk-5x173xay.js").then((m)=>m.default),stop:()=>import("./chunk-75wbh438.js").then((m)=>m.default),status:()=>import("./chunk-zf3xc1wz.js").then((m)=>m.default),__daemon:()=>import("./chunk-n5007jcz.js").then((m)=>m.default),__update_check:()=>import("./chunk-1y50g9vp.js").then((m)=>m.default),render:()=>import("./chunk-582y60bv.js").then((m)=>m.default),capture:()=>import("./chunk-aapybh30.js").then((m)=>m.default),browser:()=>import("./chunk-dt03awr1.js").then((m)=>m.default),export:()=>import("./chunk-bjnhhsak.js").then((m)=>m.default),upgrade:()=>import("./chunk-tmtzxcs5.js").then((m)=>m.default),publish:()=>import("./chunk-2mv65qxs.js").then((m)=>m.default),emit:()=>import("./chunk-40657ggd.js").then((m)=>m.default),"theme:export":()=>import("./chunk-nfr3q7mg.js").then((m)=>m.default),completions:()=>import("./chunk-h0c36khx.js").then((m)=>m.default),...traceEnabled()?{trace:()=>import("./chunk-e2ag33vd.js").then((m)=>m.default)}:{}};function guarded(name,load){return async()=>{let cmd=await load(),run=cmd.run;if(!run)return cmd;return{...cmd,async run(ctx){try{await run(ctx)}catch(err){failWithError(name,err)}}}}}var COMMANDS=Object.fromEntries(Object.entries(LOADERS).map(([name,load])=>[name,guarded(name,load)]));
3
+ export{COMMANDS};
@@ -0,0 +1,5 @@
1
+ // @bun
2
+ import{isCancel,confirm,password,select,FOLDER_ARG_DESCRIPTION,resolveDesignFolder,pickBoards}from"./chunk-8ssr8a8w.js";import{PRICING_URL,protectedSharesAllowed,PROTECTED_SHARES_UNAVAILABLE,describeCloudError}from"./chunk-mq4znqv2.js";import"./chunk-bk8b7f9a.js";import{closePooledBrowser}from"./chunk-w5rzk6ms.js";import{loadDesignFolder,screensForBoards,resolveProviders,findHostTailwindConfig,TailwindJit,extraThemeBlock}from"./chunk-329e3phg.js";import{loadCredential}from"./chunk-b7j86xq7.js";import{fail}from"./chunk-s23gtejf.js";import{confirmRenderFailures}from"./chunk-g02nd9hn.js";import{publishedDesignSubtitle,listPublishedDesigns,unpublishDesign,listPublishDestinations,designGitEnv,describePublishError,recommendedPublishSlot,exactPublishSlots,gitContext,resolveTeam,publishDesign,createPublishBundler}from"./chunk-946pcnt5.js";import{createProgress}from"./chunk-79ykzywe.js";import{fetchAccount}from"./chunk-fgw3hp2v.js";import"./chunk-1bywxgc5.js";import{defaultCloudUrl,publishedBoardsUrl,billingPageUrl,checkCloudHealth}from"./chunk-2z0k59hz.js";import{defineCommand}from"./chunk-2smsg2ct.js";import{join as join2}from"path";import{execFileSync}from"child_process";import{realpathSync}from"fs";import{join,relative,resolve}from"path";function plainJsonStem(path,dir){let prefix=`${dir}/`;if(!path.startsWith(prefix)||!path.endsWith(".json"))return null;let stem=path.slice(prefix.length,-5);if(stem.includes("/")||stem.includes("."))return null;return stem}function classifyChanges(changes){let set={screens:new Map,global:!1,snippets:new Set,assets:new Set};for(let{status,path}of changes){let screen=plainJsonStem(path,"screens");if(screen){set.screens.set(screen,status);continue}if(path.startsWith("theme/")||path===".design/config.json"){set.global=!0;continue}let snippet=plainJsonStem(path,"snippets");if(snippet){set.snippets.add(snippet);continue}if(path.startsWith("assets/"))set.assets.add(`/${path}`)}return set}function snippetIdsIn(value,acc){if(Array.isArray(value)){for(let v of value)snippetIdsIn(v,acc);return}if(value!==null&&typeof value==="object"){let id=value.$snippet;if(typeof id==="string")acc.add(id);for(let v of Object.values(value))snippetIdsIn(v,acc)}}function snippetsUsedByScreen(screen,snippets){let used=new Set;snippetIdsIn(screen.tree,used);let grew=!0;while(grew){grew=!1;for(let id of[...used]){let body=snippets.get(id);if(!body)continue;let inner=new Set;snippetIdsIn(body,inner);for(let innerId of inner)if(!used.has(innerId))used.add(innerId),grew=!0}}return used}function detectChangedScreens(changes,afterScreens,afterSnippets){let out=new Map;for(let[id,status]of changes.screens)out.set(id,{id,status:status==="A"?"added":status==="D"?"deleted":"modified",reasons:["screen"]});let markModified=(id,reason)=>{let existing=out.get(id);if(existing){if(!existing.reasons.includes(reason))existing.reasons.push(reason);return}out.set(id,{id,status:"modified",reasons:[reason]})};if(changes.global||changes.snippets.size>0||changes.assets.size>0)for(let[id,screen]of afterScreens){if(changes.global)markModified(id,"theme");if(changes.snippets.size===0&&changes.assets.size===0)continue;let used=snippetsUsedByScreen(screen,afterSnippets);for(let snippetId of changes.snippets)if(used.has(snippetId))markModified(id,`snippet:${snippetId}`);if(changes.assets.size>0){let haystack=JSON.stringify(screen);for(let snippetId of used){let body=afterSnippets.get(snippetId);if(body)haystack+=JSON.stringify(body)}for(let asset of changes.assets)if(haystack.includes(asset))markModified(id,`asset:${asset}`)}}return[...out.values()].sort((a,b)=>a.id.localeCompare(b.id))}function git(repo,args){return execFileSync("git",["-C",repo,...args],{encoding:"utf8",maxBuffer:67108864,stdio:["ignore","pipe","pipe"]})}function resolveGitContext(designFolder,base,head){let repoRoot;try{repoRoot=execFileSync("git",["-C",designFolder,"rev-parse","--show-toplevel"],{encoding:"utf8",stdio:["ignore","pipe","pipe"],env:designGitEnv(designFolder)}).trim()}catch{throw Error(`design folder ${designFolder} is not in a git repository, so there are no refs to compare`)}let designRel=relative(realpathSync(repoRoot),realpathSync(resolve(designFolder)));if(designRel.startsWith(".."))throw Error(`design folder ${designFolder} is outside the git repo at ${repoRoot}`);let rev=(ref)=>{try{return git(repoRoot,["rev-parse","--verify",`${ref}^{commit}`]).trim()}catch{throw Error(`cannot resolve git ref '${ref}'`)}},baseSha=rev(base),headSha=rev(head),currentSha=rev("HEAD");return{repoRoot,designRel,baseSha,headSha,headIsWorktree:headSha===currentSha}}function diffDesignFolder(ctx){let args=["diff","--name-status","--no-renames",ctx.baseSha];if(!ctx.headIsWorktree)args.push(ctx.headSha);if(ctx.designRel!=="")args.push("--",ctx.designRel);let output=git(ctx.repoRoot,args),prefix=ctx.designRel===""?"":`${ctx.designRel}/`,out=[];for(let line of output.split(`
3
+ `)){if(line.trim()==="")continue;let tab=line.indexOf("\t");if(tab===-1)continue;let code=line.slice(0,tab).trim(),repoPath=line.slice(tab+1);if(!repoPath.startsWith(prefix))continue;let status=code==="A"?"A":code==="D"?"D":code==="M"||code==="T"?"M":null;if(!status)continue;out.push({status,path:repoPath.slice(prefix.length)})}return out}function changedBoardId(path){if(!path.startsWith("boards/")||!path.endsWith(".json"))return null;let id=path.slice(7,-5);return id.includes("/")||id.includes(".")?null:id}function selectChangedPreviews(changes,screens,snippets,boards){let availableScreens=new Map(screens.map((screen)=>[screen.id,screen])),screenIds=new Set(detectChangedScreens(classifyChanges(changes),availableScreens,snippets).filter((change)=>change.status!=="deleted"&&availableScreens.has(change.id)).map((change)=>change.id)),directlyChangedBoards=new Set(changes.map((change)=>changedBoardId(change.path)).filter((id)=>id!==null)),boardIds=new Set(boards.filter((board)=>directlyChangedBoards.has(board.id)||board.frames.some((frame)=>screenIds.has(frame.screen))).map((board)=>board.id));return{screenIds,boardIds}}function changedPreviewsSince(designFolder,baseRef,screens,snippets,boards){let git=resolveGitContext(designFolder,baseRef,"HEAD");return selectChangedPreviews(diffDesignFolder(git),screens,snippets,boards)}async function resolveCloud(command,args){let baseUrl=args.url?args.url.replace(/\/+$/,""):defaultCloudUrl(),token=args.token??process.env.VELLOO_CLOUD_TOKEN??(await loadCredential(baseUrl))?.token;if(!token)fail(command,"not logged in. Run `velloo login` first.");return{baseUrl,token}}function cloudFailure(command,error){fail(command,describeCloudError(error))}async function listPublished(args){let{baseUrl,token}=await resolveCloud("publish",args),listed=await listPublishedDesigns({baseUrl,token});if(!listed.ok)cloudFailure("publish",listed.error);let designs=listed.value;if(designs.length===0){console.log("velloo publish: no published designs."),console.log(` ${await publishedBoardsUrl(baseUrl)}`);return}console.log(`velloo publish: ${designs.length} design${designs.length===1?"":"s"}`);for(let design of designs){let access=design.passwordProtected?"password protected":design.visibility==="private"?"private":"public";console.log(`
4
+ ${design.title?.trim()||"Untitled design"}`),console.log(` ${access}`),console.log(` ${publishedDesignSubtitle(design)}`),console.log(` ${design.url}`)}console.log(`
5
+ Manage in velloo-cloud: ${await publishedBoardsUrl(baseUrl)}`)}async function removePublished(args){let{baseUrl,token}=await resolveCloud("publish",args),interactive=Boolean(process.stdin.isTTY);if(!interactive&&!args.design)fail("publish","pass the full share URL and --yes when there is no interactive terminal");if(!interactive&&args.yes!==!0)fail("publish","refusing to remove a published design without --yes");let listed=await listPublishedDesigns({baseUrl,token});if(!listed.ok)cloudFailure("publish",listed.error);let designs=listed.value,manageable=designs.filter((design)=>design.canManage);if(manageable.length===0)fail("publish",`there are no published designs you can remove. Manage boards at ${await publishedBoardsUrl(baseUrl)}`);let target;if(args.design){if(target=designFromReference(args.design,designs),!target)fail("publish",`that share URL is not in your published designs. Manage boards at ${await publishedBoardsUrl(baseUrl)}`);if(!target.canManage)fail("publish","you do not have permission to remove that design")}else{let value=await select({message:"Design to unpublish",options:manageable.map((design)=>({value:design.slug,label:design.title?.trim()||"Untitled design",hint:publishedDesignSubtitle(design)}))});if(target=resolveUnpublishSelection(isCancel(value)?null:String(value),manageable),!target)fail("publish","cancelled")}if(args.yes!==!0){let approved=await confirm({message:`Unpublish \u201C${target.title?.trim()||"Untitled design"}\u201D? Its share URL will stop working.`,initialValue:!1});if(isCancel(approved)||!approved)fail("publish","cancelled")}let removed=await unpublishDesign({baseUrl,token,slug:target.slug});if(!removed.ok)cloudFailure("publish",removed.error);console.log(`velloo publish: removed ${target.title?.trim()||"Untitled design"}`),console.log(` ${target.url}`)}function resolveUnpublishSelection(value,designs){return value===null?null:designs.find((design)=>design.slug===value)??null}function designFromReference(reference,designs){if(!/^https?:\/\//i.test(reference.trim()))return null;let normalize=(raw)=>{try{let url=new URL(raw.trim());return url.search="",url.hash="",url.toString().replace(/\/+$/,"")}catch{return null}},normalized=normalize(reference);if(normalized===null)return null;return designs.find((design)=>normalize(design.url)===normalized)??null}function privacyFlagsError(args,protectedShares=!0,upgradeUrl=PRICING_URL){if(args.visibility!==void 0&&args.visibility!=="public"&&args.visibility!=="private")return`--visibility must be 'public' or 'private', got '${args.visibility}'`;if(args.private&&args.public)return"--private and --public cannot be used together";if(args.private&&args.visibility==="public")return"--private conflicts with --visibility public";if(args.public&&args.visibility==="private")return"--public conflicts with --visibility private";if((args.private===!0||args.visibility==="private"||args.password===!0)&&!protectedShares)return`${PROTECTED_SHARES_UNAVAILABLE}. Publish with --public, or upgrade at ${upgradeUrl}`;return null}async function resolvePublishPrivacy(args,interactive,{protectedShares=!0,upgradeUrl=PRICING_URL,choose=promptForPrivacyMode}={}){let invalid=privacyFlagsError(args,protectedShares,upgradeUrl);if(invalid)throw Error(invalid);if(args.visibility!==void 0||args.private===!0||args.public===!0||args.password===!0)return{visibility:args.private||args.visibility==="private"?"private":"public",password:args.password===!0};if(!interactive)throw Error("privacy mode is required without a terminal; pass --public, --private, --password, or --visibility");let mode=await choose(protectedShares,upgradeUrl);if(typeof mode==="symbol")throw Error("cancelled");if(mode!=="public"&&!protectedShares)throw Error(PROTECTED_SHARES_UNAVAILABLE);return mode==="private"?{visibility:"private",password:!1}:{visibility:"public",password:mode==="password"}}async function promptForPrivacyMode(protectedShares,upgradeUrl){let locked=protectedShares?{}:{disabled:!0,hint:"Team & Business plans"};return select({message:protectedShares?"Who should be able to view this publish?":`Who should be able to view this publish? (free plan: public links \u2014 upgrade at ${upgradeUrl})`,initialValue:"public",options:[{value:"public",label:"Public",hint:"anyone with the link"},{value:"private",label:"Private",hint:"only your organization",...locked},{value:"password",label:"Password protected",hint:"anyone with the password",...locked}]})}var publish_default=defineCommand({meta:{name:"publish",description:"Publish the design folder as a velloo-cloud share link (the cloud renders it). --list shows what you've published; --remove takes one down"},args:{folder:{type:"positional",required:!1,description:`${FOLDER_ARG_DESCRIPTION}. With --remove, the share URL to take down instead`},list:{type:"boolean",description:"List your published designs instead of publishing"},remove:{type:"boolean",description:"Take a published design down instead of publishing \u2014 pass its share URL, or pick one interactively"},yes:{type:"boolean",description:"Skip confirmations \u2014 the --remove prompt, and publishing a screen whose component fails to render (required without an interactive terminal)"},url:{type:"string",description:"velloo-cloud base URL (default: $VELLOO_CLOUD_URL or the built-in default)"},token:{type:"string",description:"velloo-cloud access token (default: $VELLOO_CLOUD_TOKEN)"},slug:{type:"string",description:"Custom slug for --new (default: server-generated)"},new:{type:"boolean",description:"Create a separate publish link instead of updating an existing slot"},update:{type:"boolean",description:"Update the exact matching published design"},title:{type:"string",description:"Link title (default: folder name)"},boards:{type:"string",description:"Comma-separated board ids to publish (default: pick interactively; all when non-interactive)"},visibility:{type:"string",description:"public | private \u2014 explicit alternative to the interactive privacy prompt"},public:{type:"boolean",description:"Publish for anyone with the link; skips the privacy prompt"},private:{type:"boolean",description:"Publish for your organization only; skips the privacy prompt"},password:{type:"boolean",description:"Password-protect the link; anyone with the password can view. Prompts for it, or reads $VELLOO_SHARE_PASSWORD"},"password-expires":{type:"string",description:"Stop accepting the password after this date (YYYY-MM-DD or ISO timestamp)"},team:{type:"string",description:"Publish into a team by name or UUID (default: personal workspace)"},w:{type:"string",description:"Viewport width in px (default: 1440)"},h:{type:"string",description:"Viewport height in px (default: 900)"},"changed-since":{type:"string",description:"Capture only screen/board previews affected since this git ref (the full design still publishes)"}},async run({args}){if(args.list&&args.remove)fail("publish","--list and --remove do different things");if(args.list)return listPublished(args);if(args.remove)return removePublished({...args,design:args.folder,yes:args.yes});let folder=await resolveDesignFolder(args.folder,"publish"),baseUrl=args.url?args.url.replace(/\/+$/,""):defaultCloudUrl(),token=args.token??process.env.VELLOO_CLOUD_TOKEN??(await loadCredential(baseUrl))?.token;if(!token)fail("publish","not logged in. Run `velloo login` (or pass --token / VELLOO_CLOUD_TOKEN).");let interactive=Boolean(process.stdin.isTTY),team=await resolveTeam(baseUrl,token,args.team);if(!team.ok)fail("publish",describePublishError(team.error));let teamId=team.value,viewport={w:args.w?Number(args.w):1440,h:args.h?Number(args.h):900},design=await loadDesignFolder(folder),config=design.config,health=await checkCloudHealth(baseUrl);if(health.status==="unreachable")fail("publish",`cannot reach ${baseUrl} (${health.reason}). Is velloo-cloud up? (bun cloud:up)`);if(health.status==="unhealthy")fail("publish",health.detail);let account=await fetchAccount(baseUrl,token,5000),protectedShares=protectedSharesAllowed(account.status==="ok"?account.account.tier:void 0),upgradeUrl=protectedShares?void 0:await billingPageUrl(baseUrl),flagsError=privacyFlagsError(args,protectedShares,upgradeUrl);if(flagsError)fail("publish",flagsError);let selected=await pickBoards(folder,args.boards,interactive,"publish");if(selected===null){console.log("velloo publish: no boards selected \u2014 nothing was published.");return}let provenance=gitContext(folder),selectedBoardIds=new Set(selected.map((board)=>board.id)),selectedBoards=[...design.boards.values()].filter((board)=>selectedBoardIds.has(board.id)),screenshotSelection=args["changed-since"]?(()=>{try{return changedPreviewsSince(folder,args["changed-since"],[...design.screens.values()],design.snippets,selectedBoards)}catch(error){fail("publish",`cannot determine previews changed since '${args["changed-since"]}': ${error instanceof Error?error.message:String(error)}`)}})():void 0,listed=await(async()=>{if(!config.folderId||args.new===!0)return{effectiveTeamId:teamId??null,slots:[]};let destinations=await listPublishDestinations({baseUrl,token,folderId:config.folderId,...teamId?{teamId}:{}});if(!destinations.ok)fail("publish",describePublishError(destinations.error));return destinations.value})(),source={boardIds:selected.map((board)=>board.id),teamId:listed.effectiveTeamId,...provenance},destination=await choosePublishDestination({slots:listed.slots,source,interactive,createNew:args.new===!0,updateExisting:args.update===!0,customSlug:args.slug,manageUrl:await publishedBoardsUrl(baseUrl)}),privacy=await resolvePublishPrivacy(args,interactive,{protectedShares,...upgradeUrl?{upgradeUrl}:{}}).catch((error)=>fail("publish",error instanceof Error?error.message:String(error))),visibility=privacy.visibility,password=privacy.password?await readSharePassword():void 0,passwordExpiresAt=resolvePasswordExpiry(args["password-expires"],password!=null),{providers,defaultProvider}=await resolveProviders(config,folder);await confirmRenderFailures("publish",{folder:design,providers,defaultProvider},source.boardIds.length>0?screensForBoards(design,source.boardIds):[...design.screens.values()],args.yes===!0);let bundler=createPublishBundler(folder,config),jit=new TailwindJit(Object.values(providers),join2(folder,"screens"),void 0,()=>extraThemeBlock(design),()=>bundler.hostSourceDirs(),()=>findHostTailwindConfig(folder,config.hostApp),config.styling?.framework),progress=createProgress(),report=createPublishReporter(progress),outcome;try{let published=await publishDesign({baseUrl,token},{folder:design,providers,defaultProvider,snapshotCss:()=>jit.build(),liveBundler:bundler},{boardIds:selected.map((b)=>b.id),...args.title?{title:args.title}:{},visibility,...password?{password}:{},...passwordExpiresAt?{passwordExpiresAt}:{},destination,...teamId?{teamId}:{},provenance,viewport,...screenshotSelection?{screenshotSelection}:{}},report);if(!published.ok)progress.fail("publish failed"),fail("publish",describePublishError(published.error));outcome=published.value,progress.succeed("published design")}catch(error){progress.fail("publish failed"),fail("publish",error instanceof Error?error.message:String(error))}finally{await closePooledBrowser()}console.log(`velloo publish: ${outcome.files} files, ${Math.round(outcome.bytes/1024)} KB${outcome.screenshots>0?`, ${outcome.screenshots} screenshots`:""}${outcome.commitSha?`, commit ${outcome.commitSha.slice(0,7)}`:""}`),console.log(` ${outcome.shareUrl}`),console.log(` ${describeAccess(outcome)}`);let history=outcome.history;if(history&&!history.retained&&history.pruned>0)console.log(" replaced the previous version \u2014 the free plan keeps only the latest."),console.log(` Upgrade to Team to keep version history and revisit past publishes: ${PRICING_URL}`);else if(history?.retained&&history.versions>1)console.log(` history: ${history.versions} versions kept \u2014 pin any of them from ${outcome.shareUrl}v/<version>/`)}});function resolvePublishDestinationChoice(value,slots){if(value===null)return null;if(value==="new")return{mode:"new"};let slug=value.replace(/^update:/,""),slot=slots.find((candidate)=>candidate.slug===slug);if(!slot)return null;return{mode:"update",slug:slot.slug,expectedVersionId:slot.latestVersionId}}async function choosePublishDestination(opts){if(opts.createNew&&opts.updateExisting)fail("publish","choose either --new or --update, not both");if(opts.customSlug&&!opts.createNew)fail("publish","--slug names a new link; use it together with --new");let matching=exactPublishSlots(opts.slots,opts.source);if(opts.updateExisting){let slot=matching[0];if(!slot)fail("publish",`there is no exact published-design match to update. Manage existing boards at ${opts.manageUrl}`);return{mode:"update",slug:slot.slug,expectedVersionId:slot.latestVersionId}}if(opts.createNew)return{mode:"new",...opts.customSlug?{slug:opts.customSlug}:{}};if(matching.length===0)return(opts.log??console.log)("velloo publish: no matching published design \u2014 a new link will be created."),{mode:"new"};if(!opts.interactive)fail("publish","this folder already has published designs; pass --update or --new explicitly");let recommended=recommendedPublishSlot(opts.slots,opts.source),latestMatch=matching[0],value=await select({message:"Publish destination",initialValue:recommended?`update:${recommended.slug}`:"new",options:[...latestMatch?[{value:`update:${latestMatch.slug}`,label:`Update ${latestMatch.title||"Untitled design"}`,hint:"latest exact match for this team, board selection, and source"}]:[],{value:"new",label:"Create a new link",hint:recommended?"keep the matching design separate":"recommended for this source"}]}),destination=resolvePublishDestinationChoice(isCancel(value)?null:String(value),matching);if(!destination)fail("publish",isCancel(value)?"cancelled":"selected publish slot is no longer available");return destination}function createPublishReporter(progress){let latestCapture;return(event)=>{if(event.kind==="capture"){latestCapture=`capturing previews ${event.done}/${event.total}`,progress.step(latestCapture,{transient:!0});return}if(event.kind==="step"){if(latestCapture)progress.step(latestCapture);latestCapture=void 0,progress.step(event.message);return}progress.log(event.message)}}async function readSharePassword(){let fromEnv=process.env.VELLOO_SHARE_PASSWORD?.trim();if(fromEnv){if(fromEnv.length<3)fail("publish","VELLOO_SHARE_PASSWORD must be at least 3 characters");return fromEnv}if(!process.stdin.isTTY)fail("publish","--password needs a terminal to prompt \u2014 set $VELLOO_SHARE_PASSWORD instead");let entered=await password({message:"Password for this share link",validate:(value)=>(value??"").length<3?"At least 3 characters.":void 0});if(isCancel(entered))fail("publish","cancelled");return entered}function resolvePasswordExpiry(raw,hasPassword){if(!raw)return;if(!hasPassword)fail("publish","--password-expires needs --password");let value=/^\d{4}-\d{2}-\d{2}$/.test(raw)?`${raw}T23:59:59`:raw,when=new Date(value);if(Number.isNaN(when.getTime()))fail("publish",`--password-expires must be a date (YYYY-MM-DD) or ISO timestamp, got '${raw}'`);return when.toISOString()}function describeAccess(outcome){if(outcome.visibility==="private")return outcome.passwordProtected?"private \u2014 your organization, or anyone with the password":"private \u2014 anyone signed in at your organization";return outcome.passwordProtected?"public \u2014 anyone with the link and the password":"public \u2014 anyone with the link"}export{publish_default as default};
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defProp,getOwnPropertyNames:__getOwnPropNames}=Object;var __hasOwnProp=Object.prototype.hasOwnProperty;function __accessProp(key){return this[key]}var __toESMCache_node,__toESMCache_esm,__toESM=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node??=new WeakMap:__toESMCache_esm??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create(__getProtoOf(mod)):{};let to=isNodeMode||!mod||!mod.__esModule||!__hasOwnProp.call(mod,"default")?__defProp(target,"default",{value:mod,enumerable:!0}):target;if(mod&&typeof mod==="object"||typeof mod==="function"){for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:__accessProp.bind(mod,key),enumerable:!0})}if(canCache)cache.set(mod,to);return to};var __commonJS=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports);var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var __exportCjs=(target,getters,setters)=>{for(var name in getters)__defProp(target,name,{get:getters[name],set:setters[name],enumerable:!0,configurable:!0})},__require=import.meta.require;var NUMBER_CHAR_RE=/\d/,STR_SPLITTERS=["-","_","/","."];function isUppercase(char=""){if(NUMBER_CHAR_RE.test(char))return;return char!==char.toLowerCase()}function splitByCase(str,separators){let splitters=separators??STR_SPLITTERS,parts=[];if(!str||typeof str!=="string")return parts;let buff="",previousUpper,previousSplitter;for(let char of str){let isSplitter=splitters.includes(char);if(isSplitter===!0){parts.push(buff),buff="",previousUpper=void 0;continue}let isUpper=isUppercase(char);if(previousSplitter===!1){if(previousUpper===!1&&isUpper===!0){parts.push(buff),buff=char,previousUpper=isUpper;continue}if(previousUpper===!0&&isUpper===!1&&buff.length>1){let lastChar=buff.at(-1);parts.push(buff.slice(0,Math.max(0,buff.length-1))),buff=lastChar+char,previousUpper=isUpper;continue}}buff+=char,previousUpper=isUpper,previousSplitter=isSplitter}return parts.push(buff),parts}function upperFirst(str){return str?str[0].toUpperCase()+str.slice(1):""}function lowerFirst(str){return str?str[0].toLowerCase()+str.slice(1):""}function pascalCase(str,opts){return str?(Array.isArray(str)?str:splitByCase(str)).map((p)=>upperFirst(opts?.normalize?p.toLowerCase():p)).join(""):""}function camelCase(str,opts){return lowerFirst(pascalCase(str||"",opts))}function kebabCase(str,joiner){return str?(Array.isArray(str)?str:splitByCase(str)).map((p)=>p.toLowerCase()).join(joiner??"-"):""}function snakeCase(str){return kebabCase(str||"","_")}import{parseArgs as parseArgs$1}from"util";function toArray(val){if(Array.isArray(val))return val;return val===void 0?[]:[val]}function formatLineColumns(lines,linePrefix=""){let maxLength=[];for(let line of lines)for(let[i,element]of line.entries())maxLength[i]=Math.max(maxLength[i]||0,element.length);return lines.map((l)=>l.map((c,i)=>linePrefix+c[i===0?"padStart":"padEnd"](maxLength[i])).join(" ")).join(`
3
+ `)}function resolveValue(input){return typeof input==="function"?input():input}var CLIError=class extends Error{code;constructor(message,code){super(message);this.name="CLIError",this.code=code}};function parseRawArgs(args=[],opts={}){let booleans=new Set(opts.boolean||[]),strings=new Set(opts.string||[]),aliasMap=opts.alias||{},defaults=opts.default||{},aliasToMain=new Map,mainToAliases=new Map;for(let[key,value]of Object.entries(aliasMap)){let targets=value;for(let target of targets){if(aliasToMain.set(key,target),!mainToAliases.has(target))mainToAliases.set(target,[]);if(mainToAliases.get(target).push(key),aliasToMain.set(target,key),!mainToAliases.has(key))mainToAliases.set(key,[]);mainToAliases.get(key).push(target)}}let options={};function getType(name){if(booleans.has(name))return"boolean";let aliases=mainToAliases.get(name)||[];for(let alias of aliases)if(booleans.has(alias))return"boolean";return"string"}function isStringType(name){if(strings.has(name))return!0;let aliases=mainToAliases.get(name)||[];for(let alias of aliases)if(strings.has(alias))return!0;return!1}let allOptions=new Set([...booleans,...strings,...Object.keys(aliasMap),...Object.values(aliasMap).flat(),...Object.keys(defaults)]);for(let name of allOptions)if(!options[name])options[name]={type:getType(name),default:defaults[name]};for(let[alias,main]of aliasToMain.entries())if(alias.length===1&&options[main]&&!options[main].short)options[main].short=alias;let processedArgs=[],negatedFlags={};for(let i=0;i<args.length;i++){let arg=args[i];if(arg==="--"){processedArgs.push(...args.slice(i));break}if(arg.startsWith("--no-")){let flagName=arg.slice(5);negatedFlags[flagName]=!0;continue}processedArgs.push(arg)}let parsed;try{parsed=parseArgs$1({args:processedArgs,options:Object.keys(options).length>0?options:void 0,allowPositionals:!0,strict:!1})}catch{parsed={values:{},positionals:processedArgs}}let out={_:[]};out._=parsed.positionals;for(let[key,value]of Object.entries(parsed.values)){let coerced=value;if(getType(key)==="boolean"&&typeof value==="string")coerced=value!=="false";else if(isStringType(key)&&typeof value==="boolean")coerced="";out[key]=coerced}for(let[name]of Object.entries(negatedFlags)){out[name]=!1;let mainName=aliasToMain.get(name);if(mainName)out[mainName]=!1;let aliases=mainToAliases.get(name);if(aliases)for(let alias of aliases)out[alias]=!1}for(let[alias,main]of aliasToMain.entries()){if(out[alias]!==void 0&&out[main]===void 0)out[main]=out[alias];if(out[main]!==void 0&&out[alias]===void 0)out[alias]=out[main];if(out[alias]!==out[main]&&defaults[main]===out[main])out[main]=out[alias]}return out}var noColor=(()=>{let env=globalThis.process?.env??{};return env.NO_COLOR==="1"||env.TERM==="dumb"||env.TEST||env.CI})(),_c=(c,r=39)=>(t)=>noColor?t:`\x1B[${c}m${t}\x1B[${r}m`,bold=_c(1,22),cyan=_c(36),gray=_c(90),underline=_c(4,24);function parseArgs(rawArgs,argsDef){let parseOptions={boolean:[],string:[],alias:{},default:{}},args=resolveArgs(argsDef);for(let arg of args){if(arg.type==="positional")continue;if(arg.type==="string"||arg.type==="enum")parseOptions.string.push(arg.name);else if(arg.type==="boolean")parseOptions.boolean.push(arg.name);if(arg.default!==void 0)parseOptions.default[arg.name]=arg.default;if(arg.alias)parseOptions.alias[arg.name]=arg.alias;let camelName=camelCase(arg.name),kebabName=kebabCase(arg.name);if(camelName!==arg.name||kebabName!==arg.name){let existingAliases=toArray(parseOptions.alias[arg.name]||[]);if(camelName!==arg.name&&!existingAliases.includes(camelName))existingAliases.push(camelName);if(kebabName!==arg.name&&!existingAliases.includes(kebabName))existingAliases.push(kebabName);if(existingAliases.length>0)parseOptions.alias[arg.name]=existingAliases}}let parsed=parseRawArgs(rawArgs,parseOptions),[...positionalArguments]=parsed._,parsedArgsProxy=new Proxy(parsed,{get(target,prop){return target[prop]??target[camelCase(prop)]??target[kebabCase(prop)]}});for(let[,arg]of args.entries())if(arg.type==="positional"){let nextPositionalArgument=positionalArguments.shift();if(nextPositionalArgument!==void 0)parsedArgsProxy[arg.name]=nextPositionalArgument;else if(arg.default===void 0&&arg.required!==!1)throw new CLIError(`Missing required positional argument: ${arg.name.toUpperCase()}`,"EARG");else parsedArgsProxy[arg.name]=arg.default}else if(arg.type==="enum"){let argument=parsedArgsProxy[arg.name],options=arg.options||[];if(argument!==void 0&&options.length>0&&!options.includes(argument))throw new CLIError(`Invalid value for argument: ${cyan(`--${arg.name}`)} (${cyan(argument)}). Expected one of: ${options.map((o)=>cyan(o)).join(", ")}.`,"EARG")}else if(arg.required&&parsedArgsProxy[arg.name]===void 0)throw new CLIError(`Missing required argument: --${arg.name}`,"EARG");return parsedArgsProxy}function resolveArgs(argsDef){let args=[];for(let[name,argDef]of Object.entries(argsDef||{}))args.push({...argDef,name,alias:toArray(argDef.alias)});return args}async function resolvePlugins(plugins){return Promise.all(plugins.map((p)=>resolveValue(p)))}function defineCommand(def){return def}async function runCommand(cmd,opts){let cmdArgs=await resolveValue(cmd.args||{}),parsedArgs=parseArgs(opts.rawArgs,cmdArgs),context={rawArgs:opts.rawArgs,args:parsedArgs,data:opts.data,cmd},plugins=await resolvePlugins(cmd.plugins??[]),result,runError;try{for(let plugin of plugins)await plugin.setup?.(context);if(typeof cmd.setup==="function")await cmd.setup(context);let subCommands=await resolveValue(cmd.subCommands);if(subCommands&&Object.keys(subCommands).length>0){let subCommandArgIndex=findSubCommandIndex(opts.rawArgs,cmdArgs),explicitName=opts.rawArgs[subCommandArgIndex];if(explicitName){let subCommand=await _findSubCommand(subCommands,explicitName);if(!subCommand)throw new CLIError(`Unknown command ${cyan(explicitName)}`,"E_UNKNOWN_COMMAND");await runCommand(subCommand,{rawArgs:opts.rawArgs.slice(subCommandArgIndex+1)})}else{let defaultSubCommand=await resolveValue(cmd.default);if(defaultSubCommand){if(cmd.run)throw new CLIError("Cannot specify both 'run' and 'default' on the same command.","E_DEFAULT_CONFLICT");let subCommand=await _findSubCommand(subCommands,defaultSubCommand);if(!subCommand)throw new CLIError(`Default sub command ${cyan(defaultSubCommand)} not found in subCommands.`,"E_UNKNOWN_COMMAND");await runCommand(subCommand,{rawArgs:opts.rawArgs})}else if(!cmd.run)throw new CLIError("No command specified.","E_NO_COMMAND")}}if(typeof cmd.run==="function")result=await cmd.run(context)}catch(error){runError=error}let cleanupErrors=[];if(typeof cmd.cleanup==="function")try{await cmd.cleanup(context)}catch(error){cleanupErrors.push(error)}for(let plugin of[...plugins].reverse())try{await plugin.cleanup?.(context)}catch(error){cleanupErrors.push(error)}if(runError)throw runError;if(cleanupErrors.length===1)throw cleanupErrors[0];if(cleanupErrors.length>1)throw Error("Multiple cleanup errors",{cause:cleanupErrors});return{result}}async function resolveSubCommand(cmd,rawArgs,parent){let subCommands=await resolveValue(cmd.subCommands);if(subCommands&&Object.keys(subCommands).length>0){let subCommandArgIndex=findSubCommandIndex(rawArgs,await resolveValue(cmd.args||{})),subCommandName=rawArgs[subCommandArgIndex],subCommand=await _findSubCommand(subCommands,subCommandName);if(subCommand)return resolveSubCommand(subCommand,rawArgs.slice(subCommandArgIndex+1),cmd)}return[cmd,parent]}async function _findSubCommand(subCommands,name){if(name in subCommands)return resolveValue(subCommands[name]);for(let sub of Object.values(subCommands)){let resolved=await resolveValue(sub),meta=await resolveValue(resolved?.meta);if(meta?.alias){if(toArray(meta.alias).includes(name))return resolved}}}function findSubCommandIndex(rawArgs,argsDef){for(let i=0;i<rawArgs.length;i++){let arg=rawArgs[i];if(arg==="--")return-1;if(arg.startsWith("-")){if(!arg.includes("=")&&_isValueFlag(arg,argsDef))i++;continue}return i}return-1}function _isValueFlag(flag,argsDef){let name=flag.replace(/^-{1,2}/,""),normalized=camelCase(name);for(let[key,def]of Object.entries(argsDef)){if(def.type!=="string"&&def.type!=="enum")continue;if(normalized===camelCase(key))return!0;if((Array.isArray(def.alias)?def.alias:def.alias?[def.alias]:[]).includes(name))return!0}return!1}async function showUsage(cmd,parent){try{console.log(await renderUsage(cmd,parent)+`
4
+ `)}catch(error){console.error(error)}}var negativePrefixRe=/^no[-A-Z]/;async function renderUsage(cmd,parent){let cmdMeta=await resolveValue(cmd.meta||{}),cmdArgs=resolveArgs(await resolveValue(cmd.args||{})),parentMeta=await resolveValue(parent?.meta||{}),commandName=`${parentMeta.name?`${parentMeta.name} `:""}`+(cmdMeta.name||process.argv[1]),argLines=[],posLines=[],commandsLines=[],usageLine=[];for(let arg of cmdArgs)if(arg.type==="positional"){let name=arg.name.toUpperCase(),isRequired=arg.required!==!1&&arg.default===void 0;posLines.push([cyan(name+renderValueHint(arg)),renderDescription(arg,isRequired)]),usageLine.push(isRequired?`<${name}>`:`[${name}]`)}else{let isRequired=arg.required===!0&&arg.default===void 0,argStr=[...(arg.alias||[]).map((a)=>`-${a}`),`--${arg.name}`].join(", ")+renderValueHint(arg);if(argLines.push([cyan(argStr),renderDescription(arg,isRequired)]),arg.type==="boolean"&&(arg.default===!0||arg.negativeDescription)&&!negativePrefixRe.test(arg.name)){let negativeArgStr=[...(arg.alias||[]).map((a)=>`--no-${a}`),`--no-${arg.name}`].join(", ");argLines.push([cyan(negativeArgStr),[arg.negativeDescription,isRequired?gray("(Required)"):""].filter(Boolean).join(" ")])}if(isRequired)usageLine.push(`--${arg.name}`+renderValueHint(arg))}if(cmd.subCommands){let commandNames=[],subCommands=await resolveValue(cmd.subCommands);for(let[name,sub]of Object.entries(subCommands)){let meta=await resolveValue((await resolveValue(sub))?.meta);if(meta?.hidden)continue;let aliases=toArray(meta?.alias),label=[name,...aliases].join(", ");commandsLines.push([cyan(label),meta?.description||""]),commandNames.push(name,...aliases)}usageLine.push(commandNames.join("|"))}let usageLines=[],version=cmdMeta.version||parentMeta.version;usageLines.push(gray(`${cmdMeta.description} (${commandName+(version?` v${version}`:"")})`),"");let hasOptions=argLines.length>0||posLines.length>0;if(usageLines.push(`${underline(bold("USAGE"))} ${cyan(`${commandName}${hasOptions?" [OPTIONS]":""} ${usageLine.join(" ")}`)}`,""),posLines.length>0)usageLines.push(underline(bold("ARGUMENTS")),""),usageLines.push(formatLineColumns(posLines," ")),usageLines.push("");if(argLines.length>0)usageLines.push(underline(bold("OPTIONS")),""),usageLines.push(formatLineColumns(argLines," ")),usageLines.push("");if(commandsLines.length>0)usageLines.push(underline(bold("COMMANDS")),""),usageLines.push(formatLineColumns(commandsLines," ")),usageLines.push("",`Use ${cyan(`${commandName} <command> --help`)} for more information about a command.`);return usageLines.filter((l)=>typeof l==="string").join(`
5
+ `)}function renderValueHint(arg){let valueHint=arg.valueHint?`=<${arg.valueHint}>`:"",fallbackValueHint=valueHint||`=<${snakeCase(arg.name)}>`;if(!arg.type||arg.type==="positional"||arg.type==="boolean")return valueHint;if(arg.type==="enum"&&arg.options?.length)return`=<${arg.options.join("|")}>`;return fallbackValueHint}function renderDescription(arg,required){let requiredHint=required?gray("(Required)"):"",defaultHint=arg.default===void 0?"":gray(`(Default: ${arg.default})`);return[arg.description,requiredHint,defaultHint].filter(Boolean).join(" ")}async function runMain(cmd,opts={}){let rawArgs=opts.rawArgs||process.argv.slice(2),showUsage$1=opts.showUsage||showUsage;try{let builtinFlags=await _resolveBuiltinFlags(cmd);if(builtinFlags.help.length>0&&rawArgs.some((arg)=>builtinFlags.help.includes(arg)))await showUsage$1(...await resolveSubCommand(cmd,rawArgs)),process.exit(0);else if(rawArgs.length===1&&builtinFlags.version.includes(rawArgs[0])){let meta=typeof cmd.meta==="function"?await cmd.meta():await cmd.meta;if(!meta?.version)throw new CLIError("No version specified","E_NO_VERSION");console.log(meta.version)}else await runCommand(cmd,{rawArgs})}catch(error){if(error instanceof CLIError)await showUsage$1(...await resolveSubCommand(cmd,rawArgs)),console.error(error.message);else console.error(error,`
6
+ `);process.exit(1)}}async function _resolveBuiltinFlags(cmd){let argsDef=await resolveValue(cmd.args||{}),userNames=new Set,userAliases=new Set;for(let[name,def]of Object.entries(argsDef)){userNames.add(name);for(let alias of toArray(def.alias))userAliases.add(alias)}return{help:_getBuiltinFlags("help","h",userNames,userAliases),version:_getBuiltinFlags("version","v",userNames,userAliases)}}function _getBuiltinFlags(long,short,userNames,userAliases){if(userNames.has(long)||userAliases.has(long))return[];if(userNames.has(short)||userAliases.has(short))return[`--${long}`];return[`--${long}`,`-${short}`]}
7
+ export{__toESM,__commonJS,__export,__exportCjs,__require,defineCommand,runMain};