velloo 0.0.0 → 0.2.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 (267) hide show
  1. package/BUN-LICENSE.md +91 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +9 -0
  4. package/README.md +288 -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-ClaBqcaS.js +28 -0
  16. package/canvas/assets/lucide-all-iIF-pmzN.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-08sv3k41.js +4 -0
  30. package/chunk-0fe83yzt.js +2 -0
  31. package/chunk-0t68szgr.js +3 -0
  32. package/chunk-1h55s5he.js +2 -0
  33. package/chunk-2c7jbx46.js +2 -0
  34. package/chunk-2smsg2ct.js +7 -0
  35. package/chunk-308ynsxd.js +2 -0
  36. package/chunk-3e8vez4d.js +1229 -0
  37. package/chunk-40xgcth8.js +63 -0
  38. package/chunk-4dn75m6t.js +3 -0
  39. package/chunk-4fj5tahv.js +3 -0
  40. package/chunk-6nqghjda.js +3 -0
  41. package/chunk-6tx68d90.js +3 -0
  42. package/chunk-6w6ch4ce.js +2 -0
  43. package/chunk-735ezz23.js +86 -0
  44. package/chunk-7eq7nx37.js +7 -0
  45. package/chunk-7eyb8yrf.js +6 -0
  46. package/chunk-80fjfyha.js +86 -0
  47. package/chunk-80r93t2e.js +4 -0
  48. package/chunk-94vx1yb0.js +3 -0
  49. package/chunk-9vg3yafz.js +3 -0
  50. package/chunk-a84n72m2.js +4 -0
  51. package/chunk-ampmdzz4.js +10 -0
  52. package/chunk-avns4dbf.js +2 -0
  53. package/chunk-ayrb3qnm.js +3 -0
  54. package/chunk-bwnvcncx.js +3 -0
  55. package/chunk-ccszg02q.js +5 -0
  56. package/chunk-cvn689d5.js +3 -0
  57. package/chunk-cxe6jjwj.js +3 -0
  58. package/chunk-dg6z4vdd.js +3 -0
  59. package/chunk-dgwjpbp9.js +3 -0
  60. package/chunk-dy41n60j.js +52 -0
  61. package/chunk-ek71z2fv.js +226 -0
  62. package/chunk-er1fxb7d.js +2 -0
  63. package/chunk-eyr8hrzf.js +2 -0
  64. package/chunk-fjbzk4sw.js +3 -0
  65. package/chunk-fsbsksga.js +3 -0
  66. package/chunk-h6gchare.js +3 -0
  67. package/chunk-hcb68zt7.js +85 -0
  68. package/chunk-hggap8fq.js +3 -0
  69. package/chunk-j11fyeqh.js +2 -0
  70. package/chunk-jb21jkp1.js +8 -0
  71. package/chunk-jfx9xjmr.js +18 -0
  72. package/chunk-jr0ss0mm.js +303 -0
  73. package/chunk-jrsknzjt.js +3 -0
  74. package/chunk-jv0xggh0.js +2 -0
  75. package/chunk-k17gfwq3.js +2 -0
  76. package/chunk-mh2pr7cq.js +5 -0
  77. package/chunk-mnapdp1y.js +2 -0
  78. package/chunk-mzhdrawd.js +3 -0
  79. package/chunk-n9gs6yx9.js +2 -0
  80. package/chunk-ngnymg2q.js +3 -0
  81. package/chunk-nwx5700b.js +3 -0
  82. package/chunk-pjtg3wnm.js +4 -0
  83. package/chunk-pp86v6m6.js +3 -0
  84. package/chunk-r22epxz2.js +3 -0
  85. package/chunk-rgasy862.js +5 -0
  86. package/chunk-rpwpeph5.js +3 -0
  87. package/chunk-s23gtejf.js +3 -0
  88. package/chunk-sjgqnykd.js +6 -0
  89. package/chunk-sn3x2m0m.js +6 -0
  90. package/chunk-t448rrfr.js +2 -0
  91. package/chunk-tdsk5wxa.js +451 -0
  92. package/chunk-v40fn08f.js +442 -0
  93. package/chunk-vbk1qhdz.js +3 -0
  94. package/chunk-vdkrbzh1.js +2 -0
  95. package/chunk-vgmr98cv.js +40 -0
  96. package/chunk-vsv8z729.js +6 -0
  97. package/chunk-x4f4k9pp.js +26 -0
  98. package/chunk-xt5ayg7g.js +4 -0
  99. package/chunk-ydhwv29b.js +244 -0
  100. package/chunk-zb6hc1y0.js +2 -0
  101. package/cli.js +3 -0
  102. package/launcher.cjs +97 -0
  103. package/package.json +58 -5
  104. package/pkgs/helpers/src/box.tsx +21 -0
  105. package/pkgs/helpers/src/cn.ts +32 -0
  106. package/pkgs/helpers/src/descriptors.ts +270 -0
  107. package/pkgs/helpers/src/divider.tsx +123 -0
  108. package/pkgs/helpers/src/gradient.tsx +90 -0
  109. package/pkgs/helpers/src/heading.tsx +20 -0
  110. package/pkgs/helpers/src/icon-data.ts +8009 -0
  111. package/pkgs/helpers/src/icon.tsx +53 -0
  112. package/pkgs/helpers/src/image.tsx +111 -0
  113. package/pkgs/helpers/src/index.ts +29 -0
  114. package/pkgs/helpers/src/layer.tsx +61 -0
  115. package/pkgs/helpers/src/lowering.ts +53 -0
  116. package/pkgs/helpers/src/paths.ts +47 -0
  117. package/pkgs/helpers/src/placeholder.tsx +88 -0
  118. package/pkgs/helpers/src/prose.tsx +42 -0
  119. package/pkgs/helpers/src/registry.ts +41 -0
  120. package/pkgs/helpers/src/svg.tsx +62 -0
  121. package/pkgs/helpers/src/text.tsx +16 -0
  122. package/pkgs/provider-antd/src/index.ts +78 -0
  123. package/pkgs/provider-antd/src/intro.ts +14 -0
  124. package/pkgs/provider-antd/src/manifest.ts +439 -0
  125. package/pkgs/provider-antd/src/overlays.ts +176 -0
  126. package/pkgs/provider-antd/src/registry.ts +104 -0
  127. package/pkgs/provider-antd/src/render-pass.ts +43 -0
  128. package/pkgs/provider-antd/src/tailwind-entry.css +21 -0
  129. package/pkgs/provider-antd/src/theme.ts +132 -0
  130. package/pkgs/provider-antd/src/version.ts +8 -0
  131. package/pkgs/provider-chakra/src/index.ts +80 -0
  132. package/pkgs/provider-chakra/src/intro.ts +14 -0
  133. package/pkgs/provider-chakra/src/manifest.ts +421 -0
  134. package/pkgs/provider-chakra/src/overlays.ts +246 -0
  135. package/pkgs/provider-chakra/src/registry.ts +227 -0
  136. package/pkgs/provider-chakra/src/render-pass.ts +55 -0
  137. package/pkgs/provider-chakra/src/tailwind-entry.css +21 -0
  138. package/pkgs/provider-chakra/src/theme.ts +180 -0
  139. package/pkgs/provider-chakra/src/version.ts +8 -0
  140. package/pkgs/provider-mui/src/index.ts +117 -0
  141. package/pkgs/provider-mui/src/intro.ts +12 -0
  142. package/pkgs/provider-mui/src/manifest.ts +263 -0
  143. package/pkgs/provider-mui/src/overlays.ts +124 -0
  144. package/pkgs/provider-mui/src/registry.ts +120 -0
  145. package/pkgs/provider-mui/src/render-pass.ts +36 -0
  146. package/pkgs/provider-mui/src/tailwind-entry.css +21 -0
  147. package/pkgs/provider-mui/src/theme.ts +129 -0
  148. package/pkgs/provider-mui/src/version.ts +8 -0
  149. package/pkgs/provider-none/src/components-inline.tsx +204 -0
  150. package/pkgs/provider-none/src/components.tsx +155 -0
  151. package/pkgs/provider-none/src/index.ts +57 -0
  152. package/pkgs/provider-none/src/intro.ts +18 -0
  153. package/pkgs/provider-none/src/manifest.ts +163 -0
  154. package/pkgs/provider-none/src/registry-inline.ts +36 -0
  155. package/pkgs/provider-none/src/registry.ts +39 -0
  156. package/pkgs/provider-none/src/tailwind-entry.css +57 -0
  157. package/pkgs/provider-none/src/version.ts +10 -0
  158. package/pkgs/schema/src/annotation.ts +120 -0
  159. package/pkgs/schema/src/asset.ts +66 -0
  160. package/pkgs/schema/src/board.ts +71 -0
  161. package/pkgs/schema/src/comment.ts +107 -0
  162. package/pkgs/schema/src/config.ts +185 -0
  163. package/pkgs/schema/src/css-sanitize.ts +56 -0
  164. package/pkgs/schema/src/extension.ts +105 -0
  165. package/pkgs/schema/src/fonts.ts +690 -0
  166. package/pkgs/schema/src/frame.ts +40 -0
  167. package/pkgs/schema/src/icon-name.ts +21 -0
  168. package/pkgs/schema/src/ids.ts +14 -0
  169. package/pkgs/schema/src/index.ts +169 -0
  170. package/pkgs/schema/src/migrate.ts +297 -0
  171. package/pkgs/schema/src/node.ts +229 -0
  172. package/pkgs/schema/src/paths.ts +28 -0
  173. package/pkgs/schema/src/repo.ts +134 -0
  174. package/pkgs/schema/src/screen.ts +30 -0
  175. package/pkgs/schema/src/snippet-resolve.ts +193 -0
  176. package/pkgs/schema/src/snippet.ts +104 -0
  177. package/pkgs/schema/src/svg-sanitize.ts +487 -0
  178. package/pkgs/schema/src/theme.ts +218 -0
  179. package/pkgs/schema/src/typeset.ts +693 -0
  180. package/pkgs/schema/src/validate-ids.ts +46 -0
  181. package/pkgs/schema/src/viewport.ts +8 -0
  182. package/pkgs/shadcn-snapshot/dist/manifest.json +8109 -0
  183. package/pkgs/shadcn-snapshot/src/components/canvas-portal.tsx +55 -0
  184. package/pkgs/shadcn-snapshot/src/components/ui/accordion.tsx +122 -0
  185. package/pkgs/shadcn-snapshot/src/components/ui/alert-dialog.tsx +164 -0
  186. package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +74 -0
  187. package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +13 -0
  188. package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +197 -0
  189. package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +100 -0
  190. package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +50 -0
  191. package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +109 -0
  192. package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +130 -0
  193. package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +82 -0
  194. package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +72 -0
  195. package/pkgs/shadcn-snapshot/src/components/ui/calendar.tsx +229 -0
  196. package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +92 -0
  197. package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +235 -0
  198. package/pkgs/shadcn-snapshot/src/components/ui/chart-option.ts +250 -0
  199. package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +177 -0
  200. package/pkgs/shadcn-snapshot/src/components/ui/checkbox.tsx +41 -0
  201. package/pkgs/shadcn-snapshot/src/components/ui/collapsible.tsx +32 -0
  202. package/pkgs/shadcn-snapshot/src/components/ui/combobox.tsx +196 -0
  203. package/pkgs/shadcn-snapshot/src/components/ui/context-menu.tsx +227 -0
  204. package/pkgs/shadcn-snapshot/src/components/ui/dialog.tsx +131 -0
  205. package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +24 -0
  206. package/pkgs/shadcn-snapshot/src/components/ui/drawer.tsx +112 -0
  207. package/pkgs/shadcn-snapshot/src/components/ui/dropdown-menu.tsx +205 -0
  208. package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +98 -0
  209. package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +228 -0
  210. package/pkgs/shadcn-snapshot/src/components/ui/hover-card.tsx +51 -0
  211. package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +148 -0
  212. package/pkgs/shadcn-snapshot/src/components/ui/input.tsx +43 -0
  213. package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +187 -0
  214. package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +30 -0
  215. package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +25 -0
  216. package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +71 -0
  217. package/pkgs/shadcn-snapshot/src/components/ui/menubar.tsx +243 -0
  218. package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +89 -0
  219. package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +60 -0
  220. package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +165 -0
  221. package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +117 -0
  222. package/pkgs/shadcn-snapshot/src/components/ui/popover.tsx +66 -0
  223. package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +35 -0
  224. package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +48 -0
  225. package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +59 -0
  226. package/pkgs/shadcn-snapshot/src/components/ui/select.tsx +180 -0
  227. package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +32 -0
  228. package/pkgs/shadcn-snapshot/src/components/ui/sheet.tsx +107 -0
  229. package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +17 -0
  230. package/pkgs/shadcn-snapshot/src/components/ui/slider.tsx +68 -0
  231. package/pkgs/shadcn-snapshot/src/components/ui/sonner.tsx +91 -0
  232. package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +21 -0
  233. package/pkgs/shadcn-snapshot/src/components/ui/switch.tsx +41 -0
  234. package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +93 -0
  235. package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +84 -0
  236. package/pkgs/shadcn-snapshot/src/components/ui/textarea.tsx +24 -0
  237. package/pkgs/shadcn-snapshot/src/components/ui/toggle-group.tsx +94 -0
  238. package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +50 -0
  239. package/pkgs/shadcn-snapshot/src/components/ui/tooltip.tsx +47 -0
  240. package/pkgs/shadcn-snapshot/src/examples.ts +36 -0
  241. package/pkgs/shadcn-snapshot/src/groups.ts +87 -0
  242. package/pkgs/shadcn-snapshot/src/index.ts +43 -0
  243. package/pkgs/shadcn-snapshot/src/lib/utils.ts +4 -0
  244. package/pkgs/shadcn-snapshot/src/manifest.ts +12 -0
  245. package/pkgs/shadcn-snapshot/src/notes.ts +97 -0
  246. package/pkgs/shadcn-snapshot/src/paths.ts +47 -0
  247. package/pkgs/shadcn-snapshot/src/registry-files.ts +293 -0
  248. package/pkgs/shadcn-snapshot/src/registry.ts +631 -0
  249. package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +632 -0
  250. package/pkgs/shadcn-snapshot/src/tailwind-entry.css +159 -0
  251. package/pkgs/shadcn-snapshot/src/version.ts +8 -0
  252. package/plugins/claude/velloo/.claude-plugin/plugin.json +6 -0
  253. package/plugins/claude/velloo/agents/velloo-design-reviewer.md +33 -0
  254. package/plugins/claude/velloo/agents/velloo-designer.md +39 -0
  255. package/plugins/claude/velloo/commands/design.md +11 -0
  256. package/plugins/claude/velloo/commands/implement.md +10 -0
  257. package/plugins/claude/velloo/commands/review.md +8 -0
  258. package/plugins/gemini/GEMINI.md +31 -0
  259. package/plugins/gemini/commands/velloo/design.toml +10 -0
  260. package/plugins/gemini/commands/velloo/implement.toml +9 -0
  261. package/plugins/gemini/gemini-extension.json +9 -0
  262. package/skills/velloo-brand/SKILL.md +124 -0
  263. package/skills/velloo-design/SKILL.md +144 -0
  264. package/skills/velloo-design-system/SKILL.md +90 -0
  265. package/skills/velloo-implement/SKILL.md +101 -0
  266. package/skills/velloo-logo/SKILL.md +93 -0
  267. package/skills/velloo-setup/SKILL.md +156 -0
