velloo 0.5.0 → 0.6.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 (146) hide show
  1. package/canvas/assets/index-CnyI3aig.js +29 -0
  2. package/canvas/assets/index-GNLd0pCG.css +2 -0
  3. package/canvas/assets/lucide-all-CH8LmVh0.js +1 -0
  4. package/canvas/index.html +2 -2
  5. package/{chunk-j7tzbt3d.js → chunk-08mjtg1e.js} +1 -1
  6. package/{chunk-afe25dpr.js → chunk-1gkeepkm.js} +1 -1
  7. package/{chunk-5ma8zbty.js → chunk-1td6z6ey.js} +1 -1
  8. package/{chunk-wkqrb2tz.js → chunk-2ba6edh8.js} +1 -1
  9. package/chunk-2q561dec.js +2 -0
  10. package/chunk-2web93qz.js +2 -0
  11. package/{chunk-6ytv1v2r.js → chunk-3trkmgfr.js} +1 -1
  12. package/chunk-52m26hh4.js +3 -0
  13. package/{chunk-3ffs39e8.js → chunk-56vfy0db.js} +1 -1
  14. package/{chunk-qpv28z8d.js → chunk-56z5xd5b.js} +1 -1
  15. package/{chunk-d4r0myxr.js → chunk-63y5gdzw.js} +1 -1
  16. package/{chunk-5y9hem1j.js → chunk-6813v926.js} +257 -3
  17. package/{chunk-hr3gbak5.js → chunk-69qb8p8s.js} +1 -1
  18. package/chunk-74yxy75r.js +3 -0
  19. package/{chunk-4pkw6d9n.js → chunk-8cj4swpr.js} +5 -5
  20. package/chunk-8grzf8q1.js +2 -0
  21. package/chunk-8vam2893.js +3 -0
  22. package/{chunk-675tr675.js → chunk-8vgpffn7.js} +1 -1
  23. package/{chunk-z78c1kf8.js → chunk-96qhpth5.js} +1 -1
  24. package/{chunk-tw4kw4ps.js → chunk-ab8fga32.js} +1 -1
  25. package/{chunk-asvdqkdp.js → chunk-azeqkms7.js} +1 -1
  26. package/{chunk-df557bn4.js → chunk-bc7pkjcn.js} +1 -1
  27. package/{chunk-1h3gqy7w.js → chunk-c4spp880.js} +1 -1
  28. package/{chunk-ngbqd7kb.js → chunk-chtv0yj6.js} +184 -103
  29. package/{chunk-xzkczmgg.js → chunk-dar6wbf2.js} +1 -1
  30. package/{chunk-ryga3ny1.js → chunk-e2btp1wd.js} +1 -1
  31. package/{chunk-rd65xm6r.js → chunk-eqjtq673.js} +1 -1
  32. package/{chunk-vrvkvb0v.js → chunk-esb7n55g.js} +3 -3
  33. package/chunk-ey65err5.js +5 -0
  34. package/{chunk-cqt1dpxd.js → chunk-ff0jfn0v.js} +1 -1
  35. package/chunk-ff2vt7cz.js +12 -0
  36. package/{chunk-f45p6kcb.js → chunk-g185gx8a.js} +1 -1
  37. package/{chunk-d9kx7v12.js → chunk-h85hv05d.js} +1 -1
  38. package/{chunk-vryadew3.js → chunk-hf4adxe0.js} +2 -2
  39. package/{chunk-edgwx026.js → chunk-hjc5eg5c.js} +1 -1
  40. package/{chunk-gn9wcc1b.js → chunk-hsfpbjpc.js} +1 -1
  41. package/{chunk-4sjvdakg.js → chunk-jsvkqae2.js} +1 -1
  42. package/{chunk-b3x80jc1.js → chunk-k423dkjz.js} +1 -1
  43. package/{chunk-0wqxb8r9.js → chunk-mfch0b0t.js} +1 -1
  44. package/{chunk-cdqah1hy.js → chunk-nx09zqgs.js} +1 -1
  45. package/chunk-p93x4pn2.js +3 -0
  46. package/{chunk-ahm4zd56.js → chunk-pxaxgkaq.js} +1 -1
  47. package/{chunk-5f0xv80x.js → chunk-qwccndcd.js} +1 -1
  48. package/{chunk-33t0csxs.js → chunk-rjjc9vam.js} +1 -1
  49. package/{chunk-0wafc9aw.js → chunk-rk238m15.js} +1 -1
  50. package/chunk-t2x3mztc.js +2 -0
  51. package/{chunk-42bj6r30.js → chunk-t6qr2ay9.js} +1 -1
  52. package/chunk-ta84ehgg.js +2 -0
  53. package/chunk-tac2wvc7.js +2 -0
  54. package/chunk-tbd6wn3q.js +6 -0
  55. package/chunk-w2naqxqt.js +2 -0
  56. package/chunk-wfhv9jg4.js +2 -0
  57. package/chunk-wnj432fw.js +3 -0
  58. package/chunk-x02z2ccm.js +2 -0
  59. package/{chunk-a16mz9zf.js → chunk-xtwx2p9g.js} +1 -1
  60. package/chunk-yfvc8d2g.js +716 -0
  61. package/chunk-z73q4dq9.js +2 -0
  62. package/{chunk-ycrddh47.js → chunk-ztsckexy.js} +2 -2
  63. package/cli.js +1 -1
  64. package/package.json +1 -1
  65. package/pkgs/helpers/src/descriptors.ts +1 -0
  66. package/pkgs/helpers/src/index.ts +7 -4
  67. package/pkgs/helpers/src/lowering.ts +0 -24
  68. package/pkgs/helpers/src/primitive-classes.tsx +43 -0
  69. package/pkgs/provider-antd/src/intro.ts +3 -3
  70. package/pkgs/provider-antd/src/manifest.ts +478 -57
  71. package/pkgs/provider-antd/src/registry.ts +8 -5
  72. package/pkgs/provider-antd/src/render-pass.ts +10 -4
  73. package/pkgs/provider-antd/src/reset-css.d.ts +5 -0
  74. package/pkgs/provider-antd/src/theme.ts +54 -11
  75. package/pkgs/provider-chakra/src/manifest.ts +5 -1
  76. package/pkgs/provider-mui/src/index.ts +4 -2
  77. package/pkgs/provider-mui/src/manifest.ts +10 -1
  78. package/pkgs/provider-mui/src/render-pass.ts +15 -1
  79. package/pkgs/provider-mui/src/theme.ts +10 -4
  80. package/pkgs/provider-none/src/components.tsx +15 -50
  81. package/pkgs/provider-none/src/manifest.ts +1 -0
  82. package/pkgs/schema/src/annotation.ts +6 -3
  83. package/pkgs/schema/src/comment.ts +10 -1
  84. package/pkgs/schema/src/index.ts +13 -1
  85. package/pkgs/schema/src/node-identity.ts +92 -0
  86. package/pkgs/schema/src/node.ts +13 -4
  87. package/pkgs/schema/src/theme.ts +6 -1
  88. package/pkgs/schema/src/typeset.ts +24 -17
  89. package/pkgs/shadcn-snapshot/dist/manifest.json +1 -0
  90. package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +2 -4
  91. package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +2 -3
  92. package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +3 -4
  93. package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +2 -4
  94. package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +2 -4
  95. package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +2 -4
  96. package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +2 -4
  97. package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +3 -4
  98. package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +2 -4
  99. package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +2 -4
  100. package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +3 -4
  101. package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +1 -1
  102. package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +2 -3
  103. package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +2 -4
  104. package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +3 -4
  105. package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +3 -4
  106. package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +3 -4
  107. package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +2 -3
  108. package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +2 -4
  109. package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +2 -4
  110. package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +2 -4
  111. package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +2 -4
  112. package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +2 -4
  113. package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +3 -4
  114. package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +2 -4
  115. package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +2 -4
  116. package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +2 -4
  117. package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +2 -4
  118. package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +2 -3
  119. package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +2 -3
  120. package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +2 -4
  121. package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +2 -4
  122. package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +2 -4
  123. package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +1 -1
  124. package/pkgs/shadcn-snapshot/src/tailwind-entry.css +1 -1
  125. package/canvas/assets/index-BDBBHdHH.css +0 -2
  126. package/canvas/assets/index-QdsLJNY9.js +0 -29
  127. package/canvas/assets/lucide-all-R8DUyY-B.js +0 -1
  128. package/chunk-0rdf6trc.js +0 -2
  129. package/chunk-10hap8kc.js +0 -6
  130. package/chunk-18eqh3s1.js +0 -2
  131. package/chunk-19xyzep8.js +0 -2
  132. package/chunk-49w26e94.js +0 -5
  133. package/chunk-66qgm91k.js +0 -708
  134. package/chunk-6cgvzwec.js +0 -3
  135. package/chunk-75sc3adm.js +0 -2
  136. package/chunk-7cexzg71.js +0 -2
  137. package/chunk-98rann8t.js +0 -2
  138. package/chunk-emv1j50t.js +0 -2
  139. package/chunk-ewgdcgrk.js +0 -2
  140. package/chunk-mm8wv3bg.js +0 -3
  141. package/chunk-nkqtnwzz.js +0 -2
  142. package/chunk-q3kf8243.js +0 -3
  143. package/chunk-sb5h27w9.js +0 -3
  144. package/chunk-vgx47anc.js +0 -3
  145. package/chunk-w6f40y2x.js +0 -11
  146. package/chunk-we8hvy6e.js +0 -2
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{fail,failWithError}from"./chunk-s23gtejf.js";import{firstPositional}from"./chunk-94vx1yb0.js";import{traceEnabled}from"./chunk-6tx68d90.js";var TOLERATED={upgrade:["folder-only"]},BUILTIN_FLAGS=["help","h","version","v"],camel=(name)=>name.replace(/-([a-z0-9])/g,(_,c)=>c.toUpperCase()),kebab=(name)=>name.replace(/[A-Z]/g,(c)=>`-${c.toLowerCase()}`);async function knownFlags(args){let defs=(typeof args==="function"?await args():await args)??{},known=new Set(BUILTIN_FLAGS);for(let[name,def]of Object.entries(defs)){if(def.type==="positional")continue;let alias="alias"in def?def.alias:void 0;for(let spelling of[name,...alias===void 0?[]:[alias].flat()])known.add(spelling),known.add(camel(spelling)),known.add(kebab(spelling))}return known}function flagsIn(rawArgs){let flags=[];for(let token of rawArgs){if(token==="--")break;if(!token.startsWith("-")||token==="-"||/^-\d/.test(token))continue;if(token.startsWith("--")){let name=token.slice(2).split("=")[0]??"";flags.push(name.startsWith("no-")?name.slice(3):name)}else flags.push(...token.slice(1).split("=")[0]?.split("")??[])}return flags}function strictFlags(name,cmd){let subCommands=cmd.subCommands,table=async()=>typeof subCommands==="function"?await subCommands():await subCommands,checked=subCommands?{...cmd,subCommands:async()=>Object.fromEntries(Object.entries(await table()??{}).map(([child,load])=>[child,async()=>{let def=typeof load==="function"?await load():await load;return strictFlags(`${name} ${child}`,def)}]))}:cmd;if(subCommands&&!cmd.run)return checked;let setup=cmd.setup;return{...checked,async setup(context){if(subCommands){let child=await firstPositional(context.rawArgs,cmd.args);if(child!==void 0&&Object.hasOwn(await table()??{},child)){await setup?.(context);return}}let known=await knownFlags(cmd.args),tolerated=TOLERATED[name]??[],unknown=flagsIn(context.rawArgs).filter((flag)=>flag!==""&&!known.has(flag)&&!tolerated.includes(flag));if(unknown.length>0){let listed=[...known].filter((f)=>f.length>1&&!BUILTIN_FLAGS.includes(f)&&f===kebab(f)),hint=listed.length>0?` (it takes ${listed.map((f)=>`--${f}`).join(", ")})`:"";fail(name,`unknown option ${unknown.map((f)=>f.length===1?`-${f}`:`--${f}`).join(", ")}${hint}`)}await setup?.(context)}}}var LOADERS={init:()=>import("./chunk-18eqh3s1.js").then((m)=>m.default),login:()=>import("./chunk-cdqah1hy.js").then((m)=>m.default),logout:()=>import("./chunk-gn9wcc1b.js").then((m)=>m.default),connect:()=>import("./chunk-ryga3ny1.js").then((m)=>m.default),run:()=>import("./chunk-75sc3adm.js").then((m)=>m.default),design:()=>import("./chunk-10hap8kc.js").then((m)=>m.default),mcp:()=>import("./chunk-ahm4zd56.js").then((m)=>m.default),stop:()=>import("./chunk-q3kf8243.js").then((m)=>m.default),status:()=>import("./chunk-ewgdcgrk.js").then((m)=>m.default),__daemon:()=>import("./chunk-f45p6kcb.js").then((m)=>m.default),__update_check:()=>import("./chunk-df557bn4.js").then((m)=>m.default),render:()=>import("./chunk-19xyzep8.js").then((m)=>m.default),capture:()=>import("./chunk-3ffs39e8.js").then((m)=>m.default),browser:()=>import("./chunk-1h3gqy7w.js").then((m)=>m.default),export:()=>import("./chunk-0rdf6trc.js").then((m)=>m.default),upgrade:()=>import("./chunk-98rann8t.js").then((m)=>m.default),publish:()=>import("./chunk-ycrddh47.js").then((m)=>m.default),emit:()=>import("./chunk-w6f40y2x.js").then((m)=>m.default),theme:()=>import("./chunk-5f0xv80x.js").then((m)=>m.default),completions:()=>import("./chunk-rd65xm6r.js").then((m)=>m.default),...traceEnabled()?{trace:()=>import("./chunk-d4r0myxr.js").then((m)=>m.default)}:{}};function guarded(name,load){return async()=>{let cmd=strictFlags(name,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)]));
2
+ import{fail,failWithError}from"./chunk-s23gtejf.js";import{firstPositional}from"./chunk-94vx1yb0.js";import{traceEnabled}from"./chunk-6tx68d90.js";var TOLERATED={upgrade:["folder-only"]},BUILTIN_FLAGS=["help","h","version","v"],camel=(name)=>name.replace(/-([a-z0-9])/g,(_,c)=>c.toUpperCase()),kebab=(name)=>name.replace(/[A-Z]/g,(c)=>`-${c.toLowerCase()}`);async function knownFlags(args){let defs=(typeof args==="function"?await args():await args)??{},known=new Set(BUILTIN_FLAGS);for(let[name,def]of Object.entries(defs)){if(def.type==="positional")continue;let alias="alias"in def?def.alias:void 0;for(let spelling of[name,...alias===void 0?[]:[alias].flat()])known.add(spelling),known.add(camel(spelling)),known.add(kebab(spelling))}return known}function flagsIn(rawArgs){let flags=[];for(let token of rawArgs){if(token==="--")break;if(!token.startsWith("-")||token==="-"||/^-\d/.test(token))continue;if(token.startsWith("--")){let name=token.slice(2).split("=")[0]??"";flags.push(name.startsWith("no-")?name.slice(3):name)}else flags.push(...token.slice(1).split("=")[0]?.split("")??[])}return flags}function strictFlags(name,cmd){let subCommands=cmd.subCommands,table=async()=>typeof subCommands==="function"?await subCommands():await subCommands,checked=subCommands?{...cmd,subCommands:async()=>Object.fromEntries(Object.entries(await table()??{}).map(([child,load])=>[child,async()=>{let def=typeof load==="function"?await load():await load;return strictFlags(`${name} ${child}`,def)}]))}:cmd;if(subCommands&&!cmd.run)return checked;let setup=cmd.setup;return{...checked,async setup(context){if(subCommands){let child=await firstPositional(context.rawArgs,cmd.args);if(child!==void 0&&Object.hasOwn(await table()??{},child)){await setup?.(context);return}}let known=await knownFlags(cmd.args),tolerated=TOLERATED[name]??[],unknown=flagsIn(context.rawArgs).filter((flag)=>flag!==""&&!known.has(flag)&&!tolerated.includes(flag));if(unknown.length>0){let listed=[...known].filter((f)=>f.length>1&&!BUILTIN_FLAGS.includes(f)&&f===kebab(f)),hint=listed.length>0?` (it takes ${listed.map((f)=>`--${f}`).join(", ")})`:"";fail(name,`unknown option ${unknown.map((f)=>f.length===1?`-${f}`:`--${f}`).join(", ")}${hint}`)}await setup?.(context)}}}var LOADERS={init:()=>import("./chunk-z73q4dq9.js").then((m)=>m.default),login:()=>import("./chunk-nx09zqgs.js").then((m)=>m.default),logout:()=>import("./chunk-hsfpbjpc.js").then((m)=>m.default),connect:()=>import("./chunk-e2btp1wd.js").then((m)=>m.default),run:()=>import("./chunk-tac2wvc7.js").then((m)=>m.default),design:()=>import("./chunk-tbd6wn3q.js").then((m)=>m.default),mcp:()=>import("./chunk-pxaxgkaq.js").then((m)=>m.default),stop:()=>import("./chunk-52m26hh4.js").then((m)=>m.default),status:()=>import("./chunk-x02z2ccm.js").then((m)=>m.default),__daemon:()=>import("./chunk-g185gx8a.js").then((m)=>m.default),__update_check:()=>import("./chunk-bc7pkjcn.js").then((m)=>m.default),render:()=>import("./chunk-8grzf8q1.js").then((m)=>m.default),capture:()=>import("./chunk-56vfy0db.js").then((m)=>m.default),browser:()=>import("./chunk-c4spp880.js").then((m)=>m.default),export:()=>import("./chunk-wfhv9jg4.js").then((m)=>m.default),upgrade:()=>import("./chunk-2web93qz.js").then((m)=>m.default),publish:()=>import("./chunk-ztsckexy.js").then((m)=>m.default),emit:()=>import("./chunk-ff2vt7cz.js").then((m)=>m.default),theme:()=>import("./chunk-qwccndcd.js").then((m)=>m.default),completions:()=>import("./chunk-eqjtq673.js").then((m)=>m.default),...traceEnabled()?{trace:()=>import("./chunk-63y5gdzw.js").then((m)=>m.default)}:{}};function guarded(name,load){return async()=>{let cmd=strictFlags(name,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
3
  export{COMMANDS};
@@ -0,0 +1,12 @@
1
+ // @bun
2
+ import{emitCode,emitHtml,classNamesInJsx,hostTailwindAdvisory,loadDesignFolder,registryForScreen,emitFrameworkContextFor,hostAppRootFrom,createServerProviderLoader,resolveProviders}from"./chunk-yfvc8d2g.js";import{ScreenSchema}from"./chunk-8cj4swpr.js";import"./chunk-chtv0yj6.js";import"./chunk-1gkeepkm.js";import"./chunk-80fjfyha.js";import{fail}from"./chunk-s23gtejf.js";import"./chunk-p93x4pn2.js";import"./chunk-t6qr2ay9.js";import{findDesignConfig}from"./chunk-96qhpth5.js";import{createProgress}from"./chunk-pjtg3wnm.js";import{buildDefaultConfig}from"./chunk-8vam2893.js";import{DESIGN_ARG_DESCRIPTION,resolveDesign,pickScreen}from"./chunk-8vgpffn7.js";import{defineCommand}from"./chunk-2smsg2ct.js";import{readFile,writeFile}from"fs/promises";import{dirname,extname,isAbsolute,resolve}from"path";import{stdout}from"process";async function folderEmitContext(screenPath,screen){let found=await findDesignConfig(screenPath),design=found?await loadDesignFolder(found.folder):void 0,config=design?.config??buildDefaultConfig(),{providers,defaultProvider}=found?await resolveProviders(config,found.folder):await resolveProviders(config,dirname(screenPath),createServerProviderLoader()),framework=await emitFrameworkContextFor(screen,providers,defaultProvider,config.styling?.framework);if(framework.html){let registry=registryForScreen(screen,providers,defaultProvider,config.extensions??{},config.styling?.framework);return{emit:{},html:await emitHtml(screen,{registry,...design?{snippets:design.snippets}:{}}),tailwind:framework.tailwind}}return{emit:{...design?{snippets:design.snippets}:{},...config.extensions?{extensions:config.extensions}:{},...framework.emit},tailwind:framework.tailwind}}var emit_default=defineCommand({meta:{name:"emit",description:"Print or write agent-consumed IR for a screen."},args:{screen:{type:"positional",required:!1,description:"Screen id, or a path to a screen JSON. Omit to pick interactively."},design:{type:"string",description:DESIGN_ARG_DESCRIPTION},to:{type:"string",description:"Write IR as JSON to this path; for HTML screens, a .html path writes native markup. Omit to print the native body to stdout."},"components-alias":{type:"string",description:'Override the import prefix the IR mentions in snippet identifiers. Defaults to .design/config.json#codegen.componentsAlias, else "@/components/ui".'}},async run({args}){let interactive=Boolean(process.stdin.isTTY),screenArg=args.screen,screenPath=!!screenArg&&(screenArg.includes("/")||screenArg.endsWith(".json"))?resolve(screenArg):(await pickScreen(await resolveDesign(args.design,"emit",{designFlag:"--design"}),screenArg,interactive,"emit")).path,screenJson=JSON.parse(await readFile(screenPath,"utf8")),screen=ScreenSchema.parse(screenJson),progress=createProgress();progress.start("preparing code");try{let componentsAlias=args["components-alias"]??await readConfigAlias(screenPath),context=await folderEmitContext(screenPath,screen);if(progress.step("generating code"),context.html){let ir=context.html;if(progress.succeed("generated HTML"),args.to){let outPath=isAbsolute(args.to)?args.to:resolve(args.to),asMarkup=extname(outPath).toLowerCase()===".html";await writeFile(outPath,asMarkup?ir.html:JSON.stringify(ir,null,2),"utf8"),console.log(`velloo emit: wrote ${outPath}`);for(let warning of ir.warnings)console.log(` note: ${warning}`)}else stdout.write(`${ir.html}
3
+ `);return}let result=await emitCode(screen,{...componentsAlias?{componentsAlias}:{},...context.emit});if(!result.ok){progress.fail("code generation failed");let e=result.error;if(e.kind==="UnknownComponent")fail("emit",`unknown component: ${JSON.stringify(e.ref)}`);else if(e.kind==="SnippetNotFound")fail("emit",`snippet not found: ${JSON.stringify(e.snippetId)}`);else fail("emit",`screen not found: ${JSON.stringify(e.screenId)}`)}let found=await findDesignConfig(screenPath),advisory=found&&context.tailwind?hostTailwindAdvisory(hostAppRootFrom(found.folder,found.config.hostApp),[...result.value.classesUsed,...result.value.snippetsUsed.flatMap((s)=>classNamesInJsx(s.jsx))],[found.folder]):{v3Compat:[],warnings:[]},tailwindV3Compat=advisory.v3Compat;if(args.to){progress.step("writing code");let outPath=isAbsolute(args.to)?args.to:resolve(args.to),ir={...result.value,warnings:[...result.value.warnings,...advisory.warnings],...tailwindV3Compat.length>0?{tailwindV3Compat}:{}};await writeFile(outPath,JSON.stringify(ir,null,2),"utf8"),progress.succeed("generated code"),console.log(`velloo emit: wrote ${outPath}`);for(let warning of advisory.warnings)console.log(` note: ${warning}`);return}if(progress.succeed("generated code"),stdout.write(`// screen: ${result.value.screen.id} (${result.value.screen.name})
4
+ `),stdout.write(`// components: ${result.value.componentNames.join(", ")||"(none)"}
5
+ `),result.value.iconsUsed.length>0)stdout.write(`// icons (lucide): ${result.value.iconsUsed.join(", ")}
6
+ `);if(result.value.snippetsUsed.length>0)stdout.write(`// snippets: ${result.value.snippetsUsed.map((s)=>`${s.componentName}(${s.id})`).join(", ")}
7
+ `);for(let issue of tailwindV3Compat)stdout.write(issue.v3?`// tailwind v3 host: \`${issue.class}\` \u2192 \`${issue.v3}\` (${issue.note})
8
+ `:`// tailwind v3 host: \`${issue.class}\` \u2014 ${issue.note}
9
+ `);for(let warning of advisory.warnings)stdout.write(`// note: ${warning}
10
+ `);stdout.write(`
11
+ `),stdout.write(`${result.value.jsx}
12
+ `)}catch(error){throw progress.fail("code generation failed"),error}}});async function readConfigAlias(screenPath){return(await findDesignConfig(screenPath))?.config.codegen?.componentsAlias}export{emit_default as default};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import"./chunk-4pkw6d9n.js";import{signInRequired,boardLimitReached,topUpTokens,createServer}from"./chunk-66qgm91k.js";import"./chunk-ngbqd7kb.js";import{ok,err,GUESTS_UNAVAILABLE,GuestsResponseSchema,GuestInviteResponseSchema,GuestLinkResponseSchema,unreachable,httpFailureFrom,boardLimitFrom,describeCloudError,cloudFetch}from"./chunk-afe25dpr.js";import{loadCredential,saveCredential,deleteCredential,fetchAccount,revokeCredential,performDeviceLogin}from"./chunk-wkqrb2tz.js";import{listPublishedDesigns,unpublishDesign,listPublishDestinations,describePublishError,PUBLISH_VIEWPORT,gitContext,publishableTeams,resolvePublishTeam,listTeams,publishDesign}from"./chunk-49w26e94.js";import{TOOL_VERSION}from"./chunk-42bj6r30.js";import{updateStatus,upgradeInstalledVelloo}from"./chunk-0wafc9aw.js";import{assertLoopbackHost,daemonRoot,writeLock,removeLock,readRememberedPort,rememberPort,portCandidates,registryUpsert,registryRemove}from"./chunk-asvdqkdp.js";import"./chunk-vgx47anc.js";import{defaultCloudUrl,fetchCloudAppUrl}from"./chunk-edgwx026.js";import{defineCommand}from"./chunk-2smsg2ct.js";import{existsSync as existsSync2}from"fs";import{existsSync}from"fs";import{dirname,join}from"path";import{fileURLToPath}from"url";var here=dirname(fileURLToPath(import.meta.url));function resolveCanvasDist(){let devLayout=join(here,"..","dist");return[process.env.VELLOO_CANVAS_DIST,join(here,"canvas"),devLayout].filter((p)=>Boolean(p)).find((p)=>existsSync(join(p,"index.html")))??devLayout}var canvasDistPath=resolveCanvasDist();var ACCOUNT_TTL_MS=60000,ACCOUNT_TIMEOUT_MS=5000;function createCanvasAuth(cloudUrl,dependencies={}){let runDeviceLogin=dependencies.performDeviceLogin??performDeviceLogin,login={state:"idle"},pending=null,cached=null,cachedApp=null,describe=async(token,email)=>{if(cached&&cached.token===token&&Date.now()-cached.at<ACCOUNT_TTL_MS)return{account:cached.account,verified:cached.verified};let found=await fetchAccount(cloudUrl,token,ACCOUNT_TIMEOUT_MS),resolved=found.status==="ok"?{account:found.account,verified:!0}:{account:{email},verified:found.status==="rejected"?!1:null};return cached={token,at:Date.now(),...resolved},resolved},resolveAppUrl=async()=>{if(cachedApp&&Date.now()-cachedApp.at<ACCOUNT_TTL_MS)return cachedApp.url;let url=await fetchCloudAppUrl(cloudUrl,ACCOUNT_TIMEOUT_MS);return cachedApp={at:Date.now(),url},url},status=async()=>{let cred=await loadCredential(cloudUrl),appUrlP=resolveAppUrl();if(!cred?.token)return{loggedIn:!1,cloudUrl,appUrl:await appUrlP,verified:null,login};let[{account,verified},appUrl]=await Promise.all([describe(cred.token,cred.email),appUrlP]);return{loggedIn:!0,cloudUrl,appUrl,verified,login,...account?{account}:{}}};return{status,async beginLogin(){if(login.state==="pending")return status();let attempt=new AbortController;pending=attempt,login={state:"idle"};let settle=()=>{},ready=new Promise((resolve)=>{settle=resolve});return runDeviceLogin(cloudUrl,({verificationUrl,userCode,expiresIn})=>{login={state:"pending",userCode,verificationUrl,expiresAt:new Date(Date.now()+expiresIn*1000).toISOString()},settle()},attempt.signal).then(async(result)=>{await saveCredential(cloudUrl,result),cached=null,login={state:"idle"},await topUpTokens({url:cloudUrl,token:result.token},10).catch(()=>{return})}).catch((err)=>{login=attempt.signal.aborted?{state:"idle"}:{state:"error",message:err instanceof Error?err.message:String(err)}}).finally(()=>{if(pending===attempt)pending=null;settle()}),await ready,status()},async cancelLogin(){pending?.abort(),pending=null,login={state:"idle"}},async logout(){pending?.abort(),pending=null,login={state:"idle"},cached=null;let stored=await loadCredential(cloudUrl);if(stored)await revokeCredential(cloudUrl,stored.token);await deleteCredential(cloudUrl)}}}var guestsUrl=({baseUrl,slug},rest="")=>`${baseUrl}/v1/links/${encodeURIComponent(slug)}/guests${rest}`,json=(body)=>({method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(body)});async function listGuests(target){let body=await cloudFetch(guestsUrl(target),GuestsResponseSchema,{operation:"listing guests",token:target.token});return body.ok?ok(body.value.guests):body}function inviteGuest(target,guest){return cloudFetch(guestsUrl(target),GuestInviteResponseSchema,{operation:"inviting a guest",token:target.token,...json({email:guest.email,...guest.name?{name:guest.name}:{}})})}function resendGuestLink(target,guestId){return cloudFetch(guestsUrl(target,`/${encodeURIComponent(guestId)}/resend`),GuestInviteResponseSchema,{operation:"resending a guest's link",token:target.token,...json({})})}async function mintGuestLink(target,guestId){let body=await cloudFetch(guestsUrl(target,`/${encodeURIComponent(guestId)}/link`),GuestLinkResponseSchema,{operation:"making a guest link",token:target.token,...json({})});return body.ok?ok(body.value.guestUrl):body}async function removeGuest(target,guestId){let res=await fetch(guestsUrl(target,`/${encodeURIComponent(guestId)}`),{method:"DELETE",headers:{authorization:`Bearer ${target.token}`}}).catch((error)=>error);if(!(res instanceof Response))return err(unreachable(res,{url:target.baseUrl}));if(!res.ok)return err(await httpFailureFrom("removing a guest",res));return ok(void 0)}function createCanvasPublish(cloudUrl,auth){let tokenFor=async()=>(await loadCredential(cloudUrl))?.token,access=async()=>{if(!await tokenFor())return{state:"signed-out"};return(await auth.status().catch(()=>null))?.verified===!1?{state:"expired"}:{state:"ready"}},rejection=(error)=>error.kind==="LoggedOut"?signInRequired("expired",describeCloudError(error)):Error(describeCloudError(error)),guestRejection=(error)=>error.kind==="HttpFailure"&&error.status===403&&/\bguests requires\b/.test(error.detail)?Error(GUESTS_UNAVAILABLE):rejection(error),guestTarget=async(slug)=>{let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud");return{baseUrl:cloudUrl,token,slug}},settled=(result)=>{if(!result.ok)throw guestRejection(result.error);return result.value},publishedAt=(value)=>{let parsed=value?Date.parse(value):Number.NaN;return Number.isFinite(parsed)?parsed:Number.NEGATIVE_INFINITY},soleTeamId=async(token)=>{let listed=await listTeams(cloudUrl,token);if(!listed.ok)return null;let resolved=resolvePublishTeam(listed.value);return resolved.ok&&resolved.value.kind==="team"?resolved.value.team.id:null};return{access,async teams(){let token=await tokenFor();if(!token)return[];let listed=await listTeams(cloudUrl,token);return listed.ok?publishableTeams(listed.value):[]},async blocked(){let token=await tokenFor();if(!token)return null;let listed=await listTeams(cloudUrl,token);if(!listed.ok)return null;let resolved=resolvePublishTeam(listed.value);return!resolved.ok&&resolved.error.kind==="NoPublishableTeam"?describePublishError(resolved.error):null},async published(){let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud");let listed=await listPublishedDesigns({baseUrl:cloudUrl,token});if(!listed.ok)throw rejection(listed.error);return listed.value.map((design)=>({slug:design.slug,title:design.title??"",url:design.url,visibility:design.visibility,passwordProtected:design.passwordProtected,canManage:design.canManage,lastPublishedAt:design.lastPublishedAt,...design.guestCount!==void 0?{guestCount:design.guestCount}:{},...design.visibility==="private"&&design.teamName&&design.audience?.some((entry)=>entry.type==="team")?{onlyTeam:design.teamName}:{}})).sort((left,right)=>publishedAt(right.lastPublishedAt)-publishedAt(left.lastPublishedAt))},async unpublish(slug){let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud");let removed=await unpublishDesign({baseUrl:cloudUrl,token,slug});if(!removed.ok)throw rejection(removed.error)},guests:{async list(slug){return settled(await listGuests(await guestTarget(slug))).map(canvasGuest)},async invite(slug,guest){return canvasInvite(settled(await inviteGuest(await guestTarget(slug),guest)))},async resend(slug,guestId){return canvasInvite(settled(await resendGuestLink(await guestTarget(slug),guestId)))},async link(slug,guestId){return settled(await mintGuestLink(await guestTarget(slug),guestId))},async remove(slug,guestId){settled(await removeGuest(await guestTarget(slug),guestId))}},async destinations(host){let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud");let provenance=gitContext(host.folder.root),folderId=host.folder.config.folderId;if(!folderId){let teams=await listTeams(cloudUrl,token);if(!teams.ok)throw rejection(teams.error);let publishable=publishableTeams(teams.value);return{effectiveTeamId:publishable.length===1?publishable[0]?.id??null:null,provenance,slots:[]}}let listed=await listPublishDestinations({baseUrl:cloudUrl,token,folderId});if(!listed.ok)throw rejection(listed.error);return{...listed.value,provenance}},async run(host,request,onProgress,onWarning){let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud \u2014 sign in from the account menu first.");let teamOnlyId=request.teamOnly?request.teamId??await soleTeamId(token):null;if(request.teamOnly&&!teamOnlyId)throw Error("a team-only link needs a team to publish into \u2014 choose one");let step="start",message="starting",published=await publishDesign({baseUrl:cloudUrl,token},{folder:host.folder,providers:host.providers,defaultProvider:host.defaultProvider,snapshotCss:host.snapshotCss},{boardIds:request.boardIds,...request.title?{title:request.title}:{},visibility:teamOnlyId?"private":request.visibility,...request.password?{password:request.password}:{},destination:request.destination,...request.teamId?{teamId:request.teamId}:{},...teamOnlyId?{audience:[{type:"team",id:teamOnlyId}]}:{},...request.publicComments!==void 0?{publicComments:request.publicComments}:{},provenance:gitContext(host.folder.root),viewport:PUBLISH_VIEWPORT},(event)=>{if(event.kind==="warn"){onWarning(event.message);return}if(event.kind==="note"){onWarning(event.message);return}if(event.kind==="info")return;if(event.kind==="capture"){onProgress({step,message,capture:{done:event.done,total:event.total}});return}step=event.step,message=event.message,onProgress({step,message})});if(!published.ok){let reason=describePublishError(published.error);if(published.error.kind==="LoggedOut")throw signInRequired("expired",reason);let limit=published.error.kind==="HttpFailure"?boardLimitFrom(published.error):null;if(limit)throw boardLimitReached(limit,reason);throw Error(reason)}let outcome=published.value,teamAudience=outcome.audience?.find((entry)=>entry.type==="team");return{shareUrl:outcome.shareUrl,slug:outcome.slug,visibility:outcome.visibility,passwordProtected:outcome.passwordProtected,...teamAudience?{onlyTeam:teamAudience.name||"your team"}:{},files:outcome.files,bytes:outcome.bytes,screenshots:outcome.screenshots,boards:outcome.boards,screens:outcome.screens,created:outcome.created,...outcome.tier!==void 0?{tier:outcome.tier}:{},...outcome.history!==void 0?{history:outcome.history}:{}}}}}function canvasGuest(guest){return{id:guest.id,name:guest.name,...guest.email!==void 0?{email:guest.email}:{},createdAt:guest.createdAt,lastSeenAt:guest.lastSeenAt,linkExpiresAt:guest.linkExpiresAt??null}}function canvasInvite(invite){return{guest:canvasGuest(invite.guest),emailed:invite.delivery.sent,...invite.delivery.reason?{reason:invite.delivery.reason}:{},...invite.guestUrl?{guestUrl:invite.guestUrl}:{}}}function createCanvasUpdates(){return{async status(opts={}){let status=await updateStatus(opts);return{current:status.current,latest:status.latest,available:status.available,method:status.method,channel:status.channel,upgradable:status.upgradable,...status.reason===void 0?{}:{reason:status.reason}}},async upgrade(){let outcome=await upgradeInstalledVelloo();return{upgraded:outcome.upgraded,from:outcome.from,to:outcome.to,restartRequired:outcome.upgraded}}}}var IDLE_MS=300000;function portFree(port,host){try{return Bun.serve({port,hostname:host,fetch:()=>new Response("")}).stop(!0),!0}catch{return!1}}var daemon_default=defineCommand({meta:{name:"__daemon",hidden:!0,description:"(internal) Run the persistent canvas daemon. Spawned by `velloo run` / `velloo mcp`."},args:{folder:{type:"positional",required:!0,description:"Design folder (absolute)"},port:{type:"string",description:"Preferred canvas port"},host:{type:"string",description:"Bind hostname (default 127.0.0.1)"}},async run({args}){let root=daemonRoot(args.folder),host=args.host??"127.0.0.1";assertLoopbackHost(host);let cloudUrl=defaultCloudUrl(),cred=await loadCredential(cloudUrl),cloud={url:cloudUrl,token:cred?.token,resolveToken:async()=>(await loadCredential(cloudUrl))?.token},auth=createCanvasAuth(cloudUrl),publish=createCanvasPublish(cloudUrl,auth),updates=createCanvasUpdates(),canvasPort=portCandidates({explicit:args.port?Number(args.port):void 0,remembered:await readRememberedPort(root),root}).find((port)=>portFree(port,host))??0,handle;try{handle=await createServer({folder:root,port:canvasPort,host,mcp:{transport:"http",port:0},canvasDist:canvasDistPath,cloud,auth,publish,updates})}catch(err){if(canvasPort===0)throw err;handle=await createServer({folder:root,port:0,host,mcp:{transport:"http",port:0},canvasDist:canvasDistPath,cloud,auth,publish,updates})}let rec={root,pid:process.pid,canvasUrl:handle.url,canvasPort:handle.port,mcpUrl:handle.mcpUrl??"",mcpPort:handle.mcpPort??0,cloudUrl,version:TOOL_VERSION,startedAt:new Date().toISOString()};await writeLock(rec),await registryUpsert(rec),await rememberPort(root,handle.port).catch(()=>{return}),console.error(`velloo: canvas daemon up at ${handle.url} (mcp ${handle.mcpUrl}), pid ${process.pid}`);let stopped=!1,shutdown=async()=>{if(stopped)return;stopped=!0,removeLock(root),await registryRemove(root).catch(()=>{return}),await handle.close(),process.exit(0)};for(let signal of["SIGTERM","SIGINT"])process.on(signal,()=>{console.error(`velloo: received ${signal} \u2014 shutting down.`),shutdown()});let rootMissing=0;setInterval(()=>{if(existsSync2(root)){rootMissing=0;return}if(rootMissing+=1,rootMissing>=2)console.error(`velloo: design folder ${root} is gone \u2014 shutting down.`),shutdown()},1e4);let idleSince=Date.now();setInterval(()=>{let{canvas,mcp}=handle.connections();if(canvas+mcp>0){idleSince=null;return}if(idleSince===null){idleSince=Date.now();return}if(Date.now()-idleSince>=IDLE_MS)console.error("velloo: canvas idle for 5 min \u2014 shutting down."),shutdown()},30000),await new Promise(()=>{})}});export{daemon_default as default};
2
+ import{signInRequired,boardLimitReached,topUpTokens,createServer}from"./chunk-yfvc8d2g.js";import"./chunk-8cj4swpr.js";import"./chunk-chtv0yj6.js";import{ok,err,GUESTS_UNAVAILABLE,GuestsResponseSchema,GuestInviteResponseSchema,GuestLinkResponseSchema,unreachable,httpFailureFrom,boardLimitFrom,describeCloudError,cloudFetch}from"./chunk-1gkeepkm.js";import{loadCredential,saveCredential,deleteCredential,fetchAccount,revokeCredential,performDeviceLogin}from"./chunk-2ba6edh8.js";import{listPublishedDesigns,unpublishDesign,listPublishDestinations,describePublishError,PUBLISH_VIEWPORT,gitContext,publishableTeams,resolvePublishTeam,listTeams,publishDesign}from"./chunk-ey65err5.js";import{TOOL_VERSION}from"./chunk-t6qr2ay9.js";import{updateStatus,upgradeInstalledVelloo}from"./chunk-rk238m15.js";import{assertLoopbackHost,daemonRoot,writeLock,removeLock,readRememberedPort,rememberPort,portCandidates,registryUpsert,registryRemove}from"./chunk-azeqkms7.js";import"./chunk-74yxy75r.js";import{defaultCloudUrl,fetchCloudAppUrl}from"./chunk-hjc5eg5c.js";import{defineCommand}from"./chunk-2smsg2ct.js";import{existsSync as existsSync2}from"fs";import{existsSync}from"fs";import{dirname,join}from"path";import{fileURLToPath}from"url";var here=dirname(fileURLToPath(import.meta.url));function resolveCanvasDist(){let devLayout=join(here,"..","dist");return[process.env.VELLOO_CANVAS_DIST,join(here,"canvas"),devLayout].filter((p)=>Boolean(p)).find((p)=>existsSync(join(p,"index.html")))??devLayout}var canvasDistPath=resolveCanvasDist();var ACCOUNT_TTL_MS=60000,ACCOUNT_TIMEOUT_MS=5000;function createCanvasAuth(cloudUrl,dependencies={}){let runDeviceLogin=dependencies.performDeviceLogin??performDeviceLogin,login={state:"idle"},pending=null,cached=null,cachedApp=null,describe=async(token,email)=>{if(cached&&cached.token===token&&Date.now()-cached.at<ACCOUNT_TTL_MS)return{account:cached.account,verified:cached.verified};let found=await fetchAccount(cloudUrl,token,ACCOUNT_TIMEOUT_MS),resolved=found.status==="ok"?{account:found.account,verified:!0}:{account:{email},verified:found.status==="rejected"?!1:null};return cached={token,at:Date.now(),...resolved},resolved},resolveAppUrl=async()=>{if(cachedApp&&Date.now()-cachedApp.at<ACCOUNT_TTL_MS)return cachedApp.url;let url=await fetchCloudAppUrl(cloudUrl,ACCOUNT_TIMEOUT_MS);return cachedApp={at:Date.now(),url},url},status=async()=>{let cred=await loadCredential(cloudUrl),appUrlP=resolveAppUrl();if(!cred?.token)return{loggedIn:!1,cloudUrl,appUrl:await appUrlP,verified:null,login};let[{account,verified},appUrl]=await Promise.all([describe(cred.token,cred.email),appUrlP]);return{loggedIn:!0,cloudUrl,appUrl,verified,login,...account?{account}:{}}};return{status,async beginLogin(){if(login.state==="pending")return status();let attempt=new AbortController;pending=attempt,login={state:"idle"};let settle=()=>{},ready=new Promise((resolve)=>{settle=resolve});return runDeviceLogin(cloudUrl,({verificationUrl,userCode,expiresIn})=>{login={state:"pending",userCode,verificationUrl,expiresAt:new Date(Date.now()+expiresIn*1000).toISOString()},settle()},attempt.signal).then(async(result)=>{await saveCredential(cloudUrl,result),cached=null,login={state:"idle"},await topUpTokens({url:cloudUrl,token:result.token},10).catch(()=>{return})}).catch((err)=>{login=attempt.signal.aborted?{state:"idle"}:{state:"error",message:err instanceof Error?err.message:String(err)}}).finally(()=>{if(pending===attempt)pending=null;settle()}),await ready,status()},async cancelLogin(){pending?.abort(),pending=null,login={state:"idle"}},async logout(){pending?.abort(),pending=null,login={state:"idle"},cached=null;let stored=await loadCredential(cloudUrl);if(stored)await revokeCredential(cloudUrl,stored.token);await deleteCredential(cloudUrl)}}}var guestsUrl=({baseUrl,slug},rest="")=>`${baseUrl}/v1/links/${encodeURIComponent(slug)}/guests${rest}`,json=(body)=>({method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(body)});async function listGuests(target){let body=await cloudFetch(guestsUrl(target),GuestsResponseSchema,{operation:"listing guests",token:target.token});return body.ok?ok(body.value.guests):body}function inviteGuest(target,guest){return cloudFetch(guestsUrl(target),GuestInviteResponseSchema,{operation:"inviting a guest",token:target.token,...json({email:guest.email,...guest.name?{name:guest.name}:{}})})}function resendGuestLink(target,guestId){return cloudFetch(guestsUrl(target,`/${encodeURIComponent(guestId)}/resend`),GuestInviteResponseSchema,{operation:"resending a guest's link",token:target.token,...json({})})}async function mintGuestLink(target,guestId){let body=await cloudFetch(guestsUrl(target,`/${encodeURIComponent(guestId)}/link`),GuestLinkResponseSchema,{operation:"making a guest link",token:target.token,...json({})});return body.ok?ok(body.value.guestUrl):body}async function removeGuest(target,guestId){let res=await fetch(guestsUrl(target,`/${encodeURIComponent(guestId)}`),{method:"DELETE",headers:{authorization:`Bearer ${target.token}`}}).catch((error)=>error);if(!(res instanceof Response))return err(unreachable(res,{url:target.baseUrl}));if(!res.ok)return err(await httpFailureFrom("removing a guest",res));return ok(void 0)}function createCanvasPublish(cloudUrl,auth){let tokenFor=async()=>(await loadCredential(cloudUrl))?.token,access=async()=>{if(!await tokenFor())return{state:"signed-out"};return(await auth.status().catch(()=>null))?.verified===!1?{state:"expired"}:{state:"ready"}},rejection=(error)=>error.kind==="LoggedOut"?signInRequired("expired",describeCloudError(error)):Error(describeCloudError(error)),guestRejection=(error)=>error.kind==="HttpFailure"&&error.status===403&&/\bguests requires\b/.test(error.detail)?Error(GUESTS_UNAVAILABLE):rejection(error),guestTarget=async(slug)=>{let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud");return{baseUrl:cloudUrl,token,slug}},settled=(result)=>{if(!result.ok)throw guestRejection(result.error);return result.value},publishedAt=(value)=>{let parsed=value?Date.parse(value):Number.NaN;return Number.isFinite(parsed)?parsed:Number.NEGATIVE_INFINITY},soleTeamId=async(token)=>{let listed=await listTeams(cloudUrl,token);if(!listed.ok)return null;let resolved=resolvePublishTeam(listed.value);return resolved.ok&&resolved.value.kind==="team"?resolved.value.team.id:null};return{access,async teams(){let token=await tokenFor();if(!token)return[];let listed=await listTeams(cloudUrl,token);return listed.ok?publishableTeams(listed.value):[]},async blocked(){let token=await tokenFor();if(!token)return null;let listed=await listTeams(cloudUrl,token);if(!listed.ok)return null;let resolved=resolvePublishTeam(listed.value);return!resolved.ok&&resolved.error.kind==="NoPublishableTeam"?describePublishError(resolved.error):null},async published(){let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud");let listed=await listPublishedDesigns({baseUrl:cloudUrl,token});if(!listed.ok)throw rejection(listed.error);return listed.value.map((design)=>({slug:design.slug,title:design.title??"",url:design.url,visibility:design.visibility,passwordProtected:design.passwordProtected,canManage:design.canManage,lastPublishedAt:design.lastPublishedAt,...design.guestCount!==void 0?{guestCount:design.guestCount}:{},...design.visibility==="private"&&design.teamName&&design.audience?.some((entry)=>entry.type==="team")?{onlyTeam:design.teamName}:{}})).sort((left,right)=>publishedAt(right.lastPublishedAt)-publishedAt(left.lastPublishedAt))},async unpublish(slug){let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud");let removed=await unpublishDesign({baseUrl:cloudUrl,token,slug});if(!removed.ok)throw rejection(removed.error)},guests:{async list(slug){return settled(await listGuests(await guestTarget(slug))).map(canvasGuest)},async invite(slug,guest){return canvasInvite(settled(await inviteGuest(await guestTarget(slug),guest)))},async resend(slug,guestId){return canvasInvite(settled(await resendGuestLink(await guestTarget(slug),guestId)))},async link(slug,guestId){return settled(await mintGuestLink(await guestTarget(slug),guestId))},async remove(slug,guestId){settled(await removeGuest(await guestTarget(slug),guestId))}},async destinations(host){let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud");let provenance=gitContext(host.folder.root),folderId=host.folder.config.folderId;if(!folderId){let teams=await listTeams(cloudUrl,token);if(!teams.ok)throw rejection(teams.error);let publishable=publishableTeams(teams.value);return{effectiveTeamId:publishable.length===1?publishable[0]?.id??null:null,provenance,slots:[]}}let listed=await listPublishDestinations({baseUrl:cloudUrl,token,folderId});if(!listed.ok)throw rejection(listed.error);return{...listed.value,provenance}},async run(host,request,onProgress,onWarning){let token=await tokenFor();if(!token)throw signInRequired("signed-out","not signed in to velloo-cloud \u2014 sign in from the account menu first.");let teamOnlyId=request.teamOnly?request.teamId??await soleTeamId(token):null;if(request.teamOnly&&!teamOnlyId)throw Error("a team-only link needs a team to publish into \u2014 choose one");let step="start",message="starting",published=await publishDesign({baseUrl:cloudUrl,token},{folder:host.folder,providers:host.providers,defaultProvider:host.defaultProvider,snapshotCss:host.snapshotCss},{boardIds:request.boardIds,...request.title?{title:request.title}:{},visibility:teamOnlyId?"private":request.visibility,...request.password?{password:request.password}:{},destination:request.destination,...request.teamId?{teamId:request.teamId}:{},...teamOnlyId?{audience:[{type:"team",id:teamOnlyId}]}:{},...request.publicComments!==void 0?{publicComments:request.publicComments}:{},provenance:gitContext(host.folder.root),viewport:PUBLISH_VIEWPORT},(event)=>{if(event.kind==="warn"){onWarning(event.message);return}if(event.kind==="note"){onWarning(event.message);return}if(event.kind==="info")return;if(event.kind==="capture"){onProgress({step,message,capture:{done:event.done,total:event.total}});return}step=event.step,message=event.message,onProgress({step,message})});if(!published.ok){let reason=describePublishError(published.error);if(published.error.kind==="LoggedOut")throw signInRequired("expired",reason);let limit=published.error.kind==="HttpFailure"?boardLimitFrom(published.error):null;if(limit)throw boardLimitReached(limit,reason);throw Error(reason)}let outcome=published.value,teamAudience=outcome.audience?.find((entry)=>entry.type==="team");return{shareUrl:outcome.shareUrl,slug:outcome.slug,visibility:outcome.visibility,passwordProtected:outcome.passwordProtected,...teamAudience?{onlyTeam:teamAudience.name||"your team"}:{},files:outcome.files,bytes:outcome.bytes,screenshots:outcome.screenshots,boards:outcome.boards,screens:outcome.screens,created:outcome.created,...outcome.tier!==void 0?{tier:outcome.tier}:{},...outcome.history!==void 0?{history:outcome.history}:{}}}}}function canvasGuest(guest){return{id:guest.id,name:guest.name,...guest.email!==void 0?{email:guest.email}:{},createdAt:guest.createdAt,lastSeenAt:guest.lastSeenAt,linkExpiresAt:guest.linkExpiresAt??null}}function canvasInvite(invite){return{guest:canvasGuest(invite.guest),emailed:invite.delivery.sent,...invite.delivery.reason?{reason:invite.delivery.reason}:{},...invite.guestUrl?{guestUrl:invite.guestUrl}:{}}}function createCanvasUpdates(){return{async status(opts={}){let status=await updateStatus(opts);return{current:status.current,latest:status.latest,available:status.available,method:status.method,channel:status.channel,upgradable:status.upgradable,...status.reason===void 0?{}:{reason:status.reason}}},async upgrade(){let outcome=await upgradeInstalledVelloo();return{upgraded:outcome.upgraded,from:outcome.from,to:outcome.to,restartRequired:outcome.upgraded}}}}var IDLE_MS=300000;function portFree(port,host){try{return Bun.serve({port,hostname:host,fetch:()=>new Response("")}).stop(!0),!0}catch{return!1}}var daemon_default=defineCommand({meta:{name:"__daemon",hidden:!0,description:"(internal) Run the persistent canvas daemon. Spawned by `velloo run` / `velloo mcp`."},args:{folder:{type:"positional",required:!0,description:"Design folder (absolute)"},port:{type:"string",description:"Preferred canvas port"},host:{type:"string",description:"Bind hostname (default 127.0.0.1)"}},async run({args}){let root=daemonRoot(args.folder),host=args.host??"127.0.0.1";assertLoopbackHost(host);let cloudUrl=defaultCloudUrl(),cred=await loadCredential(cloudUrl),cloud={url:cloudUrl,token:cred?.token,resolveToken:async()=>(await loadCredential(cloudUrl))?.token},auth=createCanvasAuth(cloudUrl),publish=createCanvasPublish(cloudUrl,auth),updates=createCanvasUpdates(),canvasPort=portCandidates({explicit:args.port?Number(args.port):void 0,remembered:await readRememberedPort(root),root}).find((port)=>portFree(port,host))??0,handle;try{handle=await createServer({folder:root,port:canvasPort,host,mcp:{transport:"http",port:0},canvasDist:canvasDistPath,cloud,auth,publish,updates})}catch(err){if(canvasPort===0)throw err;handle=await createServer({folder:root,port:0,host,mcp:{transport:"http",port:0},canvasDist:canvasDistPath,cloud,auth,publish,updates})}let rec={root,pid:process.pid,canvasUrl:handle.url,canvasPort:handle.port,mcpUrl:handle.mcpUrl??"",mcpPort:handle.mcpPort??0,cloudUrl,version:TOOL_VERSION,startedAt:new Date().toISOString()};await writeLock(rec),await registryUpsert(rec),await rememberPort(root,handle.port).catch(()=>{return}),console.error(`velloo: canvas daemon up at ${handle.url} (mcp ${handle.mcpUrl}), pid ${process.pid}`);let stopped=!1,shutdown=async()=>{if(stopped)return;stopped=!0,removeLock(root),await registryRemove(root).catch(()=>{return}),await handle.close(),process.exit(0)};for(let signal of["SIGTERM","SIGINT"])process.on(signal,()=>{console.error(`velloo: received ${signal} \u2014 shutting down.`),shutdown()});let rootMissing=0;setInterval(()=>{if(existsSync2(root)){rootMissing=0;return}if(rootMissing+=1,rootMissing>=2)console.error(`velloo: design folder ${root} is gone \u2014 shutting down.`),shutdown()},1e4);let idleSince=Date.now();setInterval(()=>{let{canvas,mcp}=handle.connections();if(canvas+mcp>0){idleSince=null;return}if(idleSince===null){idleSince=Date.now();return}if(Date.now()-idleSince>=IDLE_MS)console.error("velloo: canvas idle for 5 min \u2014 shutting down."),shutdown()},30000),await new Promise(()=>{})}});export{daemon_default as default};