velloo 0.5.0 → 0.7.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.
- package/README.md +116 -227
- package/THIRD-PARTY-NOTICES.md +3 -3
- package/canvas/assets/index-BQ5710lu.js +29 -0
- package/canvas/assets/index-GNLd0pCG.css +2 -0
- package/canvas/assets/lucide-all-DIRZdJPK.js +1 -0
- package/canvas/index.html +2 -2
- package/{chunk-qpv28z8d.js → chunk-0e5j6nqs.js} +1 -1
- package/{chunk-vrvkvb0v.js → chunk-0pxm5v0b.js} +3 -3
- package/{chunk-a16mz9zf.js → chunk-0vaff40g.js} +1 -1
- package/{chunk-42bj6r30.js → chunk-3m28pvzr.js} +1 -1
- package/{chunk-33t0csxs.js → chunk-4y2xy1kf.js} +2 -2
- package/{chunk-d4r0myxr.js → chunk-531xzfq5.js} +1 -1
- package/{chunk-1h3gqy7w.js → chunk-5s1wjhtj.js} +1 -1
- package/{chunk-4pkw6d9n.js → chunk-5x4nw0zz.js} +5 -5
- package/{chunk-b3x80jc1.js → chunk-5yhnnhkd.js} +1 -1
- package/{chunk-675tr675.js → chunk-64pex3mw.js} +1 -1
- package/chunk-667ag8ts.js +2 -0
- package/chunk-7gyzh0vq.js +5 -0
- package/{chunk-4sjvdakg.js → chunk-82x2jkfq.js} +1 -1
- package/{chunk-5y9hem1j.js → chunk-84n18xgx.js} +257 -3
- package/{chunk-edgwx026.js → chunk-abr2hgay.js} +1 -1
- package/{chunk-cqt1dpxd.js → chunk-acsv6m3n.js} +1 -1
- package/{chunk-j7tzbt3d.js → chunk-asfgvzse.js} +1 -1
- package/{chunk-0wqxb8r9.js → chunk-b8vcbbrg.js} +1 -1
- package/chunk-bms1sg4c.js +2 -0
- package/chunk-brnkprt5.js +723 -0
- package/{chunk-afe25dpr.js → chunk-bys7pqdb.js} +1 -1
- package/chunk-d0j8dg1e.js +3 -0
- package/chunk-d93kpv7s.js +12 -0
- package/chunk-dvh0b2r4.js +3 -0
- package/{chunk-5ma8zbty.js → chunk-eh2xp4v6.js} +1 -1
- package/{chunk-z78c1kf8.js → chunk-ejppcfa5.js} +1 -1
- package/{chunk-ngbqd7kb.js → chunk-ex36z3b3.js} +317 -119
- package/{chunk-6ytv1v2r.js → chunk-fmcm06xb.js} +1 -1
- package/{chunk-3ffs39e8.js → chunk-fvezyap4.js} +1 -1
- package/chunk-g7d065ek.js +2 -0
- package/{chunk-tw4kw4ps.js → chunk-g8xrwjvq.js} +2 -2
- package/{chunk-df557bn4.js → chunk-gbq5wv7x.js} +1 -1
- package/chunk-gcce587w.js +3 -0
- package/{chunk-cdqah1hy.js → chunk-gfppsgvv.js} +1 -1
- package/{chunk-5f0xv80x.js → chunk-j306gr0c.js} +1 -1
- package/chunk-j4fn2a2b.js +2 -0
- package/chunk-jbgde2v9.js +2 -0
- package/{chunk-wkqrb2tz.js → chunk-kkvf0xk2.js} +1 -1
- package/{chunk-d9kx7v12.js → chunk-md4mpvqc.js} +1 -1
- package/{chunk-vryadew3.js → chunk-mdgwdqnq.js} +2 -2
- package/chunk-p93x4pn2.js +3 -0
- package/chunk-pjkkp7xa.js +2 -0
- package/chunk-qp3wahg4.js +2 -0
- package/{chunk-f45p6kcb.js → chunk-qqrac4va.js} +1 -1
- package/chunk-qrnkrkkt.js +2 -0
- package/chunk-rqd4swxx.js +2 -0
- package/{chunk-xzkczmgg.js → chunk-rxkvjyst.js} +1 -1
- package/chunk-s84vxcdv.js +4 -0
- package/chunk-sjjnm4a1.js +2 -0
- package/chunk-skk6yvnw.js +3 -0
- package/{chunk-ahm4zd56.js → chunk-sme6hv6f.js} +1 -1
- package/chunk-snak5zpr.js +5 -0
- package/{chunk-gn9wcc1b.js → chunk-srp5gyr1.js} +1 -1
- package/{chunk-rd65xm6r.js → chunk-vdbr81a3.js} +1 -1
- package/chunk-vs8j3x6t.js +3 -0
- package/{chunk-hr3gbak5.js → chunk-xg71h7nb.js} +1 -1
- package/chunk-xzf52wvn.js +6 -0
- package/chunk-ykpctq15.js +6 -0
- package/chunk-zv17t1n7.js +3 -0
- package/cli.js +1 -1
- package/launcher.cjs +3 -1
- package/package.json +1 -1
- package/pkgs/helpers/src/box.tsx +12 -6
- package/pkgs/helpers/src/descriptors.ts +7 -0
- package/pkgs/helpers/src/icon.tsx +5 -3
- package/pkgs/helpers/src/index.ts +9 -6
- package/pkgs/helpers/src/lowering.ts +0 -24
- package/pkgs/helpers/src/primitive-classes.tsx +43 -0
- package/pkgs/helpers/src/text.tsx +29 -5
- package/pkgs/provider-antd/src/intro.ts +3 -3
- package/pkgs/provider-antd/src/manifest.ts +479 -57
- package/pkgs/provider-antd/src/registry.ts +8 -5
- package/pkgs/provider-antd/src/render-pass.ts +10 -4
- package/pkgs/provider-antd/src/reset-css.d.ts +5 -0
- package/pkgs/provider-antd/src/theme.ts +54 -11
- package/pkgs/provider-chakra/src/manifest.ts +6 -1
- package/pkgs/provider-mui/src/index.ts +4 -2
- package/pkgs/provider-mui/src/manifest.ts +11 -1
- package/pkgs/provider-mui/src/render-pass.ts +15 -1
- package/pkgs/provider-mui/src/theme.ts +10 -4
- package/pkgs/provider-none/src/components-inline.tsx +20 -14
- package/pkgs/provider-none/src/components.tsx +17 -54
- package/pkgs/provider-none/src/manifest.ts +1 -0
- package/pkgs/schema/src/annotation.ts +6 -3
- package/pkgs/schema/src/comment.ts +10 -1
- package/pkgs/schema/src/config.ts +4 -1
- package/pkgs/schema/src/index.ts +16 -1
- package/pkgs/schema/src/node-identity.ts +97 -0
- package/pkgs/schema/src/node.ts +49 -23
- package/pkgs/schema/src/snippet-resolve.ts +18 -12
- package/pkgs/schema/src/svg-sanitize.ts +3 -0
- package/pkgs/schema/src/theme.ts +6 -1
- package/pkgs/schema/src/typeset.ts +45 -21
- package/pkgs/shadcn-snapshot/dist/manifest.json +7 -0
- package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +1 -1
- package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +1 -1
- package/pkgs/shadcn-snapshot/src/tailwind-entry.css +1 -1
- package/canvas/assets/index-BDBBHdHH.css +0 -2
- package/canvas/assets/index-QdsLJNY9.js +0 -29
- package/canvas/assets/lucide-all-R8DUyY-B.js +0 -1
- package/chunk-0rdf6trc.js +0 -2
- package/chunk-0wafc9aw.js +0 -4
- package/chunk-10hap8kc.js +0 -6
- package/chunk-18eqh3s1.js +0 -2
- package/chunk-19xyzep8.js +0 -2
- package/chunk-49w26e94.js +0 -5
- package/chunk-66qgm91k.js +0 -708
- package/chunk-6cgvzwec.js +0 -3
- package/chunk-75sc3adm.js +0 -2
- package/chunk-7cexzg71.js +0 -2
- package/chunk-98rann8t.js +0 -2
- package/chunk-asvdqkdp.js +0 -6
- package/chunk-emv1j50t.js +0 -2
- package/chunk-ewgdcgrk.js +0 -2
- package/chunk-mm8wv3bg.js +0 -3
- package/chunk-nkqtnwzz.js +0 -2
- package/chunk-q3kf8243.js +0 -3
- package/chunk-ryga3ny1.js +0 -3
- package/chunk-sb5h27w9.js +0 -3
- package/chunk-vgx47anc.js +0 -3
- package/chunk-w6f40y2x.js +0 -11
- package/chunk-we8hvy6e.js +0 -2
- package/chunk-ycrddh47.js +0 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{snapshotVersion2}from"./chunk-
|
|
2
|
+
import{snapshotVersion2}from"./chunk-p93x4pn2.js";import{BoardSchema,ConfigSchema,isComponentNode,ScreenSchema,SnippetSchema,ThemeSchema}from"./chunk-5x4nw0zz.js";import{parseThemeCss,writeJsonAtomic,writeText,appSourceHostFiles,writeHostFiles,derivePalette,mapDesignMd}from"./chunk-brnkprt5.js";import{CHROMIUM_INSTALL_CMD,chromiumExecutable}from"./chunk-ex36z3b3.js";import{isCancel,confirm}from"./chunk-80fjfyha.js";import{BROWSER_PROMPT_DETAIL,BROWSER_PROMPT_SIZE,installChromiumInteractive}from"./chunk-eh2xp4v6.js";import{buildDefaultConfig}from"./chunk-vs8j3x6t.js";import{isServerRenderedApp,hasHtmxMarkup}from"./chunk-nbbnb5e9.js";import{detectShell,completionsInstalled,installCompletions}from"./chunk-82x2jkfq.js";import{require_picocolors}from"./chunk-jrsknzjt.js";import{__toESM}from"./chunk-2smsg2ct.js";import{HTML_VERSION}from"./chunk-6k05kqnc.js";import{noLibVersion}from"./chunk-cxe6jjwj.js";import{MUI_VERSION}from"./chunk-mzhdrawd.js";import{ANTD_VERSION}from"./chunk-0t68szgr.js";import{CHAKRA_VERSION}from"./chunk-nwx5700b.js";import{readdir,stat}from"fs/promises";import{join}from"path";async function*walkFiles(root){let entries;try{entries=await readdir(root)}catch{return}entries.sort((a,b)=>a.localeCompare(b));for(let name of entries){if(name.startsWith("."))continue;if(name==="node_modules"||name==="dist"||name===".next")continue;let full=join(root,name),s=await stat(full).catch(()=>null);if(!s)continue;if(s.isDirectory())yield*walkFiles(full);else if(s.isFile())yield full}}async function dirExists(path){return(await stat(path).catch(()=>null))?.isDirectory()??!1}import{relative as relative3,resolve as resolve2,sep as sep3}from"path";import{readdir as readdir3}from"fs/promises";import{homedir}from"os";import{delimiter,dirname as dirname3,join as join5,relative as relative2,resolve,sep as sep2}from"path";import{readFile as readFile3,stat as stat2}from"fs/promises";import{basename as basename3,dirname as dirname2,join as join4,relative,sep}from"path";import{readFile}from"fs/promises";import{basename,join as join2}from"path";function titleCaseFromSegment(segment){if(segment==="")return"Index";if(segment==="index")return"Index";let cleaned=segment.replace(/^[_[]+|[\]]+$/g,"").replace(/[-_]+/g," ");if(!cleaned)return segment;return cleaned.charAt(0).toUpperCase()+cleaned.slice(1)}function idFromRoutePath(routePath){if(routePath==="/"||routePath==="")return"index";let out=routePath.replace(/^\//,"").replace(/\//g,"-").replace(/[[\]()]/g,"").replace(/^_/,"").replace(/[^a-zA-Z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").toLowerCase();if(out.length>64){let hash=Bun.hash(routePath).toString(36).slice(0,8);return`${out.slice(0,55).replace(/-+$/,"")}-${hash}`}return out||"index"}function nameFromRoutePath(routePath){if(routePath==="/"||routePath==="")return"Home";return routePath.replace(/^\//,"").split("/").map(titleCaseFromSegment).join(" / ")}var MAX_FILES=400,MAX_FILE_BYTES=262144,MAX_ROUTES=200;function isNoiseFile(file){let base=basename(file);if(/\.(test|spec|stories)\.[jt]sx?$/.test(base))return!0;return/\/(__tests__|__mocks__|mocks|stories|e2e|tests)\//.test(file)}function looksLikeRouteConfig(content){if(/\bcreate(Browser|Hash|Memory)Router\s*\(/.test(content))return!0;if(/\bcreateRoutesFromElements\s*\(/.test(content))return!0;if(/<Route[\s/>]/.test(content))return!0;return/\bpath\s*:\s*["'`]/.test(content)&&/\b(element|Component)\s*:/.test(content)}function atPropertyPosition(src,i){for(let j=i-1;j>=0;j--){let c=src[j];if(c===" "||c==="\t"||c===`
|
|
3
3
|
`||c==="\r")continue;return c==="{"||c===","}return!0}function parseObjectRoutes(src){let roots=[],stack=[],i=0,n=src.length;while(i<n){let c=src[i];if(c==='"'||c==="'"||c==="`"){let quote=c;i++;while(i<n&&src[i]!==quote)i+=src[i]==="\\"?2:1;i++;continue}if(c==="/"&&src[i+1]==="/"){let nl=src.indexOf(`
|
|
4
4
|
`,i);i=nl===-1?n:nl+1;continue}if(c==="/"&&src[i+1]==="*"){let end=src.indexOf("*/",i+2);i=end===-1?n:end+2;continue}if(c==="{"){stack.push({children:[]}),i++;continue}if(c==="}"){let node=stack.pop();if(node){let parent=stack[stack.length-1];if(parent)parent.children.push(node);else roots.push(node)}i++;continue}let top=stack[stack.length-1];if(top&&c&&/[A-Za-z]/.test(c)&&atPropertyPosition(src,i)){let rest=src.slice(i,i+200),path=rest.match(/^path\s*:\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`)/),pathValue=path?path[1]??path[2]??path[3]:void 0;if(path&&pathValue!==void 0){top.path=pathValue,i+=path[0].length;continue}let index=rest.match(/^index\s*:\s*true/);if(index){top.index=!0,i+=index[0].length;continue}let element=rest.match(/^(?:element|Component)\s*:\s*\(?\s*<?\s*([A-Z][\w.]*)/);if(element?.[1]!==void 0){top.element=element[1],i+=element[0].length;continue}}i++}return roots}function parseJsxRoutes(src){let roots=[],stack=[],open=/<Route\b/g,close=/<\/Route\s*>/g,tags=[];for(let m of src.matchAll(open)){let start=m.index,i=start+m[0].length,depth=0,attrs="";while(i<src.length){let c=src[i];if(c==='"'||c==="'"){let q=c,from=i;i++;while(i<src.length&&src[i]!==q)i+=src[i]==="\\"?2:1;i++,attrs+=src.slice(from,i);continue}if(c==="{")depth++;if(c==="}")depth--;if(c===">"&&depth===0)break;attrs+=c,i++}let selfClosing=attrs.trimEnd().endsWith("/"),node={children:[]},path=attrs.match(/\bpath\s*=\s*(?:"([^"]*)"|'([^']*)'|\{\s*(?:"([^"]*)"|'([^']*)')\s*\})/),pathAttr=path?path[1]??path[2]??path[3]??path[4]:void 0;if(pathAttr!==void 0)node.path=pathAttr;if(/\bindex\b(?!\s*=\s*\{?\s*false)/.test(attrs))node.index=!0;let element=attrs.match(/\b(?:element|Component)\s*=\s*\{?\s*<?\s*([A-Z][\w.]*)/);if(element?.[1]!==void 0)node.element=element[1];tags.push({at:start,kind:"open",node,selfClosing})}for(let m of src.matchAll(close))tags.push({at:m.index,kind:"close"});tags.sort((a,b)=>a.at-b.at);for(let tag of tags)if(tag.kind==="open"&&tag.node){let parent=stack[stack.length-1];if(parent)parent.children.push(tag.node);else roots.push(tag.node);if(!tag.selfClosing)stack.push(tag.node)}else if(tag.kind==="close")stack.pop();return roots}function normalizeParams(path){return path.replace(/:(\w+)\??/g,"[$1]").replace(/\?/g,"")}function joinPaths(base,path){if(path.startsWith("/"))return path;return`${base==="/"?"":base}/${path}`.replace(/\/+/g,"/").replace(/\/$/,"")||"/"}function collectPaths(nodes,base,out){for(let node of nodes){if(out.size>=MAX_ROUTES)return;let resolved=node.path?joinPaths(base,normalizeParams(node.path)):base;if(node.children.length>0){if(collectPaths(node.children,resolved,out),node.path&&node.element&&!node.children.some((c)=>c.index))addPath(node,resolved,out);continue}if(node.index)addPath(node,base,out);else if(node.path)addPath(node,resolved,out)}}function addPath(node,routePath,out){if(node.element==="Navigate")return;if(routePath.includes("*"))return;out.set(routePath,!0)}async function scanReactRouter(appRoot){let srcDir=join2(appRoot,"src"),root=await dirExists(srcDir)?srcDir:appRoot,paths=new Map,sources=new Map,seen=0;for await(let file of walkFiles(root)){if(seen>=MAX_FILES||paths.size>=MAX_ROUTES)break;if(!/\.[jt]sx?$/.test(file)||isNoiseFile(file))continue;seen++;let content=await readFile(file,"utf8").catch(()=>null);if(!content||content.length>MAX_FILE_BYTES||!looksLikeRouteConfig(content))continue;let before=paths.size;if(collectPaths(parseObjectRoutes(content),"/",paths),collectPaths(parseJsxRoutes(content),"/",paths),paths.size>before){for(let p of paths.keys())if(!sources.has(p))sources.set(p,file)}}if(paths.size===0)return null;let routes=[...paths.keys()].map((routePath)=>({id:idFromRoutePath(routePath),name:nameFromRoutePath(routePath),routePath,sourceFile:sources.get(routePath)??root})),dedupedIds=new Set,deduped=routes.filter((r)=>{if(dedupedIds.has(r.id))return!1;return dedupedIds.add(r.id),!0});return deduped.sort((a,b)=>{if(a.id==="index")return-1;if(b.id==="index")return 1;return a.id.localeCompare(b.id)}),{framework:"react-router",routes:deduped,routesRoot:root}}import{existsSync}from"fs";import{readdir as readdir2,readFile as readFile2}from"fs/promises";import{basename as basename2,dirname,join as join3}from"path";var SKIP_DIRS=new Set(["node_modules","venv","env","__pycache__","migrations","site-packages","vendor","storage","tmp","log"]);async function collectFiles(root,match,maxDepth=5,maxFiles=500){let out=[];async function recurse(dir,depth){if(out.length>=maxFiles)return;let entries=await readdir2(dir,{withFileTypes:!0}).catch(()=>null);if(!entries)return;entries.sort((a,b)=>a.name.localeCompare(b.name));for(let entry of entries){if(out.length>=maxFiles)return;if(entry.name.startsWith("."))continue;if(entry.isDirectory()){if(SKIP_DIRS.has(entry.name)||depth>=maxDepth)continue;await recurse(join3(dir,entry.name),depth+1)}else if(entry.isFile()&&match(entry.name))out.push(join3(dir,entry.name))}}return await recurse(root,0),out}function normalizeParams2(path){return path.replace(/<(?:\w+:)?(\w+)>/g,"[$1]").replace(/\{(\w+)\??\}/g,"[$1]")}function normalizePath(raw){let trimmed=(raw.startsWith("/")?raw:`/${raw}`).replace(/\/+$/,"");return trimmed===""?"/":trimmed}function isPageRoute(routePath){let first=routePath.split("/").filter(Boolean)[0]??"";return first!=="api"&&first!=="admin"&&first!=="static"&&first!=="media"}function toRoute(routePath,sourceFile){return{id:idFromRoutePath(routePath),name:nameFromRoutePath(routePath),routePath,sourceFile}}function dedupeAndSort(routes){let seen=new Set,out=[];for(let r of routes){if(seen.has(r.id))continue;seen.add(r.id),out.push(r)}return out.sort((a,b)=>{if(a.id==="index")return-1;if(b.id==="index")return 1;return a.id.localeCompare(b.id)}),out}async function scanDjango(appRoot){let files=await collectFiles(appRoot,(n)=>n==="urls.py"),routes=[];for(let file of files){let content=await readFile2(file,"utf8").catch(()=>null);if(!content)continue;let pkgDir=dirname(file),prefix=existsSync(join3(pkgDir,"settings.py"))||pkgDir===appRoot?"":`/${basename2(pkgDir)}`,entry=/\b(?:path|re_path|url)\(\s*r?["']([^"']*)["']/g;for(let m of content.matchAll(entry)){let rest=content.slice(m.index,content.indexOf(`
|
|
5
5
|
`,m.index));if(rest.includes("include(")||rest.includes("admin.site.urls"))continue;let raw=m[1]??"";if(raw=raw.replace(/^\^/,"").replace(/\$$/,""),raw=raw.replace(/\(\?P<(\w+)>[^)]*\)/g,"[$1]"),raw=normalizeParams2(raw),/[\\^$+*?()|]/.test(raw))continue;let routePath=normalizePath(`${prefix}/${raw}`.replace(/\/+/g,"/"));if(!isPageRoute(routePath))continue;routes.push(toRoute(routePath,file))}}return dedupeAndSort(routes)}async function scanPythonDecorators(appRoot){let files=await collectFiles(appRoot,(n)=>n.endsWith(".py")),routes=[];for(let file of files){let content=await readFile2(file,"utf8").catch(()=>null);if(!content)continue;let entry=/@\w+\.(route|get)\(\s*["']([^"']+)["']([^)\n]*)/g;for(let m of content.matchAll(entry)){let[,kind,raw,rest]=m;if(kind==="route"&&rest&&/methods\s*=/.test(rest)&&!/GET/.test(rest))continue;let routePath=normalizePath(normalizeParams2(raw??""));if(!isPageRoute(routePath))continue;routes.push(toRoute(routePath,file))}}return dedupeAndSort(routes)}async function scanRails(routesRb){let content=await readFile2(routesRb,"utf8").catch(()=>null);if(!content)return[];let routes=[];for(let line of content.split(`
|
|
@@ -42,7 +42,7 @@ Trips that feel a little more like you.`,className:"whitespace-pre-line mt-6 tex
|
|
|
42
42
|
More looking forward.`,className:"font-display font-normal tracking-[-0.035em] text-3xl md:text-4xl whitespace-pre-line mt-3 text-white","data-accent":"ok"}},{$ref:"Text",$id:"elsewhere-overview-33",props:{children:"Your trip is coming together beautifully.",className:"text-xs mt-3 text-white/80","data-accent":"ok"}}]}]},{$ref:"Box",$id:"elsewhere-overview-34",props:{className:"grid grid-cols-2 md:grid-cols-4 gap-4"},children:[{$snippet:"elsewhere-metric",args:{label:"Departure",value:"12 October",note:"34 days to go"}},{$snippet:"elsewhere-metric",args:{label:"Your stay",value:"5 nights",note:"Higashiyama, Kyoto"}},{$snippet:"elsewhere-metric",args:{label:"Trip budget",value:"$3,200",note:"$1,470 still available"}},{$snippet:"elsewhere-metric",args:{label:"Your discoveries",value:"12 saved",note:"4 added to your itinerary"}}]},{$ref:"Box",$id:"elsewhere-overview-35",props:{className:"grid md:grid-cols-[1.4fr_1fr] gap-6"},children:[{$ref:"Card",$id:"elsewhere-overview-36",props:{className:"p-6 rounded-xl shadow-none gap-5"},children:[{$ref:"Box",$id:"elsewhere-overview-37",props:{className:"flex justify-between items-center"},children:[{$ref:"Heading",$id:"elsewhere-overview-38",props:{children:"A little room for spontaneity.",className:"font-display font-normal tracking-[-0.035em] text-2xl"}},{$ref:"Badge",$id:"elsewhere-overview-39",props:{variant:"secondary",className:"rounded-full px-3 py-1 font-normal",children:"On track"}}]},{$ref:"Box",$id:"elsewhere-overview-40",props:{className:"flex items-baseline gap-2"},children:[{$ref:"Heading",$id:"elsewhere-overview-41",props:{children:"$1,730",className:"font-display font-normal tracking-[-0.035em] text-4xl"}},{$ref:"Text",$id:"elsewhere-overview-42",props:{children:"of $3,200 planned",className:"text-xs text-muted-foreground"}}]},{$ref:"Progress",$id:"elsewhere-overview-43",props:{value:54,className:"h-2"}},{$ref:"Chart",$id:"elsewhere-overview-44",props:{kind:"bar",categories:["Stay","Food","Experiences","Transport"],series:[{name:"Planned",data:[970,360,240,160]}],className:"h-[200px] w-full",legend:!1,yLabel:"$"}},{$ref:"Box",$id:"elsewhere-overview-45",props:{className:"flex justify-between text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"elsewhere-overview-46",props:{children:"A comfortable budget for two.",className:""}},{$ref:"Button",$id:"elsewhere-overview-47",props:{variant:"ghost",className:"rounded-full h-6 text-xs"},children:[{$ref:"Icon",$id:"elsewhere-overview-48",props:{name:"ArrowUpRight",className:"size-4"}},{$ref:"Text",$id:"elsewhere-overview-49",props:{children:"View budget",className:" text-inherit",style:{color:"inherit"}}}]}]}]},{$ref:"Card",$id:"elsewhere-overview-50",props:{className:"p-6 rounded-xl shadow-none gap-4"},children:[{$ref:"Box",$id:"elsewhere-overview-51",props:{className:"flex justify-between"},children:[{$ref:"Heading",$id:"elsewhere-overview-52",props:{children:"Kyoto in October",className:"font-display font-normal tracking-[-0.035em] text-2xl"}},{$ref:"Icon",$id:"elsewhere-overview-53",props:{name:"Sun",className:"size-5"}}]},{$ref:"Box",$id:"elsewhere-overview-54",props:{className:"flex items-baseline gap-2"},children:[{$ref:"Heading",$id:"elsewhere-overview-55",props:{children:"22\xB0",className:"font-display font-normal tracking-[-0.035em] text-4xl"}},{$ref:"Text",$id:"elsewhere-overview-56",props:{children:"a little cooler, a little quieter",className:"text-xs text-muted-foreground"}}]},{$ref:"Chart",$id:"elsewhere-overview-57",props:{kind:"line",categories:["May","Jun","Jul","Aug","Sep","Oct","Nov"],series:[{name:"Typical daytime \xB0C",data:[25,28,32,33,29,22,17]}],className:"h-[170px] w-full",legend:!1,yLabel:"\xB0C"}},{$ref:"Text",$id:"elsewhere-overview-58",props:{children:"Crisp mornings, warm afternoons. Pack a light layer and your most comfortable shoes.",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Card",$id:"elsewhere-overview-59",props:{className:"p-6 rounded-xl shadow-none gap-4"},children:[{$ref:"Box",$id:"elsewhere-overview-60",props:{className:"flex justify-between items-center"},children:[{$ref:"Heading",$id:"elsewhere-overview-61",props:{children:"The essentials, taken care of.",className:"font-display font-normal tracking-[-0.035em] text-2xl"}},{$ref:"Button",$id:"elsewhere-overview-62",props:{variant:"ghost",className:"rounded-full "},children:[{$ref:"Icon",$id:"elsewhere-overview-63",props:{name:"ArrowUpRight",className:"size-4"}},{$ref:"Text",$id:"elsewhere-overview-64",props:{children:"All bookings",className:" text-inherit",style:{color:"inherit"}}}]}]},{$ref:"Table",$id:"elsewhere-overview-65",props:{},children:[{$ref:"TableHeader",$id:"elsewhere-overview-66",props:{},children:[{$ref:"TableRow",$id:"elsewhere-overview-67",props:{},children:[{$ref:"TableHead",$id:"elsewhere-overview-68",props:{children:"Booking",className:"text-xs"}},{$ref:"TableHead",$id:"elsewhere-overview-69",props:{children:"Dates",className:"text-xs"}},{$ref:"TableHead",$id:"elsewhere-overview-70",props:{children:"Status",className:"text-xs"}},{$ref:"TableHead",$id:"elsewhere-overview-71",props:{children:"Total",className:"text-xs"}}]}]},{$ref:"TableBody",$id:"elsewhere-overview-72",props:{},children:[{$ref:"TableRow",$id:"elsewhere-overview-73",props:{},children:[{$ref:"TableCell",$id:"elsewhere-overview-74",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-75",props:{children:"The Higashiyama House",className:""}}]},{$ref:"TableCell",$id:"elsewhere-overview-76",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-77",props:{children:"12\u201317 Oct",className:""}}]},{$ref:"TableCell",$id:"elsewhere-overview-78",props:{className:"py-4 text-xs"},children:[{$ref:"Badge",$id:"elsewhere-overview-79",props:{variant:"secondary",className:"rounded-full px-3 py-1 font-normal",children:"Confirmed"}}]},{$ref:"TableCell",$id:"elsewhere-overview-80",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-81",props:{children:"$970",className:""}}]}]},{$ref:"TableRow",$id:"elsewhere-overview-82",props:{},children:[{$ref:"TableCell",$id:"elsewhere-overview-83",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-84",props:{children:"Tea with a local host",className:""}}]},{$ref:"TableCell",$id:"elsewhere-overview-85",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-86",props:{children:"12 Oct \xB7 14:00",className:""}}]},{$ref:"TableCell",$id:"elsewhere-overview-87",props:{className:"py-4 text-xs"},children:[{$ref:"Badge",$id:"elsewhere-overview-88",props:{variant:"secondary",className:"rounded-full px-3 py-1 font-normal",children:"Reserved"}}]},{$ref:"TableCell",$id:"elsewhere-overview-89",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-90",props:{children:"$64",className:""}}]}]},{$ref:"TableRow",$id:"elsewhere-overview-91",props:{},children:[{$ref:"TableCell",$id:"elsewhere-overview-92",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-93",props:{children:"Airport transfer",className:""}}]},{$ref:"TableCell",$id:"elsewhere-overview-94",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-95",props:{children:"12 Oct \xB7 08:10",className:""}}]},{$ref:"TableCell",$id:"elsewhere-overview-96",props:{className:"py-4 text-xs"},children:[{$ref:"Badge",$id:"elsewhere-overview-97",props:{variant:"secondary",className:"rounded-full px-3 py-1 font-normal",children:"To book"}}]},{$ref:"TableCell",$id:"elsewhere-overview-98",props:{className:"py-4 text-xs"},children:[{$ref:"Text",$id:"elsewhere-overview-99",props:{children:"$80",className:""}}]}]}]}]}]}]},{$ref:"Box",$id:"elsewhere-overview-100",props:{className:"px-6 md:px-14 py-8 border-t border-border flex justify-between items-center gap-4 flex-wrap"},children:[{$ref:"Text",$id:"elsewhere-overview-101",props:{children:"Go a little further. Stay a little longer.",className:"font-display text-lg"}},{$ref:"Text",$id:"elsewhere-overview-102",props:{children:"elsewhere / 2026",className:"text-[10px] uppercase tracking-widest text-muted-foreground"}}]}]}};var elsewhere_stay_default={id:"elsewhere-stay",name:"02 \xB7 A stay in Kyoto",tree:{$ref:"Box",$id:"elsewhere-stay-1",props:{className:"bg-background text-foreground min-h-screen font-sans"},children:[{$snippet:"elsewhere-nav",args:{}},{$ref:"Box",$id:"elsewhere-stay-2",props:{className:"px-6 md:px-14 py-7 space-y-6"},children:[{$ref:"Box",$id:"elsewhere-stay-3",props:{className:"flex justify-between items-center text-xs"},children:[{$ref:"Text",$id:"elsewhere-stay-4",props:{children:"Discover / Japan / Kyoto",className:"text-muted-foreground"}},{$ref:"Button",$id:"elsewhere-stay-5",props:{variant:"outline",className:"rounded-full "},children:[{$ref:"Icon",$id:"elsewhere-stay-6",props:{name:"Heart",className:"size-4"}},{$ref:"Text",$id:"elsewhere-stay-7",props:{children:"Save this stay",className:" text-inherit",style:{color:"inherit"}}}]}]},{$ref:"Box",$id:"elsewhere-stay-8",props:{className:"md:flex justify-between items-end space-y-3"},children:[{$ref:"Box",$id:"elsewhere-stay-9",props:{className:"space-y-3"},children:[{$ref:"Text",$id:"elsewhere-stay-10",props:{children:"THE ELSEWHERE COLLECTION",className:"text-[10px] uppercase tracking-[0.22em] font-semibold text-primary"}},{$ref:"Heading",$id:"elsewhere-stay-11",props:{children:"The Higashiyama House",className:"font-display font-normal tracking-[-0.035em] text-4xl md:text-5xl"}},{$ref:"Text",$id:"elsewhere-stay-12",props:{children:"A quiet address in the heart of old Kyoto.",className:"text-sm text-muted-foreground max-w-xl leading-6"}}]},{$ref:"Box",$id:"elsewhere-stay-13",props:{className:"flex items-center gap-2"},children:[{$ref:"Icon",$id:"elsewhere-stay-14",props:{name:"Star",className:"size-4 text-primary"}},{$ref:"Text",$id:"elsewhere-stay-15",props:{children:"4.98",className:"font-semibold text-sm"}},{$ref:"Text",$id:"elsewhere-stay-16",props:{children:"\xB7 86 thoughtful reviews",className:"text-xs text-muted-foreground"}}]}]},{$ref:"Box",$id:"elsewhere-stay-17",props:{className:"grid grid-cols-1 md:grid-cols-[1.65fr_1fr] gap-3"},children:[{$ref:"Box",$id:"elsewhere-stay-18",props:{className:"relative overflow-hidden h-[330px] md:h-[410px] rounded-xl"},children:[{$ref:"Image",$id:"elsewhere-stay-19",props:{src:"/assets/elsewhere-room.jpg",alt:"Quiet contemporary guest room",className:"absolute inset-0 h-full w-full",fill:!0}}]},{$ref:"Box",$id:"elsewhere-stay-20",props:{className:"hidden md:grid grid-rows-2 gap-3"},children:[{$ref:"Box",$id:"elsewhere-stay-21",props:{className:"relative overflow-hidden rounded-xl"},children:[{$ref:"Image",$id:"elsewhere-stay-22",props:{src:"/assets/elsewhere-kyoto.jpg",alt:"Yasaka Pagoda above a Kyoto street at sunset",className:"absolute inset-0 h-full w-full",fill:!0}}]},{$ref:"Box",$id:"elsewhere-stay-23",props:{className:"relative overflow-hidden rounded-xl"},children:[{$ref:"Image",$id:"elsewhere-stay-24",props:{src:"/assets/elsewhere-japan.jpg",alt:"japan travel photography",className:"absolute inset-0 h-full w-full",fill:!0}},{$ref:"Button",$id:"elsewhere-stay-25",props:{variant:"secondary",className:"rounded-full absolute bottom-4 right-4"},children:[{$ref:"Icon",$id:"elsewhere-stay-26",props:{name:"Images",className:"size-4"}},{$ref:"Text",$id:"elsewhere-stay-27",props:{children:"View all 12 photos",className:" text-inherit",style:{color:"inherit"}}}]}]}]}]},{$ref:"Box",$id:"elsewhere-stay-28",props:{className:"grid md:grid-cols-[1.65fr_1fr] gap-10 pt-2"},children:[{$ref:"Box",$id:"elsewhere-stay-29",props:{className:"space-y-7"},children:[{$ref:"Box",$id:"elsewhere-stay-30",props:{className:"flex items-center gap-2"},children:[{$ref:"Badge",$id:"elsewhere-stay-31",props:{variant:"secondary",className:"rounded-full px-3 py-1 font-normal",children:"Guest favourite"}},{$ref:"Badge",$id:"elsewhere-stay-32",props:{variant:"secondary",className:"rounded-full px-3 py-1 font-normal",children:"Design-led"}},{$ref:"Badge",$id:"elsewhere-stay-33",props:{variant:"secondary",className:"rounded-full px-3 py-1 font-normal",children:"Locally hosted"}}]},{$ref:"Heading",$id:"elsewhere-stay-34",props:{children:`A little sanctuary.
|
|
43
43
|
An entire city at your door.`,className:"font-display font-normal tracking-[-0.035em] text-3xl whitespace-pre-line"}},{$ref:"Text",$id:"elsewhere-stay-35",props:{children:"Behind a discreet entrance, soft light falls across natural timber and linen. Step outside for morning markets, neighbourhood coffee, and the lanes of Higashiyama. This is Kyoto at your own pace.",className:"text-sm leading-7 text-muted-foreground max-w-2xl"}},{$ref:"Box",$id:"elsewhere-stay-36",props:{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-xs"},children:[{$ref:"Box",$id:"elsewhere-stay-37",props:{className:"flex items-center gap-2"},children:[{$ref:"Icon",$id:"elsewhere-stay-38",props:{name:"BedDouble",className:"size-4"}},{$ref:"Text",$id:"elsewhere-stay-39",props:{children:"2 guests",className:""}}]},{$ref:"Box",$id:"elsewhere-stay-40",props:{className:"flex items-center gap-2"},children:[{$ref:"Icon",$id:"elsewhere-stay-41",props:{name:"Bath",className:"size-4"}},{$ref:"Text",$id:"elsewhere-stay-42",props:{children:"Private bath",className:""}}]},{$ref:"Box",$id:"elsewhere-stay-43",props:{className:"flex items-center gap-2"},children:[{$ref:"Icon",$id:"elsewhere-stay-44",props:{name:"Wifi",className:"size-4"}},{$ref:"Text",$id:"elsewhere-stay-45",props:{children:"Fast Wi-Fi",className:""}}]},{$ref:"Box",$id:"elsewhere-stay-46",props:{className:"flex items-center gap-2"},children:[{$ref:"Icon",$id:"elsewhere-stay-47",props:{name:"Coffee",className:"size-4"}},{$ref:"Text",$id:"elsewhere-stay-48",props:{children:"Breakfast",className:""}}]}]},{$ref:"Separator",$id:"elsewhere-stay-49",props:{}},{$ref:"Box",$id:"elsewhere-stay-50",props:{className:"flex gap-4 items-center"},children:[{$ref:"Avatar",$id:"elsewhere-stay-51",props:{className:"size-8 border-2 border-background"},children:[{$ref:"AvatarFallback",$id:"elsewhere-stay-52",props:{children:"MK",className:"text-[10px] bg-secondary text-secondary-foreground"}}]},{$ref:"Box",$id:"elsewhere-stay-53",props:{className:""},children:[{$ref:"Text",$id:"elsewhere-stay-54",props:{children:"Hosted by Michiko",className:"font-semibold text-sm"}},{$ref:"Text",$id:"elsewhere-stay-55",props:{children:"Kyoto local \xB7 Welcoming guests since 2018",className:"text-xs text-muted-foreground"}}]}]}]},{$ref:"Card",$id:"elsewhere-stay-56",props:{className:"rounded-2xl p-6 shadow-sm gap-5"},children:[{$ref:"Box",$id:"elsewhere-stay-57",props:{className:"flex justify-between items-center"},children:[{$ref:"Box",$id:"elsewhere-stay-58",props:{className:"flex items-baseline gap-2"},children:[{$ref:"Heading",$id:"elsewhere-stay-59",props:{children:"$185",className:"font-display font-normal tracking-[-0.035em] text-3xl"}},{$ref:"Text",$id:"elsewhere-stay-60",props:{children:"/ night",className:"text-xs text-muted-foreground"}}]},{$ref:"Badge",$id:"elsewhere-stay-61",props:{variant:"secondary",className:"rounded-full px-3 py-1 font-normal",children:"Breakfast included"}}]},{$ref:"FieldGroup",$id:"elsewhere-stay-62",props:{},children:[{$ref:"Field",$id:"elsewhere-stay-63",props:{},children:[{$ref:"FieldLabel",$id:"elsewhere-stay-64",props:{children:"Your dates"}},{$ref:"Button",$id:"elsewhere-stay-65",props:{variant:"outline",className:"rounded-full justify-start rounded-lg w-full"},children:[{$ref:"Icon",$id:"elsewhere-stay-66",props:{name:"CalendarDays",className:"size-4"}},{$ref:"Text",$id:"elsewhere-stay-67",props:{children:"12 Oct \u2013 17 Oct 2026",className:" text-inherit",style:{color:"inherit"}}}]}]},{$ref:"Field",$id:"elsewhere-stay-68",props:{},children:[{$ref:"FieldLabel",$id:"elsewhere-stay-69",props:{children:"Travellers"}},{$ref:"NativeSelect",$id:"elsewhere-stay-70",props:{defaultValue:"2",className:"w-full"},children:[{$ref:"NativeSelectOption",$id:"elsewhere-stay-71",props:{value:"2",children:"2 adults \xB7 1 room"}},{$ref:"NativeSelectOption",$id:"elsewhere-stay-72",props:{value:"1",children:"1 adult \xB7 1 room"}}]}]}]},{$ref:"Box",$id:"elsewhere-stay-73",props:{className:"space-y-3 text-sm"},children:[{$ref:"Box",$id:"elsewhere-stay-74",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"elsewhere-stay-75",props:{children:"$185 \xD7 5 nights",className:""}},{$ref:"Text",$id:"elsewhere-stay-76",props:{children:"$925",className:""}}]},{$ref:"Box",$id:"elsewhere-stay-77",props:{className:"flex justify-between text-muted-foreground"},children:[{$ref:"Text",$id:"elsewhere-stay-78",props:{children:"Service fee",className:""}},{$ref:"Text",$id:"elsewhere-stay-79",props:{children:"$45",className:""}}]},{$ref:"Separator",$id:"elsewhere-stay-80",props:{}},{$ref:"Box",$id:"elsewhere-stay-81",props:{className:"flex justify-between font-semibold"},children:[{$ref:"Text",$id:"elsewhere-stay-82",props:{children:"Total",className:""}},{$ref:"Text",$id:"elsewhere-stay-83",props:{children:"$970",className:""}}]}]},{$ref:"Button",$id:"elsewhere-stay-84",props:{variant:"default",className:"rounded-full h-11 w-full"},children:[{$ref:"Icon",$id:"elsewhere-stay-85",props:{name:"Plus",className:"size-4"}},{$ref:"Text",$id:"elsewhere-stay-86",props:{children:"Add to my trip",className:" text-inherit",style:{color:"inherit"}}}]},{$ref:"Text",$id:"elsewhere-stay-87",props:{children:"Free cancellation until 5 October",className:"text-center text-xs text-muted-foreground"}}]}]}]},{$ref:"Box",$id:"elsewhere-stay-88",props:{className:"px-6 md:px-14 py-8 border-t border-border flex justify-between items-center gap-4 flex-wrap"},children:[{$ref:"Text",$id:"elsewhere-stay-89",props:{children:"Go a little further. Stay a little longer.",className:"font-display text-lg"}},{$ref:"Text",$id:"elsewhere-stay-90",props:{children:"elsewhere / 2026",className:"text-[10px] uppercase tracking-widest text-muted-foreground"}}]}]}};var elsewhere_trips_board_default={id:"elsewhere-trips-board",name:"B \xB7 The brief-to-plan workspace",tree:{$ref:"Box",$id:"agentic-2-1",props:{className:"min-h-screen bg-background text-foreground font-sans"},children:[{$snippet:"elsewhere-nav"},{$ref:"Box",$id:"agentic-2-2",props:{className:"px-12 py-10 space-y-8"},children:[{$ref:"Box",$id:"agentic-2-3",props:{className:"flex justify-between items-end"},children:[{$ref:"Box",$id:"agentic-2-4",props:{className:"space-y-3"},children:[{$ref:"Text",$id:"agentic-2-5",props:{children:"YOU SET THE DIRECTION",className:"text-[10px] uppercase tracking-[.2em] text-primary"}},{$ref:"Heading",$id:"agentic-2-6",props:{children:"A little brief. A thoughtful whole trip.",className:"font-display font-normal tracking-[-0.03em] text-5xl leading-[1.08]"}},{$ref:"Text",$id:"agentic-2-7",props:{children:"Tell your companion what matters. Watch the plan take shape, then make it yours.",className:"text-sm leading-7 text-muted-foreground max-w-2xl"}}]},{$ref:"Badge",$id:"agentic-2-8",props:{variant:"secondary",children:"New trip \xB7 Draft",className:"rounded-full px-3 py-1 text-[10px] font-normal"}}]},{$ref:"Box",$id:"agentic-2-9",props:{className:"grid grid-cols-[340px_1fr] gap-7 items-start"},children:[{$ref:"Box",$id:"agentic-2-10",props:{className:"space-y-6"},children:[{$ref:"Card",$id:"agentic-2-11",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Heading",$id:"agentic-2-12",props:{children:"Your starting point",className:"font-display font-normal tracking-[-0.03em] text-3xl"}},{$ref:"FieldGroup",$id:"agentic-2-13",children:[{$ref:"Field",$id:"agentic-2-14",children:[{$ref:"FieldLabel",$id:"agentic-2-15",props:{children:"Where"}},{$ref:"Input",$id:"agentic-2-16",props:{defaultValue:"Kyoto, Japan",className:"bg-card"}}]},{$ref:"Field",$id:"agentic-2-17",children:[{$ref:"FieldLabel",$id:"agentic-2-18",props:{children:"When"}},{$ref:"Input",$id:"agentic-2-19",props:{defaultValue:"12\u201317 October 2026",className:"bg-card"}}]},{$ref:"Field",$id:"agentic-2-20",children:[{$ref:"FieldLabel",$id:"agentic-2-21",props:{children:"Who\u2019s coming"}},{$ref:"Input",$id:"agentic-2-22",props:{defaultValue:"2 travellers",className:"bg-card"}}]},{$ref:"Field",$id:"agentic-2-23",children:[{$ref:"FieldLabel",$id:"agentic-2-24",props:{children:"Comfortable budget"}},{$ref:"Input",$id:"agentic-2-25",props:{defaultValue:"$3,200",className:"bg-card"}}]}]},{$ref:"Separator",$id:"agentic-2-26"},{$ref:"Text",$id:"agentic-2-27",props:{children:"YOUR KIND OF TRIP",className:"text-[9px] tracking-widest text-muted-foreground"}},{$ref:"Box",$id:"agentic-2-28",props:{className:"flex flex-wrap gap-2"},children:[{$ref:"Badge",$id:"agentic-2-29",props:{variant:"secondary",children:"Local food",className:"rounded-full px-3 py-1 text-[10px] font-normal"}},{$ref:"Badge",$id:"agentic-2-30",props:{variant:"secondary",children:"Small galleries",className:"rounded-full px-3 py-1 text-[10px] font-normal"}},{$ref:"Badge",$id:"agentic-2-31",props:{variant:"secondary",children:"Quiet stays",className:"rounded-full px-3 py-1 text-[10px] font-normal"}},{$ref:"Badge",$id:"agentic-2-32",props:{variant:"secondary",children:"Slow mornings",className:"rounded-full px-3 py-1 text-[10px] font-normal"}}]},{$ref:"Field",$id:"agentic-2-33",children:[{$ref:"FieldLabel",$id:"agentic-2-34",props:{children:"Anything else?"}},{$ref:"Textarea",$id:"agentic-2-35",props:{defaultValue:"One early start is fine. Leave a couple of afternoons free. We would love a tea experience.",className:"min-h-[110px] bg-card"}}]},{$ref:"Button",$id:"agentic-2-36",props:{variant:"default",className:"rounded-full h-11 w-full"},children:[{$ref:"Icon",$id:"agentic-2-37",props:{name:"Sparkles",className:"size-4"}},{$ref:"Box",$id:"agentic-2-38",props:{className:"",children:"Build my first draft"}}]}]},{$ref:"Card",$id:"agentic-2-39",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-muted/40"},children:[{$ref:"Box",$id:"agentic-2-40",props:{className:"flex gap-2 items-center"},children:[{$ref:"Icon",$id:"agentic-2-41",props:{name:"Compass",className:"size-4"}},{$ref:"Text",$id:"agentic-2-42",props:{children:"A little research, taken care of.",className:"font-semibold text-sm"}}]},{$ref:"Box",$id:"agentic-2-43",props:{className:"divide-y divide-border"},children:[{$ref:"Box",$id:"agentic-2-44",props:{className:"flex items-center justify-between gap-3 py-3"},children:[{$ref:"Box",$id:"agentic-2-45",props:{className:"flex items-center gap-3"},children:[{$ref:"Icon",$id:"agentic-2-46",props:{name:"CircleCheck",className:"size-4 text-primary"}},{$ref:"Text",$id:"agentic-2-47",props:{children:"Matched your pace and interests",className:"text-xs"}}]},{$ref:"Text",$id:"agentic-2-48",props:{children:"Done",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Box",$id:"agentic-2-49",props:{className:"flex items-center justify-between gap-3 py-3"},children:[{$ref:"Box",$id:"agentic-2-50",props:{className:"flex items-center gap-3"},children:[{$ref:"Icon",$id:"agentic-2-51",props:{name:"CircleCheck",className:"size-4 text-primary"}},{$ref:"Text",$id:"agentic-2-52",props:{children:"Compared 6 neighbourhood stays",className:"text-xs"}}]},{$ref:"Text",$id:"agentic-2-53",props:{children:"Done",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Box",$id:"agentic-2-54",props:{className:"flex items-center justify-between gap-3 py-3"},children:[{$ref:"Box",$id:"agentic-2-55",props:{className:"flex items-center gap-3"},children:[{$ref:"Icon",$id:"agentic-2-56",props:{name:"CircleCheck",className:"size-4 text-primary"}},{$ref:"Text",$id:"agentic-2-57",props:{children:"Grouped nearby discoveries",className:"text-xs"}}]},{$ref:"Text",$id:"agentic-2-58",props:{children:"Done",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Box",$id:"agentic-2-59",props:{className:"flex items-center justify-between gap-3 py-3"},children:[{$ref:"Box",$id:"agentic-2-60",props:{className:"flex items-center gap-3"},children:[{$ref:"Icon",$id:"agentic-2-61",props:{name:"CircleCheck",className:"size-4 text-primary"}},{$ref:"Text",$id:"agentic-2-62",props:{children:"Balanced the plan with your budget",className:"text-xs"}}]},{$ref:"Text",$id:"agentic-2-63",props:{children:"Done",className:"text-[10px] text-muted-foreground"}}]}]},{$ref:"Text",$id:"agentic-2-64",props:{children:"Suggestions prepared \xB7 Nothing booked",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Card",$id:"agentic-2-65",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-secondary/30"},children:[{$ref:"Heading",$id:"agentic-2-66",props:{children:"Your companion remembers.",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-2-67",props:{children:"These preferences guide every suggestion. Change your brief any time to update the plan.",className:"text-xs leading-6 text-muted-foreground"}},{$ref:"Box",$id:"agentic-2-68",props:{className:"flex items-center gap-3"},children:[{$ref:"Switch",$id:"agentic-2-69",props:{defaultChecked:!0}},{$ref:"Text",$id:"agentic-2-70",props:{children:"Use my saved travel preferences",className:"text-xs"}}]}]}]},{$ref:"Box",$id:"agentic-2-71",props:{className:"space-y-6"},children:[{$ref:"Card",$id:"agentic-2-72",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Box",$id:"agentic-2-73",props:{className:"flex justify-between items-center"},children:[{$ref:"Box",$id:"agentic-2-74",props:{className:"flex gap-3 items-center"},children:[{$ref:"Box",$id:"agentic-2-75",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-2-76",props:{name:"Sparkles",className:"size-4"}}]},{$ref:"Box",$id:"agentic-2-77",props:{className:""},children:[{$ref:"Text",$id:"agentic-2-78",props:{children:"Your first draft is ready",className:"font-semibold text-sm"}},{$ref:"Text",$id:"agentic-2-79",props:{children:"Built around your brief \xB7 5 nights",className:"text-[10px] text-muted-foreground"}}]}]},{$ref:"Badge",$id:"agentic-2-80",props:{variant:"secondary",children:"Ready to refine",className:"rounded-full px-3 py-1 text-[10px] font-normal"}}]},{$ref:"Heading",$id:"agentic-2-81",props:{children:"Kyoto, with room to breathe.",className:"font-display font-normal tracking-[-0.03em] text-4xl"}},{$ref:"Text",$id:"agentic-2-82",props:{children:"A central stay, five gently paced days, and a budget with plenty of breathing room. Here\u2019s the direction I suggest.",className:"text-sm leading-7 text-muted-foreground"}},{$ref:"Box",$id:"agentic-2-83",props:{className:"grid grid-cols-3 gap-4"},children:[{$ref:"Box",$id:"agentic-2-84",props:{className:"bg-muted/60 rounded-xl p-4 space-y-1"},children:[{$ref:"Heading",$id:"agentic-2-85",props:{children:"$1,730",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-2-86",props:{children:"estimated total",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Box",$id:"agentic-2-87",props:{className:"bg-muted/60 rounded-xl p-4 space-y-1"},children:[{$ref:"Heading",$id:"agentic-2-88",props:{children:"2",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-2-89",props:{children:"open afternoons",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Box",$id:"agentic-2-90",props:{className:"bg-muted/60 rounded-xl p-4 space-y-1"},children:[{$ref:"Heading",$id:"agentic-2-91",props:{children:"4.8 km",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-2-92",props:{children:"longest walking day",className:"text-[10px] text-muted-foreground"}}]}]}]},{$ref:"Card",$id:"agentic-2-93",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Box",$id:"agentic-2-94",props:{className:"flex justify-between"},children:[{$ref:"Heading",$id:"agentic-2-95",props:{children:"Choose your home base.",className:"font-display font-normal tracking-[-0.03em] text-3xl"}},{$ref:"Button",$id:"agentic-2-96",props:{variant:"ghost",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-2-97",props:{name:"ArrowUpRight",className:"size-4"}},{$ref:"Box",$id:"agentic-2-98",props:{className:"",children:"Compare stays"}}]}]},{$ref:"Box",$id:"agentic-2-99",props:{className:"grid grid-cols-2 gap-4"},children:[{$ref:"Card",$id:"agentic-2-100",props:{className:"rounded-xl overflow-hidden p-0 gap-0 shadow-none"},children:[{$ref:"Box",$id:"agentic-2-101",props:{className:"relative overflow-hidden h-[155px]"},children:[{$ref:"Image",$id:"agentic-2-102",props:{src:"/assets/elsewhere-room.jpg",alt:"room travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"CardContent",$id:"agentic-2-103",props:{className:"p-4 space-y-3"},children:[{$ref:"Heading",$id:"agentic-2-104",props:{children:"Higashiyama House",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-2-105",props:{children:"$970 / FIVE NIGHTS",className:"text-[10px] text-primary"}},{$ref:"Text",$id:"agentic-2-106",props:{children:"Recommended for your walkable, food-first week.",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Card",$id:"agentic-2-107",props:{className:"rounded-xl overflow-hidden p-0 gap-0 shadow-none"},children:[{$ref:"Box",$id:"agentic-2-108",props:{className:"relative overflow-hidden h-[155px]"},children:[{$ref:"Image",$id:"agentic-2-109",props:{src:"/assets/elsewhere-forest.jpg",alt:"forest travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"CardContent",$id:"agentic-2-110",props:{className:"p-4 space-y-3"},children:[{$ref:"Heading",$id:"agentic-2-111",props:{children:"The Garden Retreat",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-2-112",props:{children:"$1,095 / FIVE NIGHTS",className:"text-[10px] text-primary"}},{$ref:"Text",$id:"agentic-2-113",props:{children:"A quieter setting with a little more travel time.",className:"text-xs leading-6 text-muted-foreground"}}]}]}]},{$ref:"Box",$id:"agentic-2-114",props:{className:"flex justify-between items-center"},children:[{$ref:"Badge",$id:"agentic-2-115",props:{variant:"secondary",children:"Higashiyama selected",className:"rounded-full px-3 py-1 text-[10px] font-normal"}},{$ref:"Text",$id:"agentic-2-116",props:{children:"Nothing reserved yet",className:"text-[10px] text-muted-foreground"}}]}]},{$ref:"Card",$id:"agentic-2-117",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Box",$id:"agentic-2-118",props:{className:"flex justify-between items-center"},children:[{$ref:"Heading",$id:"agentic-2-119",props:{children:"Your days, laid out.",className:"font-display font-normal tracking-[-0.03em] text-3xl"}},{$ref:"Button",$id:"agentic-2-120",props:{variant:"outline",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-2-121",props:{name:"SlidersHorizontal",className:"size-4"}},{$ref:"Box",$id:"agentic-2-122",props:{className:"",children:"Edit the pace"}}]}]},{$ref:"Tabs",$id:"agentic-2-123",props:{defaultValue:"plan"},children:[{$ref:"TabsList",$id:"agentic-2-124",props:{variant:"line"},children:[{$ref:"TabsTrigger",$id:"agentic-2-125",props:{value:"plan",children:"Day by day"}},{$ref:"TabsTrigger",$id:"agentic-2-126",props:{value:"map",children:"On the map"}}]}]},{$ref:"Box",$id:"agentic-2-127",props:{className:"divide-y divide-border"},children:[{$ref:"Box",$id:"agentic-2-128",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-2-129",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-2-130",props:{children:"01",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-2-131",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-2-132",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-2-133",props:{children:"Arrive gently",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-2-134",props:{children:"$100",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-2-135",props:{children:"Nishiki Market \xB7 Gion lanes \xB7 Tea with a local host",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-2-136",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-2-137",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-2-138",props:{children:"02",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-2-139",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-2-140",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-2-141",props:{children:"A greener kind of morning",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-2-142",props:{children:"$85",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-2-143",props:{children:"Early bamboo grove \xB7 Riverside lunch \xB7 An open afternoon",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-2-144",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-2-145",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-2-146",props:{children:"03",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-2-147",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-2-148",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-2-149",props:{children:"Follow your curiosity",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-2-150",props:{children:"$120",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-2-151",props:{children:"Small galleries \xB7 Independent shops \xB7 Dinner in Pontocho",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-2-152",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-2-153",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-2-154",props:{children:"04",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-2-155",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-2-156",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-2-157",props:{children:"A little further afield",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-2-158",props:{children:"$110",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-2-159",props:{children:"A day in Uji \xB7 Tea fields \xB7 Back before sunset",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-2-160",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-2-161",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-2-162",props:{children:"05",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-2-163",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-2-164",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-2-165",props:{children:"Leave room for one more thing",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-2-166",props:{children:"$65",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-2-167",props:{children:"A slow breakfast \xB7 Your favourite neighbourhood \xB7 Homeward",className:"text-xs leading-6 text-muted-foreground"}}]}]}]},{$ref:"Alert",$id:"agentic-2-168",props:{className:"rounded-xl bg-secondary/30"},children:[{$ref:"Icon",$id:"agentic-2-169",props:{name:"Leaf",className:"size-4"}},{$ref:"AlertTitle",$id:"agentic-2-170",props:{children:"Two afternoons are deliberately open"}},{$ref:"AlertDescription",$id:"agentic-2-171",props:{children:"Day 2 and Day 4 leave space for whatever you discover along the way."}}]}]},{$ref:"Card",$id:"agentic-2-172",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Box",$id:"agentic-2-173",props:{className:"flex gap-3 items-center"},children:[{$ref:"Box",$id:"agentic-2-174",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-2-175",props:{name:"Sparkles",className:"size-4"}}]},{$ref:"Heading",$id:"agentic-2-176",props:{children:"Make a change. Keep the good parts.",className:"font-display font-normal tracking-[-0.03em] text-2xl"}}]},{$ref:"InputGroup",$id:"agentic-2-177",children:[{$ref:"InputGroupInput",$id:"agentic-2-178",props:{defaultValue:"Less temple hopping, more neighbourhood food."}},{$ref:"InputGroupAddon",$id:"agentic-2-179",props:{align:"inline-end"},children:[{$ref:"Button",$id:"agentic-2-180",props:{variant:"default",className:"rounded-full h-8 text-xs"},children:[{$ref:"Icon",$id:"agentic-2-181",props:{name:"ArrowUp",className:"size-4"}},{$ref:"Box",$id:"agentic-2-182",props:{className:"",children:"Update plan"}}]}]}]},{$ref:"Box",$id:"agentic-2-183",props:{className:"flex items-start gap-3 bg-secondary/40 rounded-xl p-4"},children:[{$ref:"Icon",$id:"agentic-2-184",props:{name:"CircleCheck",className:"size-4 mt-1 text-primary"}},{$ref:"Box",$id:"agentic-2-185",props:{className:"space-y-2"},children:[{$ref:"Text",$id:"agentic-2-186",props:{children:"Day 3 updated",className:"font-semibold text-xs"}},{$ref:"Text",$id:"agentic-2-187",props:{children:"A neighbourhood tasting walk replaces the temple circuit. Your stay and open afternoons are unchanged.",className:"text-xs leading-6 text-muted-foreground"}}]}]}]},{$ref:"Card",$id:"agentic-2-188",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Heading",$id:"agentic-2-189",props:{children:"A budget that still has room.",className:"font-display font-normal tracking-[-0.03em] text-3xl"}},{$ref:"Chart",$id:"agentic-2-190",props:{kind:"bar",categories:["Stay","Food","Experiences","Transport"],series:[{name:"Estimated cost",data:[970,360,240,160]}],yLabel:"$",className:"h-[190px] w-full",legend:!1}},{$ref:"Box",$id:"agentic-2-191",props:{className:"space-y-3 text-xs"},children:[{$ref:"Box",$id:"agentic-2-192",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"agentic-2-193",props:{children:"Stay",className:"text-inherit"}},{$ref:"Text",$id:"agentic-2-194",props:{children:"$970",className:"text-inherit"}}]},{$ref:"Box",$id:"agentic-2-195",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"agentic-2-196",props:{children:"Food & coffee",className:"text-inherit"}},{$ref:"Text",$id:"agentic-2-197",props:{children:"$360",className:"text-inherit"}}]},{$ref:"Box",$id:"agentic-2-198",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"agentic-2-199",props:{children:"Experiences",className:"text-inherit"}},{$ref:"Text",$id:"agentic-2-200",props:{children:"$240",className:"text-inherit"}}]},{$ref:"Box",$id:"agentic-2-201",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"agentic-2-202",props:{children:"Local transport",className:"text-inherit"}},{$ref:"Text",$id:"agentic-2-203",props:{children:"$160",className:"text-inherit"}}]},{$ref:"Separator",$id:"agentic-2-204"},{$ref:"Box",$id:"agentic-2-205",props:{className:"flex justify-between font-semibold"},children:[{$ref:"Text",$id:"agentic-2-206",props:{children:"Estimated trip total",className:"text-inherit"}},{$ref:"Text",$id:"agentic-2-207",props:{children:"$1,730",className:"text-inherit"}}]},{$ref:"Box",$id:"agentic-2-208",props:{className:"flex justify-between text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-2-209",props:{children:"Left for the unexpected",className:"text-inherit"}},{$ref:"Text",$id:"agentic-2-210",props:{children:"$1,470",className:"text-inherit"}}]}]}]},{$ref:"Card",$id:"agentic-2-211",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-secondary/35"},children:[{$ref:"Box",$id:"agentic-2-212",props:{className:"flex gap-3 items-center"},children:[{$ref:"Icon",$id:"agentic-2-213",props:{name:"CircleCheck",className:"size-5 text-primary"}},{$ref:"Heading",$id:"agentic-2-214",props:{children:"A trip that feels like you.",className:"font-display font-normal tracking-[-0.03em] text-2xl"}}]},{$ref:"Text",$id:"agentic-2-215",props:{children:"Save this draft to My trips. You can keep refining it with your companion, invite Jamie, and book each stay or experience when you\u2019re ready.",className:"text-xs leading-6 text-muted-foreground"}},{$ref:"Box",$id:"agentic-2-216",props:{className:"flex gap-3"},children:[{$ref:"Button",$id:"agentic-2-217",props:{variant:"default",className:"rounded-full h-11 px-6"},children:[{$ref:"Icon",$id:"agentic-2-218",props:{name:"Check",className:"size-4"}},{$ref:"Box",$id:"agentic-2-219",props:{className:"",children:"Save my trip"}}]},{$ref:"Button",$id:"agentic-2-220",props:{variant:"outline",className:"rounded-full h-11"},children:[{$ref:"Box",$id:"agentic-2-221",props:{className:"",children:"Keep refining"}}]}]},{$ref:"Text",$id:"agentic-2-222",props:{children:"Saving creates a private trip. Bookings happen separately.",className:"text-[10px] text-muted-foreground"}}]}]}]}]},{$ref:"Box",$id:"agentic-2-223",props:{className:"border-t border-border px-12 py-8 flex justify-between"},children:[{$ref:"Text",$id:"agentic-2-224",props:{children:"A little help. A world of possibilities.",className:"font-display text-xl"}},{$ref:"Text",$id:"agentic-2-225",props:{children:"ELSEWHERE / YOUR TRAVEL COMPANION",className:"text-[9px] tracking-widest text-muted-foreground"}}]}]}};var elsewhere_trips_journal_default={id:"elsewhere-trips-journal",name:"C \xB7 The inspiration-led companion",tree:{$ref:"Box",$id:"agentic-3-1",props:{className:"min-h-screen bg-background text-foreground font-sans"},children:[{$snippet:"elsewhere-nav"},{$ref:"Box",$id:"agentic-3-2",props:{className:"px-12 py-10 space-y-9"},children:[{$ref:"Box",$id:"agentic-3-3",props:{className:"space-y-3"},children:[{$ref:"Text",$id:"agentic-3-4",props:{children:"FOLLOW A FEELING",className:"text-[10px] uppercase tracking-[.2em] text-primary"}},{$ref:"Heading",$id:"agentic-3-5",props:{children:"Build a trip from the things you love.",className:"font-display font-normal tracking-[-0.03em] text-5xl leading-[1.08]"}},{$ref:"Text",$id:"agentic-3-6",props:{children:"Choose a few places, moods, and moments. Your companion will find the thread between them.",className:"text-sm leading-7 text-muted-foreground max-w-2xl"}}]},{$ref:"Box",$id:"agentic-3-7",props:{className:"grid grid-cols-[1fr_350px] gap-7 items-start"},children:[{$ref:"Box",$id:"agentic-3-8",props:{className:"space-y-8"},children:[{$ref:"Box",$id:"agentic-3-9",props:{className:"flex justify-between items-center"},children:[{$ref:"Heading",$id:"agentic-3-10",props:{children:"What draws you in?",className:"font-display font-normal tracking-[-0.03em] text-3xl"}},{$ref:"Badge",$id:"agentic-3-11",props:{variant:"secondary",children:"3 things you love",className:"rounded-full px-3 py-1 text-[10px] font-normal"}}]},{$ref:"Box",$id:"agentic-3-12",props:{className:"grid grid-cols-2 gap-5"},children:[{$ref:"Card",$id:"agentic-3-13",props:{className:"p-0 gap-0 rounded-2xl overflow-hidden shadow-none ring-2 ring-primary"},children:[{$ref:"Box",$id:"agentic-3-14",props:{className:"relative overflow-hidden h-[240px]"},children:[{$ref:"Image",$id:"agentic-3-15",props:{src:"/assets/elsewhere-kyoto.jpg",alt:"kyoto travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}},{$ref:"Box",$id:"agentic-3-16",props:{className:"absolute top-4 right-4"},children:[{$ref:"Button",$id:"agentic-3-17",props:{variant:"default",className:"rounded-full h-8 text-xs"},children:[{$ref:"Icon",$id:"agentic-3-18",props:{name:"Check",className:"size-4"}},{$ref:"Box",$id:"agentic-3-19",props:{className:"",children:"Added"}}]}]}]},{$ref:"CardContent",$id:"agentic-3-20",props:{className:"p-5 space-y-2"},children:[{$ref:"Heading",$id:"agentic-3-21",props:{children:"Streets worth getting lost in",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-3-22",props:{children:"Lanterns, little shops, and the long way home.",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Card",$id:"agentic-3-23",props:{className:"p-0 gap-0 rounded-2xl overflow-hidden shadow-none ring-2 ring-primary"},children:[{$ref:"Box",$id:"agentic-3-24",props:{className:"relative overflow-hidden h-[240px]"},children:[{$ref:"Image",$id:"agentic-3-25",props:{src:"/assets/elsewhere-room.jpg",alt:"room travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}},{$ref:"Box",$id:"agentic-3-26",props:{className:"absolute top-4 right-4"},children:[{$ref:"Button",$id:"agentic-3-27",props:{variant:"default",className:"rounded-full h-8 text-xs"},children:[{$ref:"Icon",$id:"agentic-3-28",props:{name:"Check",className:"size-4"}},{$ref:"Box",$id:"agentic-3-29",props:{className:"",children:"Added"}}]}]}]},{$ref:"CardContent",$id:"agentic-3-30",props:{className:"p-5 space-y-2"},children:[{$ref:"Heading",$id:"agentic-3-31",props:{children:"Somewhere that feels like a retreat",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-3-32",props:{children:"Warm timber, soft light, and a slow breakfast.",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Card",$id:"agentic-3-33",props:{className:"p-0 gap-0 rounded-2xl overflow-hidden shadow-none ring-2 ring-primary"},children:[{$ref:"Box",$id:"agentic-3-34",props:{className:"relative overflow-hidden h-[240px]"},children:[{$ref:"Image",$id:"agentic-3-35",props:{src:"/assets/elsewhere-forest.jpg",alt:"forest travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}},{$ref:"Box",$id:"agentic-3-36",props:{className:"absolute top-4 right-4"},children:[{$ref:"Button",$id:"agentic-3-37",props:{variant:"default",className:"rounded-full h-8 text-xs"},children:[{$ref:"Icon",$id:"agentic-3-38",props:{name:"Check",className:"size-4"}},{$ref:"Box",$id:"agentic-3-39",props:{className:"",children:"Added"}}]}]}]},{$ref:"CardContent",$id:"agentic-3-40",props:{className:"p-5 space-y-2"},children:[{$ref:"Heading",$id:"agentic-3-41",props:{children:"A quieter kind of adventure",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-3-42",props:{children:"Green paths. Fresh air. No rush.",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Card",$id:"agentic-3-43",props:{className:"p-0 gap-0 rounded-2xl overflow-hidden shadow-none "},children:[{$ref:"Box",$id:"agentic-3-44",props:{className:"relative overflow-hidden h-[240px]"},children:[{$ref:"Image",$id:"agentic-3-45",props:{src:"/assets/elsewhere-japan.jpg",alt:"japan travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}},{$ref:"Box",$id:"agentic-3-46",props:{className:"absolute top-4 right-4"},children:[{$ref:"Button",$id:"agentic-3-47",props:{variant:"secondary",className:"rounded-full h-8 text-xs"},children:[{$ref:"Icon",$id:"agentic-3-48",props:{name:"Plus",className:"size-4"}},{$ref:"Box",$id:"agentic-3-49",props:{className:"",children:"This feels like me"}}]}]}]},{$ref:"CardContent",$id:"agentic-3-50",props:{className:"p-5 space-y-2"},children:[{$ref:"Heading",$id:"agentic-3-51",props:{children:"Stay out a little later",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-3-52",props:{children:"Neighbourhood bars and another good story.",className:"text-xs leading-6 text-muted-foreground"}}]}]}]},{$ref:"Box",$id:"agentic-3-53",props:{className:"flex gap-2 flex-wrap"},children:[{$ref:"Button",$id:"agentic-3-54",props:{variant:"outline",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-3-55",props:{name:"RefreshCw",className:"size-4"}},{$ref:"Box",$id:"agentic-3-56",props:{className:"",children:"More like these"}}]},{$ref:"Button",$id:"agentic-3-57",props:{variant:"outline",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-3-58",props:{name:"Bookmark",className:"size-4"}},{$ref:"Box",$id:"agentic-3-59",props:{className:"",children:"Add a saved place"}}]},{$ref:"Button",$id:"agentic-3-60",props:{variant:"outline",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-3-61",props:{name:"ImagePlus",className:"size-4"}},{$ref:"Box",$id:"agentic-3-62",props:{className:"",children:"Upload inspiration"}}]}]},{$ref:"Card",$id:"agentic-3-63",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Box",$id:"agentic-3-64",props:{className:"flex gap-3 items-center"},children:[{$ref:"Box",$id:"agentic-3-65",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-3-66",props:{name:"Sparkles",className:"size-4"}}]},{$ref:"Heading",$id:"agentic-3-67",props:{children:"I\u2019m seeing a lovely little pattern.",className:"font-display font-normal tracking-[-0.03em] text-3xl"}}]},{$ref:"Text",$id:"agentic-3-68",props:{children:"You\u2019re drawn to atmospheric streets, quiet places to stay, and time outdoors. Kyoto can give you all three without moving hotels.",className:"text-sm leading-7 text-muted-foreground"}},{$ref:"Box",$id:"agentic-3-69",props:{className:"relative overflow-hidden h-[220px] rounded-xl"},children:[{$ref:"Image",$id:"agentic-3-70",props:{src:"/assets/elsewhere-kyoto.jpg",alt:"kyoto travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"Box",$id:"agentic-3-71",props:{className:"flex justify-between items-center"},children:[{$ref:"Box",$id:"agentic-3-72",props:{className:"space-y-1"},children:[{$ref:"Heading",$id:"agentic-3-73",props:{children:"Kyoto is your kind of elsewhere.",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-3-74",props:{children:"Walkable neighbourhoods \xB7 Small discoveries \xB7 A gentle pace",className:"text-xs text-muted-foreground"}}]},{$ref:"Button",$id:"agentic-3-75",props:{variant:"default",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-3-76",props:{name:"Check",className:"size-4"}},{$ref:"Box",$id:"agentic-3-77",props:{className:"",children:"Let\u2019s go with Kyoto"}}]}]}]},{$ref:"Card",$id:"agentic-3-78",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Heading",$id:"agentic-3-79",props:{children:"A few little details.",className:"font-display font-normal tracking-[-0.03em] text-3xl"}},{$ref:"Box",$id:"agentic-3-80",props:{className:"grid grid-cols-3 gap-4"},children:[{$ref:"Field",$id:"agentic-3-81",children:[{$ref:"FieldLabel",$id:"agentic-3-82",props:{children:"Dates"}},{$ref:"Input",$id:"agentic-3-83",props:{defaultValue:"12\u201317 October",className:"bg-card"}}]},{$ref:"Field",$id:"agentic-3-84",children:[{$ref:"FieldLabel",$id:"agentic-3-85",props:{children:"Travellers"}},{$ref:"Input",$id:"agentic-3-86",props:{defaultValue:"2 people",className:"bg-card"}}]},{$ref:"Field",$id:"agentic-3-87",children:[{$ref:"FieldLabel",$id:"agentic-3-88",props:{children:"Budget"}},{$ref:"Input",$id:"agentic-3-89",props:{defaultValue:"$3,200",className:"bg-card"}}]}]},{$ref:"Button",$id:"agentic-3-90",props:{variant:"default",className:"rounded-full h-11 self-start"},children:[{$ref:"Icon",$id:"agentic-3-91",props:{name:"Sparkles",className:"size-4"}},{$ref:"Box",$id:"agentic-3-92",props:{className:"",children:"Turn this into a trip"}}]}]},{$ref:"Card",$id:"agentic-3-93",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Box",$id:"agentic-3-94",props:{className:"flex justify-between items-center"},children:[{$ref:"Heading",$id:"agentic-3-95",props:{children:"Your collection becomes a journey.",className:"font-display font-normal tracking-[-0.03em] text-3xl"}},{$ref:"Badge",$id:"agentic-3-96",props:{variant:"secondary",children:"Draft 01",className:"rounded-full px-3 py-1 text-[10px] font-normal"}}]},{$ref:"Text",$id:"agentic-3-97",props:{children:"The places you chose, connected into days that make sense together.",className:"text-sm text-muted-foreground"}},{$ref:"Box",$id:"agentic-3-98",props:{className:"relative h-[650px] rounded-xl overflow-hidden"},children:[{$ref:"Image",$id:"agentic-3-99",props:{src:"/assets/elsewhere-kyoto-map.svg",alt:"An illustrated route connecting your Kyoto discoveries",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"Box",$id:"agentic-3-100",props:{className:"divide-y divide-border"},children:[{$ref:"Box",$id:"agentic-3-101",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-3-102",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-3-103",props:{children:"01",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-3-104",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-3-105",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-3-106",props:{children:"Arrive gently",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-3-107",props:{children:"$100",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-3-108",props:{children:"Nishiki Market \xB7 Gion lanes \xB7 Tea with a local host",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-3-109",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-3-110",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-3-111",props:{children:"02",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-3-112",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-3-113",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-3-114",props:{children:"A greener kind of morning",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-3-115",props:{children:"$85",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-3-116",props:{children:"Early bamboo grove \xB7 Riverside lunch \xB7 An open afternoon",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-3-117",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-3-118",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-3-119",props:{children:"03",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-3-120",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-3-121",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-3-122",props:{children:"Follow your curiosity",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-3-123",props:{children:"$120",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-3-124",props:{children:"Small galleries \xB7 Independent shops \xB7 Dinner in Pontocho",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-3-125",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-3-126",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-3-127",props:{children:"04",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-3-128",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-3-129",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-3-130",props:{children:"A little further afield",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-3-131",props:{children:"$110",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-3-132",props:{children:"A day in Uji \xB7 Tea fields \xB7 Back before sunset",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-3-133",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-3-134",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-3-135",props:{children:"05",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-3-136",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-3-137",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-3-138",props:{children:"Leave room for one more thing",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-3-139",props:{children:"$65",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-3-140",props:{children:"A slow breakfast \xB7 Your favourite neighbourhood \xB7 Homeward",className:"text-xs leading-6 text-muted-foreground"}}]}]}]}]},{$ref:"Card",$id:"agentic-3-141",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-secondary/35"},children:[{$ref:"Box",$id:"agentic-3-142",props:{className:"flex gap-3 items-center"},children:[{$ref:"Icon",$id:"agentic-3-143",props:{name:"CircleCheck",className:"size-5 text-primary"}},{$ref:"Heading",$id:"agentic-3-144",props:{children:"A trip that feels like you.",className:"font-display font-normal tracking-[-0.03em] text-2xl"}}]},{$ref:"Text",$id:"agentic-3-145",props:{children:"Save this draft to My trips. You can keep refining it with your companion, invite Jamie, and book each stay or experience when you\u2019re ready.",className:"text-xs leading-6 text-muted-foreground"}},{$ref:"Box",$id:"agentic-3-146",props:{className:"flex gap-3"},children:[{$ref:"Button",$id:"agentic-3-147",props:{variant:"default",className:"rounded-full h-11 px-6"},children:[{$ref:"Icon",$id:"agentic-3-148",props:{name:"Check",className:"size-4"}},{$ref:"Box",$id:"agentic-3-149",props:{className:"",children:"Save my trip"}}]},{$ref:"Button",$id:"agentic-3-150",props:{variant:"outline",className:"rounded-full h-11"},children:[{$ref:"Box",$id:"agentic-3-151",props:{className:"",children:"Keep refining"}}]}]},{$ref:"Text",$id:"agentic-3-152",props:{children:"Saving creates a private trip. Bookings happen separately.",className:"text-[10px] text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-3-153",props:{className:"space-y-6"},children:[{$ref:"Card",$id:"agentic-3-154",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Box",$id:"agentic-3-155",props:{className:"flex gap-3 items-center"},children:[{$ref:"Box",$id:"agentic-3-156",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-3-157",props:{name:"Sparkles",className:"size-4"}}]},{$ref:"Box",$id:"agentic-3-158",props:{className:""},children:[{$ref:"Text",$id:"agentic-3-159",props:{children:"Your travel companion",className:"font-semibold text-sm"}},{$ref:"Text",$id:"agentic-3-160",props:{children:"Learning what feels like you",className:"text-[10px] text-muted-foreground"}}]}]},{$ref:"Message",$id:"agentic-3-161",props:{align:"start",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-3-162",children:[{$ref:"Box",$id:"agentic-3-163",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-3-164",props:{name:"Sparkles",className:"size-4"}}]}]},{$ref:"Box",$id:"agentic-3-165",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-3-166",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-3-167",props:{children:"Elsewhere",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-3-168",props:{className:"space-y-4"},children:[{$ref:"Text",$id:"agentic-3-169",props:{children:"Start with anything that catches your eye. A place, a room, even just a feeling.",className:"text-sm leading-7"}}]}]}]},{$ref:"Box",$id:"agentic-3-170",props:{className:"flex flex-wrap gap-2"},children:[{$ref:"Badge",$id:"agentic-3-171",props:{variant:"secondary",children:"Quiet corners",className:"rounded-full px-3 py-1 text-[10px] font-normal"}},{$ref:"Badge",$id:"agentic-3-172",props:{variant:"secondary",children:"Beautiful stays",className:"rounded-full px-3 py-1 text-[10px] font-normal"}},{$ref:"Badge",$id:"agentic-3-173",props:{variant:"secondary",children:"A little greenery",className:"rounded-full px-3 py-1 text-[10px] font-normal"}}]},{$ref:"Separator",$id:"agentic-3-174"},{$ref:"Message",$id:"agentic-3-175",props:{align:"end",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-3-176",children:[{$ref:"Avatar",$id:"agentic-3-177",props:{className:"size-8"},children:[{$ref:"AvatarFallback",$id:"agentic-3-178",props:{children:"AL",className:"bg-secondary text-[10px]"}}]}]},{$ref:"Box",$id:"agentic-3-179",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-3-180",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-3-181",props:{children:"You",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-3-182",props:{className:"bg-secondary/65 rounded-2xl px-5 py-4"},children:[{$ref:"Text",$id:"agentic-3-183",props:{children:"These are lovely. We\u2019d like to avoid changing hotels.",className:"text-sm leading-7"}}]}]}]},{$ref:"Message",$id:"agentic-3-184",props:{align:"start",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-3-185",children:[{$ref:"Box",$id:"agentic-3-186",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-3-187",props:{name:"Sparkles",className:"size-4"}}]}]},{$ref:"Box",$id:"agentic-3-188",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-3-189",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-3-190",props:{children:"Elsewhere",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-3-191",props:{className:"space-y-4"},children:[{$ref:"Text",$id:"agentic-3-192",props:{children:"One thoughtful base, then. I\u2019ll keep the discoveries close enough for easy day trips.",className:"text-sm leading-7"}}]}]}]},{$ref:"Box",$id:"agentic-3-193",props:{className:"space-y-2 bg-secondary/40 rounded-xl p-4"},children:[{$ref:"Text",$id:"agentic-3-194",props:{children:"ADDED TO YOUR BRIEF",className:"text-[9px] tracking-widest text-primary"}},{$ref:"Text",$id:"agentic-3-195",props:{children:"One base \xB7 Easy day trips \xB7 Unhurried pace",className:"text-xs leading-6"}}]}]},{$ref:"Card",$id:"agentic-3-196",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Text",$id:"agentic-3-197",props:{children:"YOUR COLLECTION",className:"text-[9px] tracking-widest text-muted-foreground"}},{$ref:"Box",$id:"agentic-3-198",props:{className:"flex gap-3 items-center"},children:[{$ref:"Box",$id:"agentic-3-199",props:{className:"relative overflow-hidden size-14 rounded-lg shrink-0"},children:[{$ref:"Image",$id:"agentic-3-200",props:{src:"/assets/elsewhere-kyoto.jpg",alt:"kyoto travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"Text",$id:"agentic-3-201",props:{children:"Kyoto\u2019s old streets",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-3-202",props:{className:"flex gap-3 items-center"},children:[{$ref:"Box",$id:"agentic-3-203",props:{className:"relative overflow-hidden size-14 rounded-lg shrink-0"},children:[{$ref:"Image",$id:"agentic-3-204",props:{src:"/assets/elsewhere-room.jpg",alt:"room travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"Text",$id:"agentic-3-205",props:{children:"A warm, quiet guest room",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-3-206",props:{className:"flex gap-3 items-center"},children:[{$ref:"Box",$id:"agentic-3-207",props:{className:"relative overflow-hidden size-14 rounded-lg shrink-0"},children:[{$ref:"Image",$id:"agentic-3-208",props:{src:"/assets/elsewhere-forest.jpg",alt:"forest travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"Text",$id:"agentic-3-209",props:{children:"A little time in the green",className:"text-xs"}}]}]},{$ref:"Card",$id:"agentic-3-210",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-card"},children:[{$ref:"Textarea",$id:"agentic-3-211",props:{placeholder:"A little more about us\u2026",className:"border-0 shadow-none resize-none p-0 min-h-[62px] bg-transparent text-sm"}},{$ref:"Box",$id:"agentic-3-212",props:{className:"flex justify-between items-center"},children:[{$ref:"Button",$id:"agentic-3-213",props:{variant:"ghost",className:"rounded-full px-0 text-xs"},children:[{$ref:"Icon",$id:"agentic-3-214",props:{name:"Paperclip",className:"size-4"}},{$ref:"Box",$id:"agentic-3-215",props:{className:"",children:"Add inspiration"}}]},{$ref:"Button",$id:"agentic-3-216",props:{variant:"default",className:"rounded-full h-9"},children:[{$ref:"Icon",$id:"agentic-3-217",props:{name:"ArrowUp",className:"size-4"}},{$ref:"Box",$id:"agentic-3-218",props:{className:"",children:"Send"}}]}]}]},{$ref:"Card",$id:"agentic-3-219",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-secondary/30"},children:[{$ref:"Icon",$id:"agentic-3-220",props:{name:"Heart",className:"size-6 text-primary"}},{$ref:"Heading",$id:"agentic-3-221",props:{children:`Your taste,
|
|
44
44
|
not a template.`,className:"font-display font-normal tracking-[-0.03em] text-3xl whitespace-pre-line"}},{$ref:"Text",$id:"agentic-3-222",props:{children:"Every choice helps your companion make better suggestions. Remove a saved moment any time and the plan can adapt.",className:"text-xs leading-7 text-muted-foreground"}}]}]}]}]},{$ref:"Box",$id:"agentic-3-223",props:{className:"border-t border-border px-12 py-8 flex justify-between"},children:[{$ref:"Text",$id:"agentic-3-224",props:{children:"A little help. A world of possibilities.",className:"font-display text-xl"}},{$ref:"Text",$id:"agentic-3-225",props:{children:"ELSEWHERE / YOUR TRAVEL COMPANION",className:"text-[9px] tracking-widest text-muted-foreground"}}]}]}};var elsewhere_trips_library_default={id:"elsewhere-trips-library",name:"A \xB7 The conversational concierge",tree:{$ref:"Box",$id:"agentic-1-1",props:{className:"min-h-screen bg-background text-foreground font-sans"},children:[{$snippet:"elsewhere-nav"},{$ref:"Box",$id:"agentic-1-2",props:{className:"px-12 pt-10 pb-8"},children:[{$ref:"Box",$id:"agentic-1-3",props:{className:"space-y-3"},children:[{$ref:"Text",$id:"agentic-1-4",props:{children:"YOUR PERSONAL TRAVEL COMPANION",className:"text-[10px] uppercase tracking-[.2em] text-primary"}},{$ref:"Heading",$id:"agentic-1-5",props:{children:"Tell us what a good trip feels like.",className:"font-display font-normal tracking-[-0.03em] text-5xl leading-[1.08]"}},{$ref:"Text",$id:"agentic-1-6",props:{children:"A conversation, a few thoughtful suggestions, and a plan that gets more you with every turn.",className:"text-sm leading-7 text-muted-foreground max-w-2xl"}}]}]},{$ref:"Box",$id:"agentic-1-7",props:{className:"grid grid-cols-[1fr_410px] gap-9 px-12 pb-10"},children:[{$ref:"Box",$id:"agentic-1-8",props:{className:"space-y-7"},children:[{$ref:"Box",$id:"agentic-1-9",props:{className:"flex items-center justify-between pb-3 border-b border-border"},children:[{$ref:"Box",$id:"agentic-1-10",props:{className:"flex gap-3 items-center"},children:[{$ref:"Box",$id:"agentic-1-11",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-1-12",props:{name:"Sparkles",className:"size-4"}}]},{$ref:"Box",$id:"agentic-1-13",props:{className:""},children:[{$ref:"Text",$id:"agentic-1-14",props:{children:"Elsewhere companion",className:"font-semibold text-sm"}},{$ref:"Text",$id:"agentic-1-15",props:{children:"Planning together \xB7 Kyoto",className:"text-[10px] text-muted-foreground"}}]}]},{$ref:"Button",$id:"agentic-1-16",props:{variant:"ghost",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-1-17",props:{name:"RotateCcw",className:"size-4"}},{$ref:"Box",$id:"agentic-1-18",props:{className:"",children:"Start fresh"}}]}]},{$ref:"MessageGroup",$id:"agentic-1-19",props:{className:"space-y-7"},children:[{$ref:"Message",$id:"agentic-1-20",props:{align:"end",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-1-21",children:[{$ref:"Avatar",$id:"agentic-1-22",props:{className:"size-8"},children:[{$ref:"AvatarFallback",$id:"agentic-1-23",props:{children:"AL",className:"bg-secondary text-[10px]"}}]}]},{$ref:"Box",$id:"agentic-1-24",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-1-25",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-1-26",props:{children:"You",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-1-27",props:{className:"bg-secondary/65 rounded-2xl px-5 py-4"},children:[{$ref:"Text",$id:"agentic-1-28",props:{children:"Jamie and I have five nights in October. We love food, quiet streets and a beautiful little place to stay. Somewhere in Japan, around $3,200 for both of us.",className:"text-sm leading-7"}}]}]}]},{$ref:"Message",$id:"agentic-1-29",props:{align:"start",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-1-30",children:[{$ref:"Box",$id:"agentic-1-31",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-1-32",props:{name:"Sparkles",className:"size-4"}}]}]},{$ref:"Box",$id:"agentic-1-33",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-1-34",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-1-35",props:{children:"Elsewhere",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-1-36",props:{className:"space-y-4"},children:[{$ref:"Text",$id:"agentic-1-37",props:{children:"Kyoto feels like a lovely fit. Before I shape the week: do you prefer slow mornings, or getting out early to beat the crowds?",className:"text-sm leading-7"}},{$ref:"Box",$id:"agentic-1-38",props:{className:"flex gap-2"},children:[{$ref:"Button",$id:"agentic-1-39",props:{variant:"secondary",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-1-40",props:{name:"Coffee",className:"size-4"}},{$ref:"Box",$id:"agentic-1-41",props:{className:"",children:"Slow mornings"}}]},{$ref:"Button",$id:"agentic-1-42",props:{variant:"outline",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-1-43",props:{name:"Sunrise",className:"size-4"}},{$ref:"Box",$id:"agentic-1-44",props:{className:"",children:"Early adventures"}}]},{$ref:"Button",$id:"agentic-1-45",props:{variant:"outline",className:"rounded-full text-xs"},children:[{$ref:"Box",$id:"agentic-1-46",props:{className:"",children:"A little of both"}}]}]}]}]}]},{$ref:"Message",$id:"agentic-1-47",props:{align:"end",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-1-48",children:[{$ref:"Avatar",$id:"agentic-1-49",props:{className:"size-8"},children:[{$ref:"AvatarFallback",$id:"agentic-1-50",props:{children:"AL",className:"bg-secondary text-[10px]"}}]}]},{$ref:"Box",$id:"agentic-1-51",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-1-52",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-1-53",props:{children:"You",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-1-54",props:{className:"bg-secondary/65 rounded-2xl px-5 py-4"},children:[{$ref:"Text",$id:"agentic-1-55",props:{children:"A little of both. One early start is fine, but please leave space to wander.",className:"text-sm leading-7"}}]}]}]},{$ref:"Message",$id:"agentic-1-56",props:{align:"start",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-1-57",children:[{$ref:"Box",$id:"agentic-1-58",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-1-59",props:{name:"Sparkles",className:"size-4"}}]}]},{$ref:"Box",$id:"agentic-1-60",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-1-61",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-1-62",props:{children:"Elsewhere",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-1-63",props:{className:"space-y-4"},children:[{$ref:"Text",$id:"agentic-1-64",props:{children:"A good balance. I\u2019ll keep you in a walkable neighbourhood, group the bigger sights into one early morning, and leave two afternoons open.",className:"text-sm leading-7"}},{$ref:"Card",$id:"agentic-1-65",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-muted/40"},children:[{$ref:"Box",$id:"agentic-1-66",props:{className:"flex gap-2 items-center"},children:[{$ref:"Icon",$id:"agentic-1-67",props:{name:"Compass",className:"size-4"}},{$ref:"Text",$id:"agentic-1-68",props:{children:"A little research, taken care of.",className:"font-semibold text-sm"}}]},{$ref:"Box",$id:"agentic-1-69",props:{className:"divide-y divide-border"},children:[{$ref:"Box",$id:"agentic-1-70",props:{className:"flex items-center justify-between gap-3 py-3"},children:[{$ref:"Box",$id:"agentic-1-71",props:{className:"flex items-center gap-3"},children:[{$ref:"Icon",$id:"agentic-1-72",props:{name:"CircleCheck",className:"size-4 text-primary"}},{$ref:"Text",$id:"agentic-1-73",props:{children:"Matched your pace and interests",className:"text-xs"}}]},{$ref:"Text",$id:"agentic-1-74",props:{children:"Done",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Box",$id:"agentic-1-75",props:{className:"flex items-center justify-between gap-3 py-3"},children:[{$ref:"Box",$id:"agentic-1-76",props:{className:"flex items-center gap-3"},children:[{$ref:"Icon",$id:"agentic-1-77",props:{name:"CircleCheck",className:"size-4 text-primary"}},{$ref:"Text",$id:"agentic-1-78",props:{children:"Compared 6 neighbourhood stays",className:"text-xs"}}]},{$ref:"Text",$id:"agentic-1-79",props:{children:"Done",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Box",$id:"agentic-1-80",props:{className:"flex items-center justify-between gap-3 py-3"},children:[{$ref:"Box",$id:"agentic-1-81",props:{className:"flex items-center gap-3"},children:[{$ref:"Icon",$id:"agentic-1-82",props:{name:"CircleCheck",className:"size-4 text-primary"}},{$ref:"Text",$id:"agentic-1-83",props:{children:"Grouped nearby discoveries",className:"text-xs"}}]},{$ref:"Text",$id:"agentic-1-84",props:{children:"Done",className:"text-[10px] text-muted-foreground"}}]},{$ref:"Box",$id:"agentic-1-85",props:{className:"flex items-center justify-between gap-3 py-3"},children:[{$ref:"Box",$id:"agentic-1-86",props:{className:"flex items-center gap-3"},children:[{$ref:"Icon",$id:"agentic-1-87",props:{name:"CircleCheck",className:"size-4 text-primary"}},{$ref:"Text",$id:"agentic-1-88",props:{children:"Balanced the plan with your budget",className:"text-xs"}}]},{$ref:"Text",$id:"agentic-1-89",props:{children:"Done",className:"text-[10px] text-muted-foreground"}}]}]},{$ref:"Text",$id:"agentic-1-90",props:{children:"Suggestions prepared \xB7 Nothing booked",className:"text-[10px] text-muted-foreground"}}]}]}]}]},{$ref:"Message",$id:"agentic-1-91",props:{align:"start",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-1-92",children:[{$ref:"Box",$id:"agentic-1-93",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-1-94",props:{name:"Sparkles",className:"size-4"}}]}]},{$ref:"Box",$id:"agentic-1-95",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-1-96",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-1-97",props:{children:"Elsewhere",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-1-98",props:{className:"space-y-4"},children:[{$ref:"Text",$id:"agentic-1-99",props:{children:"Two stays I think you\u2019ll love. Both keep the city close and the pace gentle.",className:"text-sm leading-7"}},{$ref:"Box",$id:"agentic-1-100",props:{className:"grid grid-cols-2 gap-4"},children:[{$ref:"Card",$id:"agentic-1-101",props:{className:"rounded-xl overflow-hidden p-0 gap-0 shadow-none"},children:[{$ref:"Box",$id:"agentic-1-102",props:{className:"relative overflow-hidden h-[155px]"},children:[{$ref:"Image",$id:"agentic-1-103",props:{src:"/assets/elsewhere-room.jpg",alt:"room travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"CardContent",$id:"agentic-1-104",props:{className:"p-4 space-y-3"},children:[{$ref:"Heading",$id:"agentic-1-105",props:{children:"Higashiyama House",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-1-106",props:{children:"$185 / NIGHT \xB7 BREAKFAST INCLUDED",className:"text-[10px] text-primary"}},{$ref:"Text",$id:"agentic-1-107",props:{children:"A quiet base, with old Kyoto right outside.",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Card",$id:"agentic-1-108",props:{className:"rounded-xl overflow-hidden p-0 gap-0 shadow-none"},children:[{$ref:"Box",$id:"agentic-1-109",props:{className:"relative overflow-hidden h-[155px]"},children:[{$ref:"Image",$id:"agentic-1-110",props:{src:"/assets/elsewhere-forest.jpg",alt:"forest travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"CardContent",$id:"agentic-1-111",props:{className:"p-4 space-y-3"},children:[{$ref:"Heading",$id:"agentic-1-112",props:{children:"The Garden Retreat",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Text",$id:"agentic-1-113",props:{children:"$210 / NIGHT \xB7 PRIVATE GARDEN",className:"text-[10px] text-primary"}},{$ref:"Text",$id:"agentic-1-114",props:{children:"More space to switch off, a little further out.",className:"text-xs leading-6 text-muted-foreground"}}]}]}]},{$ref:"Box",$id:"agentic-1-115",props:{className:"flex gap-3"},children:[{$ref:"Button",$id:"agentic-1-116",props:{variant:"default",className:"rounded-full text-xs"},children:[{$ref:"Icon",$id:"agentic-1-117",props:{name:"Check",className:"size-4"}},{$ref:"Box",$id:"agentic-1-118",props:{className:"",children:"Choose Higashiyama"}}]},{$ref:"Button",$id:"agentic-1-119",props:{variant:"outline",className:"rounded-full text-xs"},children:[{$ref:"Box",$id:"agentic-1-120",props:{className:"",children:"Show me more stays"}}]}]}]}]}]},{$ref:"Message",$id:"agentic-1-121",props:{align:"end",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-1-122",children:[{$ref:"Avatar",$id:"agentic-1-123",props:{className:"size-8"},children:[{$ref:"AvatarFallback",$id:"agentic-1-124",props:{children:"AL",className:"bg-secondary text-[10px]"}}]}]},{$ref:"Box",$id:"agentic-1-125",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-1-126",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-1-127",props:{children:"You",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-1-128",props:{className:"bg-secondary/65 rounded-2xl px-5 py-4"},children:[{$ref:"Text",$id:"agentic-1-129",props:{children:"Higashiyama looks perfect. Could we swap the busy temple afternoon for something quieter?",className:"text-sm leading-7"}}]}]}]},{$ref:"Message",$id:"agentic-1-130",props:{align:"start",className:"w-full"},children:[{$ref:"MessageAvatar",$id:"agentic-1-131",children:[{$ref:"Box",$id:"agentic-1-132",props:{className:"size-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shrink-0"},children:[{$ref:"Icon",$id:"agentic-1-133",props:{name:"Sparkles",className:"size-4"}}]}]},{$ref:"Box",$id:"agentic-1-134",props:{className:"min-w-0 flex-1 space-y-2"},children:[{$ref:"MessageHeader",$id:"agentic-1-135",props:{className:"text-xs text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-1-136",props:{children:"Elsewhere",className:"text-inherit"}}]},{$ref:"MessageContent",$id:"agentic-1-137",props:{className:"space-y-4"},children:[{$ref:"Text",$id:"agentic-1-138",props:{children:"Absolutely. I\u2019ve replaced that afternoon with a small gallery walk and tea in a tucked-away courtyard. It saves $40 and leaves more time between stops.",className:"text-sm leading-7"}},{$ref:"Alert",$id:"agentic-1-139",props:{className:"bg-secondary/40 rounded-xl"},children:[{$ref:"Icon",$id:"agentic-1-140",props:{name:"RefreshCw",className:"size-4"}},{$ref:"AlertTitle",$id:"agentic-1-141",props:{children:"Your plan, adjusted"}},{$ref:"AlertDescription",$id:"agentic-1-142",props:{children:"Day 3 is quieter \xB7 Estimated total is now $1,730 \xB7 Two afternoons remain open"}}]}]}]}]}]},{$ref:"Card",$id:"agentic-1-143",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-card"},children:[{$ref:"Textarea",$id:"agentic-1-144",props:{placeholder:"One more thing\u2026",className:"border-0 shadow-none resize-none p-0 min-h-[62px] bg-transparent text-sm"}},{$ref:"Box",$id:"agentic-1-145",props:{className:"flex justify-between items-center"},children:[{$ref:"Button",$id:"agentic-1-146",props:{variant:"ghost",className:"rounded-full px-0 text-xs"},children:[{$ref:"Icon",$id:"agentic-1-147",props:{name:"Paperclip",className:"size-4"}},{$ref:"Box",$id:"agentic-1-148",props:{className:"",children:"Add inspiration"}}]},{$ref:"Button",$id:"agentic-1-149",props:{variant:"default",className:"rounded-full h-9"},children:[{$ref:"Icon",$id:"agentic-1-150",props:{name:"ArrowUp",className:"size-4"}},{$ref:"Box",$id:"agentic-1-151",props:{className:"",children:"Send"}}]}]}]},{$ref:"Card",$id:"agentic-1-152",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-secondary/35"},children:[{$ref:"Box",$id:"agentic-1-153",props:{className:"flex gap-3 items-center"},children:[{$ref:"Icon",$id:"agentic-1-154",props:{name:"CircleCheck",className:"size-5 text-primary"}},{$ref:"Heading",$id:"agentic-1-155",props:{children:"A trip that feels like you.",className:"font-display font-normal tracking-[-0.03em] text-2xl"}}]},{$ref:"Text",$id:"agentic-1-156",props:{children:"Save this draft to My trips. You can keep refining it with your companion, invite Jamie, and book each stay or experience when you\u2019re ready.",className:"text-xs leading-6 text-muted-foreground"}},{$ref:"Box",$id:"agentic-1-157",props:{className:"flex gap-3"},children:[{$ref:"Button",$id:"agentic-1-158",props:{variant:"default",className:"rounded-full h-11 px-6"},children:[{$ref:"Icon",$id:"agentic-1-159",props:{name:"Check",className:"size-4"}},{$ref:"Box",$id:"agentic-1-160",props:{className:"",children:"Save my trip"}}]},{$ref:"Button",$id:"agentic-1-161",props:{variant:"outline",className:"rounded-full h-11"},children:[{$ref:"Box",$id:"agentic-1-162",props:{className:"",children:"Keep refining"}}]}]},{$ref:"Text",$id:"agentic-1-163",props:{children:"Saving creates a private trip. Bookings happen separately.",className:"text-[10px] text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-1-164",props:{className:"space-y-6"},children:[{$ref:"Card",$id:"agentic-1-165",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Box",$id:"agentic-1-166",props:{className:"flex justify-between items-center"},children:[{$ref:"Text",$id:"agentic-1-167",props:{children:"YOUR TRIP, TAKING SHAPE",className:"text-[9px] tracking-widest text-muted-foreground"}},{$ref:"Badge",$id:"agentic-1-168",props:{variant:"secondary",children:"Draft 02",className:"rounded-full px-3 py-1 text-[10px] font-normal"}}]},{$ref:"Box",$id:"agentic-1-169",props:{className:"relative overflow-hidden h-[210px] rounded-xl"},children:[{$ref:"Image",$id:"agentic-1-170",props:{src:"/assets/elsewhere-kyoto.jpg",alt:"kyoto travel inspiration",fill:!0,className:"absolute inset-0 w-full h-full"}}]},{$ref:"Heading",$id:"agentic-1-171",props:{children:"A week in Kyoto",className:"font-display font-normal tracking-[-0.03em] text-3xl"}},{$ref:"Text",$id:"agentic-1-172",props:{children:"12\u201317 October 2026 \xB7 2 travellers",className:"text-xs text-muted-foreground"}},{$ref:"Box",$id:"agentic-1-173",props:{className:"flex flex-wrap gap-2"},children:[{$ref:"Badge",$id:"agentic-1-174",props:{variant:"secondary",children:"Slow mornings",className:"rounded-full px-3 py-1 text-[10px] font-normal"}},{$ref:"Badge",$id:"agentic-1-175",props:{variant:"secondary",children:"Local food",className:"rounded-full px-3 py-1 text-[10px] font-normal"}},{$ref:"Badge",$id:"agentic-1-176",props:{variant:"secondary",children:"Under $3,200",className:"rounded-full px-3 py-1 text-[10px] font-normal"}}]},{$ref:"Separator",$id:"agentic-1-177"},{$ref:"Box",$id:"agentic-1-178",props:{className:"space-y-3 text-xs"},children:[{$ref:"Box",$id:"agentic-1-179",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"agentic-1-180",props:{children:"Stay",className:"text-inherit"}},{$ref:"Text",$id:"agentic-1-181",props:{children:"$970",className:"text-inherit"}}]},{$ref:"Box",$id:"agentic-1-182",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"agentic-1-183",props:{children:"Food & coffee",className:"text-inherit"}},{$ref:"Text",$id:"agentic-1-184",props:{children:"$360",className:"text-inherit"}}]},{$ref:"Box",$id:"agentic-1-185",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"agentic-1-186",props:{children:"Experiences",className:"text-inherit"}},{$ref:"Text",$id:"agentic-1-187",props:{children:"$240",className:"text-inherit"}}]},{$ref:"Box",$id:"agentic-1-188",props:{className:"flex justify-between"},children:[{$ref:"Text",$id:"agentic-1-189",props:{children:"Local transport",className:"text-inherit"}},{$ref:"Text",$id:"agentic-1-190",props:{children:"$160",className:"text-inherit"}}]},{$ref:"Separator",$id:"agentic-1-191"},{$ref:"Box",$id:"agentic-1-192",props:{className:"flex justify-between font-semibold"},children:[{$ref:"Text",$id:"agentic-1-193",props:{children:"Estimated trip total",className:"text-inherit"}},{$ref:"Text",$id:"agentic-1-194",props:{children:"$1,730",className:"text-inherit"}}]},{$ref:"Box",$id:"agentic-1-195",props:{className:"flex justify-between text-muted-foreground"},children:[{$ref:"Text",$id:"agentic-1-196",props:{children:"Left for the unexpected",className:"text-inherit"}},{$ref:"Text",$id:"agentic-1-197",props:{children:"$1,470",className:"text-inherit"}}]}]},{$ref:"Button",$id:"agentic-1-198",props:{variant:"outline",className:"rounded-full w-full"},children:[{$ref:"Icon",$id:"agentic-1-199",props:{name:"ArrowUpRight",className:"size-4"}},{$ref:"Box",$id:"agentic-1-200",props:{className:"",children:"View full itinerary"}}]}]},{$ref:"Card",$id:"agentic-1-201",props:{className:"rounded-2xl shadow-none p-6 gap-5 "},children:[{$ref:"Heading",$id:"agentic-1-202",props:{children:"Five days, softly planned.",className:"font-display font-normal tracking-[-0.03em] text-2xl"}},{$ref:"Box",$id:"agentic-1-203",props:{className:"divide-y divide-border"},children:[{$ref:"Box",$id:"agentic-1-204",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-1-205",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-1-206",props:{children:"01",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-1-207",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-1-208",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-1-209",props:{children:"Arrive gently",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-1-210",props:{children:"$100",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-1-211",props:{children:"Nishiki Market \xB7 Gion lanes \xB7 Tea with a local host",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-1-212",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-1-213",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-1-214",props:{children:"02",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-1-215",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-1-216",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-1-217",props:{children:"A greener kind of morning",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-1-218",props:{children:"$85",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-1-219",props:{children:"Early bamboo grove \xB7 Riverside lunch \xB7 An open afternoon",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-1-220",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-1-221",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-1-222",props:{children:"03",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-1-223",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-1-224",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-1-225",props:{children:"Follow your curiosity",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-1-226",props:{children:"$120",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-1-227",props:{children:"Small galleries \xB7 Independent shops \xB7 Dinner in Pontocho",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-1-228",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-1-229",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-1-230",props:{children:"04",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-1-231",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-1-232",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-1-233",props:{children:"A little further afield",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-1-234",props:{children:"$110",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-1-235",props:{children:"A day in Uji \xB7 Tea fields \xB7 Back before sunset",className:"text-xs leading-6 text-muted-foreground"}}]}]},{$ref:"Box",$id:"agentic-1-236",props:{className:"flex gap-4 items-start py-5"},children:[{$ref:"Box",$id:"agentic-1-237",props:{className:"size-10 rounded-full bg-secondary flex justify-center items-center shrink-0"},children:[{$ref:"Text",$id:"agentic-1-238",props:{children:"05",className:"text-xs"}}]},{$ref:"Box",$id:"agentic-1-239",props:{className:"flex-1 space-y-2"},children:[{$ref:"Box",$id:"agentic-1-240",props:{className:"flex items-center justify-between"},children:[{$ref:"Text",$id:"agentic-1-241",props:{children:"Leave room for one more thing",className:"text-sm font-semibold"}},{$ref:"Text",$id:"agentic-1-242",props:{children:"$65",className:"text-xs text-muted-foreground"}}]},{$ref:"Text",$id:"agentic-1-243",props:{children:"A slow breakfast \xB7 Your favourite neighbourhood \xB7 Homeward",className:"text-xs leading-6 text-muted-foreground"}}]}]}]}]},{$ref:"Card",$id:"agentic-1-244",props:{className:"rounded-2xl shadow-none p-6 gap-5 bg-secondary/25"},children:[{$ref:"Text",$id:"agentic-1-245",props:{children:"WHY THIS FITS",className:"text-[9px] tracking-widest text-primary"}},{$ref:"Box",$id:"agentic-1-246",props:{className:"space-y-4"},children:[{$ref:"Text",$id:"agentic-1-247",props:{children:"A walkable base, so less time disappears into transport.",className:"text-xs leading-6"}},{$ref:"Text",$id:"agentic-1-248",props:{children:"One early start. Two open afternoons. Plenty of room to linger.",className:"text-xs leading-6"}},{$ref:"Text",$id:"agentic-1-249",props:{children:"Local food and small discoveries woven into every day.",className:"text-xs leading-6"}}]}]}]}]},{$ref:"Box",$id:"agentic-1-250",props:{className:"border-t border-border px-12 py-8 flex justify-between"},children:[{$ref:"Text",$id:"agentic-1-251",props:{children:"A little help. A world of possibilities.",className:"font-display text-xl"}},{$ref:"Text",$id:"agentic-1-252",props:{children:"ELSEWHERE / YOUR TRAVEL COMPANION",className:"text-[9px] tracking-widest text-muted-foreground"}}]}]}};var elsewhere_details_default={id:"elsewhere-details",name:"Agentic trip creation exploration",frames:[{id:"elsewhere-trips-library-desktop",screen:"elsewhere-trips-library",x:0,y:270,w:1440,h:2540,label:"A \xB7 The conversational concierge"},{id:"elsewhere-trips-board-desktop",screen:"elsewhere-trips-board",x:1580,y:270,w:1440,h:2909,label:"B \xB7 The brief-to-plan workspace"},{id:"elsewhere-trips-journal-desktop",screen:"elsewhere-trips-journal",x:3160,y:270,w:1440,h:3547,label:"C \xB7 The inspiration-led companion"}],groups:[]};var main_default={id:"main",name:"Elsewhere \xB7 The journey",frames:[{id:"elsewhere-discover-desktop",screen:"elsewhere-discover",x:0,y:0,w:1440,h:1361,label:"01 \xB7 Discover your elsewhere / Desktop",scheme:"light"},{id:"elsewhere-stay-desktop",screen:"elsewhere-stay",x:1550,y:0,w:1440,h:1337,label:"02 \xB7 A stay in Kyoto / Desktop"},{id:"elsewhere-itinerary-desktop",screen:"elsewhere-itinerary",x:0,y:1600,w:1440,h:1324,label:"03 \xB7 A day in Kyoto / Desktop"},{id:"elsewhere-overview-desktop",screen:"elsewhere-overview",x:1550,y:1600,w:1440,h:1543,label:"04 \xB7 Your trip, at a glance / Desktop",scheme:"light"},{id:"elsewhere-discover-mobile",screen:"elsewhere-discover",x:3100,y:0,w:390,h:2390,label:"Shared screen / Mobile"},{id:"elsewhere-itinerary-mobile",screen:"elsewhere-itinerary",x:3610,y:0,w:390,h:2000,label:"Shared screen / Mobile"},{id:"elsewhere-discover-dark",screen:"elsewhere-discover",x:0,y:3300,w:1440,h:1361,label:"Discover / Dark mode",scheme:"dark"},{id:"elsewhere-overview-dark",screen:"elsewhere-overview",x:1550,y:3300,w:1440,h:1543,label:"Trip overview / Dark mode",scheme:"dark"}],groups:[]};function buildSampleScreens(){return structuredClone([elsewhere_discover_default,elsewhere_itinerary_default,elsewhere_overview_default,elsewhere_stay_default,elsewhere_trips_board_default,elsewhere_trips_journal_default,elsewhere_trips_library_default])}function buildSampleBoards(){return structuredClone([main_default,elsewhere_details_default])}var elsewhere_destination_default={id:"elsewhere-destination",name:"DestinationCard",params:[{name:"image",type:"string"},{name:"name",type:"string"},{name:"country",type:"string"},{name:"note",type:"string"}],tree:{$ref:"Card",props:{className:"overflow-hidden p-0 gap-0 rounded-2xl shadow-none"},children:[{$ref:"Box",props:{className:"relative h-[210px] overflow-hidden"},children:[{$ref:"Image",props:{src:{$param:"image"},fill:!0,className:"absolute inset-0 h-full w-full"}},{$ref:"Button",props:{variant:"secondary",size:"icon",className:"absolute right-3 top-3 rounded-full size-8","aria-label":"Save destination"},children:[{$ref:"Icon",props:{name:"Heart",className:"size-4"}}]}]},{$ref:"CardContent",props:{className:"p-5"},children:[{$ref:"Text",props:{children:{$param:"country"},className:"text-[10px] uppercase tracking-[0.18em] text-muted-foreground"}},{$ref:"Box",props:{className:"flex items-center justify-between mt-2"},children:[{$ref:"Heading",props:{children:{$param:"name"},className:"font-display font-normal tracking-[-0.035em] text-3xl"}},{$ref:"Icon",props:{name:"ArrowUpRight",className:"size-4"}}]},{$ref:"Text",props:{children:{$param:"note"},className:"text-xs mt-2 text-muted-foreground"}}]}]}};var elsewhere_metric_default={id:"elsewhere-metric",name:"TripMetric",params:[{name:"label",type:"string"},{name:"value",type:"string"},{name:"note",type:"string"}],tree:{$ref:"Card",props:{className:"p-5 gap-3 rounded-xl shadow-none"},children:[{$ref:"Text",props:{children:{$param:"label"},className:"text-xs text-muted-foreground"}},{$ref:"Heading",props:{children:{$param:"value"},className:"font-display font-normal tracking-[-0.035em] text-3xl"}},{$ref:"Text",props:{children:{$param:"note"},className:"text-xs text-muted-foreground"}}]}};var elsewhere_nav_default={id:"elsewhere-nav",name:"ElsewhereNav",params:[],tree:{$ref:"Box",props:{className:"h-20 border-b border-border flex items-center justify-between px-6 md:px-14 bg-background"},children:[{$ref:"Box",props:{className:"flex items-center gap-2"},children:[{$ref:"SVG",props:{viewBox:"0 0 32 32",content:'<circle cx="16" cy="16" r="14" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M8 21 22 9l-4 15-3-7-7 4Z" fill="currentColor"/>',className:"size-8 text-primary"}},{$ref:"Text",props:{children:"elsewhere",className:"font-display text-[30px] tracking-[-0.05em]"}}]},{$ref:"Box",props:{className:"hidden md:flex items-center gap-8 text-sm"},children:[{$ref:"Text",props:{children:"Discover",className:"font-semibold"}},{$ref:"Text",props:{children:"Our kind of stays",className:"text-muted-foreground"}},{$ref:"Text",props:{children:"Field notes",className:"text-muted-foreground"}}]},{$ref:"Box",props:{className:"flex items-center gap-4"},children:[{$ref:"Button",props:{variant:"ghost",className:"rounded-full hidden md:inline-flex"},children:[{$ref:"Icon",props:{name:"Bookmark",className:"size-4"}},{$ref:"Text",props:{children:"My trips",className:""}}]},{$ref:"Avatar",props:{className:"size-8 border-2 border-background"},children:[{$ref:"AvatarFallback",props:{children:"AL",className:"text-[10px] bg-secondary text-secondary-foreground"}}]}]}]}};function buildSampleSnippets(){return structuredClone([elsewhere_destination_default,elsewhere_metric_default,elsewhere_nav_default])}function buildElsewhereScaffold(library,theme){let screens=buildSampleScreens(),snippets=buildSampleSnippets(),native=library==="shadcn-upstream"?void 0:nativeElsewhere(library,screens,snippets);return{theme,screens:native?.screens??screens,snippets:native?.snippets??snippets,boards:buildSampleBoards(),annotations:[],notes:[{boardId:"elsewhere-details",entries:structuredClone(elsewhere_details_notes_default)}],customCss:`${custom_default}
|
|
45
|
-
${native?.css??""}`,assetMetadata:structuredClone(assets_default),assetFiles:{"assets/elsewhere-alps.jpg":resolve3(import.meta.dir,elsewhere_alps_default),"assets/elsewhere-bali.jpg":resolve3(import.meta.dir,elsewhere_bali_default),"assets/elsewhere-forest.jpg":resolve3(import.meta.dir,elsewhere_forest_default),"assets/elsewhere-japan.jpg":resolve3(import.meta.dir,elsewhere_japan_default),"assets/elsewhere-kyoto-map.svg":resolve3(import.meta.dir,elsewhere_kyoto_map_default),"assets/elsewhere-kyoto.jpg":resolve3(import.meta.dir,elsewhere_kyoto_default),"assets/elsewhere-room.jpg":resolve3(import.meta.dir,elsewhere_room_default)},documents:{"ASSET-SOURCES.md":ASSET_SOURCES_default}}}function html(as,props={},children=[]){return{$ref:"Html",props:{as,...props},...children.length?{children}:{}}}var text=(as,value,style={})=>html(as,{children:value,...Object.keys(style).length?{style}:{}});function buildHtmlSampleScaffold(theme){let screen={id:"contacts",name:"Contacts \xB7 HTML and htmx",route:"/contacts",tree:html("main",{style:{boxSizing:"border-box",minHeight:"100vh",padding:"48px 28px",background:"#f5f3ed",color:"#183b37",fontFamily:"system-ui, sans-serif"}},[html("div",{style:{maxWidth:840,margin:"0 auto"}},[html("header",{style:{marginBottom:28}},[text("small","PEOPLE DIRECTORY",{letterSpacing:"0.14em",fontWeight:700}),text("h1","Contacts",{fontSize:44,margin:"10px 0 4px"}),text("p","A native HTML screen. Edit the elements, then emit a server template.",{color:"#63706e"})]),html("section",{style:{padding:24,background:"#ffffff",border:"1px solid #d7dfda",borderRadius:12}},[text("h2","Directory",{marginTop:0}),html("form",{"hx-get":"/contacts/search","hx-target":"#contact-results","hx-trigger":"submit, keyup changed delay:300ms from:input",style:{display:"flex",gap:8,marginBottom:20}},[html("input",{name:"q",type:"search",placeholder:"Search contacts","aria-label":"Search contacts",style:{flex:1,padding:12,border:"1px solid #d7dfda",borderRadius:6}}),html("button",{type:"submit",style:{padding:"10px 20px",border:0,borderRadius:6,background:"#183b37",color:"#ffffff",cursor:"pointer"},children:"Search"})]),html("ul",{id:"contact-results",style:{lineHeight:2}},[text("li","Alex Rivera"),text("li","Morgan Lee"),text("li","Sam Patel")]),html("details",{style:{marginTop:24,color:"#63706e"}},[text("summary","Wire the search to your server"),text("p","Serve /contacts/search with HTML list items; the form's hx-* attributes fetch them in the implementation. The design itself stays a fixed picture.")])])])])},board={id:"main",name:"HTML + htmx",groups:[],frames:[{id:"contacts-desktop",screen:screen.id,x:0,y:0,w:1200,h:850},{id:"contacts-mobile",screen:screen.id,x:1320,y:0,w:390,h:850}]};return{theme,screens:[screen],boards:[board],snippets:[],annotations:[],notes:[]}}function bundledComponentsSection(){return["## Bundled components","","The shadcn snapshot lives inside the velloo binary. No files were","written to your app. When you're ready to bring shadcn into your","project, run `npx shadcn@latest init` there separately, then","`velloo theme export <app>` to align the theme.",""]}var WIZARD_PROVIDERS={"shadcn-upstream":{label:"shadcn",hint:"Real shadcn, Tailwind classes. Recommended.",order:0,defaultSource:"in-repo",asksComponentsSubfolder:!0,scanScreenOpts:{hasBadge:!0},planInstall(answers){let targetDir=resolve4(answers.appRoot,answers.componentsRelative);return{library:{id:"shadcn-upstream",version:snapshotVersion2,source:"in-repo",componentsPath:relative4(answers.folder,dirname4(targetDir)).split(sep4).join("/")||"."},summary:{name:"shadcn (upstream)",location:`canvas reads client-safe components from ${answers.componentsRelative}; canvas-safe fallbacks cover missing or unsupported files`},pendingUpstream:{targetDir,relative:answers.componentsRelative}}},buildSampleScaffold:(theme)=>buildElsewhereScaffold("shadcn-upstream",theme),stylingFor:()=>{return},scanMatch:(detected)=>detected.uiLibrary==="shadcn",scanNote:(detected)=>`Detected ${detected.uiLibrary} \u2014 using that library.`,handoffComponentsLabel:"my shadcn components",readmeComponentsSection:(plan)=>plan.pendingUpstream?["## Bringing shadcn into your app","","Init did not write anything into your app. To add shadcn at",`\`${plan.pendingUpstream.relative}\`, ask your AI`,"agent (it was wired up during init) to finish setup \u2014 or run","`npx shadcn@latest add <component>` yourself. Client-safe files render","directly from the repo; overlays use labeled canvas adaptations and","broken or missing files visibly fall back to Velloo's snapshot. Then","`velloo theme export <app>` aligns the theme.",""]:bundledComponentsSection()},none:{label:"No library",hint:"Plain Box / Stack / Text primitives.",order:9,defaultSource:"binary",asksComponentsSubfolder:!1,scanScreenOpts:{hasBadge:!1},planInstall:()=>({library:{id:"none",version:noLibVersion,source:"binary",componentsPath:"binary"},summary:{name:`no-library primitives (${noLibVersion})`,location:"bundled with velloo"}}),buildSampleScaffold:(theme)=>buildElsewhereScaffold("none",theme),stylingFor:(answers)=>({framework:answers.detected?.tailwindMajor?"tailwind":"none"}),scanMatch:(detected)=>Boolean(detected.unsupportedUi),scanNote:(detected)=>`Detected ${detected.unsupportedUi} (no Velloo adapter) \u2014 the no-framework adapter supplies the primitives, and your ${detected.unsupportedUi} components render from your own install once the setup step writes their preview entry.`,handoffComponentsLabel:"Velloo's primitives",readmeComponentsSection:()=>["## Components","","Velloo's no-framework primitives ship inside the velloo binary. Your","app's own components \u2014 including ones from a UI framework Velloo has no","adapter for \u2014 appear on the Repo shelves of the canvas Library and render","from your own install, inside this design's preview entry (`preview.tsx`","here; the setup step writes it). `emit_code` keeps their exact imports.",""]},html:{label:"HTML + htmx",hint:"Native HTML styled by your app's own CSS.",order:1,defaultSource:"binary",asksComponentsSubfolder:!1,usesStack:!1,scanScreenOpts:{hasBadge:!1,tree:"html"},planInstall:()=>({library:{id:"html",version:HTML_VERSION,source:"binary",componentsPath:"binary"},summary:{name:"HTML + htmx",location:"bundled with velloo"}}),buildSampleScaffold:buildHtmlSampleScaffold,stylingFor:()=>({framework:"none"}),scanMatch:(detected)=>detected.uiLibrary==="html",scanNote:()=>"Detected an HTML app \u2014 its pages are designed and emitted as native HTML.",handoffComponentsLabel:"`Html` nodes and my app's own CSS classes",detectedCanvas:"semantic HTML styled by your app's own stylesheets",readmeComponentsSection:()=>["## HTML and htmx","","Compose semantic HTML with the Html component and ordinary hx-* attributes.","The design is styled by the app's own stylesheets (hostApp.stylesheets in",".design/config.json), from the copies it keeps in assets/host/ \u2014 it never","contacts the running app. The store_host_files tool refreshes those copies.","emit_code returns HTML with its htmx attributes; emit_theme writes the","CSS variables stylesheet that inline theme values reference.",""]},mui:{label:"Material UI",hint:"Real @mui/material, sx styling.",order:4,defaultSource:"binary",asksComponentsSubfolder:!1,scanScreenOpts:{hasBadge:!0,tree:"mui"},planInstall:()=>({library:{id:"mui",version:MUI_VERSION,source:"binary",componentsPath:"binary"},summary:{name:`Material UI v${MUI_VERSION}`,location:"bundled with velloo"}}),buildSampleScaffold:(theme)=>buildElsewhereScaffold("mui",theme),stylingFor:()=>{return},scanMatch:(detected)=>detected.uiLibrary==="mui",scanNote:(detected)=>`Detected ${detected.uiLibrary} \u2014 using that library.`,handoffComponentsLabel:"my Material UI components",readmeComponentsSection:()=>["## Material UI in your app","","The canvas renders **real Material UI** components (bundled with velloo,","emotion-rendered) \u2014 no files were written to your app. When you implement","a screen, `emit_code` emits idiomatic MUI (`sx` props + `@mui/material`","imports) and `emit_theme` emits a `createTheme(...)` module. For that code","to build, install the runtime deps in your app:","","```bash","npm install @mui/material @emotion/react @emotion/styled","```","","Once installed, velloo can also client-render the canvas against your","app's exact MUI version. Style nodes with the `sx` editor (canvas) or","`update_props`'s `style` (agent).",""]},antd:{label:"Ant Design",hint:"Real antd v5, inline style objects.",order:2,defaultSource:"binary",asksComponentsSubfolder:!1,scanScreenOpts:{hasBadge:!0,tree:"antd"},planInstall:()=>({library:{id:"antd",version:ANTD_VERSION,source:"binary",componentsPath:"binary"},summary:{name:`Ant Design v${ANTD_VERSION}`,location:"bundled with velloo"}}),buildSampleScaffold:(theme)=>buildElsewhereScaffold("antd",theme),stylingFor:()=>{return},scanMatch:(detected)=>detected.uiLibrary==="antd",scanNote:(detected)=>`Detected ${detected.uiLibrary} \u2014 using that library.`,handoffComponentsLabel:"my Ant Design components",readmeComponentsSection:()=>["## Ant Design in your app","","The canvas renders **real Ant Design** components (bundled with velloo,","cssinjs-rendered) \u2014 no files were written to your app. When you implement","a screen, `emit_code` emits idiomatic antd (inline `style` objects +","`antd` imports) and `emit_theme` emits a ConfigProvider `ThemeConfig`","module. For that code to build, install the runtime dep in your app:","","```bash","npm install antd","```","","Style nodes with the inline-style editor (canvas) or `update_props`'s `style` (agent).",""]},chakra:{label:"Chakra UI",hint:"Real Chakra v2, sx styling.",order:3,defaultSource:"binary",asksComponentsSubfolder:!1,scanScreenOpts:{hasBadge:!0,tree:"chakra"},planInstall:()=>({library:{id:"chakra",version:CHAKRA_VERSION,source:"binary",componentsPath:"binary"},summary:{name:`Chakra UI v${CHAKRA_VERSION}`,location:"bundled with velloo"}}),buildSampleScaffold:(theme)=>buildElsewhereScaffold("chakra",theme),stylingFor:()=>{return},scanMatch:(detected)=>detected.uiLibrary==="chakra",scanNote:(detected)=>`Detected ${detected.uiLibrary} \u2014 using that library.`,handoffComponentsLabel:"my Chakra UI components",readmeComponentsSection:()=>["## Chakra UI in your app","","The canvas renders **real Chakra UI v2** components (bundled with velloo,","emotion-rendered) \u2014 no files were written to your app. When you implement","a screen, `emit_code` emits idiomatic chakra (`sx` props +","`@chakra-ui/react` imports) and `emit_theme` emits an `extendTheme(...)`","module. For that code to build, install the runtime deps in your app:","","```bash","npm install @chakra-ui/react@2 @emotion/react @emotion/styled framer-motion","```","","Style nodes with the `sx` editor (canvas) or `update_props`'s `style` (agent).",""]}},LIBRARY_IDS=Object.keys(WIZARD_PROVIDERS),DEFAULT_LIBRARY_ID="shadcn-upstream";function interactiveLibraryChoices(){return LIBRARY_IDS.toSorted((a,b)=>WIZARD_PROVIDERS[a].order-WIZARD_PROVIDERS[b].order).map((id)=>({value:id,label:WIZARD_PROVIDERS[id].label,hint:WIZARD_PROVIDERS[id].hint}))}function planInstall(answers){return WIZARD_PROVIDERS[answers.library].planInstall(answers)}function sampleScaffold(answers,theme){return WIZARD_PROVIDERS[answers.library].buildSampleScaffold(theme,answers)}function scanAdoption(detected){for(let id of LIBRARY_IDS){let entry=WIZARD_PROVIDERS[id];if(entry.scanMatch?.(detected))return{library:id,note:entry.scanNote?.(detected)??""}}return}import{copyFile,mkdir,readdir as readdir4}from"fs/promises";import{isAbsolute,join as join8,relative as relative5,resolve as resolve5,sep as sep5}from"path";function buildDefaultConfig(opts={}){return{schemaVersion:CURRENT_SCHEMA_VERSION,toolVersion:TOOL_VERSION,name:opts.name??"design",folderId:crypto.randomUUID(),libraries:{default:opts.library??{id:"shadcn-upstream",version:snapshotVersion2,source:"binary",componentsPath:"binary"}},defaultLibrary:"default",viewportPresets:[{name:"Mobile",w:390,h:844},{name:"Tablet",w:768,h:1024},{name:"Desktop",w:1440,h:900}],...opts.defaultScreen?{defaultScreen:opts.defaultScreen}:{},...opts.defaultBoard?{defaultBoard:opts.defaultBoard}:{},...opts.hostApp?{hostApp:opts.hostApp}:{},...opts.hostApps?{hostApps:opts.hostApps}:{},...opts.feedback?{feedback:opts.feedback}:{},...opts.styling?{styling:opts.styling}:{},...opts.codegen?{codegen:opts.codegen}:{},...opts.designSystem?{designSystem:opts.designSystem}:{}}}var DESKTOP={w:1280,h:800},MOBILE2={w:390,h:844,gap:40};function slugifyName(name,fallback="screen"){return name.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||fallback}function placeholderTree(label){return{$ref:"Box",props:{className:"flex min-h-screen flex-col items-center justify-center gap-3 p-8"},children:[{$ref:"Heading",props:{children:label,className:"text-2xl font-semibold"}},{$ref:"Text",props:{children:"Placeholder \u2014 ask your agent to recreate this, then explore alternatives.",className:"text-muted-foreground text-sm"}}]}}function desktopMobileFrames(screenId,label){return[{id:`f-${screenId}`,screen:screenId,x:80,y:80,w:DESKTOP.w,h:DESKTOP.h,label},{id:`f-${screenId}-m`,screen:screenId,x:80+DESKTOP.w+MOBILE2.gap,y:80,w:MOBILE2.w,h:MOBILE2.h,label:`${label} \xB7 Mobile`}]}function redesignScreenScaffold(theme,screenName){let id=slugifyName(screenName),screen={id,name:screenName.trim()||id,tree:placeholderTree(screenName.trim()||id)},board={id:"main",name:"Main",frames:desktopMobileFrames(id,screen.name),groups:[]};return{theme,screens:[screen],boards:[board],snippets:[],annotations:[],notes:[]}}function componentScaffold(theme,componentDescription){let label=componentDescription.trim()||"Component",id=slugifyName(label,"component"),screen={id,name:label,tree:placeholderTree(label)},board={id:"component",name:"Component",frames:desktopMobileFrames(id,label).map((f)=>({...f,group:"explorations"})),groups:[{id:"explorations",name:"Explorations"}]};return{theme,screens:[screen],boards:[board],snippets:[],annotations:[],notes:[]}}function customRequestScaffold(theme){return{theme,screens:[],boards:[{id:"main",name:"Main",frames:[],groups:[]}],snippets:[],annotations:[],notes:[]}}import{readFileSync}from"fs";var default_default={name:"forest",colors:{background:"#F8F7F2",foreground:"#203C32",primary:{DEFAULT:"#244D3C",foreground:"#FFFFFF"},secondary:{DEFAULT:"#E9EDDF",foreground:"#294332"},muted:{DEFAULT:"#F0F0E8",foreground:"#626D63"},accent:{DEFAULT:"#E8EDDA",foreground:"#244D3C"},destructive:{DEFAULT:"oklch(0.577 0.245 27)",foreground:"oklch(0.985 0 0)"},card:{DEFAULT:"#FFFFFF",foreground:"#203C32"},popover:{DEFAULT:"oklch(0.99 0.01 145)",foreground:"oklch(0.21 0.04 145)"},border:"#DFE3D8",input:"#DFE3D8",ring:"oklch(0.42 0.12 145)"},colorsDark:{background:"#14251F",foreground:"#F0F1E8",primary:{DEFAULT:"#BED5A4",foreground:"#14251F"},secondary:{DEFAULT:"#2B4235",foreground:"#E8EDDF"},muted:{DEFAULT:"#263D31",foreground:"#B0BEAE"},accent:{DEFAULT:"#304737",foreground:"#E8EDDF"},card:{DEFAULT:"#1C3128",foreground:"#F0F1E8"},border:"#3B5143",input:"#3B5143"},typography:{fontFamily:{sans:'"DM Sans", Arial, sans-serif',mono:"ui-monospace, SFMono-Regular, monospace",display:'"DM Serif Display", Georgia, serif'},googleFonts:["DM+Serif+Display","DM+Sans:wght@400;500;600;700"],typesets:{default:{size:14,leading:1.5,flow:"1.25em",fontBody:"sans",fontHeading:"display",fontMono:"mono"},docs:{size:15,leading:1.75,flow:"1.5em"},chat:{leading:1.6,flow:"1em"},compact:{size:14,leading:1.6,flow:"1em"},reading:{size:18,leading:1.9,flow:"2em"}}},spacing:{"0":0,"1":4,"2":8,"3":12,"4":16,"6":24,"8":32,"12":48,"16":64},radius:{sm:4,md:6,lg:8,xl:12,full:9999}};function buildDefaultTheme(){return structuredClone(default_default)}var THEME_PRESETS=[{id:"elsewhere",label:"Elsewhere",seed:"#244d3c"},{id:"indigo",label:"Indigo",seed:"#5e6ad2"},{id:"violet",label:"Violet",seed:"#7c3aed"},{id:"blue",label:"Blue",seed:"#2563eb"},{id:"emerald",label:"Emerald",seed:"#059669"},{id:"rose",label:"Rose",seed:"#e11d48"},{id:"orange",label:"Orange",seed:"#ea580c"},{id:"amber",label:"Amber",seed:"#d97706"},{id:"zinc",label:"Zinc (neutral)",seed:"#52525b"}],CURATED_PRESET="elsewhere",DEFAULT_THEME_PRESET="elsewhere",NEUTRAL_THEME_PRESET="zinc";function presetById(id){return id?THEME_PRESETS.find((p)=>p.id===id):void 0}function isValidPreset(id){return THEME_PRESETS.some((p)=>p.id===id)}function buildPresetTheme(id,name="default"){let base=buildDefaultTheme(),preset=presetById(id);if(!preset||preset.id===CURATED_PRESET)return{...base,name};let derived=derivePalette(preset.seed,base,name);return derived.ok?derived.value.theme:{...base,name}}function importThemeFromDesignMd(filePath,presetId,base){let source;try{source=readFileSync(filePath,"utf8")}catch{return null}let mapped=mapDesignMd(base??buildPresetTheme(presetId,"default"),source);if(!mapped.ok)return null;let{theme,coverage,warnings,designSystem}=mapped.value;if(coverage.semantic===0)return null;return{theme,importedFrom:filePath,tokenCount:coverage.semantic+coverage.palette,warnings,designSystem,coverage:{semantic:coverage.semantic,semanticTotal:coverage.semanticTotal}}}import{existsSync as existsSync2,readFileSync as readFileSync2}from"fs";import{join as join6}from"path";var IDENT_CHAR=/[A-Za-z0-9_$]/;function skipWs(code,i){while(i<code.length&&/\s/.test(code.charAt(i)))i++;return i}function scanString(code,i){let quote=code.charAt(i);i++;while(i<code.length){let ch=code.charAt(i);if(ch==="\\"){i+=2;continue}if(ch===quote)return i+1;if(quote==="`"&&ch==="$"&&code.charAt(i+1)==="{"){i=scanBalanced(code,i+1);continue}if(quote!=="`"&&ch===`
|
|
45
|
+
${native?.css??""}`,assetMetadata:structuredClone(assets_default),assetFiles:{"assets/elsewhere-alps.jpg":resolve3(import.meta.dir,elsewhere_alps_default),"assets/elsewhere-bali.jpg":resolve3(import.meta.dir,elsewhere_bali_default),"assets/elsewhere-forest.jpg":resolve3(import.meta.dir,elsewhere_forest_default),"assets/elsewhere-japan.jpg":resolve3(import.meta.dir,elsewhere_japan_default),"assets/elsewhere-kyoto-map.svg":resolve3(import.meta.dir,elsewhere_kyoto_map_default),"assets/elsewhere-kyoto.jpg":resolve3(import.meta.dir,elsewhere_kyoto_default),"assets/elsewhere-room.jpg":resolve3(import.meta.dir,elsewhere_room_default)},documents:{"ASSET-SOURCES.md":ASSET_SOURCES_default}}}function html(as,props={},children=[]){return{$ref:"Html",props:{as,...props},...children.length?{children}:{}}}var text=(as,value,style={})=>html(as,{children:value,...Object.keys(style).length?{style}:{}});function buildHtmlSampleScaffold(theme){let screen={id:"contacts",name:"Contacts \xB7 HTML and htmx",route:"/contacts",tree:html("main",{style:{boxSizing:"border-box",minHeight:"100vh",padding:"48px 28px",background:"#f5f3ed",color:"#183b37",fontFamily:"system-ui, sans-serif"}},[html("div",{style:{maxWidth:840,margin:"0 auto"}},[html("header",{style:{marginBottom:28}},[text("small","PEOPLE DIRECTORY",{letterSpacing:"0.14em",fontWeight:700}),text("h1","Contacts",{fontSize:44,margin:"10px 0 4px"}),text("p","A native HTML screen. Edit the elements, then emit a server template.",{color:"#63706e"})]),html("section",{style:{padding:24,background:"#ffffff",border:"1px solid #d7dfda",borderRadius:12}},[text("h2","Directory",{marginTop:0}),html("form",{"hx-get":"/contacts/search","hx-target":"#contact-results","hx-trigger":"submit, keyup changed delay:300ms from:input",style:{display:"flex",gap:8,marginBottom:20}},[html("input",{name:"q",type:"search",placeholder:"Search contacts","aria-label":"Search contacts",style:{flex:1,padding:12,border:"1px solid #d7dfda",borderRadius:6}}),html("button",{type:"submit",style:{padding:"10px 20px",border:0,borderRadius:6,background:"#183b37",color:"#ffffff",cursor:"pointer"},children:"Search"})]),html("ul",{id:"contact-results",style:{lineHeight:2}},[text("li","Alex Rivera"),text("li","Morgan Lee"),text("li","Sam Patel")]),html("details",{style:{marginTop:24,color:"#63706e"}},[text("summary","Wire the search to your server"),text("p","Serve /contacts/search with HTML list items; the form's hx-* attributes fetch them in the implementation. The design itself stays a fixed picture.")])])])])},board={id:"main",name:"HTML + htmx",groups:[],frames:[{id:"contacts-desktop",screen:screen.id,x:0,y:0,w:1200,h:850},{id:"contacts-mobile",screen:screen.id,x:1320,y:0,w:390,h:850}]};return{theme,screens:[screen],boards:[board],snippets:[],annotations:[],notes:[]}}function bundledComponentsSection(){return["## Bundled components","","The shadcn snapshot lives inside the velloo binary. No files were","written to your app. When you're ready to bring shadcn into your","project, run `npx shadcn@latest init` there separately, then","`velloo theme export <app>` to align the theme.",""]}var WIZARD_PROVIDERS={"shadcn-upstream":{label:"shadcn",hint:"Real shadcn, Tailwind classes. Recommended.",order:0,defaultSource:"in-repo",asksComponentsSubfolder:!0,scanScreenOpts:{hasBadge:!0},planInstall(answers){let targetDir=resolve4(answers.appRoot,answers.componentsRelative);return{library:{id:"shadcn-upstream",version:snapshotVersion2,source:"in-repo",componentsPath:relative4(answers.folder,dirname4(targetDir)).split(sep4).join("/")||"."},summary:{name:"shadcn (upstream)",location:`canvas reads client-safe components from ${answers.componentsRelative}; canvas-safe fallbacks cover missing or unsupported files`},pendingUpstream:{targetDir,relative:answers.componentsRelative}}},buildSampleScaffold:(theme)=>buildElsewhereScaffold("shadcn-upstream",theme),stylingFor:()=>{return},scanMatch:(detected)=>detected.uiLibrary==="shadcn",scanNote:(detected)=>`Detected ${detected.uiLibrary} \u2014 using that library.`,handoffComponentsLabel:"my shadcn components",readmeComponentsSection:(plan)=>plan.pendingUpstream?["## Bringing shadcn into your app","","Init did not write anything into your app. To add shadcn at",`\`${plan.pendingUpstream.relative}\`, ask your AI`,"agent (it was wired up during init) to finish setup \u2014 or run","`npx shadcn@latest add <component>` yourself. Client-safe files render","directly from the repo; overlays use labeled canvas adaptations and","broken or missing files visibly fall back to Velloo's snapshot. Then","`velloo theme export <app>` aligns the theme.",""]:bundledComponentsSection()},none:{label:"No library",hint:"Plain Box / Stack / Text primitives.",order:9,defaultSource:"binary",asksComponentsSubfolder:!1,scanScreenOpts:{hasBadge:!1},planInstall:()=>({library:{id:"none",version:noLibVersion,source:"binary",componentsPath:"binary"},summary:{name:`no-library primitives (${noLibVersion})`,location:"bundled with velloo"}}),buildSampleScaffold:(theme)=>buildElsewhereScaffold("none",theme),stylingFor:(answers)=>({framework:answers.detected?.tailwindMajor?"tailwind":"none"}),scanMatch:(detected)=>Boolean(detected.unsupportedUi),scanNote:(detected)=>`Detected ${detected.unsupportedUi} (no Velloo adapter) \u2014 the no-framework adapter supplies the primitives, and your ${detected.unsupportedUi} components render from your own install once the setup step writes their preview entry.`,handoffComponentsLabel:"Velloo's primitives",readmeComponentsSection:()=>["## Components","","Velloo's no-framework primitives ship inside the velloo binary. Your","app's own components \u2014 including ones from a UI framework Velloo has no","adapter for \u2014 appear on the Repo shelves of the canvas Library and render","from your own install, inside this design's preview entry (`preview.tsx`","here; the setup step writes it). `emit_code` keeps their exact imports.",""]},html:{label:"HTML + htmx",hint:"Native HTML styled by your app's own CSS.",order:1,defaultSource:"binary",asksComponentsSubfolder:!1,usesStack:!1,scanScreenOpts:{hasBadge:!1,tree:"html"},planInstall:()=>({library:{id:"html",version:HTML_VERSION,source:"binary",componentsPath:"binary"},summary:{name:"HTML + htmx",location:"bundled with velloo"}}),buildSampleScaffold:buildHtmlSampleScaffold,stylingFor:()=>({framework:"none"}),scanMatch:(detected)=>detected.uiLibrary==="html",scanNote:()=>"Detected an HTML app \u2014 its pages are designed and emitted as native HTML.",handoffComponentsLabel:"`Html` nodes and my app's own CSS classes",detectedCanvas:"semantic HTML styled by your app's own stylesheets",readmeComponentsSection:()=>["## HTML and htmx","","Compose semantic HTML with the Html component and ordinary hx-* attributes.","The design is styled by the app's own stylesheets (hostApp.stylesheets in",".design/config.json), from the copies it keeps in assets/host/ \u2014 it never","contacts the running app. The store_host_files tool refreshes those copies.","emit_code returns HTML with its htmx attributes; emit_theme writes the","CSS variables stylesheet that inline theme values reference.",""]},mui:{label:"Material UI",hint:"Real @mui/material, sx styling.",order:4,defaultSource:"binary",asksComponentsSubfolder:!1,scanScreenOpts:{hasBadge:!0,tree:"mui"},planInstall:()=>({library:{id:"mui",version:MUI_VERSION,source:"binary",componentsPath:"binary"},summary:{name:`Material UI v${MUI_VERSION}`,location:"bundled with velloo"}}),buildSampleScaffold:(theme)=>buildElsewhereScaffold("mui",theme),stylingFor:()=>{return},scanMatch:(detected)=>detected.uiLibrary==="mui",scanNote:(detected)=>`Detected ${detected.uiLibrary} \u2014 using that library.`,handoffComponentsLabel:"my Material UI components",readmeComponentsSection:()=>["## Material UI in your app","","The canvas renders **real Material UI** components (bundled with velloo,","emotion-rendered) \u2014 no files were written to your app. When you implement","a screen, `emit_code` emits idiomatic MUI (`sx` props + `@mui/material`","imports) and `emit_theme` emits a `createTheme(...)` module. For that code","to build, install the runtime deps in your app:","","```bash","npm install @mui/material @emotion/react @emotion/styled","```","","Once installed, velloo can also client-render the canvas against your","app's exact MUI version. Style nodes with the `sx` editor (canvas) or","`update_props`'s `style` (agent).",""]},antd:{label:"Ant Design",hint:"Real antd v5, inline style objects.",order:2,defaultSource:"binary",asksComponentsSubfolder:!1,scanScreenOpts:{hasBadge:!0,tree:"antd"},planInstall:()=>({library:{id:"antd",version:ANTD_VERSION,source:"binary",componentsPath:"binary"},summary:{name:`Ant Design v${ANTD_VERSION}`,location:"bundled with velloo"}}),buildSampleScaffold:(theme)=>buildElsewhereScaffold("antd",theme),stylingFor:()=>{return},scanMatch:(detected)=>detected.uiLibrary==="antd",scanNote:(detected)=>`Detected ${detected.uiLibrary} \u2014 using that library.`,handoffComponentsLabel:"my Ant Design components",readmeComponentsSection:()=>["## Ant Design in your app","","The canvas renders **real Ant Design** components (bundled with velloo,","cssinjs-rendered) \u2014 no files were written to your app. When you implement","a screen, `emit_code` emits idiomatic antd (inline `style` objects +","`antd` imports) and `emit_theme` emits a ConfigProvider `ThemeConfig`","module. For that code to build, install the runtime dep in your app:","","```bash","npm install antd","```","","Style nodes with the inline-style editor (canvas) or `update_props`'s `style` (agent).",""]},chakra:{label:"Chakra UI",hint:"Real Chakra v2, sx styling.",order:3,defaultSource:"binary",asksComponentsSubfolder:!1,scanScreenOpts:{hasBadge:!0,tree:"chakra"},planInstall:()=>({library:{id:"chakra",version:CHAKRA_VERSION,source:"binary",componentsPath:"binary"},summary:{name:`Chakra UI v${CHAKRA_VERSION}`,location:"bundled with velloo"}}),buildSampleScaffold:(theme)=>buildElsewhereScaffold("chakra",theme),stylingFor:()=>{return},scanMatch:(detected)=>detected.uiLibrary==="chakra",scanNote:(detected)=>`Detected ${detected.uiLibrary} \u2014 using that library.`,handoffComponentsLabel:"my Chakra UI components",readmeComponentsSection:()=>["## Chakra UI in your app","","The canvas renders **real Chakra UI v2** components (bundled with velloo,","emotion-rendered) \u2014 no files were written to your app. When you implement","a screen, `emit_code` emits idiomatic chakra (`sx` props +","`@chakra-ui/react` imports) and `emit_theme` emits an `extendTheme(...)`","module. For that code to build, install the runtime deps in your app:","","```bash","npm install @chakra-ui/react@2 @emotion/react @emotion/styled framer-motion","```","","Style nodes with the `sx` editor (canvas) or `update_props`'s `style` (agent).",""]}},LIBRARY_IDS=Object.keys(WIZARD_PROVIDERS),DEFAULT_LIBRARY_ID="shadcn-upstream";function interactiveLibraryChoices(){return LIBRARY_IDS.toSorted((a,b)=>WIZARD_PROVIDERS[a].order-WIZARD_PROVIDERS[b].order).map((id)=>({value:id,label:WIZARD_PROVIDERS[id].label,hint:WIZARD_PROVIDERS[id].hint}))}function planInstall(answers){return WIZARD_PROVIDERS[answers.library].planInstall(answers)}function sampleScaffold(answers,theme){return WIZARD_PROVIDERS[answers.library].buildSampleScaffold(theme,answers)}function scanAdoption(detected){for(let id of LIBRARY_IDS){let entry=WIZARD_PROVIDERS[id];if(entry.scanMatch?.(detected))return{library:id,note:entry.scanNote?.(detected)??""}}return}import{copyFile,mkdir,readdir as readdir4}from"fs/promises";import{isAbsolute,join as join8,relative as relative5,resolve as resolve5,sep as sep5}from"path";var DESKTOP={w:1280,h:800},MOBILE2={w:390,h:844,gap:40};function slugifyName(name,fallback="screen"){return name.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||fallback}function placeholderTree(label){return{$ref:"Box",props:{className:"flex min-h-screen flex-col items-center justify-center gap-3 p-8"},children:[{$ref:"Heading",props:{children:label,className:"text-2xl font-semibold"}},{$ref:"Text",props:{children:"Placeholder \u2014 ask your agent to recreate this, then explore alternatives.",className:"text-muted-foreground text-sm"}}]}}function desktopMobileFrames(screenId,label){return[{id:`f-${screenId}`,screen:screenId,x:80,y:80,w:DESKTOP.w,h:DESKTOP.h,label},{id:`f-${screenId}-m`,screen:screenId,x:80+DESKTOP.w+MOBILE2.gap,y:80,w:MOBILE2.w,h:MOBILE2.h,label:`${label} \xB7 Mobile`}]}function redesignScreenScaffold(theme,screenName){let id=slugifyName(screenName),screen={id,name:screenName.trim()||id,tree:placeholderTree(screenName.trim()||id)},board={id:"main",name:"Main",frames:desktopMobileFrames(id,screen.name),groups:[]};return{theme,screens:[screen],boards:[board],snippets:[],annotations:[],notes:[]}}function componentScaffold(theme,componentDescription){let label=componentDescription.trim()||"Component",id=slugifyName(label,"component"),screen={id,name:label,tree:placeholderTree(label)},board={id:"component",name:"Component",frames:desktopMobileFrames(id,label).map((f)=>({...f,group:"explorations"})),groups:[{id:"explorations",name:"Explorations"}]};return{theme,screens:[screen],boards:[board],snippets:[],annotations:[],notes:[]}}function customRequestScaffold(theme){return{theme,screens:[],boards:[{id:"main",name:"Main",frames:[],groups:[]}],snippets:[],annotations:[],notes:[]}}import{readFileSync}from"fs";var default_default={name:"forest",colors:{background:"#F8F7F2",foreground:"#203C32",primary:{DEFAULT:"#244D3C",foreground:"#FFFFFF"},secondary:{DEFAULT:"#E9EDDF",foreground:"#294332"},muted:{DEFAULT:"#F0F0E8",foreground:"#626D63"},accent:{DEFAULT:"#E8EDDA",foreground:"#244D3C"},destructive:{DEFAULT:"oklch(0.577 0.245 27)",foreground:"oklch(0.985 0 0)"},card:{DEFAULT:"#FFFFFF",foreground:"#203C32"},popover:{DEFAULT:"oklch(0.99 0.01 145)",foreground:"oklch(0.21 0.04 145)"},border:"#DFE3D8",input:"#DFE3D8",ring:"oklch(0.42 0.12 145)"},colorsDark:{background:"#14251F",foreground:"#F0F1E8",primary:{DEFAULT:"#BED5A4",foreground:"#14251F"},secondary:{DEFAULT:"#2B4235",foreground:"#E8EDDF"},muted:{DEFAULT:"#263D31",foreground:"#B0BEAE"},accent:{DEFAULT:"#304737",foreground:"#E8EDDF"},card:{DEFAULT:"#1C3128",foreground:"#F0F1E8"},border:"#3B5143",input:"#3B5143"},typography:{fontFamily:{sans:'"DM Sans", Arial, sans-serif',mono:"ui-monospace, SFMono-Regular, monospace",display:'"DM Serif Display", Georgia, serif'},googleFonts:["DM+Serif+Display","DM+Sans:wght@400;500;600;700"],typesets:{default:{size:14,leading:1.5,flow:"1.25em",fontBody:"sans",fontHeading:"display",fontMono:"mono"},docs:{size:15,leading:1.75,flow:"1.5em"},chat:{leading:1.6,flow:"1em"},compact:{size:14,leading:1.6,flow:"1em"},reading:{size:18,leading:1.9,flow:"2em"}}},spacing:{"0":0,"1":4,"2":8,"3":12,"4":16,"6":24,"8":32,"12":48,"16":64},radius:{sm:4,md:6,lg:8,xl:12,full:9999}};function buildDefaultTheme(){return structuredClone(default_default)}var THEME_PRESETS=[{id:"elsewhere",label:"Elsewhere",seed:"#244d3c"},{id:"indigo",label:"Indigo",seed:"#5e6ad2"},{id:"violet",label:"Violet",seed:"#7c3aed"},{id:"blue",label:"Blue",seed:"#2563eb"},{id:"emerald",label:"Emerald",seed:"#059669"},{id:"rose",label:"Rose",seed:"#e11d48"},{id:"orange",label:"Orange",seed:"#ea580c"},{id:"amber",label:"Amber",seed:"#d97706"},{id:"zinc",label:"Zinc (neutral)",seed:"#52525b"}],CURATED_PRESET="elsewhere",DEFAULT_THEME_PRESET="elsewhere",NEUTRAL_THEME_PRESET="zinc";function presetById(id){return id?THEME_PRESETS.find((p)=>p.id===id):void 0}function isValidPreset(id){return THEME_PRESETS.some((p)=>p.id===id)}function buildPresetTheme(id,name="default"){let base=buildDefaultTheme(),preset=presetById(id);if(!preset||preset.id===CURATED_PRESET)return{...base,name};let derived=derivePalette(preset.seed,base,name);return derived.ok?derived.value.theme:{...base,name}}function importThemeFromDesignMd(filePath,presetId,base){let source;try{source=readFileSync(filePath,"utf8")}catch{return null}let mapped=mapDesignMd(base??buildPresetTheme(presetId,"default"),source);if(!mapped.ok)return null;let{theme,coverage,warnings,designSystem}=mapped.value;if(coverage.semantic===0)return null;return{theme,importedFrom:filePath,tokenCount:coverage.semantic+coverage.palette,warnings,designSystem,coverage:{semantic:coverage.semantic,semanticTotal:coverage.semanticTotal}}}import{existsSync as existsSync2,readFileSync as readFileSync2}from"fs";import{join as join6}from"path";var IDENT_CHAR=/[A-Za-z0-9_$]/;function skipWs(code,i){while(i<code.length&&/\s/.test(code.charAt(i)))i++;return i}function scanString(code,i){let quote=code.charAt(i);i++;while(i<code.length){let ch=code.charAt(i);if(ch==="\\"){i+=2;continue}if(ch===quote)return i+1;if(quote==="`"&&ch==="$"&&code.charAt(i+1)==="{"){i=scanBalanced(code,i+1);continue}if(quote!=="`"&&ch===`
|
|
46
46
|
`)return i;i++}return i}function scanBalanced(code,i){let open=code.charAt(i),close=open==="{"?"}":open==="("?")":"]",depth=0;while(i<code.length){let ch=code.charAt(i);if(ch==='"'||ch==="'"||ch==="`"){i=scanString(code,i);continue}if(ch===open)depth++;else if(ch===close){if(depth--,depth===0)return i+1}i++}return i}function stripComments(src){let out="",i=0;while(i<src.length){let ch=src.charAt(i);if(ch==="/"&&src.charAt(i+1)==="/"){while(i<src.length&&src.charAt(i)!==`
|
|
47
47
|
`)i++;continue}if(ch==="/"&&src.charAt(i+1)==="*"){i+=2;while(i<src.length&&!(src.charAt(i)==="*"&&src.charAt(i+1)==="/"))i++;i+=2,out+=" ";continue}if(ch==='"'||ch==="'"||ch==="`"){let end=scanString(src,i);out+=src.slice(i,end),i=end;continue}out+=ch,i++}return out}var ESCAPES={n:`
|
|
48
48
|
`,t:"\t",r:"\r",b:"\b",f:"\f",v:"\v","0":"\x00"};function parseStringLiteral(code,i){let quote=code.charAt(i),out="",j=i+1;while(j<code.length){let ch=code.charAt(j);if(ch==="\\"){let next=code.charAt(j+1);out+=ESCAPES[next]??next,j+=2;continue}if(ch===quote)return{value:out,end:j+1};if(quote==="`"&&ch==="$"&&code.charAt(j+1)==="{")return;if(quote!=="`"&&ch===`
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{existsSync}from"fs";import{dirname,join}from"path";import{fileURLToPath}from"url";var package_default={name:"@velloo/shadcn-snapshot",version:"0.0.0",license:"Apache-2.0",private:!0,type:"module",description:"[internal] Canvas design-mode runtime for provider-shadcn-upstream \u2014 pinned shadcn snapshot, Tailwind v4 entry CSS, prop manifest. Not a user-facing provider.",snapshotVersion:"2026.09.30",shadcnStyle:"radix-nova",shadcnCliVersion:"4.21.0",exports:{".":"./src/index.ts","./tailwind-entry.css":"./src/tailwind-entry.css","./manifest.json":"./dist/manifest.json","./registry-files":"./src/registry-files.ts","./version":"./src/version.ts"},scripts:{build:"bun run build.ts"},dependencies:{"@velloo/helpers":"workspace:*","@velloo/provider":"workspace:*","class-variance-authority":"0.7.1",echarts:"6.1.0","embla-carousel-react":"8.6.0","lucide-react":"1.40.0","radix-ui":"1.6.7",react:"19.2.8","react-day-picker":"10.0.1","react-dom":"19.2.8",sonner:"2.0.8",tailwindcss:"4.3.3","tw-animate-css":"1.4.0"},devDependencies:{"@types/react":"19.2.18","@types/react-dom":"19.2.7","ts-morph":"28.0.0"}};var snapshotVersion2=package_default.snapshotVersion,here=dirname(fileURLToPath(import.meta.url));function resolveRoot(){let dev=join(here,"..");return[process.env.VELLOO_SNAPSHOT_ROOT,join(here,"pkgs","shadcn-snapshot"),dev].filter((p)=>Boolean(p)).find((r)=>existsSync(join(r,"src","tailwind-entry.css")))??dev}var root=resolveRoot(),srcDir=join(root,"src"),distDir=join(root,"dist"),entryCssPath3=join(srcDir,"tailwind-entry.css"),componentsDir3=join(srcDir,"components"),manifestPath=join(distDir,"manifest.json");
|
|
3
|
+
export{snapshotVersion2,entryCssPath3,componentsDir3,manifestPath};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{isCancel,select}from"./chunk-80fjfyha.js";import{chromiumExecutable,closePooledBrowser}from"./chunk-ex36z3b3.js";import"./chunk-5x4nw0zz.js";import{writeText,findFrame,exportFilename,exportFramePng,exportBoardPng,exportFramePdf,exportBoardPdf,exportScreenHtml,exportScreenPng,exportScreenPdf,exportFrameHtml,exportBoardHtml,hostFilesFetch,screensForExportTarget}from"./chunk-brnkprt5.js";import"./chunk-bys7pqdb.js";import{fail}from"./chunk-s23gtejf.js";import{captureWithBrowserSetup}from"./chunk-eh2xp4v6.js";import{confirmRenderFailures}from"./chunk-asfgvzse.js";import{LIVE_BUNDLE_PATH,withAssetServer,loadPipeline}from"./chunk-zv17t1n7.js";import{DESIGN_ARG_DESCRIPTION,resolveDesign}from"./chunk-64pex3mw.js";import{defineCommand}from"./chunk-2smsg2ct.js";import{extname,isAbsolute,resolve}from"path";var export_default=defineCommand({meta:{name:"export",description:"Export a screen, frame, or board as PNG, PDF, or standalone HTML (format = --to extension)"},args:{target:{type:"positional",required:!1,description:"Screen, frame, or board id. Omit to pick interactively."},design:{type:"string",description:DESIGN_ARG_DESCRIPTION},to:{type:"string",description:"Output path; extension picks the format (.png | .pdf | .html). Default: ./<target>.png"},mode:{type:"string",description:"light (default) | dark | compare (side-by-side light|dark; PNG, non-board only)"},scale:{type:"string",description:"PNG raster density (0.25\u20133; default 1; 2 = retina)"},theme:{type:"string",description:"Named theme to render with (default: the board's pin, else the folder default)"},w:{type:"string",description:"Viewport width for screen targets (default: first preset)"},h:{type:"string",description:"Viewport height for screen targets (default: first preset)"},yes:{type:"boolean",description:"Export even when a component fails to render (required without an interactive terminal)"}},async run({args}){let folder=await resolveDesign(args.design,"export",{designFlag:"--design"}),pipeline=await loadPipeline(folder),design=pipeline.design,mode=args.mode??"light";if(!["light","dark","compare"].includes(mode))fail("export",`--mode must be light, dark, or compare \u2014 got '${args.mode}'`);let scale=args.scale?Number(args.scale):1;if(!Number.isFinite(scale)||scale<0.25||scale>3)fail("export",`--scale must be between 0.25 and 3 \u2014 got '${args.scale}'`);let targetId=args.target;if(!targetId){let options=[...[...design.boards.values()].map((b)=>({value:b.id,label:b.name,hint:`board \xB7 ${b.frames.length} frame${b.frames.length===1?"":"s"}`})),...[...design.screens.values()].map((s)=>({value:s.id,label:s.name||s.id,hint:"screen"}))];if(options.length===0)fail("export",`nothing to export in ${folder}.`);if(!process.stdin.isTTY)fail("export",`pass a target: ${options.map((o)=>o.value).join(", ")} (boards and screens; frame ids work too)`);let chosen=await select({message:"Export what?",options});if(isCancel(chosen))fail("export","cancelled.");targetId=chosen}let screen=design.screens.get(targetId),framed=screen?null:findFrame(design,targetId),board=screen||framed?null:design.boards.get(targetId),kind=screen?"screen":framed?"frame":board?"board":null;if(!kind)fail("export",`no screen, frame, or board with id "${targetId}" in ${folder}. Boards: ${[...design.boards.keys()].join(", ")||"(none)"}; screens: ${[...design.screens.keys()].join(", ")||"(none)"}.`);let name=screen?.name||framed?.frame.label||(framed?design.screens.get(framed.frame.screen)?.name:void 0)||board?.name||targetId,outPath=args.to?isAbsolute(args.to)?args.to:resolve(args.to):resolve(exportFilename(name,"png")),ext=extname(outPath).toLowerCase().slice(1);if(ext!=="png"&&ext!=="pdf"&&ext!=="html")fail("export",`unsupported output extension ".${ext}" \u2014 use .png, .pdf, or .html.`);let format=ext;if(mode==="compare"&&(format!=="png"||kind==="board"))fail("export",'mode "compare" is PNG-only and not available for boards.');let preset=design.config.viewportPresets[0]??{name:"default",w:1440,h:900},viewport={w:args.w?Number(args.w):preset.w,h:args.h?Number(args.h):preset.h};await confirmRenderFailures("export",{folder:design,providers:pipeline.providers,defaultProvider:pipeline.defaultProvider},screensForExportTarget(design,kind,targetId),args.yes===!0);let opts={mode,scale,...args.theme?{theme:args.theme}:{}},assetOrigin,live=format==="html"?null:await pipeline.liveModule(),notes=[],p={folder:design,providers:pipeline.providers,defaultProvider:pipeline.defaultProvider,snapshotCss:async()=>pipeline.snapshotCss,assetOrigin:()=>assetOrigin,canvasBundleFor:pipeline.capture.forScreen,appCss:pipeline.capture.appCss,mountProblems:pipeline.capture.problems,warn:(message)=>{if(!notes.includes(message))notes.push(message)},liveBundleUrl:()=>live?.code?LIVE_BUNDLE_PATH:void 0},produce=async()=>{if(kind==="screen"&&screen){if(format==="html"){let out=await exportScreenHtml(p,screen,{dark:mode==="dark",...args.theme?{theme:args.theme}:{},viewport});return{bytes:out.html,warnings:out.warnings}}if(format==="pdf")return{bytes:await exportScreenPdf(p,screen,{...opts,viewport}),warnings:[]};return{bytes:await exportScreenPng(p,screen,{...opts,viewport}),warnings:[]}}if(kind==="frame"&&framed){if(format==="html"){let out=await exportFrameHtml(p,framed.board,framed.frame,opts);return{bytes:out.html,warnings:out.warnings}}return{bytes:format==="pdf"?await exportFramePdf(p,framed.board,framed.frame,opts):await exportFramePng(p,framed.board,framed.frame,opts),warnings:[]}}if(!board)fail("export","internal: target resolution failed");if(format==="html"){let out=await exportBoardHtml(p,board,opts);return{bytes:out.html,warnings:out.warnings}}return{bytes:format==="pdf"?await exportBoardPdf(p,board,opts):await exportBoardPng(p,board,opts),warnings:[]}},result;try{if(format==="html"&&await chromiumExecutable()===null)result=await produce();else if(format==="html")await withAssetServer(folder,null,async(baseHref)=>{assetOrigin=baseHref,result=await produce()},{bundle:pipeline.capture.serve,host:hostFilesFetch(()=>folder)});else await withAssetServer(folder,live?.code??null,async(baseHref)=>{assetOrigin=baseHref,await captureWithBrowserSetup("export",async()=>{result=await produce()})},{bundle:pipeline.capture.serve,host:hostFilesFetch(()=>folder)})}finally{await closePooledBrowser()}if(!result)fail("export","capture produced no output");if(typeof result.bytes==="string")await writeText(outPath,result.bytes);else await Bun.write(outPath,result.bytes);console.log(`velloo export: wrote ${outPath} (${kind}=${targetId}, mode=${mode})`);for(let warning of[...live?.warnings??[],...notes,...result.warnings])console.log(` note: ${warning}`)}});export{export_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-brnkprt5.js";import"./chunk-5x4nw0zz.js";import"./chunk-ex36z3b3.js";import{ok,err,GUESTS_UNAVAILABLE,GuestsResponseSchema,GuestInviteResponseSchema,GuestLinkResponseSchema,unreachable,httpFailureFrom,boardLimitFrom,describeCloudError,cloudFetch}from"./chunk-bys7pqdb.js";import{loadCredential,saveCredential,deleteCredential,fetchAccount,revokeCredential,performDeviceLogin}from"./chunk-kkvf0xk2.js";import{listPublishedDesigns,unpublishDesign,listPublishDestinations,describePublishError,PUBLISH_VIEWPORT,gitContext,publishableTeams,resolvePublishTeam,listTeams,publishDesign}from"./chunk-snak5zpr.js";import{TOOL_VERSION}from"./chunk-3m28pvzr.js";import{updateStatus,upgradeInstalledVelloo}from"./chunk-s84vxcdv.js";import{assertLoopbackHost,daemonRoot,writeLock,removeLock,readRememberedPort,rememberPort,portCandidates,registryUpsert,registryRemove}from"./chunk-xzf52wvn.js";import"./chunk-zv17t1n7.js";import{defaultCloudUrl,fetchCloudAppUrl}from"./chunk-abr2hgay.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};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{styleObjectFromCss}from"./chunk-5x4nw0zz.js";import{NONE_MANIFEST2,inlineRegistry,entryCssPath2,componentsDir2}from"./chunk-gcce587w.js";import{STYLE_PROP,require_react_development}from"./chunk-ex36z3b3.js";import{__toESM}from"./chunk-2smsg2ct.js";import{HTML_VERSION}from"./chunk-6k05kqnc.js";var import_react=__toESM(require_react_development(),1),SAFE_TAG=/^(?:a|abbr|address|article|aside|b|bdi|bdo|blockquote|br|button|caption|circle|cite|clipPath|code|col|colgroup|data|dd|defs|del|details|dfn|div|dl|dt|ellipse|em|fieldset|figcaption|figure|footer|form|g|h[1-6]|header|hr|i|img|input|ins|kbd|label|legend|li|line|linearGradient|main|mark|mask|meter|nav|ol|optgroup|option|output|p|path|picture|polygon|polyline|pre|progress|q|radialGradient|rect|s|samp|section|select|small|source|span|stop|strong|sub|summary|sup|svg|table|tbody|td|text|textarea|tfoot|th|thead|time|tr|tspan|u|ul|var|wbr)$/,URL_ATTRIBUTES=new Set(["href","src","action","formaction","poster","cite","xlinkhref","xlink:href"]),SCRIPT_URL=/^(?:javascript|vbscript):|^data:text\/html/i,withoutControls=(value)=>[...value].filter((char)=>char.charCodeAt(0)>32).join(""),REACT_PROP={class:"className",for:"htmlFor",autocomplete:"autoComplete",autofocus:"autoFocus",tabindex:"tabIndex",readonly:"readOnly",maxlength:"maxLength",minlength:"minLength",colspan:"colSpan",rowspan:"rowSpan",enctype:"encType",novalidate:"noValidate",datetime:"dateTime",srcset:"srcSet",crossorigin:"crossOrigin",accesskey:"accessKey",contenteditable:"contentEditable",spellcheck:"spellCheck",formaction:"formAction",formmethod:"formMethod",inputmode:"inputMode",referrerpolicy:"referrerPolicy"};function safeAttributeValue(name,value){let key=name.toLowerCase();if(key.startsWith("on")||key==="dangerouslysetinnerhtml")return!1;if(URL_ATTRIBUTES.has(key)&&typeof value==="string")return!SCRIPT_URL.test(withoutControls(value));return!0}function safeTag(component,as){if(!SAFE_TAG.test(as))throw Error(`${component}: unsupported HTML tag ${JSON.stringify(as)}`);return as}function nativeAttributes(props){return Object.fromEntries(Object.entries(props).map(([name,value])=>[REACT_PROP[name]??name,value]).filter(([name,value])=>safeAttributeValue(name,value)).flatMap(([name,value])=>{if(name!=="style"||typeof value!=="string")return[[name,value]];let style=styleObjectFromCss(value);return style?[[name,style]]:[]}))}function Html({as="div",children,...props}){return import_react.createElement(safeTag("Html",as),nativeAttributes(props),children)}var registry={...inlineRegistry,Html};var htmlDescriptors=[{id:"Html",category:"ui",source:"velloo",group:"layout",family:"Html",allowUnknownProps:!0,designModeNotes:"Use for a native HTML element. Set as to a semantic tag and pass ordinary HTML or hx-* attributes as props.",props:[{name:"as",type:"string",optional:!0,control:"string",defaultValue:"div"},{name:"className",type:"string",optional:!0,control:"string"},{name:"style",type:"CSSProperties",optional:!0,control:"string"},{name:"children",type:"ReactNode",optional:!0,control:"string"}]}],HTML_MANIFEST=[...NONE_MANIFEST2,...htmlDescriptors],HTML_INTRO=["**This is a server-rendered HTML/htmx app.** Compose semantic HTML with `Html` nodes (`as=\"form\"`, \u2026), styled by the app's own CSS classes or inline `style` \u2014 there is no Tailwind; new classes need CSS authored in the app. Give forms and controls the real `hx-*` attributes: the canvas never fires them, and `emit_code` keeps them in the native HTML it returns for the app's templates.","","A design never contacts the running app: it is styled by copies of the app's stylesheets, which `store_host_files` refreshes from source or from a capture (including built CSS a `screenshot` reports missing). Reference the app's files by their real paths (`src=\"/static/logo.png\"`), not as Velloo assets. Theme tokens are CSS variables (`var(--color-primary)`); `emit_theme` writes the stylesheet that defines them.","","To reproduce a page, capture it from the running app with `start_capture_session` (the user signs in if needed), rebuild it from `get_capture` with the content written into the nodes, and verify with `compare_to_url { captureId }`.","","On a form, a custom `hx-trigger` replaces htmx's default submit trigger \u2014 include `submit` when a submit button must swap a response instead of navigating.",""];function createProvider(){return{id:"html",version:HTML_VERSION,label:"HTML + htmx",componentsDir:componentsDir2,styleEntryPath:entryCssPath2,registry,loadManifest:async()=>HTML_MANIFEST,styleChannel:STYLE_PROP,styleChannels:["style"],registryForChannel:()=>registry,mcpIntro:()=>HTML_INTRO,hostStylesheets:!0,codegenFormat:"html",elementComponent:"Html"}}export{createProvider};
|