@@ -0,0 +1,163 @@
1
+ import { helperDescriptors } from "@velloo/helpers";
2
+ import type { ComponentDescriptor, Manifest } from "@velloo/provider";
3
+ import { REUSED_HELPER_IDS } from "./registry.ts";
4
+
5
+ /**
6
+ * Manifest for the no-library provider. The six bare primitives are
7
+ * hand-authored (a dozen props, easier to maintain by hand than to wire a
8
+ * ts-morph pipeline for); the reused helpers (`Heading`, `Text`, `Icon`, …)
9
+ * come from `@velloo/helpers`' canonical descriptors so the props the
10
+ * inspector sees can't drift from the components the registry renders.
11
+ */
12
+ const PRIMITIVE_DESCRIPTORS: ComponentDescriptor[] = [
13
+ {
14
+ id: "Box",
15
+ category: "ui",
16
+ source: "velloo",
17
+ props: [
18
+ {
19
+ name: "className",
20
+ type: "string | undefined",
21
+ optional: true,
22
+ control: "string",
23
+ },
24
+ ],
25
+ },
26
+ {
27
+ id: "Stack",
28
+ category: "ui",
29
+ source: "velloo",
30
+ props: [
31
+ {
32
+ name: "direction",
33
+ type: '"row" | "col" | undefined',
34
+ optional: true,
35
+ control: "enum",
36
+ enumValues: ["row", "col"],
37
+ defaultValue: "col",
38
+ },
39
+ {
40
+ name: "gap",
41
+ type: "number | undefined",
42
+ optional: true,
43
+ control: "number",
44
+ defaultValue: "4",
45
+ },
46
+ {
47
+ name: "align",
48
+ type: '"start" | "center" | "end" | "stretch" | undefined',
49
+ optional: true,
50
+ control: "enum",
51
+ enumValues: ["start", "center", "end", "stretch"],
52
+ },
53
+ {
54
+ name: "justify",
55
+ type: '"start" | "center" | "end" | "between" | "around" | undefined',
56
+ optional: true,
57
+ control: "enum",
58
+ enumValues: ["start", "center", "end", "between", "around"],
59
+ },
60
+ {
61
+ name: "className",
62
+ type: "string | undefined",
63
+ optional: true,
64
+ control: "string",
65
+ },
66
+ ],
67
+ },
68
+ {
69
+ id: "Container",
70
+ category: "ui",
71
+ source: "velloo",
72
+ props: [
73
+ {
74
+ name: "size",
75
+ type: '"sm" | "md" | "lg" | "xl" | "full" | undefined',
76
+ optional: true,
77
+ control: "enum",
78
+ enumValues: ["sm", "md", "lg", "xl", "full"],
79
+ defaultValue: "md",
80
+ },
81
+ {
82
+ name: "className",
83
+ type: "string | undefined",
84
+ optional: true,
85
+ control: "string",
86
+ },
87
+ ],
88
+ },
89
+ {
90
+ id: "Card",
91
+ category: "ui",
92
+ source: "velloo",
93
+ props: [
94
+ {
95
+ name: "className",
96
+ type: "string | undefined",
97
+ optional: true,
98
+ control: "string",
99
+ },
100
+ ],
101
+ },
102
+ {
103
+ id: "Button",
104
+ category: "ui",
105
+ source: "velloo",
106
+ props: [
107
+ {
108
+ name: "variant",
109
+ type: '"default" | "ghost" | "outline" | undefined',
110
+ optional: true,
111
+ control: "enum",
112
+ enumValues: ["default", "ghost", "outline"],
113
+ defaultValue: "default",
114
+ },
115
+ {
116
+ name: "className",
117
+ type: "string | undefined",
118
+ optional: true,
119
+ control: "string",
120
+ },
121
+ ],
122
+ },
123
+ {
124
+ id: "Input",
125
+ category: "ui",
126
+ source: "velloo",
127
+ props: [
128
+ {
129
+ name: "placeholder",
130
+ type: "string | undefined",
131
+ optional: true,
132
+ control: "string",
133
+ },
134
+ {
135
+ name: "value",
136
+ type: "string | undefined",
137
+ optional: true,
138
+ control: "string",
139
+ },
140
+ {
141
+ name: "type",
142
+ type: "string | undefined",
143
+ optional: true,
144
+ control: "string",
145
+ defaultValue: "text",
146
+ },
147
+ {
148
+ name: "className",
149
+ type: "string | undefined",
150
+ optional: true,
151
+ control: "string",
152
+ },
153
+ ],
154
+ },
155
+ ] satisfies ComponentDescriptor[];
156
+
157
+ export const NONE_MANIFEST: Manifest = [
158
+ ...PRIMITIVE_DESCRIPTORS,
159
+ // Reused velloo helpers — the same canonical descriptors the shadcn
160
+ // snapshot's generated manifest carries (minus the build-time lucide
161
+ // name sampling for `Icon`).
162
+ ...helperDescriptors(REUSED_HELPER_IDS),
163
+ ];
@@ -0,0 +1,36 @@
1
+ import { helpersRegistry } from "@velloo/helpers";
2
+ import type { ComponentRegistry } from "@velloo/provider";
3
+ import { Box, Button, Card, Container, Heading, Input, Stack, Text } from "./components-inline.tsx";
4
+
5
+ /**
6
+ * The no-library registry for a `none`-CSS folder (inline `style` channel). Same
7
+ * shape as the Tailwind `registry`, but the primitives + typography are the
8
+ * inline-styled variants so they paint with the JIT off. The remaining helpers
9
+ * are structural (an SVG, an image, a gradient layer) — they carry no Tailwind
10
+ * visual defaults that the inline channel would lose — so they're reused
11
+ * verbatim from `@velloo/helpers`, same as the Tailwind registry. `Prose` joins
12
+ * them: its `typeset` class is velloo-owned CSS that `themeToCss` ships on every
13
+ * channel, not a Tailwind utility, so it needs no inline variant.
14
+ */
15
+ const REUSED_HELPER_IDS = [
16
+ "Prose",
17
+ "Icon",
18
+ "SVG",
19
+ "Image",
20
+ "Layer",
21
+ "Divider",
22
+ "Gradient",
23
+ "Placeholder",
24
+ ];
25
+
26
+ export const inlineRegistry: ComponentRegistry = {
27
+ Box,
28
+ Stack,
29
+ Container,
30
+ Card,
31
+ Button,
32
+ Input,
33
+ Heading,
34
+ Text,
35
+ ...helpersRegistry(REUSED_HELPER_IDS),
36
+ };
@@ -0,0 +1,39 @@
1
+ import { helpersRegistry } from "@velloo/helpers";
2
+ import type { ComponentRegistry } from "@velloo/provider";
3
+ import { Box, Button, Card, Container, Input, Stack } from "./components.tsx";
4
+
5
+ /**
6
+ * Framework-neutral velloo helpers (no portals, no providers, no shadcn
7
+ * idioms) useful in no-lib designs. Reused verbatim from `@velloo/helpers`
8
+ * instead of forking — these helpers haven't needed to change in a year.
9
+ */
10
+ export const REUSED_HELPER_IDS = [
11
+ "Heading",
12
+ "Text",
13
+ "Prose",
14
+ "Icon",
15
+ "SVG",
16
+ "Image",
17
+ "Layer",
18
+ "Divider",
19
+ "Gradient",
20
+ "Placeholder",
21
+ ] as const;
22
+
23
+ /**
24
+ * The no-library provider's runtime registry. Five bare primitives
25
+ * (`Box`, `Stack`, `Container`, `Card`, `Button`, `Input`) plus the
26
+ * reusable velloo helpers from the shadcn snapshot. No `Avatar`,
27
+ * `Tabs`, `Dialog`, etc. — those would require either a real component
28
+ * library or a custom implementation; users in this mode either don't
29
+ * need them or write them as snippets.
30
+ */
31
+ export const registry: ComponentRegistry = {
32
+ Box,
33
+ Stack,
34
+ Container,
35
+ Card,
36
+ Button,
37
+ Input,
38
+ ...helpersRegistry(REUSED_HELPER_IDS),
39
+ };
@@ -0,0 +1,57 @@
1
+ @import "tailwindcss";
2
+
3
+ @source "./components.tsx";
4
+
5
+ /*
6
+ * Same canvas-mode variant overrides as the shadcn snapshot — the
7
+ * canvas writes data-velloo-state on the selected node so the user can
8
+ * preview hover/focus/active without actually triggering the pseudo-class.
9
+ */
10
+ @custom-variant hover (&:hover, &[data-velloo-state*="hover"]);
11
+ @custom-variant focus (&:focus, &[data-velloo-state*="focus"]);
12
+ @custom-variant focus-visible (&:focus-visible, &[data-velloo-state*="focus"]);
13
+ @custom-variant active (&:active, &[data-velloo-state*="active"]);
14
+ @custom-variant disabled (&:disabled, &[data-velloo-state*="disabled"]);
15
+
16
+ /*
17
+ * Default token values. Designs override these via inline :root styles
18
+ * injected by @velloo/renderer at render time.
19
+ */
20
+ @theme {
21
+ --color-background: oklch(1 0 0);
22
+ --color-foreground: oklch(0.145 0 0);
23
+
24
+ --color-card: oklch(1 0 0);
25
+ --color-card-foreground: oklch(0.145 0 0);
26
+
27
+ --color-primary: oklch(0.205 0 0);
28
+ --color-primary-foreground: oklch(0.985 0 0);
29
+
30
+ --color-secondary: oklch(0.97 0 0);
31
+ --color-secondary-foreground: oklch(0.205 0 0);
32
+
33
+ --color-muted: oklch(0.97 0 0);
34
+ --color-muted-foreground: oklch(0.556 0 0);
35
+
36
+ --color-accent: oklch(0.97 0 0);
37
+ --color-accent-foreground: oklch(0.205 0 0);
38
+
39
+ --color-destructive: oklch(0.577 0.245 27.325);
40
+ --color-destructive-foreground: oklch(0.985 0 0);
41
+
42
+ --color-border: oklch(0.922 0 0);
43
+ --color-input: oklch(0.922 0 0);
44
+ --color-ring: oklch(0.708 0 0);
45
+
46
+ --radius: 0.5rem;
47
+
48
+ --font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
49
+ --font-mono: ui-monospace, SFMono-Regular, monospace;
50
+ }
51
+
52
+ html, body {
53
+ background: var(--color-background);
54
+ color: var(--color-foreground);
55
+ font-family: var(--font-sans);
56
+ -webkit-font-smoothing: antialiased;
57
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Version of the no-library primitive set. Bumped on breaking changes
3
+ * to the Box/Stack/Button surface (a renamed prop, a removed variant,
4
+ * a behavior change).
5
+ *
6
+ * Lives in its own module (exported as `@velloo/provider-none/version`) so
7
+ * version-only consumers — the CLI init wizard — don't pull the provider's
8
+ * registry into their import graph.
9
+ */
10
+ export const noLibVersion = "0.1.0";
@@ -0,0 +1,120 @@
1
+ import { z } from "zod";
2
+ import { ResourceIdSchema } from "./ids.ts";
3
+
4
+ /**
5
+ * Two annotation primitives, deliberately split:
6
+ *
7
+ * - **CanvasNote**: markdown board markup, either free-positioned in board
8
+ * coordinate space or attached to a node inside a frame. Lives per board
9
+ * in `boards/<id>.notes.json`.
10
+ *
11
+ * - **Annotation**: tied to a specific node in a Screen via `locator`.
12
+ * The screen id is implied by the sidecar filename
13
+ * (`screens/<screenId>.annotations.json`). Canvas draws a dashed
14
+ * connector between the annotation pill and the targeted node's
15
+ * bounding box across every Frame that shows that screen. Exposed
16
+ * read-only to the agent so designer commentary flows into the agent's
17
+ * context naturally.
18
+ *
19
+ * Both formats use markdown for `body` (a small subset: headers, bold,
20
+ * italic, line breaks, emoji as literal unicode). Stored verbatim;
21
+ * canvas renders, agent reads as-is.
22
+ */
23
+
24
+ /**
25
+ * Locator value embedded in an annotation target. Mirrors the server's
26
+ * `Locator` union but the schema package can't depend on server code so
27
+ * the validation is repeated here.
28
+ */
29
+ const AnnotationLocatorSchema = z.union([
30
+ z.array(z.number().int().nonnegative()),
31
+ z.string().regex(/^@[a-zA-Z][a-zA-Z0-9_-]*$/),
32
+ ]);
33
+
34
+ export const AnnotationTargetSchema = z.object({
35
+ /** Path array or `"@id"` string identifying the anchored node within a screen tree. */
36
+ locator: AnnotationLocatorSchema,
37
+ });
38
+ export type AnnotationTarget = z.infer<typeof AnnotationTargetSchema>;
39
+
40
+ const PositionSchema = z.union([z.object({ x: z.number(), y: z.number() }), z.literal("auto")]);
41
+
42
+ export const AnnotationSchema = z.object({
43
+ id: ResourceIdSchema,
44
+ target: AnnotationTargetSchema,
45
+ /**
46
+ * Canvas placement. `"auto"` lets the canvas position it to the left of
47
+ * the anchored node's bounding box; an explicit `{x, y}` is set when the
48
+ * user drags the annotation to override.
49
+ */
50
+ position: PositionSchema.default("auto"),
51
+ /** Markdown body. */
52
+ body: z.string(),
53
+ /** Persisted collapsed state. Optional — undefined means "use canvas default". */
54
+ collapsed: z.boolean().optional(),
55
+ /**
56
+ * Who wrote it. Agents may create annotations (questions pinned to a
57
+ * node, review remarks) but may only edit/remove their own —
58
+ * user-authored annotations remain the protected designer→agent
59
+ * channel.
60
+ */
61
+ author: z.enum(["user", "agent"]),
62
+ /**
63
+ * Provenance for an annotation pulled from a velloo-cloud share-link
64
+ * comment (the `pull_comments` sync). `commentId` keys idempotent
65
+ * re-pulls — a cloud comment lands as at most one annotation, on any
66
+ * machine that syncs this folder. `slug` names the share link it came
67
+ * from; `author` is the commenter's display name. Locally authored
68
+ * annotations never carry this field.
69
+ */
70
+ cloud: z
71
+ .object({
72
+ commentId: z.string().min(1),
73
+ slug: z.string().min(1),
74
+ author: z.string().optional(),
75
+ })
76
+ .optional(),
77
+ });
78
+ export type Annotation = z.infer<typeof AnnotationSchema>;
79
+
80
+ /**
81
+ * Anchors a note to a node inside a frame. The frame is named explicitly
82
+ * (a screen can be framed more than once on a board, and the note belongs
83
+ * to the one the author clicked) with `screenId` alongside it so the
84
+ * locator can be resolved without walking the board first.
85
+ */
86
+ export const CanvasNoteAttachmentSchema = z.object({
87
+ frameId: ResourceIdSchema,
88
+ screenId: ResourceIdSchema,
89
+ locator: AnnotationLocatorSchema,
90
+ });
91
+ export type CanvasNoteAttachment = z.infer<typeof CanvasNoteAttachmentSchema>;
92
+
93
+ export const CanvasNoteSchema = z
94
+ .object({
95
+ id: ResourceIdSchema,
96
+ /**
97
+ * Board-space placement. Required for a free note. An attached note
98
+ * omits it until the user drags the card, which pins it here — the same
99
+ * "auto until moved" rule as `Annotation.position`.
100
+ */
101
+ x: z.number().optional(),
102
+ y: z.number().optional(),
103
+ /**
104
+ * User-resizable width. Height is always derived from content (notes
105
+ * never scroll; the box expands downward).
106
+ */
107
+ width: z.number().positive(),
108
+ /** Markdown body. */
109
+ body: z.string(),
110
+ /** Present when the note is about a specific node rather than the board. */
111
+ attachment: CanvasNoteAttachmentSchema.optional(),
112
+ })
113
+ .refine(
114
+ (note) => note.attachment !== undefined || (note.x !== undefined && note.y !== undefined),
115
+ {
116
+ message: "A note without an attachment needs x and y",
117
+ path: ["x"],
118
+ },
119
+ );
120
+ export type CanvasNote = z.infer<typeof CanvasNoteSchema>;
@@ -0,0 +1,66 @@
1
+ import { z } from "zod";
2
+
3
+ /**
4
+ * Provenance for the assets `generate_asset` produced, stored in the design
5
+ * folder's `assets.json`.
6
+ *
7
+ * A generated image is the one asset a designer cannot re-derive by looking at
8
+ * it: the prompt that made it lives only in the agent transcript that ran the
9
+ * generation, so a week later nobody can nudge the image without starting over.
10
+ * Recording it next to the design turns every generated asset into something
11
+ * you can re-roll or rewrite from the canvas.
12
+ *
13
+ * Keyed by folder-relative asset path, so an image the canvas has selected
14
+ * (`/assets/hero.png` → `assets/hero.png`) is a direct lookup, and an asset
15
+ * that isn't in the map is simply one velloo didn't generate.
16
+ */
17
+ export const GeneratedAssetSchema = z.object({
18
+ /** Verbatim prompt, so it can be edited and re-run. */
19
+ prompt: z.string(),
20
+ /**
21
+ * Intent name from the cloud catalogue ("photo", "illustration", …). This is
22
+ * as specific as provenance gets on purpose: which model serves an intent is
23
+ * the cloud's to change, so recording a model name here would bake a
24
+ * server-side detail into every design folder.
25
+ */
26
+ intent: z.string(),
27
+ /** Requested aspect; absent for intents whose output follows their input. */
28
+ aspect: z.string().optional(),
29
+ /** Pixel dimensions, when the result was a raster. */
30
+ width: z.number().int().positive().optional(),
31
+ height: z.number().int().positive().optional(),
32
+ /** ISO-8601, so the panel can say how old an image is. */
33
+ generatedAt: z.string(),
34
+ /** Reference assets the generation worked from (edit/cutout/upscale). */
35
+ reference: z.array(z.string()).optional(),
36
+ /**
37
+ * The asset this one was generated to replace. Set when a regenerate ran
38
+ * from the canvas, so the chain back to the original stays walkable after
39
+ * several re-rolls.
40
+ */
41
+ replaces: z.string().optional(),
42
+ });
43
+ export type GeneratedAsset = z.infer<typeof GeneratedAssetSchema>;
44
+
45
+ export const AssetsFileSchema = z.object({
46
+ version: z.literal(1),
47
+ /** Keyed by folder-relative asset path, e.g. "assets/hero.png". */
48
+ generated: z.record(z.string(), GeneratedAssetSchema),
49
+ });
50
+ export type AssetsFile = z.infer<typeof AssetsFileSchema>;
51
+
52
+ export const EMPTY_ASSETS_FILE: AssetsFile = { version: 1, generated: {} };
53
+
54
+ /**
55
+ * Folder-relative asset path for a node's `src`, or null when the src points
56
+ * somewhere else (a remote URL, a host-app path). The canvas writes srcs as
57
+ * `/assets/<name>`; the store keys on `assets/<name>`.
58
+ */
59
+ export function assetPathFromSrc(src: string): string | null {
60
+ if (typeof src !== "string" || src.length === 0) return null;
61
+ const trimmed = src.replace(/^\.?\//, "");
62
+ if (!trimmed.startsWith("assets/")) return null;
63
+ // A query/hash is a cache-buster, not part of the stored name.
64
+ const clean = trimmed.split(/[?#]/)[0] ?? "";
65
+ return clean.length > "assets/".length ? clean : null;
66
+ }
@@ -0,0 +1,71 @@
1
+ import { z } from "zod";
2
+ import { FrameSchema } from "./frame.ts";
3
+ import { ResourceIdSchema } from "./ids.ts";
4
+
5
+ /**
6
+ * A colored, named container. Used at two levels, same shape both times:
7
+ * `config.boardGroups` holds the sidebar's groups of *boards* (an area of
8
+ * work — "Side pane", "Account page") and `Board.groups` holds a board's
9
+ * regions of *frames*. The member carries the group id (`Board.group`,
10
+ * `Frame.group`); the group itself only defines name + color.
11
+ */
12
+ export const BoardGroupSchema = z.object({
13
+ id: ResourceIdSchema,
14
+ name: z.string().min(1),
15
+ /** CSS color value; canvas uses it for the group region tint and tag chip. */
16
+ color: z.string().optional(),
17
+ });
18
+
19
+ export type BoardGroup = z.infer<typeof BoardGroupSchema>;
20
+
21
+ /**
22
+ * Cap on board names, enforced at the mutation boundary (add/update), not
23
+ * here in the on-disk schema — a pre-existing folder with a longer name
24
+ * must still load. Ids are safe regardless (slugify caps them at 48).
25
+ */
26
+ export const MAX_BOARD_NAME_LENGTH = 80;
27
+
28
+ /**
29
+ * A Board is one infinite canvas with its own collection of frames + groups.
30
+ * A design folder has many Boards (one per "flow" — onboarding, settings,
31
+ * pricing, etc.). Each Board persists as `boards/<id>.json`.
32
+ *
33
+ * Frames within a Board reference Screens by id. The same Screen can appear
34
+ * in multiple Boards (and multiple frames within a single Board); edits to
35
+ * the underlying screen propagate to every frame everywhere.
36
+ */
37
+ export const BoardSchema = z.object({
38
+ id: ResourceIdSchema,
39
+ name: z.string().min(1),
40
+ /**
41
+ * Named theme (stem of `theme/<name>.json`) the canvas applies when
42
+ * rendering this board's frames. Absent = the folder default. Lets
43
+ * candidate boards carry their own palette/typography side by side —
44
+ * mirroring the per-screen `library` twin pattern.
45
+ */
46
+ theme: z.string().min(1).optional(),
47
+ /**
48
+ * ISO timestamp of when the board was archived. **Presence is the state** —
49
+ * there is no `archived: false` twin to contradict it. Archived boards drop
50
+ * out of the sidebar, `/api/design`, `list_boards`, and a default publish,
51
+ * but stay on disk untouched and fully editable; archive is not lock.
52
+ * Absent ⇒ active, so existing folders are unaffected.
53
+ */
54
+ archivedAt: z.string().datetime().optional(),
55
+ /**
56
+ * Id of the `config.boardGroups` entry this board is filed under — the
57
+ * sidebar section it appears in. Absent ⇒ Ungrouped, which is also every
58
+ * existing folder, so grouping is additive.
59
+ */
60
+ group: z.string().min(1).optional(),
61
+ frames: z.array(FrameSchema).default([]),
62
+ /** Frame regions within this board (see {@link BoardGroupSchema}). */
63
+ groups: z.array(BoardGroupSchema).default([]),
64
+ });
65
+
66
+ export type Board = z.infer<typeof BoardSchema>;
67
+
68
+ /** Archived state is the presence of `archivedAt` — never a separate boolean. */
69
+ export function isArchived(board: Pick<Board, "archivedAt">): boolean {
70
+ return board.archivedAt !== undefined;
71
+ }
@@ -0,0 +1,107 @@
1
+ import { z } from "zod";
2
+ import { ResourceIdSchema } from "./ids.ts";
3
+
4
+ export const CommentLocatorSchema = z.union([
5
+ z.array(z.number().int().nonnegative()),
6
+ z.string().regex(/^@[a-zA-Z][a-zA-Z0-9_-]*$/),
7
+ ]);
8
+ export type CommentLocator = z.infer<typeof CommentLocatorSchema>;
9
+
10
+ export const CommentBoundsSchema = z.object({
11
+ x: z.number(),
12
+ y: z.number(),
13
+ w: z.number().nonnegative(),
14
+ h: z.number().nonnegative(),
15
+ });
16
+ export type CommentBounds = z.infer<typeof CommentBoundsSchema>;
17
+
18
+ export const CommentNodeFingerprintSchema = z.object({
19
+ ref: z.string().min(1).optional(),
20
+ text: z.string().max(500).optional(),
21
+ ancestorIds: z.array(z.string().min(1)).max(16).optional(),
22
+ });
23
+ export type CommentNodeFingerprint = z.infer<typeof CommentNodeFingerprintSchema>;
24
+
25
+ /**
26
+ * A comment anchor always names the board it was authored on. Node anchors
27
+ * additionally retain the exact frame + screen + locator and rendered bounds
28
+ * the author saw. The locator is authoritative only for the origin design
29
+ * state; bounds and fingerprint preserve honest context when it goes stale.
30
+ */
31
+ export const CommentAnchorSchema = z.discriminatedUnion("kind", [
32
+ z.object({
33
+ kind: z.literal("node"),
34
+ boardId: ResourceIdSchema,
35
+ frameId: ResourceIdSchema,
36
+ screenId: ResourceIdSchema,
37
+ locator: CommentLocatorSchema,
38
+ bounds: CommentBoundsSchema,
39
+ fingerprint: CommentNodeFingerprintSchema.optional(),
40
+ }),
41
+ z.object({
42
+ kind: z.literal("board"),
43
+ boardId: ResourceIdSchema,
44
+ x: z.number(),
45
+ y: z.number(),
46
+ }),
47
+ ]);
48
+ export type CommentAnchor = z.infer<typeof CommentAnchorSchema>;
49
+
50
+ export const CommentAuthorSchema = z.object({
51
+ kind: z.enum(["user", "agent", "reviewer"]),
52
+ displayName: z.string().min(1).max(200).optional(),
53
+ accountId: z.string().min(1).max(200).optional(),
54
+ });
55
+ export type CommentAuthor = z.infer<typeof CommentAuthorSchema>;
56
+
57
+ export const CommentMessageSchema = z
58
+ .object({
59
+ id: z.uuid(),
60
+ author: CommentAuthorSchema,
61
+ /** Empty only on a tombstone — taking a message back erases what it said. */
62
+ body: z.string().trim().max(4000),
63
+ createdAt: z.iso.datetime(),
64
+ /**
65
+ * When the author took this message back. The message stays in the thread
66
+ * so the conversation still reads in order and replies keep their
67
+ * antecedent; only the body goes.
68
+ */
69
+ deletedAt: z.iso.datetime().optional(),
70
+ })
71
+ .refine((message) => message.deletedAt !== undefined || message.body.length > 0, {
72
+ message: "A comment needs something to say",
73
+ path: ["body"],
74
+ });
75
+ export type CommentMessage = z.infer<typeof CommentMessageSchema>;
76
+
77
+ export const CommentOriginSchema = z.discriminatedUnion("kind", [
78
+ z.object({ kind: z.literal("local") }),
79
+ z.object({
80
+ kind: z.literal("published"),
81
+ slug: z.string().min(1),
82
+ versionId: z.string().min(1),
83
+ }),
84
+ ]);
85
+ export type CommentOrigin = z.infer<typeof CommentOriginSchema>;
86
+
87
+ export const CommentThreadSchema = z.object({
88
+ id: z.uuid(),
89
+ scope: z.enum(["local", "shared"]),
90
+ folderId: z.string().min(1),
91
+ boardId: ResourceIdSchema,
92
+ anchor: CommentAnchorSchema.optional(),
93
+ origin: CommentOriginSchema,
94
+ status: z.enum(["open", "resolved"]),
95
+ messages: z.array(CommentMessageSchema).min(1),
96
+ createdAt: z.iso.datetime(),
97
+ updatedAt: z.iso.datetime(),
98
+ resolvedAt: z.iso.datetime().optional(),
99
+ });
100
+ export type CommentThread = z.infer<typeof CommentThreadSchema>;
101
+
102
+ export type CommentAnchorState =
103
+ | { status: "board" }
104
+ | { status: "attached"; resolvedPath: number[] }
105
+ | { status: "stale" };
106
+
107
+ export type CommentThreadView = CommentThread & { anchorState: CommentAnchorState };