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,226 @@
1
+ // @bun
2
+ import{fail}from"./chunk-s23gtejf.js";import{FOLDER_ARG_DESCRIPTION,resolveDesignFolder}from"./chunk-8ssr8a8w.js";import{string,number,boolean,unknown,array,object}from"./chunk-bk8b7f9a.js";import"./chunk-329e3phg.js";import"./chunk-mq4znqv2.js";import"./chunk-w5rzk6ms.js";import{openUrl}from"./chunk-hggap8fq.js";import"./chunk-1bywxgc5.js";import{defineCommand}from"./chunk-2smsg2ct.js";import{writeFileSync}from"fs";import{basename,join as join3,resolve as resolve2}from"path";import{readFileSync}from"fs";import{join,resolve,sep}from"path";var AssetRefSchema=object({file:string(),mimeType:string(),bytes:number()}),TapeRecordSchema=object({seq:number().optional(),ts:string().optional(),tool:string().optional(),durationMs:number().optional(),ok:boolean().optional(),params:unknown().optional(),text:string().optional(),images:array(AssetRefSchema).optional(),isError:boolean().optional(),error:object({name:string().optional(),message:string().optional(),stack:string().optional()}).optional(),sessionId:string().optional()}),TapeMetaSchema=object({tapeId:string().optional(),startedAt:string().optional(),folder:string().optional(),pid:number().optional()}),PendingCallSchema=object({seq:number().optional(),ts:string().optional(),tool:string().optional(),params:unknown().optional(),sessionId:string().optional()});function loadTape(dir){let meta={};try{let parsed=TapeMetaSchema.safeParse(JSON.parse(readFileSync(join(dir,"meta.json"),"utf8")));if(parsed.success)meta=parsed.data}catch{}let records=[],raw="";try{raw=readFileSync(join(dir,"tape.jsonl"),"utf8")}catch{}for(let line of raw.split(`
3
+ `)){let t=line.trim();if(!t)continue;try{let parsed=TapeRecordSchema.safeParse(JSON.parse(t));if(parsed.success)records.push(parsed.data)}catch{}}let pending=[];try{let raw=JSON.parse(readFileSync(join(dir,"pending.json"),"utf8"));if(Array.isArray(raw))pending=raw.flatMap((entry)=>{let parsed=PendingCallSchema.safeParse(entry);return parsed.success?[parsed.data]:[]})}catch{}let done=new Set(records.map((r)=>r.seq));return pending=pending.filter((p)=>!done.has(p.seq)),{dir,meta,records,pending}}var ESC={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function esc(s){return s.replace(/[&<>"']/g,(c)=>ESC[c]??c)}function isBad(r){return r.ok===!1||r.isError===!0||Boolean(r.error)}function prettyJsonText(text){try{return JSON.stringify(JSON.parse(text),null,2)}catch{return text}}function fmtDuration(ms){if(ms===void 0)return"";return ms>=1000?`${(ms/1000).toFixed(2)}s`:`${ms}ms`}function fmtBytes(n){if(n>=1048576)return`${(n/1048576).toFixed(1)}MB`;if(n>=1024)return`${(n/1024).toFixed(0)}KB`;return`${n}B`}function timeOnly(iso){if(!iso)return"";let m=/T(\d{2}:\d{2}:\d{2})/.exec(iso);return m?m[1]:iso}function tapeStats(tape){let totalMs=tape.records.reduce((s,r)=>s+(r.durationMs??0),0);return{calls:tape.records.length,errors:tape.records.filter(isBad).length,totalLabel:fmtDuration(totalMs)}}function safeMimeType(mime){return/^[a-z0-9.+-]+\/[a-z0-9.+-]+$/i.test(mime)?mime:"application/octet-stream"}function inlineImage(dir,asset){let dataUri="";try{let abs=resolve(dir,asset.file);if(abs!==resolve(dir)&&!abs.startsWith(resolve(dir)+sep))return`<div class="missing">out-of-tree asset: ${esc(asset.file)}</div>`;let buf=readFileSync(abs);dataUri=`data:${safeMimeType(asset.mimeType)};base64,${buf.toString("base64")}`}catch{return`<div class="missing">missing asset: ${esc(asset.file)}</div>`}return`<img class="shot" loading="lazy" src="${dataUri}" alt="${esc(asset.file)}"/>`}function renderResult(dir,rec){if(rec.error){let head=esc([rec.error.name,rec.error.message].filter(Boolean).join(": ")||"error"),stack=rec.error.stack?`<pre class="stack">${esc(rec.error.stack)}</pre>`:"";return`<div class="err-box"><div class="err-head">${head}</div>${stack}</div>`}let parts=[];if(rec.text)parts.push(`<pre class="json">${esc(prettyJsonText(rec.text))}</pre>`);if(rec.images?.length){let imgs=rec.images.map((a)=>`<figure>${inlineImage(dir,a)}<figcaption>${esc(a.file.replace(/^assets\//,""))} \xB7 ${fmtBytes(a.bytes)}</figcaption></figure>`).join("");parts.push(`<div class="shots">${imgs}</div>`)}if(rec.isError)parts.unshift('<div class="flag">isError: true</div>');return parts.join("")||'<div class="muted">no output</div>'}function renderRow(dir,rec){let bad=isBad(rec),tool=esc(rec.tool??"?"),seq=rec.seq??"",params=esc(JSON.stringify(rec.params??null,null,2)),search=esc(`${rec.tool??""} ${rec.text??""} ${JSON.stringify(rec.params??"")}`.toLowerCase().slice(0,4000)),nShots=rec.images?.length?` \xB7 ${rec.images.length}\uD83D\uDCF7`:"";return`<details class="call${bad?" bad":""}" data-seq="${rec.seq??""}" data-error="${bad?1:0}" data-search="${search}">
4
+ <summary>
5
+ <span class="dot"></span>
6
+ <span class="seq">#${seq}</span>
7
+ <span class="tool">${tool}</span>
8
+ <span class="meta">${fmtDuration(rec.durationMs)}${nShots}</span>
9
+ <span class="ts">${esc(timeOnly(rec.ts))}</span>
10
+ </summary>
11
+ <div class="body">
12
+ <div class="col"><h4>params</h4><pre class="json">${params}</pre></div>
13
+ <div class="col"><h4>result</h4>${renderResult(dir,rec)}</div>
14
+ </div>
15
+ </details>`}function renderPendingRow(p){let tool=esc(p.tool??"?"),seq=p.seq??"",params=esc(JSON.stringify(p.params??null,null,2)),search=esc(`${p.tool??""} ${JSON.stringify(p.params??"")}`.toLowerCase().slice(0,4000));return`<details class="call pending" data-seq="${seq}" data-pending="1" data-error="0" data-search="${search}" open>
16
+ <summary>
17
+ <span class="dot"></span>
18
+ <span class="seq">#${seq}</span>
19
+ <span class="tool">${tool}</span>
20
+ <span class="meta">running\u2026</span>
21
+ <span class="ts">${esc(timeOnly(p.ts))}</span>
22
+ </summary>
23
+ <div class="body">
24
+ <div class="col"><h4>params</h4><pre class="json">${params}</pre></div>
25
+ <div class="col"><h4>result</h4><div class="muted">awaiting result \u2014 this call hasn't returned yet.</div></div>
26
+ </div>
27
+ </details>`}var STYLE=`
28
+ :root { color-scheme: dark; }
29
+ * { box-sizing: border-box; }
30
+ body { margin: 0; background: #0b0c0e; color: #d7dce3;
31
+ font: 14px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; }
32
+ code, pre, .mono { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }
33
+ header { position: sticky; top: 0; z-index: 5; background: #111317; border-bottom: 1px solid #23262d;
34
+ padding: 14px 20px; }
35
+ header h1 { margin: 0 0 4px; font-size: 15px; font-weight: 600; }
36
+ header h1 .badge { color: #8b93a1; font-weight: 400; }
37
+ .live { color: #3fb950; font-size: 11px; font-weight: 600; margin-left: 8px;
38
+ animation: pulse 1.6s ease-in-out infinite; }
39
+ @keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }
40
+ .stats { display: flex; gap: 18px; flex-wrap: wrap; color: #8b93a1; font-size: 12.5px; }
41
+ .stats b { color: #d7dce3; font-weight: 600; }
42
+ .stats .err { color: #ff6b6b; }
43
+ .bar { display: flex; gap: 10px; align-items: center; margin-top: 10px; }
44
+ .bar input[type=search] { flex: 1; max-width: 360px; background: #0b0c0e; border: 1px solid #2b2f37;
45
+ color: #d7dce3; border-radius: 6px; padding: 6px 10px; font-size: 13px; }
46
+ .bar label { color: #8b93a1; font-size: 12.5px; display: flex; gap: 6px; align-items: center; cursor: pointer; }
47
+ main { padding: 16px 20px 80px; max-width: 1200px; margin: 0 auto; }
48
+ .call { border: 1px solid #23262d; border-radius: 8px; margin-bottom: 8px; background: #111317; overflow: hidden; }
49
+ .call.bad { border-color: #5a2730; }
50
+ summary { display: flex; align-items: center; gap: 12px; padding: 10px 14px; cursor: pointer;
51
+ list-style: none; user-select: none; }
52
+ summary::-webkit-details-marker { display: none; }
53
+ summary:hover { background: #15181d; }
54
+ .dot { width: 8px; height: 8px; border-radius: 50%; background: #3fb950; flex: none; }
55
+ .call.bad .dot { background: #f85149; }
56
+ .call.pending { border-color: #5a4a1f; }
57
+ .call.pending .dot { background: #ffb86b; animation: pulse 1.2s ease-in-out infinite; }
58
+ .call.pending .meta { color: #ffb86b; }
59
+ .seq { color: #6b7280; font-variant-numeric: tabular-nums; font-size: 12px; min-width: 34px; }
60
+ .tool { font-weight: 600; font-family: ui-monospace, monospace; }
61
+ .meta { color: #8b93a1; font-size: 12px; }
62
+ .ts { margin-left: auto; color: #5b626d; font-size: 12px; font-variant-numeric: tabular-nums; }
63
+ .body { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 4px 14px 16px; }
64
+ @media (max-width: 820px) { .body { grid-template-columns: 1fr; } }
65
+ h4 { margin: 8px 0 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: #6b7280; }
66
+ pre.json { margin: 0; padding: 10px 12px; background: #0b0c0e; border: 1px solid #20242b; border-radius: 6px;
67
+ font-size: 12.5px; overflow-x: auto; white-space: pre-wrap; word-break: break-word; max-height: 460px; }
68
+ .shots { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
69
+ figure { margin: 0; }
70
+ figure img.shot { max-width: 320px; max-height: 360px; border: 1px solid #2b2f37; border-radius: 6px;
71
+ display: block; cursor: zoom-in; }
72
+ figcaption { color: #6b7280; font-size: 11px; margin-top: 4px; }
73
+ .err-box { background: #1c1011; border: 1px solid #5a2730; border-radius: 6px; padding: 10px 12px; }
74
+ .err-head { color: #ff8b8b; font-weight: 600; font-family: ui-monospace, monospace; font-size: 12.5px; }
75
+ pre.stack { margin: 8px 0 0; font-size: 11.5px; color: #c98b8b; white-space: pre-wrap; overflow-x: auto; }
76
+ .flag { color: #ffb86b; font-size: 12px; margin-bottom: 6px; }
77
+ .muted { color: #5b626d; font-size: 12.5px; }
78
+ .missing { color: #f85149; font-size: 12px; }
79
+ footer { color: #4b515b; font-size: 11.5px; text-align: center; padding: 24px; }
80
+ .lb { position: fixed; inset: 0; background: rgba(0,0,0,.92); display: none; align-items: center;
81
+ justify-content: center; z-index: 100; cursor: zoom-out; padding: 2vmin; }
82
+ .lb.open { display: flex; }
83
+ .lb img { max-width: 96vw; max-height: 96vh; border-radius: 4px; box-shadow: 0 10px 50px rgba(0,0,0,.6); }
84
+ `;function pageScript(live,initialCount){if(!live)return`
85
+ var q = document.getElementById('q');
86
+ var eo = document.getElementById('errOnly');
87
+ function apply() {
88
+ var needle = q.value.trim().toLowerCase();
89
+ var errsOnly = eo.checked;
90
+ var rows = document.querySelectorAll('.call');
91
+ for (var i = 0; i < rows.length; i++) {
92
+ var r = rows[i];
93
+ var hit = !needle || (r.getAttribute('data-search') || '').indexOf(needle) !== -1;
94
+ var isErr = r.getAttribute('data-error') === '1';
95
+ r.style.display = (hit && (!errsOnly || isErr)) ? '' : 'none';
96
+ }
97
+ }
98
+ q.addEventListener('input', apply);
99
+ eo.addEventListener('change', apply);
100
+
101
+ var lb = document.getElementById('lb'), lbimg = document.getElementById('lbimg');
102
+ document.addEventListener('click', function(e) {
103
+ var t = e.target;
104
+ if (t && t.classList && t.classList.contains('shot')) { lbimg.src = t.src; lb.classList.add('open'); }
105
+ else if (lb.classList.contains('open')) { lb.classList.remove('open'); lbimg.removeAttribute('src'); }
106
+ });
107
+ document.addEventListener('keydown', function(e) {
108
+ if (e.key === 'Escape') { lb.classList.remove('open'); lbimg.removeAttribute('src'); }
109
+ });`;return`${`
110
+ var q = document.getElementById('q');
111
+ var eo = document.getElementById('errOnly');
112
+ function apply() {
113
+ var needle = q.value.trim().toLowerCase();
114
+ var errsOnly = eo.checked;
115
+ var rows = document.querySelectorAll('.call');
116
+ for (var i = 0; i < rows.length; i++) {
117
+ var r = rows[i];
118
+ var hit = !needle || (r.getAttribute('data-search') || '').indexOf(needle) !== -1;
119
+ var isErr = r.getAttribute('data-error') === '1';
120
+ r.style.display = (hit && (!errsOnly || isErr)) ? '' : 'none';
121
+ }
122
+ }
123
+ q.addEventListener('input', apply);
124
+ eo.addEventListener('change', apply);
125
+
126
+ var lb = document.getElementById('lb'), lbimg = document.getElementById('lbimg');
127
+ document.addEventListener('click', function(e) {
128
+ var t = e.target;
129
+ if (t && t.classList && t.classList.contains('shot')) { lbimg.src = t.src; lb.classList.add('open'); }
130
+ else if (lb.classList.contains('open')) { lb.classList.remove('open'); lbimg.removeAttribute('src'); }
131
+ });
132
+ document.addEventListener('keydown', function(e) {
133
+ if (e.key === 'Escape') { lb.classList.remove('open'); lbimg.removeAttribute('src'); }
134
+ });`}
135
+
136
+ function setLive(on) {
137
+ var l = document.getElementById('liveDot');
138
+ if (!l) return;
139
+ if (on) { l.textContent = '\u25CF live'; l.style.color = '#3fb950'; l.style.animation = ''; }
140
+ else { l.textContent = '\u25CB disconnected'; l.style.color = '#f85149'; l.style.animation = 'none'; }
141
+ }
142
+ var main = document.querySelector('main');
143
+ // Upsert by call identity (seq): a row replaces any prior row with the same
144
+ // seq, so a completed call overwrites its "running" placeholder and a
145
+ // reconnect re-send can't duplicate.
146
+ function upsert(seq, html) {
147
+ var ph = document.getElementById('placeholder'); if (ph) ph.remove();
148
+ var ex = (seq != null) ? main.querySelector('.call[data-seq="' + seq + '"]') : null;
149
+ if (ex) ex.outerHTML = html; else main.insertAdjacentHTML('beforeend', html);
150
+ }
151
+ var es = new EventSource('/events?since=${initialCount}');
152
+ es.addEventListener('open', function() { setLive(true); });
153
+ es.addEventListener('call', function(ev) {
154
+ var d = JSON.parse(ev.data);
155
+ upsert(d.seq, d.html);
156
+ if (d.stats) {
157
+ document.getElementById('n-calls').textContent = d.stats.calls;
158
+ document.getElementById('n-errors').textContent = d.stats.errors;
159
+ document.getElementById('errstat').className = d.stats.errors ? 'err' : '';
160
+ document.getElementById('n-total').textContent = d.stats.totalLabel;
161
+ }
162
+ apply();
163
+ });
164
+ es.addEventListener('pending', function(ev) {
165
+ var list = JSON.parse(ev.data);
166
+ var want = {};
167
+ for (var i = 0; i < list.length; i++) want[list[i].seq] = 1;
168
+ var cur = main.querySelectorAll('.call[data-pending]');
169
+ for (var j = 0; j < cur.length; j++) {
170
+ if (!want[cur[j].getAttribute('data-seq')]) cur[j].remove();
171
+ }
172
+ for (var k = 0; k < list.length; k++) {
173
+ if (!main.querySelector('.call[data-seq="' + list[k].seq + '"]')) {
174
+ main.insertAdjacentHTML('beforeend', list[k].html);
175
+ }
176
+ }
177
+ apply();
178
+ });
179
+ es.addEventListener('reload', function() { location.reload(); });
180
+ es.onerror = function() { setLive(false); };`}function renderReport(tape,opts={}){let{dir,meta,records,pending}=tape,live=opts.live===!0,stats=tapeStats(tape),title=`velloo trace \xB7 ${meta.tapeId??"session"}`,calls=[...records.map((r)=>renderRow(dir,r)),...pending.map((p)=>renderPendingRow(p))].join(`
181
+ `),placeholder=live?'<p class="muted" id="placeholder">Waiting for MCP calls\u2026 this view updates live.</p>':'<p class="muted">No calls recorded in this tape.</p>';return`<!doctype html>
182
+ <html lang="en">
183
+ <head>
184
+ <meta charset="utf-8"/>
185
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
186
+ <title>${esc(title)}</title>
187
+ <style>${STYLE}</style>
188
+ </head>
189
+ <body>
190
+ <header>
191
+ <h1>velloo trace <span class="badge">${esc(meta.tapeId??"")}</span>${live?'<span class="live" id="liveDot">\u25CF live</span>':""}</h1>
192
+ <div class="stats">
193
+ <span><b id="n-calls">${stats.calls}</b> calls</span>
194
+ <span id="errstat" class="${stats.errors?"err":""}"><b id="n-errors">${stats.errors}</b> errors</span>
195
+ <span><b id="n-total">${stats.totalLabel}</b> total</span>
196
+ ${meta.startedAt?`<span>started <b>${esc(meta.startedAt)}</b></span>`:""}
197
+ ${meta.folder?`<span class="mono">${esc(meta.folder)}</span>`:""}
198
+ </div>
199
+ <div class="bar">
200
+ <input id="q" type="search" placeholder="filter by tool, params, or result\u2026"/>
201
+ <label><input id="errOnly" type="checkbox"/> errors only</label>
202
+ </div>
203
+ </header>
204
+ <main>
205
+ ${calls||placeholder}
206
+ </main>
207
+ <footer>Recorded MCP session \xB7 ${esc(meta.tapeId??"")}</footer>
208
+ <div class="lb" id="lb"><img id="lbimg" alt=""/></div>
209
+ <script>${pageScript(live,records.length)}</script>
210
+ </body>
211
+ </html>
212
+ `}import{existsSync,readdirSync,statSync}from"fs";import{join as join2}from"path";var TRACE_SUBDIR=join2(".velloo","trace");function isTapeDir(dir){return existsSync(join2(dir,"tape.jsonl"))}function findTapes(root){if(isTapeDir(root))return[root];let entries;try{entries=readdirSync(root)}catch{return[]}return entries.map((e)=>join2(root,e)).filter((p)=>{try{return statSync(p).isDirectory()&&isTapeDir(p)}catch{return!1}}).sort().reverse()}function newestTape(root){return findTapes(root)[0]??null}function resumeCursor(req,since){let last=req.headers.get("last-event-id");if(last&&Number.isFinite(Number(last)))return Number(last);return since}function sse(req,startDir,since,pollMs,pinned,root){let enc=new TextEncoder,timer,stream=new ReadableStream({start(controller){let curDir=startDir,sent=resumeCursor(req,since),pendingSig="",write=(s)=>controller.enqueue(enc.encode(s));write(`: connected
213
+
214
+ `),timer=setInterval(()=>{try{let newest=pinned?curDir:newestTape(root);if(!pinned&&newest&&newest!==curDir){curDir=newest,write(`event: reload
215
+ data: {}
216
+
217
+ `);return}let tape=curDir?loadTape(curDir):null,quiet=!0;if(tape&&tape.records.length>sent){let stats=tapeStats(tape);for(let i=sent;i<tape.records.length;i++){let rec=tape.records[i];if(!rec)continue;let data=JSON.stringify({html:renderRow(curDir,rec),stats,seq:rec.seq});write(`id: ${i+1}
218
+ event: call
219
+ data: ${data}
220
+
221
+ `)}sent=tape.records.length,quiet=!1}let pendingCalls=tape?.pending??[],sig=pendingCalls.map((p)=>p.seq).join(",");if(sig!==pendingSig){pendingSig=sig;let rows=pendingCalls.map((p)=>({seq:p.seq,html:renderPendingRow(p)}));write(`event: pending
222
+ data: ${JSON.stringify(rows)}
223
+
224
+ `),quiet=!1}if(quiet)write(`: ping
225
+
226
+ `)}catch{}},pollMs),req.signal.addEventListener("abort",()=>{if(timer)clearInterval(timer);try{controller.close()}catch{}})},cancel(){if(timer)clearInterval(timer)}});return new Response(stream,{headers:{"content-type":"text/event-stream","cache-control":"no-cache"}})}function serveLiveReport(opts){let pollMs=opts.pollMs??600,pinned=opts.session!==void 0,currentTape=()=>opts.session??newestTape(opts.root),server=Bun.serve({hostname:opts.hostname,port:opts.port,idleTimeout:0,fetch(req){let url=new URL(req.url);if(url.pathname==="/"){let dir=currentTape(),tape=dir?loadTape(dir):{dir:opts.root,meta:{},records:[],pending:[]};return new Response(renderReport(tape,{live:!0}),{headers:{"content-type":"text/html; charset=utf-8"}})}if(url.pathname==="/events"){let since=Number(url.searchParams.get("since")??"0")||0;return sse(req,currentTape(),since,pollMs,pinned,opts.root)}return new Response("not found",{status:404})}});return{url:`http://${opts.hostname==="0.0.0.0"?"127.0.0.1":opts.hostname}:${server.port}/`,stop:()=>server.stop(!0)}}var trace_default=defineCommand({meta:{name:"trace",description:"Render a recorded MCP session as a standalone offline HTML report"},args:{folder:{type:"positional",required:!1,description:FOLDER_ARG_DESCRIPTION},dir:{type:"string",description:"Trace root or a single tape dir (default: <folder>/.velloo/trace)"},session:{type:"string",description:"Tape id to render (default: the most recent)"},watch:{type:"boolean",description:"Serve a live report that updates as calls happen (Ctrl-C to stop)"},port:{type:"string",description:"Port for --watch (default: an ephemeral one)"},out:{type:"string",description:"Output HTML path for the static report (default: <tape>/report.html)"},list:{type:"boolean",description:"List recorded sessions and exit"},open:{type:"boolean",default:!0,description:"Open the report in your browser (use --no-open to skip)"}},async run({args}){let root=args.dir?resolve2(args.dir):join3(await resolveDesignFolder(args.folder,"trace"),TRACE_SUBDIR);if(args.watch){let session;if(args.session){if(session=findTapes(root).find((t)=>basename(t)===args.session),!session)fail("trace",`session "${args.session}" not found in ${root}.`)}let server=serveLiveReport({root,hostname:"127.0.0.1",port:args.port?Number(args.port):0,session});if(console.log(`velloo trace: live at ${server.url} \u2014 Ctrl-C to stop`),args.open)await openUrl(server.url);await new Promise((done)=>{let stop=()=>{server.stop(),done()};process.on("SIGINT",stop),process.on("SIGTERM",stop)});return}let tapes=findTapes(root);if(tapes.length===0)fail("trace",`no recorded sessions found in ${root}.`);if(args.list){for(let dir of tapes){let{meta,records}=loadTape(dir);console.log(`${meta.tapeId??basename(dir)} ${records.length} calls ${meta.startedAt??""}`.trim())}return}let tapeDir=tapes[0];if(args.session){let match=tapes.find((t)=>basename(t)===args.session);if(!match)fail("trace",`session "${args.session}" not found in ${root}.`);tapeDir=match}let tape=loadTape(tapeDir),html=renderReport(tape),out=args.out?resolve2(args.out):join3(tapeDir,"report.html");if(writeFileSync(out,html),console.log(`velloo trace: wrote ${out} (${tape.records.length} calls)`),console.log("velloo trace: tip \u2014 add `--watch` for a live report that updates as the agent works."),args.open)await openUrl(`file://${out}`)}});export{trace_default as default};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ import"./chunk-bk8b7f9a.js";import{localDesignOf}from"./chunk-329e3phg.js";import"./chunk-mq4znqv2.js";import"./chunk-w5rzk6ms.js";import{FOLDER_ARG_DESCRIPTION,resolveDesignFolder}from"./chunk-8ssr8a8w.js";import{AGENT_IDS,PROJECT_AGENT_IDS,GLOBAL_AGENT_IDS,resolveProjectRoot,DEFAULT_MCP_URL,MANUAL_AGENT_ID,manualSetupText,askAgentWiring,localDesignScopeProblem,connect}from"./chunk-1gx45384.js";import"./chunk-65wb0g7d.js";import{DesignFolderFormatError,assertFolderFormatCurrent}from"./chunk-k784090q.js";import{fail}from"./chunk-s23gtejf.js";import{createProgress}from"./chunk-79ykzywe.js";import"./chunk-1bywxgc5.js";import"./chunk-2z0k59hz.js";import{require_picocolors}from"./chunk-jrsknzjt.js";import{__toESM,defineCommand}from"./chunk-2smsg2ct.js";import{resolve}from"path";var import_picocolors=__toESM(require_picocolors(),1);var connect_default=defineCommand({meta:{name:"connect",description:"Wire the velloo MCP server into your AI coding agent's config"},args:{folder:{type:"positional",required:!1,description:FOLDER_ARG_DESCRIPTION},agent:{type:"string",description:`Comma-separated agents: ${AGENT_IDS.join(", ")}, manual \u2014 print the config for any other agent (default ${PROJECT_AGENT_IDS.join(",")})`},projectRoot:{type:"string",description:"Where to write the config (default: the velloo.json root that registers the folder, else the nearest package.json above it)"},http:{type:"boolean",default:!1,description:"Wire the HTTP transport (agent dials a running server) instead of stdio"},mcpUrl:{type:"string",description:`MCP server URL for --http (default ${DEFAULT_MCP_URL})`},skill:{type:"boolean",default:!0,description:"Install the velloo-design Claude Code skill into .claude/skills"}},async run({args}){let folder=await resolveDesignFolder(args.folder,"connect",{interactive:!0});try{assertFolderFormatCurrent(folder)}catch(err){if(!(err instanceof DesignFolderFormatError))throw err;console.log(import_picocolors.default.yellow(`\u26A0 ${err.message.slice(8)}`))}let interactive=Boolean(process.stdin.isTTY),agents,manual=!1,local=localDesignOf(folder)!==null;if(args.agent){agents=args.agent.split(",").map((s)=>s.trim()).filter(Boolean);let problem=localDesignScopeProblem(folder,agents);if(problem)fail("connect",problem)}else if(interactive){let wiring=await askAgentWiring({projectRoot:await resolveProjectRoot(folder),globalOnly:local});if(wiring===null)fail("connect","cancelled.");if(wiring.agents.length===0&&!wiring.manual){console.log(import_picocolors.default.dim("No agents selected \u2014 nothing wired."));return}manual=wiring.manual,agents=wiring.agents}else agents=local?GLOBAL_AGENT_IDS:PROJECT_AGENT_IDS;if(agents.includes(MANUAL_AGENT_ID))manual=!0,agents=agents.filter((id)=>id!==MANUAL_AGENT_ID);if(manual){console.log(""),console.log(import_picocolors.default.bold(" Manual MCP setup"));for(let line of manualSetupText().split(`
3
+ `))console.log(` ${line}`);console.log("")}if(agents.length===0)return;let progress=createProgress();progress.start("connecting agent");let result;try{result=await connect({designFolder:folder,agents,projectRoot:args.projectRoot?resolve(args.projectRoot):void 0,transport:args.http?"http":"stdio",mcpUrl:args.mcpUrl,installSkill:args.skill})}catch(error){throw progress.fail("agent connection failed"),error}if(result.unknownAgents.length>0)progress.fail("agent connection failed"),fail("connect",`unknown agent(s): ${result.unknownAgents.join(", ")}. Valid: ${AGENT_IDS.join(", ")}.`);progress.succeed("connected agent"),console.log(""),console.log(import_picocolors.default.green("\u2713 Connected velloo to your agent.")),console.log("");for(let c of result.configs)console.log(` ${c.action==="created"?"wrote ":"updated "} ${import_picocolors.default.cyan(c.path)}`);if(result.plugin)console.log(` plugin ${import_picocolors.default.cyan("velloo@velloo")} ${import_picocolors.default.dim(`(skills + commands + subagents \u2014 local marketplace at ${result.plugin.marketplaceDir})`)}`);for(let s of result.skills??[])console.log(` skill ${import_picocolors.default.cyan(s.path??s.name)}`);if(result.geminiExtension)console.log(` gemini ${import_picocolors.default.cyan(result.geminiExtension.dir)} ${result.geminiExtension.linked?import_picocolors.default.dim("(linked)"):import_picocolors.default.dim(`(link it: gemini extensions link ${result.geminiExtension.dir})`)}`);if(result.cursorRules?.installed&&result.cursorRules.path)console.log(` rule ${import_picocolors.default.cyan(result.cursorRules.path)}`);let folderArg=args.folder?` ${args.folder}`:"";if(console.log(""),console.log(import_picocolors.default.bold(" Next")),result.transport==="http")console.log(` 1. ${import_picocolors.default.cyan(`velloo mcp --http${folderArg}`)} ${import_picocolors.default.dim("\u2014 starts the MCP server your agent dials")}`),console.log(" 2. Restart your agent so it loads the new MCP config.");else console.log(` 1. Restart your agent so it loads the new MCP config ${import_picocolors.default.dim("\u2014 it starts velloo itself")}.`),console.log(` 2. ${import_picocolors.default.cyan(`velloo run${folderArg}`)} ${import_picocolors.default.dim("\u2014 optional: open the canvas to watch")}`);console.log("")}});export{connect_default as default};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ import{AuthConfigResponseSchema,AccountResponseSchema,DeviceCodeResponseSchema,DeviceTokenResponseSchema,CliTokenResponseSchema,readFailure}from"./chunk-mq4znqv2.js";import{openUrl}from"./chunk-hggap8fq.js";import{isSecureCloudUrl,assertSecureCloudUrl}from"./chunk-2z0k59hz.js";async function fetchAccount(cloudUrl,token,timeoutMs=8000){if(!isSecureCloudUrl(cloudUrl))return{status:"unreachable"};let res=await fetch(`${cloudUrl}/v1/me`,{headers:{authorization:`Bearer ${token}`},signal:AbortSignal.timeout(timeoutMs)}).catch(()=>null);if(!res)return{status:"unreachable"};if(res.status===401||res.status===403)return{status:"rejected"};if(!res.ok)return{status:"unreachable"};let parsed=AccountResponseSchema.safeParse(await res.json().catch(()=>null));if(!parsed.success)return{status:"unreachable"};let body=parsed.data;return{status:"ok",account:{email:body.email,...body.name?{name:body.name}:{},...body.tier?{tier:body.tier}:{},...body.creditMicros!==void 0?{creditMicros:body.creditMicros}:{}}}}async function verifyCredential(cloudUrl,token,timeoutMs=8000){let found=await fetchAccount(cloudUrl,token,timeoutMs);return found.status==="ok"?found.account.email:null}var sleepCancelable=(ms,signal)=>new Promise((resolve,reject)=>{if(signal.aborted){reject(Error("cancelled"));return}let timer=setTimeout(resolve,ms);signal.addEventListener("abort",()=>{clearTimeout(timer),reject(Error("cancelled"))},{once:!0})});async function performDeviceLogin(cloudUrl,onPrompt,signal){assertSecureCloudUrl(cloudUrl);let configRes=await fetch(`${cloudUrl}/v1/auth/config`).catch(()=>null);if(!configRes?.ok)throw Error(`cannot reach ${cloudUrl} \u2014 is velloo-cloud up?`);let config=AuthConfigResponseSchema.safeParse(await configRes.json().catch(()=>null)),issuer=config.success?config.data.issuer:void 0,clientId=config.success?config.data.clientId:void 0;if(issuer===void 0||clientId===void 0)throw Error(`${cloudUrl} does not advertise a sign-in service \u2014 is velloo-cloud current?`);let codeRes=await fetch(`${issuer}/api/auth/device/code`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({client_id:clientId})}).catch(()=>null);if(!codeRes?.ok)throw Error(`the auth service at ${issuer} is not answering \u2014 is it up?`);let deviceBody=DeviceCodeResponseSchema.safeParse(await codeRes.json().catch(()=>null));if(!deviceBody.success)throw Error(`the auth service at ${issuer} answered something this velloo can't read`);let device=deviceBody.data;await onPrompt({verificationUrl:device.verification_uri_complete,userCode:device.user_code,expiresIn:device.expires_in}),openUrl(device.verification_uri_complete);let deadline=Date.now()+device.expires_in*1000,intervalMs=Math.max(1,device.interval)*1000,accessToken=null,abortSignal=signal??new AbortController().signal;while(Date.now()<deadline){await sleepCancelable(intervalMs,abortSignal);let res=await fetch(`${issuer}/api/auth/device/token`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({grant_type:"urn:ietf:params:oauth:grant-type:device_code",device_code:device.device_code,client_id:clientId}),signal:abortSignal}),polled=DeviceTokenResponseSchema.safeParse(await res.json().catch(()=>({}))),body=polled.success?polled.data:{};if(body.access_token){accessToken=body.access_token;break}if(body.error==="authorization_pending")continue;if(body.error==="slow_down"){intervalMs+=5000;continue}throw Error(body.error_description??body.error??"device authorization failed")}if(!accessToken)throw Error("the sign-in code expired \u2014 run velloo login again");let exchangeRes=await fetch(`${cloudUrl}/v1/auth/cli-token`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({accessToken})});if(exchangeRes.status!==201){let{detail}=await readFailure(exchangeRes);throw Error(`token exchange failed (${exchangeRes.status}): ${detail}`)}let exchanged=CliTokenResponseSchema.safeParse(await exchangeRes.json().catch(()=>null));if(!exchanged.success)throw Error(`${cloudUrl} returned a sign-in token this velloo can't read`);return exchanged.data}
3
+ export{fetchAccount,verifyCredential,performDeviceLogin};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ import{existsSync}from"fs";import{join}from"path";function resolveProviderSrcDir(here,pkgName,envOverride){let dev=join(here,"..","src");return[envOverride,join(here,"pkgs",pkgName,"src"),dev].filter((p)=>Boolean(p)).find((d)=>existsSync(join(d,"tailwind-entry.css")))??dev}
3
+ export{resolveProviderSrcDir};
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import{isCancel,select}from"./chunk-8ssr8a8w.js";import{preflightScreens}from"./chunk-329e3phg.js";import{fail}from"./chunk-s23gtejf.js";import{copyToClipboard}from"./chunk-vbk1qhdz.js";import{require_picocolors}from"./chunk-jrsknzjt.js";import{__toESM}from"./chunk-2smsg2ct.js";import{stripVTControlCharacters}from"util";var import_picocolors=__toESM(require_picocolors(),1);function plural(count,noun){return`${count} ${noun}${count===1?"":"s"}`}function formatFailures(command,failures){let byScreen=new Map;for(let failure of failures)byScreen.set(failure.screenId,[...byScreen.get(failure.screenId)??[],failure]);let notDrawn=[...byScreen.values()].filter((group)=>group.some((failure)=>failure.componentId===null)),placeholders=[...byScreen.values()].filter((group)=>!notDrawn.includes(group)).reduce((sum,group)=>sum+group.length,0),consequences=[placeholders>0&&`${plural(placeholders,"component")} will appear as placeholders`,notDrawn.length>0&&`${plural(notDrawn.length,"screen")} will not render at all`].filter(Boolean),lines=[`${import_picocolors.default.yellow(`velloo ${command}:`)} render failures on ${plural(byScreen.size,"screen")} \u2014 ${consequences.join(", and ")}:`];for(let group of byScreen.values()){let[first]=group;if(!first)continue;let boards=first.boards.length>0?first.boards.map((board)=>board.name).join(", "):"no board";lines.push("",` ${import_picocolors.default.dim(`${boards} \u203A`)} ${import_picocolors.default.bold(first.screenName)} ${import_picocolors.default.dim(`(${first.screenId})`)}`);let pinned=group.some((failure)=>failure.componentId!==null);for(let failure of group)if(failure.componentId!==null)lines.push(` ${import_picocolors.default.cyan(failure.componentId)}: ${failure.reason}`);else{let label=pinned?"screen not drawn":"screen not drawn \u2014 the error could not be pinned on one component";lines.push(` ${import_picocolors.default.red(label)}: ${failure.reason}`)}}return lines}async function confirmRenderFailures(command,source,screens,yes){let failures=preflightScreens(source,screens);if(failures.length===0)return;let report=formatFailures(command,failures);for(let line of report)console.error(line);if(console.error(""),yes)return;if(!process.stdin.isTTY)fail(command,"refusing to continue \u2014 re-run with --yes to accept the placeholders.");for(;;){let choice=await select({message:"Continue anyway?",options:[{value:"cancel",label:"No, cancel"},{value:"continue",label:"Yes, continue with the failures"},{value:"copy",label:"Copy errors to clipboard"}],initialValue:"cancel"});if(isCancel(choice)||choice==="cancel")fail(command,"cancelled.");if(choice==="continue")return;let copied=await copyToClipboard(stripVTControlCharacters(report.join(`
3
+ `)));console.error(copied?` ${import_picocolors.default.green("\u2713")} Errors copied to the clipboard.`:import_picocolors.default.dim(" Couldn't reach a clipboard tool \u2014 copy the errors printed above."))}}
4
+ export{confirmRenderFailures};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{fail}from"./chunk-s23gtejf.js";import"./chunk-1yhc252b.js";import{SHELLS,completionScript,commandSpecs,detectShell,installCompletions}from"./chunk-7dggmqwq.js";import{require_picocolors}from"./chunk-jrsknzjt.js";import{__toESM,defineCommand}from"./chunk-2smsg2ct.js";var import_picocolors=__toESM(require_picocolors(),1);var completions_default=defineCommand({meta:{name:"completions",description:"Shell TAB completions \u2014 print the script, or install it with --install"},args:{shell:{type:"positional",required:!1,description:`Shell: ${SHELLS.join(" | ")} (default: detected from $SHELL)`},install:{type:"boolean",default:!1,description:"Write the script + wire it into your shell (idempotent)"}},async run({args}){let shell=args.shell??detectShell();if(!shell||!SHELLS.includes(shell))fail("completions",`unsupported or undetected shell${args.shell?` "${args.shell}"`:""} \u2014 pass one of: ${SHELLS.join(", ")}.`);if(!args.install){console.log(completionScript(shell,await commandSpecs()));return}let r=await installCompletions(shell);if(console.log(""),console.log(import_picocolors.default.green(`\u2713 ${shell} completions installed.`)),console.log(` script ${import_picocolors.default.cyan(r.scriptPath)}`),r.rcPath)console.log(r.rcUpdated?` rc ${import_picocolors.default.cyan(r.rcPath)} ${import_picocolors.default.dim("(source line appended)")}`:` rc ${import_picocolors.default.cyan(r.rcPath)} ${import_picocolors.default.dim("(already wired)")}`);console.log(""),console.log(import_picocolors.default.dim(shell==="fish"?" New fish sessions pick it up automatically.":` Restart your shell (or \`source ${r.rcPath}\`) to activate TAB completion.`))}});export{completions_default as default};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ function _objectWithoutPropertiesLoose(r,e){if(r==null)return{};var t={};for(var n in r)if({}.hasOwnProperty.call(r,n)){if(e.indexOf(n)!==-1)continue;t[n]=r[n]}return t}function _extends(){return _extends=Object.assign?Object.assign.bind():function(n){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var r in t)({}).hasOwnProperty.call(t,r)&&(n[r]=t[r])}return n},_extends.apply(null,arguments)}function _assertThisInitialized(e){if(e===void 0)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _setPrototypeOf(t,e){return _setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},_setPrototypeOf(t,e)}
3
+ export{_objectWithoutPropertiesLoose,_extends,_assertThisInitialized,_setPrototypeOf};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ async function openUrl(url){let cmd=process.platform==="darwin"?["open",url]:process.platform==="win32"?["cmd","/c","start","",url]:["xdg-open",url];try{await Bun.spawn(cmd,{stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited}catch{}}
3
+ export{openUrl};