@adminide-stack/yantra-mobile 12.0.125-alpha.1 → 12.0.125
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/lib/features/canvas/AudioEditorExperience.js +207 -109
- package/lib/features/canvas/AudioEditorExperience.js.map +1 -1
- package/lib/features/canvas/CanvasAgentChatPane.js +87 -72
- package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -1
- package/lib/features/canvas/CanvasBoardsGrid.js +494 -387
- package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
- package/lib/features/canvas/CanvasChatResultCard.js +78 -59
- package/lib/features/canvas/CanvasChatResultCard.js.map +1 -1
- package/lib/features/canvas/CanvasEditToolsPanel.js +126 -84
- package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -1
- package/lib/features/canvas/CanvasExperience.js +108 -126
- package/lib/features/canvas/CanvasExperience.js.map +1 -1
- package/lib/features/canvas/CanvasGeneratePanel.js +178 -166
- package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -1
- package/lib/features/canvas/CanvasLibrarySheet.js +119 -123
- package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -1
- package/lib/features/canvas/CanvasLooksPanel.js +113 -89
- package/lib/features/canvas/CanvasLooksPanel.js.map +1 -1
- package/lib/features/canvas/CanvasModelPicker.js +79 -79
- package/lib/features/canvas/CanvasModelPicker.js.map +1 -1
- package/lib/features/canvas/CanvasTasksPanel.js +193 -128
- package/lib/features/canvas/CanvasTasksPanel.js.map +1 -1
- package/lib/features/canvas/CanvasTemplatesPanel.js +106 -94
- package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -1
- package/lib/features/canvas/CanvasToolDock.js +195 -127
- package/lib/features/canvas/CanvasToolDock.js.map +1 -1
- package/lib/features/canvas/FrameExtractorExperience.js +163 -100
- package/lib/features/canvas/FrameExtractorExperience.js.map +1 -1
- package/lib/features/canvas/GeneratorReferenceSlots.js +132 -69
- package/lib/features/canvas/GeneratorReferenceSlots.js.map +1 -1
- package/lib/features/canvas/ImageEditorExperience.js +278 -209
- package/lib/features/canvas/ImageEditorExperience.js.map +1 -1
- package/lib/features/canvas/InfluencerStudioExperience.js +167 -125
- package/lib/features/canvas/InfluencerStudioExperience.js.map +1 -1
- package/lib/features/canvas/MoodboardExperience.js +102 -85
- package/lib/features/canvas/MoodboardExperience.js.map +1 -1
- package/lib/features/canvas/NativeCanvasViewer.js +203 -192
- package/lib/features/canvas/NativeCanvasViewer.js.map +1 -1
- package/lib/features/canvas/PromoContextFields.js +125 -92
- package/lib/features/canvas/PromoContextFields.js.map +1 -1
- package/lib/features/canvas/SetStudioExperience.js +225 -143
- package/lib/features/canvas/SetStudioExperience.js.map +1 -1
- package/lib/features/canvas/VideoClipsExperience.js +126 -92
- package/lib/features/canvas/VideoClipsExperience.js.map +1 -1
- package/lib/features/canvas/VideoEditExperience.js +154 -142
- package/lib/features/canvas/VideoEditExperience.js.map +1 -1
- package/lib/features/canvas/VideoEditorExperience.js +551 -492
- package/lib/features/canvas/VideoEditorExperience.js.map +1 -1
- package/lib/features/canvas/VideoGeneratorExperience.js +284 -131
- package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -1
- package/lib/features/canvas/canvasTasks.js +7 -3
- package/lib/features/canvas/canvasTasks.js.map +1 -1
- package/lib/features/canvas/canvasTheme.js +265 -0
- package/lib/features/canvas/canvasTheme.js.map +1 -0
- package/lib/features/canvas/canvasUi.js +381 -0
- package/lib/features/canvas/canvasUi.js.map +1 -0
- package/lib/features/canvas/recorder/CameraRecorderExperience.js +109 -52
- package/lib/features/canvas/recorder/CameraRecorderExperience.js.map +1 -1
- package/lib/features/canvas/serverTasks.js +1 -1
- package/lib/features/canvas/serverTasks.js.map +1 -1
- package/lib/features/canvas/set/SetViewportWebView.js +1 -1
- package/lib/features/canvas/set/SetViewportWebView.js.map +1 -1
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +8 -7
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js.map +1 -1
- package/lib/features/canvas/videoEditor/ExportTaskCard.js +44 -41
- package/lib/features/canvas/videoEditor/ExportTaskCard.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +50 -45
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -1
- package/lib/features/canvas/videoEditor/exportTask.js +3 -2
- package/lib/features/canvas/videoEditor/exportTask.js.map +1 -1
- package/lib/features/canvas/videoEditor/formWidgets.js +116 -64
- package/lib/features/canvas/videoEditor/formWidgets.js.map +1 -1
- package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js +77 -63
- package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js.map +1 -1
- package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js +95 -79
- package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js.map +1 -1
- package/lib/features/design/DesignEditorExperience.js +241 -160
- package/lib/features/design/DesignEditorExperience.js.map +1 -1
- package/lib/features/design/DesignExperience.js +300 -143
- package/lib/features/design/DesignExperience.js.map +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
- package/lib/features/webbuilder/buildFragments.js +3 -2
- package/lib/features/webbuilder/buildFragments.js.map +1 -1
- package/lib/features/webbuilder/components/PublishSheet.js +1 -1
- package/lib/features/webbuilder/components/PublishSheet.js.map +1 -1
- package/lib/features/webbuilder/webbuilderPrompts.js +2 -5
- package/lib/features/webbuilder/webbuilderPrompts.js.map +1 -1
- package/lib/screens/WebBuilderNative/sandboxProxyApi.js +120 -0
- package/lib/screens/WebBuilderNative/sandboxProxyApi.js.map +1 -0
- package/lib/screens/WebBuilderNative/useRestoredSandboxes.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +26 -4
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
- package/lib/screens/WebBuilderNative/webbuilderTransport.js +110 -7
- package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildFragments.js","sources":["../../../src/features/webbuilder/buildFragments.ts"],"sourcesContent":["/**\n * Reads builds out of a build chat's posts.\n *\n * The build workflow posts its result as a \"fragment\" on an assistant post:\n * sandbox id and preview URL, the source files, and after a publish the live\n * address. Native twin of the web host's `creationsFromMessages`\n * (browser `pages/webbuilder/remoteWebbuilder.ts`) and the surface's\n * `extractFragmentFromSource` lookup order: `propsConfiguration.contents`\n * first (where the real fragment lives; `props` is account-scoped), then the\n * post's own fields. Pure, so the host and jest can both use it.\n */\nimport type { WebBuilderBuild, WebBuilderProject } from './types';\n\ntype Loose = Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n\ninterface Fragment {\n sandboxUrl?: string;\n sandboxId?: string;\n liveUrl?: string;\n files?: Record<string, string> | null;\n title?: string;\n projectId?: string;\n /** Stack the build was made from (`vite-react`, `nextjs`), shown on the tile. */\n template?: string;\n /** Screenshot of the build: an object key or a full URL. */\n coverImageUrl?: string;\n /** CDN origin the cover key was stored under. */\n coverImagePath?: string;\n /** The agent's restore point for this build (design-pro snapshots after each turn). */\n snapshotId?: string;\n /** Read from the agent's words (the agent-chat lane), not a workflow fragment. */\n fromReply?: boolean;\n isCreatingSandbox: boolean;\n isDeploying: boolean;\n}\n\n/** `contents` arrives as an object or, from some resolvers, as JSON text. */\nfunction asObject(value: unknown): Loose | null {\n if (!value) return null;\n if (typeof value === 'object') return Array.isArray(value) ? null : (value as Loose);\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed.startsWith('{')) return null;\n try {\n const parsed = JSON.parse(trimmed);\n return parsed && typeof parsed === 'object' ? (parsed as Loose) : null;\n } catch {\n return null;\n }\n }\n return null;\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\n/** `props` is account-scoped (`props[\"<accountId>\"] = {…}`): the records one level down. */\nfunction accountRecords(record: Loose): Loose[] {\n return Object.values(record)\n .map((v) => asObject(v))\n .filter((v): v is Loose => v !== null);\n}\n\n/** First non-empty string among `key` on each record (and on its `fragment`). */\nfunction pick(records: Loose[], key: string): string | undefined {\n for (const record of records) {\n const value = str(record[key]) || str(asObject(record.fragment)?.[key]);\n if (value) return value;\n }\n return undefined;\n}\n\n/** A live sandbox URL (`https://3000-<id>.e2b.dev`) - never a cover. */\nconst LIVE_SANDBOX = /^https?:\\/\\/\\d+-[a-z0-9]+(\\.|\\/|$)/i;\n\n/**\n * The preview origin for a sandbox. A bare `https://3000-<id>` (no domain) is\n * the E2B default domain, as the surface's `liveSandboxIframeSrc` maps it.\n */\nexport function sandboxPreviewUrl(url: string | undefined, sandboxId: string | undefined): string | null {\n const given = str(url);\n if (given) {\n if (/^https?:\\/\\/\\d+-[a-z0-9]+\\/?$/i.test(given)) return `${given.replace(/\\/$/, '')}.e2b.dev`;\n return given;\n }\n const id = str(sandboxId);\n return id ? `https://3000-${id}.e2b.dev` : null;\n}\n\nfunction httpOrigin(value: string | undefined): string | null {\n const match = /^(https?:\\/\\/[^/?#]+)/i.exec((value ?? '').trim());\n return match && !LIVE_SANDBOX.test(match[1]) ? match[1] : null;\n}\n\n/**\n * The image to show for a cover - the web `resolveCoverDisplayUrl`: an object\n * key joined to the origin it was stored under, else to the app's CDN, else a\n * full https URL as given. A live sandbox URL is never a cover.\n */\nexport function coverDisplayUrl(cover: string | undefined, path?: string, cdnOrigin?: string): string | null {\n const raw = str(cover);\n if (!raw || LIVE_SANDBOX.test(raw)) return null;\n if (/^https?:\\/\\//i.test(raw)) return raw.split('?')[0];\n const key = raw.replace(/^\\/+/, '');\n if (!/\\/uploads\\//i.test(`/${key}`) && !/\\.(png|jpe?g|webp|gif|svg)$/i.test(key)) return null;\n const origin = httpOrigin(path) || httpOrigin(cdnOrigin);\n return origin ? `${origin}/${key}` : null;\n}\n\nexport function readFragment(post: unknown): Fragment | null {\n if (!post || typeof post !== 'object') return null;\n const p = post as Loose;\n const cfg: Loose = p.propsConfiguration || {};\n const contents: Loose = asObject(cfg.contents) || asObject(cfg.content) || {};\n const contentsProps: Loose = asObject(contents.props) || {};\n const props: Loose = asObject(p.props) || {};\n const fragment: Loose | null =\n asObject(contentsProps.fragment) ||\n asObject(contents.fragment) ||\n asObject(cfg.fragment) ||\n asObject(props.fragment) ||\n asObject(p.fragment) ||\n null;\n const f: Loose = fragment || {};\n const sandboxUrl = str(f.sandboxUrl) || str(f.url) || str(p.sandboxUrl) || str(contents.sandboxUrl);\n const sandboxId = str(f.sandboxId) || str(p.sandboxId) || str(contents.sandboxId) || str(cfg.sandboxId);\n const publish = asObject(f.publish);\n const liveUrl =\n str(f.customDomainUrl) || str(f.cloudflareUrl) || str(f.deployUrl) || str(publish?.url) || undefined;\n const attachment = asObject(props.attachment) || asObject(contents.attachment) || {};\n const isCreatingSandbox =\n f.isCreatingSandbox === true || contents.isCreatingSandbox === true || p.isCreatingSandbox === true;\n const isDeploying = attachment.isDeploying === true || f.isDeploying === true;\n if (!sandboxUrl && !sandboxId && !liveUrl && !fragment && !isCreatingSandbox && !isDeploying) return null;\n const files = f.files && typeof f.files === 'object' ? (f.files as Record<string, string>) : null;\n // The cover rides on the fragment, the post's props, or an account record of either.\n const coverSources = [f, props, contents, contentsProps, p, ...accountRecords(props), ...accountRecords(contents)];\n const coverImageUrl = [\n pick(coverSources, 'coverImageUrl'),\n pick(coverSources, 'previewImageUrl'),\n str(f.cover),\n ].find((c) => c && !LIVE_SANDBOX.test(c));\n return {\n sandboxUrl,\n sandboxId,\n liveUrl,\n files,\n title: str(f.title),\n projectId: str(f.projectId) || str(contentsProps.projectId),\n template: str(f.templateId) || str(f.template) || str(contentsProps.template) || str(contents.template),\n coverImageUrl,\n coverImagePath: pick(coverSources, 'coverImagePath'),\n isCreatingSandbox,\n isDeploying,\n };\n}\n\n/** Sandbox previews and published addresses the agent names (web `chat/agentBuild.ts`). */\nconst E2B_PREVIEW_RE = /https:\\/\\/(\\d{2,5})-([a-z0-9]{8,40})\\.e2b\\.(?:dev|app)\\b[^\\s)\\]\"'<>*`]*/gi;\nconst LIVE_URL_RE = /https:\\/\\/([a-z0-9][a-z0-9-]{1,60})\\.(?:pages\\.dev|yarntra\\.com)\\b[^\\s)\\]\"'<>*`]*/gi;\nconst RESTORE_POINT_RE = /restore point \\(snapshot `([^`\\s]{4,200})`\\)/gi;\n\nconst trimUrl = (url: string) => url.replace(/[.,;:!?]+$/, '');\n\n/** The last sandbox preview link in the text (the agent's latest), with its sandbox id. */\nexport function previewFrom(text: string): { url: string; sandboxId: string } | null {\n const all = Array.from(text.matchAll(E2B_PREVIEW_RE));\n const last = all[all.length - 1];\n return last ? { url: trimUrl(last[0]), sandboxId: last[2] } : null;\n}\n\n/** The published address the agent reports (pages.dev preferred, as the web does). */\nexport function liveUrlFrom(text: string): string | null {\n const hits = Array.from(text.matchAll(LIVE_URL_RE)).map((m) => trimUrl(m[0]));\n if (!hits.length) return null;\n return hits.find((h) => h.includes('.pages.dev')) ?? hits[0];\n}\n\n/** The restore point the skill reports: \"Saved a restore point (snapshot `<id>`).\" (design-pro 3.3, #388). */\nexport function snapshotFrom(text: string): string | null {\n const all = Array.from(text.matchAll(RESTORE_POINT_RE));\n return all.length ? all[all.length - 1][1] : null;\n}\n\n/** \"Your Lotus Flow site is built…\", \"**Lotus Flow** is live\" -> \"Lotus Flow\". */\nexport function siteNameFrom(text: string): string | null {\n const m =\n text.match(\n /\\bYour ([A-Z][\\w&'’ .-]{1,40}?)(?: (?:yoga|coffee|wedding|photography|bakery))? (?:site|website|app) is (?:built|ready|live|running)/,\n ) ??\n text.match(/\\*\\*([A-Z][^*\\n]{1,40})\\*\\* is (?:live|ready|built)/) ??\n text.match(/^([A-Z][\\w&'’ .-]{1,40}?) is live at\\b/m);\n return m ? m[1].trim() : null;\n}\n\n/** The agent's reply as the reader sees it: the restore point's id is for the builder, not them. */\nexport function displayAgentText(text: string): string {\n return text.replace(/(restore point) \\(snapshot `[^`]+`\\)/gi, '$1');\n}\n\n/**\n * A build named only in the agent's words: the agent-chat lane (template remix,\n * building from chat) replies with the preview link, the live address once it\n * publishes, and its restore point - no fragment - so those are the build.\n */\nfunction linkFragment(post: unknown): Fragment | null {\n const p = (post ?? {}) as Loose;\n const text = typeof p.message === 'string' ? p.message : '';\n const preview = previewFrom(text);\n const liveUrl = liveUrlFrom(text) ?? undefined;\n const snapshotId = snapshotFrom(text) ?? undefined;\n if (!preview && !liveUrl && !snapshotId) return null;\n return {\n sandboxUrl: preview?.url,\n sandboxId: preview?.sandboxId,\n liveUrl,\n snapshotId,\n title: siteNameFrom(text) ?? undefined,\n fromReply: true,\n isCreatingSandbox: false,\n isDeploying: false,\n };\n}\n\nfunction postTime(post: unknown): number {\n const p = (post ?? {}) as Loose;\n const raw = p.updatedAt || p.createdAt;\n const ms = typeof raw === 'number' ? raw : Date.parse(String(raw ?? ''));\n return Number.isFinite(ms) ? ms : 0;\n}\n\n/** Posts in the order they happened (the query is not sorted). */\nfunction chronological(posts: readonly unknown[]): unknown[] {\n return [...posts].sort((a, b) => postTime(a) - postTime(b));\n}\n\nfunction isUserPost(post: unknown): boolean {\n const p = (post ?? {}) as Loose;\n const contents = asObject(p.propsConfiguration?.contents) || {};\n const props = asObject(p.props) || {};\n const role = String(props.role ?? contents.role ?? asObject(contents.props)?.role ?? '').toUpperCase();\n return role === 'USER';\n}\n\n/** The stack label the web tile shows when a build does not name one. */\nexport const DEFAULT_TEMPLATE = 'vite-react';\n\n/**\n * Newest-first builds of one site. A later post about the same sandbox (a\n * publish, a re-post, its screenshot) updates that build.\n */\nexport function buildsFromPosts(\n posts: readonly unknown[],\n fallbackTitle?: string,\n cdnOrigin?: string,\n): WebBuilderBuild[] {\n const fallback = fallbackTitle ?? 'Web app';\n const byKey = new Map<string, WebBuilderBuild>();\n let lastKey: string | null = null;\n // The web hydrate's rule: a build is an ASSISTANT post with something to show - a\n // preview URL, a live address or a screenshot. A user turn carries the sandbox it\n // edits (and a bare sandbox id is a turn in flight), neither is a build.\n const fragments = chronological(posts)\n .filter((post) => !isUserPost(post))\n .map((post) => ({ post, fragment: readFragment(post) ?? linkFragment(post) }))\n .filter(\n (row): row is { post: unknown; fragment: Fragment } =>\n row.fragment !== null &&\n Boolean(\n row.fragment.sandboxUrl ||\n row.fragment.liveUrl ||\n row.fragment.coverImageUrl ||\n row.fragment.snapshotId,\n ),\n );\n for (const { post, fragment } of fragments) {\n const previewUrl = sandboxPreviewUrl(fragment.sandboxUrl, fragment.sandboxId);\n const key = fragment.sandboxId || previewUrl || '';\n // A publish or screenshot post may name no sandbox: it belongs to the latest build.\n const target: string | null =\n key || (fragment.liveUrl || fragment.coverImageUrl || fragment.snapshotId ? lastKey : null);\n if (target) {\n const existing = byKey.get(target);\n byKey.set(target, {\n key: target,\n // A workflow fragment names the build; a reply's site name only names a build with none yet.\n title:\n (fragment.fromReply ? existing?.title || fragment.title : fragment.title || existing?.title) ||\n fallback,\n previewUrl: previewUrl || existing?.previewUrl || null,\n sandboxId: fragment.sandboxId || existing?.sandboxId || null,\n projectId: fragment.projectId || existing?.projectId || null,\n liveUrl: fragment.liveUrl || existing?.liveUrl || null,\n files: fragment.files || existing?.files || null,\n snapshotId: fragment.snapshotId || existing?.snapshotId || null,\n origin: existing?.origin === 'workflow' || !fragment.fromReply ? 'workflow' : 'agent',\n templateId: fragment.template || existing?.templateId || DEFAULT_TEMPLATE,\n coverUrl:\n coverDisplayUrl(fragment.coverImageUrl, fragment.coverImagePath, cdnOrigin) ||\n existing?.coverUrl ||\n null,\n updatedAt: Math.max(postTime(post), existing?.updatedAt ?? 0),\n });\n lastKey = target;\n }\n }\n return [...byKey.values()].filter((b) => b.previewUrl || b.liveUrl).sort((a, b) => b.updatedAt - a.updatedAt);\n}\n\n/** The newest post flags a sandbox still being created or a publish still running. */\nexport function pendingWork(posts: readonly unknown[]): 'creating' | 'publishing' | null {\n const newest = chronological(posts)\n .map((post) => readFragment(post))\n .filter((f): f is Fragment => f !== null)\n .pop();\n if (!newest) return null;\n if (newest.isCreatingSandbox && !newest.sandboxUrl && !newest.sandboxId) return 'creating';\n if (newest.isDeploying && !newest.liveUrl) return 'publishing';\n return null;\n}\n\n// ── Titles: the web surface's `resolveArtifactTitle` rules ─────────────────\n\n/** Not a product name: what the workflow and the chat call a site before it has one. */\nexport function isGenericTitle(title?: string | null): boolean {\n const t = (title || '').trim().toLowerCase();\n return (\n !t ||\n t === 'generated page' ||\n t === 'generated project' ||\n t === 'generated with cdecli' ||\n t === 'ai assistant' ||\n t === 'web app' ||\n /^build \\d+$/.test(t) ||\n /^build\\s+me\\b/.test(t) ||\n /^remix\\s+the\\b/.test(t) ||\n /^(build|chat)[- ]channel\\b/.test(t) ||\n t.startsWith('selected skill') ||\n /^code[\\s_-]?assist/.test(t)\n );\n}\n\nconst TITLE_STOP_WORDS = new Set([\n 'a',\n 'an',\n 'the',\n 'create',\n 'build',\n 'make',\n 'please',\n 'me',\n 'my',\n 'for',\n 'with',\n 'simple',\n 'using',\n 'from',\n 'template',\n 'to',\n 'and',\n 'or',\n 'remix',\n 'yantra',\n]);\n\nfunction titleCase(words: string[]): string {\n return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(' ');\n}\n\n/** The person's words, without the internal lines a turn carries. */\nexport function cleanPrompt(text: string): string {\n return text\n .replace(/^\\[webbuilder context:[^\\]]*\\]\\s*/i, '')\n .replace(/^build\\s*me\\s*:\\s*/i, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Product name from a brief: \"Build me: todo app\" -> \"Todo App\". An edit\n * (\"make the header blue\") is not a name.\n */\nexport function titleFromPrompt(message?: string | null): string | null {\n const raw = (message || '').replace(/^\\[webbuilder context:[^\\]]*\\]\\s*/i, '').trim();\n if (!raw) return null;\n const buildMe = raw.match(/^\\s*Build me:\\s*(.+)$/im)?.[1]?.trim();\n if (!buildMe && /^(change|update|rename|fix|edit|add|remove|delete|improve|make|refactor)\\b/i.test(raw)) {\n return null;\n }\n const source = (buildMe || raw.split(/\\n+/)[0] || '').replace(/^[\"']|[\"']$/g, '');\n const words = source\n .replace(/[^\\w\\s-]/g, ' ')\n .split(/\\s+/)\n .filter((w) => w.length > 1 && !TITLE_STOP_WORDS.has(w.toLowerCase()))\n .slice(0, 3);\n if (!words.length) return null;\n const title = titleCase(words);\n return isGenericTitle(title) ? null : title;\n}\n\n/** `package.json` name of the build (\"bakery-site\" -> \"Bakery Site\"). */\nfunction titleFromPackageJson(files?: Record<string, string> | null): string | null {\n if (!files) return null;\n const raw = Object.entries(files).find(([path]) => /(^|\\/)package\\.json$/.test(path))?.[1];\n if (!raw) return null;\n try {\n const name = String((JSON.parse(raw) as { name?: string }).name || '').trim();\n if (!name || name === 'vite-react' || name === 'project') return null;\n return name\n .replace(/^@[^/]+\\//, '')\n .replace(/[-_]+/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n } catch {\n return null;\n }\n}\n\n/** The build's own title, then the brief's product name, the chat's name, the package name. */\nexport function resolveSiteTitle(opts: {\n fragmentTitle?: string | null;\n channelTitle?: string | null;\n userPrompt?: string | null;\n files?: Record<string, string> | null;\n}): string {\n const candidates = [\n opts.fragmentTitle,\n titleFromPrompt(opts.userPrompt),\n opts.channelTitle,\n titleFromPackageJson(opts.files),\n ];\n const found = candidates.find((c) => c && !isGenericTitle(c));\n return (found || 'Generated Page').trim();\n}\n\n// ── Sites ──────────────────────────────────────────────────────────────────\n\nexport interface ChannelLike {\n id?: string | null;\n title?: string | null;\n displayName?: string | null;\n updatedAt?: unknown;\n createdAt?: unknown;\n lastMessage?: unknown;\n}\n\n/** True when the newest build in `lastMessage` already carries a cover - the web skips the thread read then. */\nexport function lastMessageHasCover(channel: ChannelLike): boolean {\n return Boolean(readFragment(channel.lastMessage)?.coverImageUrl);\n}\n\n/**\n * A site from one chat's posts, the way the web gallery hydrates a tile: only\n * a chat with a build is a site; its name follows `resolveSiteTitle`.\n */\nexport function projectFromPosts(\n channel: ChannelLike,\n posts: readonly unknown[],\n cdnOrigin?: string,\n): WebBuilderProject | null {\n const channelId = str(channel.id);\n if (!channelId) return null;\n const builds = buildsFromPosts(posts, '', cdnOrigin);\n const latest = builds[0];\n if (!latest) return null;\n const userPrompts = chronological(posts)\n .filter((post) => isUserPost(post) && str((post as Loose).message))\n .map((post) => String((post as Loose).message));\n // The brief names the product (\"Build me: …\"); a later message (\"the live preview is\n // not loading\") never does, so only the brief - or failing that the first ask - counts.\n const brief = userPrompts.find((m) => /build\\s*me\\s*:/i.test(m)) ?? userPrompts[0];\n const rawChannelTitle = [channel.displayName, channel.title]\n .map((t) => str(t))\n .find((t) => t && !isGenericTitle(t));\n // A chat named after its brief (\"Build simple calculator app\") gives the product name, not the sentence.\n const channelTitle =\n rawChannelTitle && /^(build|create|make)\\b/i.test(rawChannelTitle)\n ? (titleFromPrompt(rawChannelTitle) ?? rawChannelTitle)\n : rawChannelTitle;\n const title = resolveSiteTitle({\n fragmentTitle: latest.title,\n channelTitle,\n userPrompt: brief,\n files: latest.files,\n });\n const updated = Date.parse(String(channel.updatedAt ?? channel.createdAt ?? ''));\n return {\n channelId,\n title,\n updatedAt: Math.max(Number.isFinite(updated) ? updated : 0, latest.updatedAt),\n previewUrl: latest.previewUrl,\n liveUrl: builds.find((b) => b.liveUrl)?.liveUrl ?? null,\n coverUrl: builds.find((b) => b.coverUrl)?.coverUrl ?? null,\n templateId: latest.templateId,\n };\n}\n\n/** `?wb=<n>` on the preview so a rebuilt sandbox is fetched again, not served from cache. */\nexport function cacheBustedUrl(url: string, nonce: number | string): string {\n const [base, hash = ''] = url.split('#');\n const clean = base.replace(/([?&])wb=[^&]*(&|$)/, '$1').replace(/[?&]$/, '');\n const sep = clean.includes('?') ? '&' : '?';\n return `${clean}${sep}wb=${nonce}${hash ? `#${hash}` : ''}`;\n}\n\n/**\n * The publish name the web dialog suggests: the site's title as a slug,\n * `[a-z0-9-]`, at most 58 characters (`<name>.pages.dev`).\n */\nexport function publishSlug(title: string): string {\n const slug = title\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 58)\n .replace(/-+$/, '');\n return slug || 'my-site';\n}\n\nexport function isValidPublishSlug(value: string): boolean {\n return /^[a-z0-9](?:[a-z0-9-]{0,56}[a-z0-9])?$/.test(value);\n}\n\n/** Display host of a URL: `https://bakery.pages.dev/` -> `bakery.pages.dev`. */\nexport function displayHost(url: string | null | undefined): string {\n const match = /^https?:\\/\\/([^/?#]+)/i.exec((url ?? '').trim());\n return match ? match[1] : (url ?? '').trim();\n}\n\n/** \"just now\", \"5 min ago\", \"3 h ago\", \"Yesterday\", \"12 Oct\". */\nexport function relativeTime(ms: number, now = Date.now()): string {\n if (!ms) return '';\n const diff = Math.max(0, now - ms);\n const min = Math.floor(diff / 60_000);\n if (min < 1) return 'just now';\n if (min < 60) return `${min} min ago`;\n const hours = Math.floor(min / 60);\n if (hours < 24) return `${hours} h ago`;\n if (hours < 48) return 'Yesterday';\n const d = new Date(ms);\n const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n return `${d.getDate()} ${months[d.getMonth()]}`;\n}\n\n// ── The agent transcript: the build chat's posts, as the web Agent pane shows them ──\n\n/** A live progress row (web `isThinkingPost`): shown as the agent's status, never kept. */\nexport function isThinkingPost(post: unknown): boolean {\n const p = (post ?? {}) as Loose;\n const props = asObject(p.props) || {};\n const attachment = asObject(props.attachment) || {};\n const msg = String(p.message ?? '')\n .trim()\n .toLowerCase();\n return (\n String(p.type ?? '').toUpperCase() === 'THINKING' ||\n Boolean(props.thinking ?? props.isThinking) ||\n props.kind === 'thinking' ||\n Boolean(attachment.isThinking) ||\n msg === 'thinking...' ||\n msg === 'initializing...' ||\n msg === 'initializing…'\n );\n}\n\nfunction readFragmentStatus(p: Loose): string | undefined {\n const contents = asObject(p.propsConfiguration?.contents) || {};\n return (\n str(asObject(asObject(contents.props)?.fragment)?.statusText) || str(asObject(contents.fragment)?.statusText)\n );\n}\n\n/** The workflow's progress line on a post: its thought, else the fragment's status. */\nexport function progressText(post: unknown): string | null {\n const p = (post ?? {}) as Loose;\n const props = asObject(p.props) || {};\n const thought = str(asObject(props.attachment)?.thought);\n if (thought) return thought;\n const status = str(asObject(props.fragment)?.statusText) || str(readFragmentStatus(p));\n if (status) return status;\n return isThinkingPost(post) ? (str(p.message) ?? null) : null;\n}\n\n/** A post the workflow wrote when the build failed (`fragment.isError` / `type: 'error'`). */\nexport function isErrorPost(post: unknown): boolean {\n const p = (post ?? {}) as Loose;\n const props = asObject(p.props) || {};\n const contents = asObject(p.propsConfiguration?.contents) || {};\n const f =\n asObject(props.fragment) || asObject(asObject(contents.props)?.fragment) || asObject(contents.fragment) || {};\n return f.isError === true || f.type === 'error';\n}\n\nexport interface TranscriptMessage {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n createdAt: number;\n}\n\n/**\n * The conversation in a build chat: the person's turns and the agent's replies,\n * oldest first, without progress rows or empty build markers.\n */\nexport function transcriptFromPosts(posts: readonly unknown[]): TranscriptMessage[] {\n const out: TranscriptMessage[] = [];\n for (const post of chronological(posts)) {\n const p = post as Loose;\n const text = str(p.message);\n if (text && !isThinkingPost(post)) {\n const user = isUserPost(post);\n out.push({\n id: String(p.id ?? `${user ? 'u' : 'a'}-${out.length}`),\n role: user ? 'user' : 'assistant',\n content: user ? cleanPrompt(text) || text : text,\n createdAt: postTime(post),\n });\n }\n }\n return out;\n}\n\n/**\n * How a turn started at `since` is going, read from the posts that arrived after it.\n * `heard` is whether the build posted anything back yet (a progress row, an answer).\n */\nexport function turnState(\n posts: readonly unknown[],\n since: number,\n): { status: 'running' | 'done' | 'failed'; progress: string | null; error: string | null; heard: boolean } {\n // A clock skew allowance, as the web ignores posts older than start - 2 s.\n const after = chronological(posts).filter((post) => postTime(post) >= since - 2_000);\n let progress: string | null = null;\n for (const post of after) {\n if (!isUserPost(post)) {\n if (isErrorPost(post)) {\n const p = post as Loose;\n return { status: 'failed', progress: null, error: str(p.message) ?? 'The build failed.', heard: true };\n }\n const fragment = readFragment(post);\n if (fragment && (fragment.sandboxUrl || fragment.liveUrl) && !isThinkingPost(post)) {\n return { status: 'done', progress: null, error: null, heard: true };\n }\n progress = progressText(post) ?? progress;\n }\n }\n // A plain answer (the agent asked a question, or replied without building) ends\n // the turn too - unless progress rows keep arriving after it.\n const newest = after.filter((post) => !isUserPost(post)).pop() as Loose | undefined;\n if (newest && !isThinkingPost(newest) && !progressText(newest) && str(newest.message)) {\n return { status: 'done', progress: null, error: null, heard: true };\n }\n return { status: 'running', progress, error: null, heard: Boolean(newest) };\n}\n\n/**\n * A turn sent through the build workflow: its USER post carries the workflow's\n * route (`templateTarget`). A blank build sends an empty fragment, which\n * the server drops, so this post is the only workflow mark until a build lands.\n */\nfunction isWorkflowTurnPost(post: unknown): boolean {\n if (!post || typeof post !== 'object') return false;\n const p = post as Loose;\n const contents = asObject(p.propsConfiguration?.contents) || {};\n return Boolean(str(asObject(p.props)?.templateTarget) || str(asObject(contents.props)?.templateTarget));\n}\n\n/**\n * The chat was built through the build workflow (its posts carry fragments or\n * the workflow's route): edits go back through the workflow. A chat without\n * any is an agent-chat site (a template remix), and its turns stay in the\n * agent chat.\n */\nexport function hasWorkflowPosts(posts: readonly unknown[]): boolean {\n return posts.some((post) => readFragment(post) !== null || isWorkflowTurnPost(post));\n}\n\n/** The person's words, without the agent-only template note a remix turn carries. */\nexport function stripAgentNote(content: string): string {\n return content.replace(/\\n*\\[(?:Template|Open build)\\][\\s\\S]*$/, '').trim();\n}\n"],"names":["_a"],"mappings":"AAoCA,SAAS,SAAS,KAA8B,EAAA;AAC9C,EAAI,IAAA,CAAC,OAAc,OAAA,IAAA;AACnB,EAAI,IAAA,OAAO,UAAU,QAAU,EAAA,OAAO,MAAM,OAAQ,CAAA,KAAK,IAAI,IAAO,GAAA,KAAA;AACpE,EAAI,IAAA,OAAO,UAAU,QAAU,EAAA;AAC7B,IAAM,MAAA,OAAA,GAAU,MAAM,IAAK,EAAA;AAC3B,IAAA,IAAI,CAAC,OAAA,CAAQ,UAAW,CAAA,GAAG,GAAU,OAAA,IAAA;AACrC,IAAI,IAAA;AACF,MAAM,MAAA,MAAA,GAAS,IAAK,CAAA,KAAA,CAAM,OAAO,CAAA;AACjC,MAAA,OAAO,MAAU,IAAA,OAAO,MAAW,KAAA,QAAA,GAAW,MAAkB,GAAA,IAAA;AAAA,KAC1D,CAAA,OAAA,CAAA,EAAA;AACN,MAAO,OAAA,IAAA;AAAA;AACT;AAEF,EAAO,OAAA,IAAA;AACT;AACA,SAAS,IAAI,KAAoC,EAAA;AAC/C,EAAO,OAAA,OAAO,UAAU,QAAY,IAAA,KAAA,CAAM,MAAS,GAAA,KAAA,CAAM,MAAS,GAAA,MAAA;AACpE;AAGA,SAAS,eAAe,MAAwB,EAAA;AAC9C,EAAA,OAAO,MAAO,CAAA,MAAA,CAAO,MAAM,CAAA,CAAE,IAAI,CAAK,CAAA,KAAA,QAAA,CAAS,CAAC,CAAC,CAAE,CAAA,MAAA,CAAO,CAAC,CAAA,KAAkB,MAAM,IAAI,CAAA;AACzF;AAGA,SAAS,IAAA,CAAK,SAAkB,GAAiC,EAAA;AA7DjE,EAAA,IAAA,EAAA;AA8DE,EAAA,KAAA,MAAW,UAAU,OAAS,EAAA;AAC5B,IAAA,MAAM,KAAQ,GAAA,GAAA,CAAI,MAAO,CAAA,GAAG,CAAC,CAAA,IAAK,GAAI,CAAA,CAAA,EAAA,GAAA,QAAA,CAAS,MAAO,CAAA,QAAQ,CAAxB,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAA4B,GAAI,CAAA,CAAA;AACtE,IAAA,IAAI,OAAc,OAAA,KAAA;AAAA;AAEpB,EAAO,OAAA,MAAA;AACT;AAGA,MAAM,YAAe,GAAA,qCAAA;AAML,SAAA,iBAAA,CAAkB,KAAyB,SAA8C,EAAA;AACvG,EAAM,MAAA,KAAA,GAAQ,IAAI,GAAG,CAAA;AACrB,EAAA,IAAI,KAAO,EAAA;AACT,IAAI,IAAA,gCAAA,CAAiC,IAAK,CAAA,KAAK,CAAG,EAAA,OAAO,GAAG,KAAM,CAAA,OAAA,CAAQ,KAAO,EAAA,EAAE,CAAC,CAAA,QAAA,CAAA;AACpF,IAAO,OAAA,KAAA;AAAA;AAET,EAAM,MAAA,EAAA,GAAK,IAAI,SAAS,CAAA;AACxB,EAAO,OAAA,EAAA,GAAK,CAAgB,aAAA,EAAA,EAAE,CAAa,QAAA,CAAA,GAAA,IAAA;AAC7C;AACA,SAAS,WAAW,KAA0C,EAAA;AAC5D,EAAA,MAAM,QAAQ,wBAAyB,CAAA,IAAA,CAAA,CAAM,KAAS,IAAA,IAAA,GAAA,KAAA,GAAA,EAAA,EAAI,MAAM,CAAA;AAChE,EAAO,OAAA,KAAA,IAAS,CAAC,YAAA,CAAa,IAAK,CAAA,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,KAAM,CAAA,CAAC,CAAI,GAAA,IAAA;AAC5D;AAOgB,SAAA,eAAA,CAAgB,KAA2B,EAAA,IAAA,EAAe,SAAmC,EAAA;AAC3G,EAAM,MAAA,GAAA,GAAM,IAAI,KAAK,CAAA;AACrB,EAAA,IAAI,CAAC,GAAO,IAAA,YAAA,CAAa,IAAK,CAAA,GAAG,GAAU,OAAA,IAAA;AAC3C,EAAI,IAAA,eAAA,CAAgB,KAAK,GAAG,CAAA,SAAU,GAAI,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA;AACtD,EAAA,MAAM,GAAM,GAAA,GAAA,CAAI,OAAQ,CAAA,MAAA,EAAQ,EAAE,CAAA;AAClC,EAAA,IAAI,CAAC,cAAA,CAAe,IAAK,CAAA,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAK,IAAA,CAAC,8BAA+B,CAAA,IAAA,CAAK,GAAG,CAAA,EAAU,OAAA,IAAA;AACzF,EAAA,MAAM,MAAS,GAAA,UAAA,CAAW,IAAI,CAAA,IAAK,WAAW,SAAS,CAAA;AACvD,EAAA,OAAO,MAAS,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAK,CAAA,GAAA,IAAA;AACvC;AACO,SAAS,aAAa,IAAgC,EAAA;AAC3D,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAiB,OAAA,IAAA;AAC9C,EAAA,MAAM,CAAI,GAAA,IAAA;AACV,EAAM,MAAA,GAAA,GAAa,CAAE,CAAA,kBAAA,IAAsB,EAAC;AAC5C,EAAM,MAAA,QAAA,GAAkB,SAAS,GAAI,CAAA,QAAQ,KAAK,QAAS,CAAA,GAAA,CAAI,OAAO,CAAA,IAAK,EAAC;AAC5E,EAAA,MAAM,aAAuB,GAAA,QAAA,CAAS,QAAS,CAAA,KAAK,KAAK,EAAC;AAC1D,EAAA,MAAM,KAAe,GAAA,QAAA,CAAS,CAAE,CAAA,KAAK,KAAK,EAAC;AAC3C,EAAM,MAAA,QAAA,GAAyB,SAAS,aAAc,CAAA,QAAQ,KAAK,QAAS,CAAA,QAAA,CAAS,QAAQ,CAAK,IAAA,QAAA,CAAS,IAAI,QAAQ,CAAA,IAAK,SAAS,KAAM,CAAA,QAAQ,KAAK,QAAS,CAAA,CAAA,CAAE,QAAQ,CAAK,IAAA,IAAA;AAChL,EAAM,MAAA,CAAA,GAAW,YAAY,EAAC;AAC9B,EAAA,MAAM,UAAa,GAAA,GAAA,CAAI,CAAE,CAAA,UAAU,KAAK,GAAI,CAAA,CAAA,CAAE,GAAG,CAAA,IAAK,IAAI,CAAE,CAAA,UAAU,CAAK,IAAA,GAAA,CAAI,SAAS,UAAU,CAAA;AAClG,EAAA,MAAM,SAAY,GAAA,GAAA,CAAI,CAAE,CAAA,SAAS,KAAK,GAAI,CAAA,CAAA,CAAE,SAAS,CAAA,IAAK,IAAI,QAAS,CAAA,SAAS,CAAK,IAAA,GAAA,CAAI,IAAI,SAAS,CAAA;AACtG,EAAM,MAAA,OAAA,GAAU,QAAS,CAAA,CAAA,CAAE,OAAO,CAAA;AAClC,EAAA,MAAM,UAAU,GAAI,CAAA,CAAA,CAAE,eAAe,CAAA,IAAK,IAAI,CAAE,CAAA,aAAa,CAAK,IAAA,GAAA,CAAI,EAAE,SAAS,CAAA,IAAK,GAAI,CAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,GAAG,CAAK,IAAA,MAAA;AAC3G,EAAM,MAAA,UAAA,GAAa,SAAS,KAAM,CAAA,UAAU,KAAK,QAAS,CAAA,QAAA,CAAS,UAAU,CAAA,IAAK,EAAC;AACnF,EAAM,MAAA,iBAAA,GAAoB,EAAE,iBAAsB,KAAA,IAAA,IAAQ,SAAS,iBAAsB,KAAA,IAAA,IAAQ,EAAE,iBAAsB,KAAA,IAAA;AACzH,EAAA,MAAM,WAAc,GAAA,UAAA,CAAW,WAAgB,KAAA,IAAA,IAAQ,EAAE,WAAgB,KAAA,IAAA;AACzE,EAAA,IAAI,CAAC,UAAA,IAAc,CAAC,SAAA,IAAa,CAAC,OAAA,IAAW,CAAC,QAAA,IAAY,CAAC,iBAAA,IAAqB,CAAC,WAAA,EAAoB,OAAA,IAAA;AACrG,EAAM,MAAA,KAAA,GAAQ,EAAE,KAAS,IAAA,OAAO,EAAE,KAAU,KAAA,QAAA,GAAW,EAAE,KAAkC,GAAA,IAAA;AAE3F,EAAA,MAAM,YAAe,GAAA,CAAC,CAAG,EAAA,KAAA,EAAO,UAAU,aAAe,EAAA,CAAA,EAAG,GAAG,cAAA,CAAe,KAAK,CAAA,EAAG,GAAG,cAAA,CAAe,QAAQ,CAAC,CAAA;AACjH,EAAM,MAAA,aAAA,GAAgB,CAAC,IAAK,CAAA,YAAA,EAAc,eAAe,CAAG,EAAA,IAAA,CAAK,YAAc,EAAA,iBAAiB,CAAG,EAAA,GAAA,CAAI,EAAE,KAAK,CAAC,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,KAAK,CAAC,YAAA,CAAa,IAAK,CAAA,CAAC,CAAC,CAAA;AACrJ,EAAO,OAAA;AAAA,IACL,UAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA,EAAO,GAAI,CAAA,CAAA,CAAE,KAAK,CAAA;AAAA,IAClB,WAAW,GAAI,CAAA,CAAA,CAAE,SAAS,CAAK,IAAA,GAAA,CAAI,cAAc,SAAS,CAAA;AAAA,IAC1D,QAAU,EAAA,GAAA,CAAI,CAAE,CAAA,UAAU,KAAK,GAAI,CAAA,CAAA,CAAE,QAAQ,CAAA,IAAK,IAAI,aAAc,CAAA,QAAQ,CAAK,IAAA,GAAA,CAAI,SAAS,QAAQ,CAAA;AAAA,IACtG,aAAA;AAAA,IACA,cAAA,EAAgB,IAAK,CAAA,YAAA,EAAc,gBAAgB,CAAA;AAAA,IACnD,iBAAA;AAAA,IACA;AAAA,GACF;AACF;AAGA,MAAM,cAAiB,GAAA,2EAAA;AACvB,MAAM,WAAc,GAAA,qFAAA;AACpB,MAAM,gBAAmB,GAAA,gDAAA;AACzB,MAAM,UAAU,CAAC,GAAA,KAAgB,GAAI,CAAA,OAAA,CAAQ,cAAc,EAAE,CAAA;AAGtD,SAAS,YAAY,IAGnB,EAAA;AACP,EAAA,MAAM,MAAM,KAAM,CAAA,IAAA,CAAK,IAAK,CAAA,QAAA,CAAS,cAAc,CAAC,CAAA;AACpD,EAAA,MAAM,IAAO,GAAA,GAAA,CAAI,GAAI,CAAA,MAAA,GAAS,CAAC,CAAA;AAC/B,EAAA,OAAO,IAAO,GAAA;AAAA,IACZ,GAAK,EAAA,OAAA,CAAQ,IAAK,CAAA,CAAC,CAAC,CAAA;AAAA,IACpB,SAAA,EAAW,KAAK,CAAC;AAAA,GACf,GAAA,IAAA;AACN;AAGO,SAAS,YAAY,IAA6B,EAAA;AAhKzD,EAAA,IAAA,EAAA;AAiKE,EAAA,MAAM,IAAO,GAAA,KAAA,CAAM,IAAK,CAAA,IAAA,CAAK,SAAS,WAAW,CAAC,CAAE,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,OAAA,CAAQ,CAAE,CAAA,CAAC,CAAC,CAAC,CAAA;AAC1E,EAAI,IAAA,CAAC,IAAK,CAAA,MAAA,EAAe,OAAA,IAAA;AACzB,EAAO,OAAA,CAAA,EAAA,GAAA,IAAA,CAAK,IAAK,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,QAAA,CAAS,YAAY,CAAC,CAAA,KAAvC,IAA4C,GAAA,EAAA,GAAA,IAAA,CAAK,CAAC,CAAA;AAC3D;AAGO,SAAS,aAAa,IAA6B,EAAA;AACxD,EAAA,MAAM,MAAM,KAAM,CAAA,IAAA,CAAK,IAAK,CAAA,QAAA,CAAS,gBAAgB,CAAC,CAAA;AACtD,EAAO,OAAA,GAAA,CAAI,SAAS,GAAI,CAAA,GAAA,CAAI,SAAS,CAAC,CAAA,CAAE,CAAC,CAAI,GAAA,IAAA;AAC/C;AAGO,SAAS,aAAa,IAA6B,EAAA;AA7K1D,EAAA,IAAA,EAAA,EAAA,EAAA;AA8KE,EAAA,MAAM,CAAI,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,KAAM,CAAA,sIAAsI,CAAjJ,KAAA,IAAA,GAAA,EAAA,GAAsJ,IAAK,CAAA,KAAA,CAAM,qDAAqD,CAAA,KAAtN,IAA2N,GAAA,EAAA,GAAA,IAAA,CAAK,MAAM,yCAAyC,CAAA;AACzR,EAAA,OAAO,CAAI,GAAA,CAAA,CAAE,CAAC,CAAA,CAAE,MAAS,GAAA,IAAA;AAC3B;AAGO,SAAS,iBAAiB,IAAsB,EAAA;AACrD,EAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,wCAAA,EAA0C,IAAI,CAAA;AACpE;AAOA,SAAS,aAAa,IAAgC,EAAA;AA5LtD,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA6LE,EAAM,MAAA,CAAA,GAAK,sBAAQ,EAAC;AACpB,EAAA,MAAM,OAAO,OAAO,CAAA,CAAE,OAAY,KAAA,QAAA,GAAW,EAAE,OAAU,GAAA,EAAA;AACzD,EAAM,MAAA,OAAA,GAAU,YAAY,IAAI,CAAA;AAChC,EAAA,MAAM,OAAU,GAAA,CAAA,EAAA,GAAA,WAAA,CAAY,IAAI,CAAA,KAAhB,IAAqB,GAAA,EAAA,GAAA,MAAA;AACrC,EAAA,MAAM,UAAa,GAAA,CAAA,EAAA,GAAA,YAAA,CAAa,IAAI,CAAA,KAAjB,IAAsB,GAAA,EAAA,GAAA,MAAA;AACzC,EAAA,IAAI,CAAC,OAAW,IAAA,CAAC,OAAW,IAAA,CAAC,YAAmB,OAAA,IAAA;AAChD,EAAO,OAAA;AAAA,IACL,YAAY,OAAS,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,GAAA;AAAA,IACrB,WAAW,OAAS,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,SAAA;AAAA,IACpB,OAAA;AAAA,IACA,UAAA;AAAA,IACA,KAAO,EAAA,CAAA,EAAA,GAAA,YAAA,CAAa,IAAI,CAAA,KAAjB,IAAsB,GAAA,EAAA,GAAA,MAAA;AAAA,IAC7B,SAAW,EAAA,IAAA;AAAA,IACX,iBAAmB,EAAA,KAAA;AAAA,IACnB,WAAa,EAAA;AAAA,GACf;AACF;AACA,SAAS,SAAS,IAAuB,EAAA;AACvC,EAAM,MAAA,CAAA,GAAK,sBAAQ,EAAC;AACpB,EAAM,MAAA,GAAA,GAAM,CAAE,CAAA,SAAA,IAAa,CAAE,CAAA,SAAA;AAC7B,EAAM,MAAA,EAAA,GAAK,OAAO,GAAA,KAAQ,QAAW,GAAA,GAAA,GAAM,KAAK,KAAM,CAAA,MAAA,CAAO,GAAO,IAAA,IAAA,GAAA,GAAA,GAAA,EAAE,CAAC,CAAA;AACvE,EAAA,OAAO,MAAO,CAAA,QAAA,CAAS,EAAE,CAAA,GAAI,EAAK,GAAA,CAAA;AACpC;AAGA,SAAS,cAAc,KAAsC,EAAA;AAC3D,EAAA,OAAO,CAAC,GAAG,KAAK,CAAA,CAAE,IAAK,CAAA,CAAC,CAAG,EAAA,CAAA,KAAM,QAAS,CAAA,CAAC,CAAI,GAAA,QAAA,CAAS,CAAC,CAAC,CAAA;AAC5D;AACA,SAAS,WAAW,IAAwB,EAAA;AAzN5C,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA0NE,EAAM,MAAA,CAAA,GAAK,sBAAQ,EAAC;AACpB,EAAA,MAAM,WAAW,QAAS,CAAA,CAAA,EAAA,GAAA,CAAA,CAAE,uBAAF,IAAsB,GAAA,MAAA,GAAA,EAAA,CAAA,QAAQ,KAAK,EAAC;AAC9D,EAAA,MAAM,KAAQ,GAAA,QAAA,CAAS,CAAE,CAAA,KAAK,KAAK,EAAC;AACpC,EAAA,MAAM,OAAO,MAAO,CAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,KAAA,CAAM,IAAN,KAAA,IAAA,GAAA,EAAA,GAAc,SAAS,IAAvB,KAAA,IAAA,GAAA,EAAA,GAAA,CAA+B,EAAS,GAAA,QAAA,CAAA,QAAA,CAAS,KAAK,CAAvB,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAA0B,SAAzD,IAAiE,GAAA,EAAA,GAAA,EAAE,EAAE,WAAY,EAAA;AACrG,EAAA,OAAO,IAAS,KAAA,MAAA;AAClB;AAGO,MAAM,gBAAmB,GAAA;AAMhB,SAAA,eAAA,CAAgB,KAA2B,EAAA,aAAA,EAAwB,SAAuC,EAAA;AAxO1H,EAAA,IAAA,EAAA;AAyOE,EAAA,MAAM,WAAW,aAAiB,IAAA,IAAA,GAAA,aAAA,GAAA,SAAA;AAClC,EAAM,MAAA,KAAA,uBAAY,GAA6B,EAAA;AAC/C,EAAA,IAAI,OAAyB,GAAA,IAAA;AAI7B,EAAA,MAAM,SAAY,GAAA,aAAA,CAAc,KAAK,CAAA,CAAE,MAAO,CAAA,CAAA,IAAA,KAAQ,CAAC,UAAA,CAAW,IAAI,CAAC,CAAE,CAAA,GAAA,CAAI,CAAK,IAAA,KAAA;AA/OpF,IAAAA,IAAAA,GAAAA;AA+OwF,IAAA,OAAA;AAAA,MACpF,IAAA;AAAA,MACA,QAAA,EAAA,CAAUA,MAAA,YAAa,CAAA,IAAI,MAAjB,IAAAA,GAAAA,GAAAA,GAAsB,aAAa,IAAI;AAAA,KACnD;AAAA,GAAE,CAAA,CAAE,OAAO,CAAC,GAAA,KAGP,IAAI,QAAa,KAAA,IAAA,IAAQ,QAAQ,GAAI,CAAA,QAAA,CAAS,cAAc,GAAI,CAAA,QAAA,CAAS,WAAW,GAAI,CAAA,QAAA,CAAS,iBAAiB,GAAI,CAAA,QAAA,CAAS,UAAU,CAAC,CAAA;AAC/I,EAAW,KAAA,MAAA;AAAA,IACT,IAAA;AAAA,IACA;AAAA,OACG,SAAW,EAAA;AACd,IAAA,MAAM,UAAa,GAAA,iBAAA,CAAkB,QAAS,CAAA,UAAA,EAAY,SAAS,SAAS,CAAA;AAC5E,IAAM,MAAA,GAAA,GAAM,QAAS,CAAA,SAAA,IAAa,UAAc,IAAA,EAAA;AAEhD,IAAM,MAAA,MAAA,GAAwB,QAAQ,QAAS,CAAA,OAAA,IAAW,SAAS,aAAiB,IAAA,QAAA,CAAS,aAAa,OAAU,GAAA,IAAA,CAAA;AACpH,IAAA,IAAI,MAAQ,EAAA;AACV,MAAM,MAAA,QAAA,GAAW,KAAM,CAAA,GAAA,CAAI,MAAM,CAAA;AACjC,MAAA,KAAA,CAAM,IAAI,MAAQ,EAAA;AAAA,QAChB,GAAK,EAAA,MAAA;AAAA;AAAA,QAEL,KAAA,EAAA,CAAQ,QAAS,CAAA,SAAA,GAAA,CAAY,QAAU,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAA,KAAA,KAAS,SAAS,KAAQ,GAAA,QAAA,CAAS,KAAS,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,KAAU,CAAA,KAAA,QAAA;AAAA,QACvG,UAAA,EAAY,UAAc,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,UAAc,CAAA,IAAA,IAAA;AAAA,QAClD,SAAW,EAAA,QAAA,CAAS,SAAa,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,SAAa,CAAA,IAAA,IAAA;AAAA,QACxD,SAAW,EAAA,QAAA,CAAS,SAAa,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,SAAa,CAAA,IAAA,IAAA;AAAA,QACxD,OAAS,EAAA,QAAA,CAAS,OAAW,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,OAAW,CAAA,IAAA,IAAA;AAAA,QAClD,KAAO,EAAA,QAAA,CAAS,KAAS,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,KAAS,CAAA,IAAA,IAAA;AAAA,QAC5C,UAAY,EAAA,QAAA,CAAS,UAAc,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,UAAc,CAAA,IAAA,IAAA;AAAA,QAC3D,SAAQ,QAAU,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAA,MAAA,MAAW,cAAc,CAAC,QAAA,CAAS,YAAY,UAAa,GAAA,OAAA;AAAA,QAC9E,UAAY,EAAA,QAAA,CAAS,QAAY,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,UAAc,CAAA,IAAA,gBAAA;AAAA,QACzD,QAAA,EAAU,gBAAgB,QAAS,CAAA,aAAA,EAAe,SAAS,cAAgB,EAAA,SAAS,CAAK,KAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,QAAY,CAAA,IAAA,IAAA;AAAA,QAC/G,SAAA,EAAW,KAAK,GAAI,CAAA,QAAA,CAAS,IAAI,CAAG,EAAA,CAAA,EAAA,GAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,SAAV,KAAA,IAAA,GAAA,EAAA,GAAuB,CAAC;AAAA,OAC7D,CAAA;AACD,MAAU,OAAA,GAAA,MAAA;AAAA;AACZ;AAEF,EAAO,OAAA,CAAC,GAAG,KAAM,CAAA,MAAA,EAAQ,CAAE,CAAA,MAAA,CAAO,OAAK,CAAE,CAAA,UAAA,IAAc,EAAE,OAAO,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,MAAM,CAAE,CAAA,SAAA,GAAY,EAAE,SAAS,CAAA;AAC5G;AAGO,SAAS,YAAY,KAA6D,EAAA;AACvF,EAAA,MAAM,SAAS,aAAc,CAAA,KAAK,CAAE,CAAA,GAAA,CAAI,UAAQ,YAAa,CAAA,IAAI,CAAC,CAAA,CAAE,OAAO,CAAC,CAAA,KAAqB,CAAM,KAAA,IAAI,EAAE,GAAI,EAAA;AACjH,EAAI,IAAA,CAAC,QAAe,OAAA,IAAA;AACpB,EAAI,IAAA,MAAA,CAAO,qBAAqB,CAAC,MAAA,CAAO,cAAc,CAAC,MAAA,CAAO,WAAkB,OAAA,UAAA;AAChF,EAAA,IAAI,MAAO,CAAA,WAAA,IAAe,CAAC,MAAA,CAAO,SAAgB,OAAA,YAAA;AAClD,EAAO,OAAA,IAAA;AACT;AAKO,SAAS,eAAe,KAAgC,EAAA;AAC7D,EAAA,MAAM,CAAK,GAAA,CAAA,KAAA,IAAS,EAAI,EAAA,IAAA,GAAO,WAAY,EAAA;AAC3C,EAAA,OAAO,CAAC,CAAA,IAAK,CAAM,KAAA,gBAAA,IAAoB,MAAM,mBAAuB,IAAA,CAAA,KAAM,uBAA2B,IAAA,CAAA,KAAM,kBAAkB,CAAM,KAAA,SAAA,IAAa,aAAc,CAAA,IAAA,CAAK,CAAC,CAAK,IAAA,eAAA,CAAgB,IAAK,CAAA,CAAC,CAAK,IAAA,gBAAA,CAAiB,IAAK,CAAA,CAAC,KAAK,4BAA6B,CAAA,IAAA,CAAK,CAAC,CAAA,IAAK,EAAE,UAAW,CAAA,gBAAgB,CAAK,IAAA,oBAAA,CAAqB,KAAK,CAAC,CAAA;AACvU;AACA,MAAM,gBAAA,mBAAuB,IAAA,GAAA,CAAI,CAAC,GAAA,EAAK,MAAM,KAAO,EAAA,QAAA,EAAU,OAAS,EAAA,MAAA,EAAQ,QAAU,EAAA,IAAA,EAAM,MAAM,KAAO,EAAA,MAAA,EAAQ,QAAU,EAAA,OAAA,EAAS,MAAQ,EAAA,UAAA,EAAY,MAAM,KAAO,EAAA,IAAA,EAAM,OAAS,EAAA,QAAQ,CAAC,CAAA;AAChM,SAAS,UAAU,KAAyB,EAAA;AAC1C,EAAA,OAAO,MAAM,GAAI,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,CAAO,CAAC,CAAE,CAAA,WAAA,EAAgB,GAAA,CAAA,CAAE,MAAM,CAAC,CAAA,CAAE,aAAa,CAAA,CAAE,KAAK,GAAG,CAAA;AACtF;AAGO,SAAS,YAAY,IAAsB,EAAA;AAChD,EAAA,OAAO,IAAK,CAAA,OAAA,CAAQ,oCAAsC,EAAA,EAAE,CAAE,CAAA,OAAA,CAAQ,qBAAuB,EAAA,EAAE,CAAE,CAAA,OAAA,CAAQ,MAAQ,EAAA,GAAG,EAAE,IAAK,EAAA;AAC7H;AAMO,SAAS,gBAAgB,OAAwC,EAAA;AAnTxE,EAAA,IAAA,EAAA,EAAA,EAAA;AAoTE,EAAA,MAAM,OAAO,OAAW,IAAA,EAAA,EAAI,QAAQ,oCAAsC,EAAA,EAAE,EAAE,IAAK,EAAA;AACnF,EAAI,IAAA,CAAC,KAAY,OAAA,IAAA;AACjB,EAAA,MAAM,WAAU,EAAI,GAAA,CAAA,EAAA,GAAA,GAAA,CAAA,KAAA,CAAM,yBAAyB,CAAnC,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAuC,OAAvC,IAA2C,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA;AAC3D,EAAA,IAAI,CAAC,OAAA,IAAW,6EAA8E,CAAA,IAAA,CAAK,GAAG,CAAG,EAAA;AACvG,IAAO,OAAA,IAAA;AAAA;AAET,EAAM,MAAA,MAAA,GAAA,CAAU,OAAW,IAAA,GAAA,CAAI,KAAM,CAAA,KAAK,CAAE,CAAA,CAAC,CAAK,IAAA,EAAA,EAAI,OAAQ,CAAA,cAAA,EAAgB,EAAE,CAAA;AAChF,EAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,OAAA,CAAQ,WAAa,EAAA,GAAG,EAAE,KAAM,CAAA,KAAK,CAAE,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,CAAK,IAAA,CAAC,gBAAiB,CAAA,GAAA,CAAI,CAAE,CAAA,WAAA,EAAa,CAAC,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,CAAC,CAAA;AAC1I,EAAI,IAAA,CAAC,KAAM,CAAA,MAAA,EAAe,OAAA,IAAA;AAC1B,EAAM,MAAA,KAAA,GAAQ,UAAU,KAAK,CAAA;AAC7B,EAAO,OAAA,cAAA,CAAe,KAAK,CAAA,GAAI,IAAO,GAAA,KAAA;AACxC;AAGA,SAAS,qBAAqB,KAAsD,EAAA;AAlUpF,EAAA,IAAA,EAAA;AAmUE,EAAI,IAAA,CAAC,OAAc,OAAA,IAAA;AACnB,EAAA,MAAM,GAAM,GAAA,CAAA,EAAA,GAAA,MAAA,CAAO,OAAQ,CAAA,KAAK,EAAE,IAAK,CAAA,CAAC,CAAC,IAAI,MAAM,sBAAuB,CAAA,IAAA,CAAK,IAAI,CAAC,MAAxE,IAA4E,GAAA,MAAA,GAAA,EAAA,CAAA,CAAA,CAAA;AACxF,EAAI,IAAA,CAAC,KAAY,OAAA,IAAA;AACjB,EAAI,IAAA;AACF,IAAM,MAAA,IAAA,GAAO,OAAQ,IAAK,CAAA,KAAA,CAAM,GAAG,CAEhC,CAAA,IAAA,IAAQ,EAAE,CAAA,CAAE,IAAK,EAAA;AACpB,IAAA,IAAI,CAAC,IAAQ,IAAA,IAAA,KAAS,YAAgB,IAAA,IAAA,KAAS,WAAkB,OAAA,IAAA;AACjE,IAAA,OAAO,IAAK,CAAA,OAAA,CAAQ,WAAa,EAAA,EAAE,EAAE,OAAQ,CAAA,QAAA,EAAU,GAAG,CAAA,CAAE,OAAQ,CAAA,OAAA,EAAS,CAAK,CAAA,KAAA,CAAA,CAAE,aAAa,CAAA;AAAA,GAC3F,CAAA,OAAA,CAAA,EAAA;AACN,IAAO,OAAA,IAAA;AAAA;AAEX;AAGO,SAAS,iBAAiB,IAKtB,EAAA;AACT,EAAA,MAAM,UAAa,GAAA,CAAC,IAAK,CAAA,aAAA,EAAe,eAAgB,CAAA,IAAA,CAAK,UAAU,CAAA,EAAG,IAAK,CAAA,YAAA,EAAc,oBAAqB,CAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AAC7H,EAAM,MAAA,KAAA,GAAQ,WAAW,IAAK,CAAA,CAAA,CAAA,KAAK,KAAK,CAAC,cAAA,CAAe,CAAC,CAAC,CAAA;AAC1D,EAAQ,OAAA,CAAA,KAAA,IAAS,kBAAkB,IAAK,EAAA;AAC1C;AAcO,SAAS,oBAAoB,OAA+B,EAAA;AAzWnE,EAAA,IAAA,EAAA;AA0WE,EAAA,OAAO,SAAQ,EAAa,GAAA,YAAA,CAAA,OAAA,CAAQ,WAAW,CAAA,KAAhC,mBAAmC,aAAa,CAAA;AACjE;AAMgB,SAAA,gBAAA,CAAiB,OAAsB,EAAA,KAAA,EAA2B,SAA8C,EAAA;AAjXhI,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAkXE,EAAM,MAAA,SAAA,GAAY,GAAI,CAAA,OAAA,CAAQ,EAAE,CAAA;AAChC,EAAI,IAAA,CAAC,WAAkB,OAAA,IAAA;AACvB,EAAA,MAAM,MAAS,GAAA,eAAA,CAAgB,KAAO,EAAA,EAAA,EAAI,SAAS,CAAA;AACnD,EAAM,MAAA,MAAA,GAAS,OAAO,CAAC,CAAA;AACvB,EAAI,IAAA,CAAC,QAAe,OAAA,IAAA;AACpB,EAAA,MAAM,cAAc,aAAc,CAAA,KAAK,EAAE,MAAO,CAAA,CAAA,IAAA,KAAQ,WAAW,IAAI,CAAA,IAAK,IAAK,IAAe,CAAA,OAAO,CAAC,CAAE,CAAA,GAAA,CAAI,UAAQ,MAAQ,CAAA,IAAA,CAAe,OAAO,CAAC,CAAA;AAGrJ,EAAM,MAAA,KAAA,GAAA,CAAQ,EAAY,GAAA,WAAA,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,iBAAA,CAAkB,IAAK,CAAA,CAAC,CAAC,CAAA,KAA/C,IAAoD,GAAA,EAAA,GAAA,WAAA,CAAY,CAAC,CAAA;AAC/E,EAAA,MAAM,kBAAkB,CAAC,OAAA,CAAQ,aAAa,OAAQ,CAAA,KAAK,EAAE,GAAI,CAAA,CAAA,CAAA,KAAK,IAAI,CAAC,CAAC,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,KAAK,CAAC,cAAA,CAAe,CAAC,CAAC,CAAA;AAE/G,EAAM,MAAA,YAAA,GAAe,eAAmB,IAAA,yBAAA,CAA0B,IAAK,CAAA,eAAe,KAAI,EAAgB,GAAA,eAAA,CAAA,eAAe,CAA/B,KAAA,IAAA,GAAA,EAAA,GAAoC,eAAkB,GAAA,eAAA;AAChJ,EAAA,MAAM,QAAQ,gBAAiB,CAAA;AAAA,IAC7B,eAAe,MAAO,CAAA,KAAA;AAAA,IACtB,YAAA;AAAA,IACA,UAAY,EAAA,KAAA;AAAA,IACZ,OAAO,MAAO,CAAA;AAAA,GACf,CAAA;AACD,EAAM,MAAA,OAAA,GAAU,IAAK,CAAA,KAAA,CAAM,MAAO,CAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,SAAR,KAAA,IAAA,GAAA,EAAA,GAAqB,OAAQ,CAAA,SAAA,KAA7B,IAA0C,GAAA,EAAA,GAAA,EAAE,CAAC,CAAA;AAC/E,EAAO,OAAA;AAAA,IACL,SAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA,EAAW,IAAK,CAAA,GAAA,CAAI,MAAO,CAAA,QAAA,CAAS,OAAO,CAAI,GAAA,OAAA,GAAU,CAAG,EAAA,MAAA,CAAO,SAAS,CAAA;AAAA,IAC5E,YAAY,MAAO,CAAA,UAAA;AAAA,IACnB,OAAA,EAAA,CAAS,kBAAO,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,OAAO,CAAA,KAA1B,IAA6B,GAAA,MAAA,GAAA,EAAA,CAAA,OAAA,KAA7B,IAAwC,GAAA,EAAA,GAAA,IAAA;AAAA,IACjD,QAAA,EAAA,CAAU,kBAAO,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,QAAQ,CAAA,KAA3B,IAA8B,GAAA,MAAA,GAAA,EAAA,CAAA,QAAA,KAA9B,IAA0C,GAAA,EAAA,GAAA,IAAA;AAAA,IACpD,YAAY,MAAO,CAAA;AAAA,GACrB;AACF;AAGgB,SAAA,cAAA,CAAe,KAAa,KAAgC,EAAA;AAC1E,EAAA,MAAM,CAAC,IAAM,EAAA,IAAA,GAAO,EAAE,CAAI,GAAA,GAAA,CAAI,MAAM,GAAG,CAAA;AACvC,EAAM,MAAA,KAAA,GAAQ,KAAK,OAAQ,CAAA,qBAAA,EAAuB,IAAI,CAAE,CAAA,OAAA,CAAQ,SAAS,EAAE,CAAA;AAC3E,EAAA,MAAM,GAAM,GAAA,KAAA,CAAM,QAAS,CAAA,GAAG,IAAI,GAAM,GAAA,GAAA;AACxC,EAAO,OAAA,CAAA,EAAG,KAAK,CAAA,EAAG,GAAG,CAAA,GAAA,EAAM,KAAK,CAAA,EAAG,IAAO,GAAA,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA;AAC3D;AAMO,SAAS,YAAY,KAAuB,EAAA;AACjD,EAAM,MAAA,IAAA,GAAO,KAAM,CAAA,WAAA,EAAc,CAAA,SAAA,CAAU,MAAM,CAAE,CAAA,OAAA,CAAQ,kBAAoB,EAAA,EAAE,CAAE,CAAA,OAAA,CAAQ,eAAe,GAAG,CAAA,CAAE,OAAQ,CAAA,UAAA,EAAY,EAAE,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,EAAE,CAAA,CAAE,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAA;AACrK,EAAA,OAAO,IAAQ,IAAA,SAAA;AACjB;AACO,SAAS,mBAAmB,KAAwB,EAAA;AACzD,EAAO,OAAA,wCAAA,CAAyC,KAAK,KAAK,CAAA;AAC5D;AAGO,SAAS,YAAY,GAAwC,EAAA;AAClE,EAAA,MAAM,QAAQ,wBAAyB,CAAA,IAAA,CAAA,CAAM,GAAO,IAAA,IAAA,GAAA,GAAA,GAAA,EAAA,EAAI,MAAM,CAAA;AAC9D,EAAA,OAAO,QAAQ,KAAM,CAAA,CAAC,CAAK,GAAA,CAAA,GAAA,IAAA,IAAA,GAAA,GAAA,GAAO,IAAI,IAAK,EAAA;AAC7C;AAGO,SAAS,YAAa,CAAA,EAAA,EAAY,GAAM,GAAA,IAAA,CAAK,KAAe,EAAA;AACjE,EAAI,IAAA,CAAC,IAAW,OAAA,EAAA;AAChB,EAAA,MAAM,IAAO,GAAA,IAAA,CAAK,GAAI,CAAA,CAAA,EAAG,MAAM,EAAE,CAAA;AACjC,EAAA,MAAM,GAAM,GAAA,IAAA,CAAK,KAAM,CAAA,IAAA,GAAO,GAAM,CAAA;AACpC,EAAI,IAAA,GAAA,GAAM,GAAU,OAAA,UAAA;AACpB,EAAA,IAAI,GAAM,GAAA,EAAA,EAAW,OAAA,CAAA,EAAG,GAAG,CAAA,QAAA,CAAA;AAC3B,EAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,KAAM,CAAA,GAAA,GAAM,EAAE,CAAA;AACjC,EAAA,IAAI,KAAQ,GAAA,EAAA,EAAW,OAAA,CAAA,EAAG,KAAK,CAAA,MAAA,CAAA;AAC/B,EAAI,IAAA,KAAA,GAAQ,IAAW,OAAA,WAAA;AACvB,EAAM,MAAA,CAAA,GAAI,IAAI,IAAA,CAAK,EAAE,CAAA;AACrB,EAAA,MAAM,MAAS,GAAA,CAAC,KAAO,EAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,OAAO,KAAK,CAAA;AAClG,EAAO,OAAA,CAAA,EAAG,EAAE,OAAQ,EAAC,IAAI,MAAO,CAAA,CAAA,CAAE,QAAS,EAAC,CAAC,CAAA,CAAA;AAC/C;AAKO,SAAS,eAAe,IAAwB,EAAA;AA5bvD,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA6bE,EAAM,MAAA,CAAA,GAAK,sBAAQ,EAAC;AACpB,EAAA,MAAM,KAAQ,GAAA,QAAA,CAAS,CAAE,CAAA,KAAK,KAAK,EAAC;AACpC,EAAA,MAAM,UAAa,GAAA,QAAA,CAAS,KAAM,CAAA,UAAU,KAAK,EAAC;AAClD,EAAM,MAAA,GAAA,GAAM,QAAO,EAAE,GAAA,CAAA,CAAA,OAAA,KAAF,YAAa,EAAE,CAAA,CAAE,IAAK,EAAA,CAAE,WAAY,EAAA;AACvD,EAAO,OAAA,MAAA,CAAA,CAAO,EAAE,GAAA,CAAA,CAAA,IAAA,KAAF,IAAU,GAAA,EAAA,GAAA,EAAE,CAAE,CAAA,WAAA,EAAkB,KAAA,UAAA,IAAc,OAAQ,CAAA,CAAA,EAAA,GAAA,KAAA,CAAM,QAAN,KAAA,IAAA,GAAA,EAAA,GAAkB,KAAM,CAAA,UAAU,CAAK,IAAA,KAAA,CAAM,IAAS,KAAA,UAAA,IAAc,OAAQ,CAAA,UAAA,CAAW,UAAU,CAAA,IAAK,GAAQ,KAAA,aAAA,IAAiB,GAAQ,KAAA,iBAAA,IAAqB,GAAQ,KAAA,oBAAA;AAC1O;AACA,SAAS,mBAAmB,CAA8B,EAAA;AAnc1D,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAocE,EAAA,MAAM,WAAW,QAAS,CAAA,CAAA,EAAA,GAAA,CAAA,CAAE,uBAAF,IAAsB,GAAA,MAAA,GAAA,EAAA,CAAA,QAAQ,KAAK,EAAC;AAC9D,EAAA,OAAO,KAAI,EAAS,GAAA,QAAA,CAAA,CAAA,EAAA,GAAA,QAAA,CAAS,SAAS,KAAK,CAAA,KAAvB,mBAA0B,QAAQ,CAAA,KAA3C,IAA8C,GAAA,MAAA,GAAA,EAAA,CAAA,UAAU,KAAK,GAAI,CAAA,CAAA,EAAA,GAAA,QAAA,CAAS,SAAS,QAAQ,CAAA,KAA1B,mBAA6B,UAAU,CAAA;AACrH;AAGO,SAAS,aAAa,IAA8B,EAAA;AAzc3D,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA0cE,EAAM,MAAA,CAAA,GAAK,sBAAQ,EAAC;AACpB,EAAA,MAAM,KAAQ,GAAA,QAAA,CAAS,CAAE,CAAA,KAAK,KAAK,EAAC;AACpC,EAAA,MAAM,UAAU,GAAI,CAAA,CAAA,EAAA,GAAA,QAAA,CAAS,MAAM,UAAU,CAAA,KAAzB,mBAA4B,OAAO,CAAA;AACvD,EAAA,IAAI,SAAgB,OAAA,OAAA;AACpB,EAAA,MAAM,MAAS,GAAA,GAAA,CAAA,CAAI,EAAS,GAAA,QAAA,CAAA,KAAA,CAAM,QAAQ,CAAA,KAAvB,IAA0B,GAAA,MAAA,GAAA,EAAA,CAAA,UAAU,CAAK,IAAA,GAAA,CAAI,kBAAmB,CAAA,CAAC,CAAC,CAAA;AACrF,EAAA,IAAI,QAAe,OAAA,MAAA;AACnB,EAAO,OAAA,cAAA,CAAe,IAAI,CAAI,GAAA,CAAA,EAAA,GAAA,GAAA,CAAI,EAAE,OAAO,CAAA,KAAb,YAAkB,IAAO,GAAA,IAAA;AACzD;AAGO,SAAS,YAAY,IAAwB,EAAA;AApdpD,EAAA,IAAA,EAAA,EAAA,EAAA;AAqdE,EAAM,MAAA,CAAA,GAAK,sBAAQ,EAAC;AACpB,EAAA,MAAM,KAAQ,GAAA,QAAA,CAAS,CAAE,CAAA,KAAK,KAAK,EAAC;AACpC,EAAA,MAAM,WAAW,QAAS,CAAA,CAAA,EAAA,GAAA,CAAA,CAAE,uBAAF,IAAsB,GAAA,MAAA,GAAA,EAAA,CAAA,QAAQ,KAAK,EAAC;AAC9D,EAAA,MAAM,IAAI,QAAS,CAAA,KAAA,CAAM,QAAQ,CAAA,IAAK,UAAS,EAAS,GAAA,QAAA,CAAA,QAAA,CAAS,KAAK,CAAA,KAAvB,mBAA0B,QAAQ,CAAA,IAAK,SAAS,QAAS,CAAA,QAAQ,KAAK,EAAC;AACtH,EAAA,OAAO,CAAE,CAAA,OAAA,KAAY,IAAQ,IAAA,CAAA,CAAE,IAAS,KAAA,OAAA;AAC1C;AAYO,SAAS,oBAAoB,KAAgD,EAAA;AAtepF,EAAA,IAAA,EAAA;AAueE,EAAA,MAAM,MAA2B,EAAC;AAClC,EAAW,KAAA,MAAA,IAAA,IAAQ,aAAc,CAAA,KAAK,CAAG,EAAA;AACvC,IAAA,MAAM,CAAI,GAAA,IAAA;AACV,IAAM,MAAA,IAAA,GAAO,GAAI,CAAA,CAAA,CAAE,OAAO,CAAA;AAC1B,IAAA,IAAI,IAAQ,IAAA,CAAC,cAAe,CAAA,IAAI,CAAG,EAAA;AACjC,MAAM,MAAA,IAAA,GAAO,WAAW,IAAI,CAAA;AAC5B,MAAA,GAAA,CAAI,IAAK,CAAA;AAAA,QACP,EAAI,EAAA,MAAA,CAAA,CAAO,EAAE,GAAA,CAAA,CAAA,EAAA,KAAF,IAAQ,GAAA,EAAA,GAAA,CAAA,EAAG,IAAO,GAAA,GAAA,GAAM,GAAG,CAAA,CAAA,EAAI,GAAI,CAAA,MAAM,CAAE,CAAA,CAAA;AAAA,QACtD,IAAA,EAAM,OAAO,MAAS,GAAA,WAAA;AAAA,QACtB,OAAS,EAAA,IAAA,GAAO,WAAY,CAAA,IAAI,KAAK,IAAO,GAAA,IAAA;AAAA,QAC5C,SAAA,EAAW,SAAS,IAAI;AAAA,OACzB,CAAA;AAAA;AACH;AAEF,EAAO,OAAA,GAAA;AACT;AAMgB,SAAA,SAAA,CAAU,OAA2B,KAKnD,EAAA;AAjgBF,EAAA,IAAA,EAAA,EAAA,EAAA;AAmgBE,EAAM,MAAA,KAAA,GAAQ,aAAc,CAAA,KAAK,CAAE,CAAA,MAAA,CAAO,UAAQ,QAAS,CAAA,IAAI,CAAK,IAAA,KAAA,GAAQ,GAAK,CAAA;AACjF,EAAA,IAAI,QAA0B,GAAA,IAAA;AAC9B,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAI,IAAA,CAAC,UAAW,CAAA,IAAI,CAAG,EAAA;AACrB,MAAI,IAAA,WAAA,CAAY,IAAI,CAAG,EAAA;AACrB,QAAA,MAAM,CAAI,GAAA,IAAA;AACV,QAAO,OAAA;AAAA,UACL,MAAQ,EAAA,QAAA;AAAA,UACR,QAAU,EAAA,IAAA;AAAA,UACV,KAAO,EAAA,CAAA,EAAA,GAAA,GAAA,CAAI,CAAE,CAAA,OAAO,MAAb,IAAkB,GAAA,EAAA,GAAA,mBAAA;AAAA,UACzB,KAAO,EAAA;AAAA,SACT;AAAA;AAEF,MAAM,MAAA,QAAA,GAAW,aAAa,IAAI,CAAA;AAClC,MAAI,IAAA,QAAA,KAAa,SAAS,UAAc,IAAA,QAAA,CAAS,YAAY,CAAC,cAAA,CAAe,IAAI,CAAG,EAAA;AAClF,QAAO,OAAA;AAAA,UACL,MAAQ,EAAA,MAAA;AAAA,UACR,QAAU,EAAA,IAAA;AAAA,UACV,KAAO,EAAA,IAAA;AAAA,UACP,KAAO,EAAA;AAAA,SACT;AAAA;AAEF,MAAW,QAAA,GAAA,CAAA,EAAA,GAAA,YAAA,CAAa,IAAI,CAAA,KAAjB,IAAsB,GAAA,EAAA,GAAA,QAAA;AAAA;AACnC;AAIF,EAAM,MAAA,MAAA,GAAS,MAAM,MAAO,CAAA,CAAA,IAAA,KAAQ,CAAC,UAAW,CAAA,IAAI,CAAC,CAAA,CAAE,GAAI,EAAA;AAC3D,EAAA,IAAI,MAAU,IAAA,CAAC,cAAe,CAAA,MAAM,CAAK,IAAA,CAAC,YAAa,CAAA,MAAM,CAAK,IAAA,GAAA,CAAI,MAAO,CAAA,OAAO,CAAG,EAAA;AACrF,IAAO,OAAA;AAAA,MACL,MAAQ,EAAA,MAAA;AAAA,MACR,QAAU,EAAA,IAAA;AAAA,MACV,KAAO,EAAA,IAAA;AAAA,MACP,KAAO,EAAA;AAAA,KACT;AAAA;AAEF,EAAO,OAAA;AAAA,IACL,MAAQ,EAAA,SAAA;AAAA,IACR,QAAA;AAAA,IACA,KAAO,EAAA,IAAA;AAAA,IACP,KAAA,EAAO,QAAQ,MAAM;AAAA,GACvB;AACF;AAOA,SAAS,mBAAmB,IAAwB,EAAA;AApjBpD,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAqjBE,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAiB,OAAA,KAAA;AAC9C,EAAA,MAAM,CAAI,GAAA,IAAA;AACV,EAAA,MAAM,WAAW,QAAS,CAAA,CAAA,EAAA,GAAA,CAAA,CAAE,uBAAF,IAAsB,GAAA,MAAA,GAAA,EAAA,CAAA,QAAQ,KAAK,EAAC;AAC9D,EAAA,OAAO,QAAQ,GAAI,CAAA,CAAA,EAAA,GAAA,QAAA,CAAS,CAAE,CAAA,KAAK,MAAhB,IAAmB,GAAA,MAAA,GAAA,EAAA,CAAA,cAAc,CAAK,IAAA,GAAA,CAAA,CAAI,cAAS,QAAS,CAAA,KAAK,CAAvB,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAA0B,cAAc,CAAC,CAAA;AACxG;AAQO,SAAS,iBAAiB,KAAoC,EAAA;AACnE,EAAO,OAAA,KAAA,CAAM,KAAK,CAAQ,IAAA,KAAA,YAAA,CAAa,IAAI,CAAM,KAAA,IAAA,IAAQ,kBAAmB,CAAA,IAAI,CAAC,CAAA;AACnF;AAGO,SAAS,eAAe,OAAyB,EAAA;AACtD,EAAA,OAAO,OAAQ,CAAA,OAAA,CAAQ,wCAA0C,EAAA,EAAE,EAAE,IAAK,EAAA;AAC5E"}
|
|
1
|
+
{"version":3,"file":"buildFragments.js","sources":["../../../src/features/webbuilder/buildFragments.ts"],"sourcesContent":["/**\n * Reads builds out of a build chat's posts.\n *\n * The build workflow posts its result as a \"fragment\" on an assistant post:\n * sandbox id and preview URL, the source files, and after a publish the live\n * address. Native twin of the web host's `creationsFromMessages`\n * (browser `pages/webbuilder/remoteWebbuilder.ts`) and the surface's\n * `extractFragmentFromSource` lookup order: `propsConfiguration.contents`\n * first (where the real fragment lives; `props` is account-scoped), then the\n * post's own fields. Pure, so the host and jest can both use it.\n */\nimport type { WebBuilderBuild, WebBuilderProject } from './types';\n\ntype Loose = Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n\ninterface Fragment {\n sandboxUrl?: string;\n sandboxId?: string;\n liveUrl?: string;\n files?: Record<string, string> | null;\n title?: string;\n projectId?: string;\n /** Stack the build was made from (`vite-react`, `nextjs`), shown on the tile. */\n template?: string;\n /** Screenshot of the build: an object key or a full URL. */\n coverImageUrl?: string;\n /** CDN origin the cover key was stored under. */\n coverImagePath?: string;\n /** The agent's restore point for this build (design-pro snapshots after each turn). */\n snapshotId?: string;\n /** Read from the agent's words (the agent-chat lane), not a workflow fragment. */\n fromReply?: boolean;\n isCreatingSandbox: boolean;\n isDeploying: boolean;\n}\n\n/** `contents` arrives as an object or, from some resolvers, as JSON text. */\nfunction asObject(value: unknown): Loose | null {\n if (!value) return null;\n if (typeof value === 'object') return Array.isArray(value) ? null : (value as Loose);\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed.startsWith('{')) return null;\n try {\n const parsed = JSON.parse(trimmed);\n return parsed && typeof parsed === 'object' ? (parsed as Loose) : null;\n } catch {\n return null;\n }\n }\n return null;\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\n/** `props` is account-scoped (`props[\"<accountId>\"] = {…}`): the records one level down. */\nfunction accountRecords(record: Loose): Loose[] {\n return Object.values(record)\n .map((v) => asObject(v))\n .filter((v): v is Loose => v !== null);\n}\n\n/** First non-empty string among `key` on each record (and on its `fragment`). */\nfunction pick(records: Loose[], key: string): string | undefined {\n for (const record of records) {\n const value = str(record[key]) || str(asObject(record.fragment)?.[key]);\n if (value) return value;\n }\n return undefined;\n}\n\n/** A live sandbox URL (`https://3000-<id>.e2b.dev`) - never a cover. */\nconst LIVE_SANDBOX = /^https?:\\/\\/\\d+-[a-z0-9]+(\\.|\\/|$)/i;\n\n/**\n * The preview origin for a sandbox. A bare `https://3000-<id>` (no domain) is\n * the E2B default domain, as the surface's `liveSandboxIframeSrc` maps it.\n */\nexport function sandboxPreviewUrl(url: string | undefined, sandboxId: string | undefined): string | null {\n const given = str(url);\n if (given) {\n if (/^https?:\\/\\/\\d+-[a-z0-9]+\\/?$/i.test(given)) return `${given.replace(/\\/$/, '')}.e2b.dev`;\n return given;\n }\n const id = str(sandboxId);\n return id ? `https://3000-${id}.e2b.dev` : null;\n}\n\nfunction httpOrigin(value: string | undefined): string | null {\n const match = /^(https?:\\/\\/[^/?#]+)/i.exec((value ?? '').trim());\n return match && !LIVE_SANDBOX.test(match[1]) ? match[1] : null;\n}\n\n/**\n * The image to show for a cover - the web `resolveCoverDisplayUrl`: an object\n * key joined to the origin it was stored under, else to the app's CDN, else a\n * full https URL as given. A live sandbox URL is never a cover.\n */\nexport function coverDisplayUrl(cover: string | undefined, path?: string, cdnOrigin?: string): string | null {\n const raw = str(cover);\n if (!raw || LIVE_SANDBOX.test(raw)) return null;\n if (/^https?:\\/\\//i.test(raw)) return raw.split('?')[0];\n const key = raw.replace(/^\\/+/, '');\n if (!/\\/uploads\\//i.test(`/${key}`) && !/\\.(png|jpe?g|webp|gif|svg)$/i.test(key)) return null;\n const origin = httpOrigin(path) || httpOrigin(cdnOrigin);\n return origin ? `${origin}/${key}` : null;\n}\n\nexport function readFragment(post: unknown): Fragment | null {\n if (!post || typeof post !== 'object') return null;\n const p = post as Loose;\n const cfg: Loose = p.propsConfiguration || {};\n const contents: Loose = asObject(cfg.contents) || asObject(cfg.content) || {};\n const contentsProps: Loose = asObject(contents.props) || {};\n const props: Loose = asObject(p.props) || {};\n const fragment: Loose | null =\n asObject(contentsProps.fragment) ||\n asObject(contents.fragment) ||\n asObject(cfg.fragment) ||\n asObject(props.fragment) ||\n asObject(p.fragment) ||\n null;\n const f: Loose = fragment || {};\n const sandboxUrl = str(f.sandboxUrl) || str(f.url) || str(p.sandboxUrl) || str(contents.sandboxUrl);\n const sandboxId = str(f.sandboxId) || str(p.sandboxId) || str(contents.sandboxId) || str(cfg.sandboxId);\n const publish = asObject(f.publish);\n const liveUrl =\n str(f.customDomainUrl) || str(f.cloudflareUrl) || str(f.deployUrl) || str(publish?.url) || undefined;\n const attachment = asObject(props.attachment) || asObject(contents.attachment) || {};\n const isCreatingSandbox =\n f.isCreatingSandbox === true || contents.isCreatingSandbox === true || p.isCreatingSandbox === true;\n const isDeploying = attachment.isDeploying === true || f.isDeploying === true;\n if (!sandboxUrl && !sandboxId && !liveUrl && !fragment && !isCreatingSandbox && !isDeploying) return null;\n const files = f.files && typeof f.files === 'object' ? (f.files as Record<string, string>) : null;\n // The cover rides on the fragment, the post's props, or an account record of either.\n const coverSources = [f, props, contents, contentsProps, p, ...accountRecords(props), ...accountRecords(contents)];\n const coverImageUrl = [\n pick(coverSources, 'coverImageUrl'),\n pick(coverSources, 'previewImageUrl'),\n str(f.cover),\n ].find((c) => c && !LIVE_SANDBOX.test(c));\n return {\n sandboxUrl,\n sandboxId,\n liveUrl,\n files,\n title: str(f.title),\n projectId: str(f.projectId) || str(contentsProps.projectId),\n template: str(f.templateId) || str(f.template) || str(contentsProps.template) || str(contents.template),\n coverImageUrl,\n coverImagePath: pick(coverSources, 'coverImagePath'),\n isCreatingSandbox,\n isDeploying,\n };\n}\n\n/** Sandbox previews and published addresses the agent names (web `chat/agentBuild.ts`). */\nconst E2B_PREVIEW_RE = /https:\\/\\/(\\d{2,5})-([a-z0-9]{8,40})\\.e2b\\.(?:dev|app)\\b[^\\s)\\]\"'<>*`]*/gi;\nconst LIVE_URL_RE = /https:\\/\\/([a-z0-9][a-z0-9-]{1,60})\\.(?:pages\\.dev|yarntra\\.com)\\b[^\\s)\\]\"'<>*`]*/gi;\nconst RESTORE_POINT_RE = /restore point \\(snapshot `([^`\\s]{4,200})`\\)/gi;\n\nconst trimUrl = (url: string) => url.replace(/[.,;:!?]+$/, '');\n\n/** The last sandbox preview link in the text (the agent's latest), with its sandbox id. */\nexport function previewFrom(text: string): { url: string; sandboxId: string } | null {\n const all = Array.from(text.matchAll(E2B_PREVIEW_RE));\n const last = all[all.length - 1];\n return last ? { url: trimUrl(last[0]), sandboxId: last[2] } : null;\n}\n\n/** The published address the agent reports: `<name>.yarntra.com` first, pages.dev only when it is the only one (web #428). */\nexport function liveUrlFrom(text: string): string | null {\n const hits = Array.from(text.matchAll(LIVE_URL_RE)).map((m) => trimUrl(m[0]));\n if (!hits.length) return null;\n return hits.find((h) => h.includes('.yarntra.com')) ?? hits[0];\n}\n\n/** The restore point the skill reports: \"Saved a restore point (snapshot `<id>`).\" (design-pro 3.3, #388). */\nexport function snapshotFrom(text: string): string | null {\n const all = Array.from(text.matchAll(RESTORE_POINT_RE));\n return all.length ? all[all.length - 1][1] : null;\n}\n\n/** \"Your Lotus Flow site is built…\", \"**Lotus Flow** is live\" -> \"Lotus Flow\". */\nexport function siteNameFrom(text: string): string | null {\n const m =\n text.match(\n /\\bYour ([A-Z][\\w&'’ .-]{1,40}?)(?: (?:yoga|coffee|wedding|photography|bakery))? (?:site|website|app) is (?:built|ready|live|running)/,\n ) ??\n text.match(/\\*\\*([A-Z][^*\\n]{1,40})\\*\\* is (?:live|ready|built)/) ??\n text.match(/^([A-Z][\\w&'’ .-]{1,40}?) is live at\\b/m);\n return m ? m[1].trim() : null;\n}\n\n/** A sandbox preview link, without the sentence's closing punctuation. */\nconst E2B_LINK = String.raw`https:\\/\\/\\d{2,5}-[a-z0-9]{8,40}\\.e2b\\.(?:dev|app)\\b(?:[^\\s)\\]\"'<>*\\x60]*[^\\s)\\]\"'<>*\\x60.,;:!?])?`;\n\n/**\n * The agent's reply as the reader sees it. The restore point's id and the sandbox\n * preview are for the builder, not them (web `assistantBubbleContent`, design-pro\n * 3.11): a sandbox link dies with the sandbox (\"Sandbox not found\"), so the site\n * card's Preview, which can wake it, is the way in. Replies from before 3.11 wrote\n * the link in the prose; it goes too, keeping a markdown link's words.\n */\nexport function displayAgentText(text: string): string {\n return text\n .replace(/(restore point) \\(snapshot `[^`]+`\\)/gi, '$1')\n .replace(/\\s*\\(preview `[^`]+`\\)/gi, '')\n .replace(new RegExp(String.raw`\\[([^\\]]+)\\]\\(${E2B_LINK}\\)`, 'gi'), '$1')\n .replace(new RegExp(String.raw`:?[ \\t]*<?${E2B_LINK}>?`, 'gi'), '');\n}\n\n/**\n * A build named only in the agent's words: the agent-chat lane (template remix,\n * building from chat) replies with the preview link, the live address once it\n * publishes, and its restore point - no fragment - so those are the build.\n */\nfunction linkFragment(post: unknown): Fragment | null {\n const p = (post ?? {}) as Loose;\n const text = typeof p.message === 'string' ? p.message : '';\n const preview = previewFrom(text);\n const liveUrl = liveUrlFrom(text) ?? undefined;\n const snapshotId = snapshotFrom(text) ?? undefined;\n if (!preview && !liveUrl && !snapshotId) return null;\n return {\n sandboxUrl: preview?.url,\n sandboxId: preview?.sandboxId,\n liveUrl,\n snapshotId,\n title: siteNameFrom(text) ?? undefined,\n fromReply: true,\n isCreatingSandbox: false,\n isDeploying: false,\n };\n}\n\nfunction postTime(post: unknown): number {\n const p = (post ?? {}) as Loose;\n const raw = p.updatedAt || p.createdAt;\n const ms = typeof raw === 'number' ? raw : Date.parse(String(raw ?? ''));\n return Number.isFinite(ms) ? ms : 0;\n}\n\n/** Posts in the order they happened (the query is not sorted). */\nfunction chronological(posts: readonly unknown[]): unknown[] {\n return [...posts].sort((a, b) => postTime(a) - postTime(b));\n}\n\nfunction isUserPost(post: unknown): boolean {\n const p = (post ?? {}) as Loose;\n const contents = asObject(p.propsConfiguration?.contents) || {};\n const props = asObject(p.props) || {};\n const role = String(props.role ?? contents.role ?? asObject(contents.props)?.role ?? '').toUpperCase();\n return role === 'USER';\n}\n\n/** The stack label the web tile shows when a build does not name one. */\nexport const DEFAULT_TEMPLATE = 'vite-react';\n\n/**\n * Newest-first builds of one site. A later post about the same sandbox (a\n * publish, a re-post, its screenshot) updates that build.\n */\nexport function buildsFromPosts(\n posts: readonly unknown[],\n fallbackTitle?: string,\n cdnOrigin?: string,\n): WebBuilderBuild[] {\n const fallback = fallbackTitle ?? 'Web app';\n const byKey = new Map<string, WebBuilderBuild>();\n let lastKey: string | null = null;\n // The web hydrate's rule: a build is an ASSISTANT post with something to show - a\n // preview URL, a live address or a screenshot. A user turn carries the sandbox it\n // edits (and a bare sandbox id is a turn in flight), neither is a build.\n const fragments = chronological(posts)\n .filter((post) => !isUserPost(post))\n .map((post) => ({ post, fragment: readFragment(post) ?? linkFragment(post) }))\n .filter(\n (row): row is { post: unknown; fragment: Fragment } =>\n row.fragment !== null &&\n Boolean(\n row.fragment.sandboxUrl ||\n row.fragment.liveUrl ||\n row.fragment.coverImageUrl ||\n row.fragment.snapshotId,\n ),\n );\n for (const { post, fragment } of fragments) {\n const previewUrl = sandboxPreviewUrl(fragment.sandboxUrl, fragment.sandboxId);\n const key = fragment.sandboxId || previewUrl || '';\n // A publish or screenshot post may name no sandbox: it belongs to the latest build.\n const target: string | null =\n key || (fragment.liveUrl || fragment.coverImageUrl || fragment.snapshotId ? lastKey : null);\n if (target) {\n const existing = byKey.get(target);\n byKey.set(target, {\n key: target,\n // A workflow fragment names the build; a reply's site name only names a build with none yet.\n title:\n (fragment.fromReply ? existing?.title || fragment.title : fragment.title || existing?.title) ||\n fallback,\n previewUrl: previewUrl || existing?.previewUrl || null,\n sandboxId: fragment.sandboxId || existing?.sandboxId || null,\n projectId: fragment.projectId || existing?.projectId || null,\n liveUrl: fragment.liveUrl || existing?.liveUrl || null,\n files: fragment.files || existing?.files || null,\n snapshotId: fragment.snapshotId || existing?.snapshotId || null,\n origin: existing?.origin === 'workflow' || !fragment.fromReply ? 'workflow' : 'agent',\n templateId: fragment.template || existing?.templateId || DEFAULT_TEMPLATE,\n coverUrl:\n coverDisplayUrl(fragment.coverImageUrl, fragment.coverImagePath, cdnOrigin) ||\n existing?.coverUrl ||\n null,\n updatedAt: Math.max(postTime(post), existing?.updatedAt ?? 0),\n });\n lastKey = target;\n }\n }\n return [...byKey.values()].filter((b) => b.previewUrl || b.liveUrl).sort((a, b) => b.updatedAt - a.updatedAt);\n}\n\n/** The newest post flags a sandbox still being created or a publish still running. */\nexport function pendingWork(posts: readonly unknown[]): 'creating' | 'publishing' | null {\n const newest = chronological(posts)\n .map((post) => readFragment(post))\n .filter((f): f is Fragment => f !== null)\n .pop();\n if (!newest) return null;\n if (newest.isCreatingSandbox && !newest.sandboxUrl && !newest.sandboxId) return 'creating';\n if (newest.isDeploying && !newest.liveUrl) return 'publishing';\n return null;\n}\n\n// ── Titles: the web surface's `resolveArtifactTitle` rules ─────────────────\n\n/** Not a product name: what the workflow and the chat call a site before it has one. */\nexport function isGenericTitle(title?: string | null): boolean {\n const t = (title || '').trim().toLowerCase();\n return (\n !t ||\n t === 'generated page' ||\n t === 'generated project' ||\n t === 'generated with cdecli' ||\n t === 'ai assistant' ||\n t === 'web app' ||\n /^build \\d+$/.test(t) ||\n /^build\\s+me\\b/.test(t) ||\n /^remix\\s+the\\b/.test(t) ||\n /^(build|chat)[- ]channel\\b/.test(t) ||\n t.startsWith('selected skill') ||\n /^code[\\s_-]?assist/.test(t)\n );\n}\n\nconst TITLE_STOP_WORDS = new Set([\n 'a',\n 'an',\n 'the',\n 'create',\n 'build',\n 'make',\n 'please',\n 'me',\n 'my',\n 'for',\n 'with',\n 'simple',\n 'using',\n 'from',\n 'template',\n 'to',\n 'and',\n 'or',\n 'remix',\n 'yantra',\n]);\n\nfunction titleCase(words: string[]): string {\n return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(' ');\n}\n\n/** The person's words, without the internal lines a turn carries. */\nexport function cleanPrompt(text: string): string {\n return text\n .replace(/^\\[webbuilder context:[^\\]]*\\]\\s*/i, '')\n .replace(/^build\\s*me\\s*:\\s*/i, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Product name from a brief: \"Build me: todo app\" -> \"Todo App\". An edit\n * (\"make the header blue\") is not a name.\n */\nexport function titleFromPrompt(message?: string | null): string | null {\n const raw = (message || '').replace(/^\\[webbuilder context:[^\\]]*\\]\\s*/i, '').trim();\n if (!raw) return null;\n const buildMe = raw.match(/^\\s*Build me:\\s*(.+)$/im)?.[1]?.trim();\n if (!buildMe && /^(change|update|rename|fix|edit|add|remove|delete|improve|make|refactor)\\b/i.test(raw)) {\n return null;\n }\n const source = (buildMe || raw.split(/\\n+/)[0] || '').replace(/^[\"']|[\"']$/g, '');\n const words = source\n .replace(/[^\\w\\s-]/g, ' ')\n .split(/\\s+/)\n .filter((w) => w.length > 1 && !TITLE_STOP_WORDS.has(w.toLowerCase()))\n .slice(0, 3);\n if (!words.length) return null;\n const title = titleCase(words);\n return isGenericTitle(title) ? null : title;\n}\n\n/** `package.json` name of the build (\"bakery-site\" -> \"Bakery Site\"). */\nfunction titleFromPackageJson(files?: Record<string, string> | null): string | null {\n if (!files) return null;\n const raw = Object.entries(files).find(([path]) => /(^|\\/)package\\.json$/.test(path))?.[1];\n if (!raw) return null;\n try {\n const name = String((JSON.parse(raw) as { name?: string }).name || '').trim();\n if (!name || name === 'vite-react' || name === 'project') return null;\n return name\n .replace(/^@[^/]+\\//, '')\n .replace(/[-_]+/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n } catch {\n return null;\n }\n}\n\n/** The build's own title, then the brief's product name, the chat's name, the package name. */\nexport function resolveSiteTitle(opts: {\n fragmentTitle?: string | null;\n channelTitle?: string | null;\n userPrompt?: string | null;\n files?: Record<string, string> | null;\n}): string {\n const candidates = [\n opts.fragmentTitle,\n titleFromPrompt(opts.userPrompt),\n opts.channelTitle,\n titleFromPackageJson(opts.files),\n ];\n const found = candidates.find((c) => c && !isGenericTitle(c));\n return (found || 'Generated Page').trim();\n}\n\n// ── Sites ──────────────────────────────────────────────────────────────────\n\nexport interface ChannelLike {\n id?: string | null;\n title?: string | null;\n displayName?: string | null;\n updatedAt?: unknown;\n createdAt?: unknown;\n lastMessage?: unknown;\n}\n\n/** True when the newest build in `lastMessage` already carries a cover - the web skips the thread read then. */\nexport function lastMessageHasCover(channel: ChannelLike): boolean {\n return Boolean(readFragment(channel.lastMessage)?.coverImageUrl);\n}\n\n/**\n * A site from one chat's posts, the way the web gallery hydrates a tile: only\n * a chat with a build is a site; its name follows `resolveSiteTitle`.\n */\nexport function projectFromPosts(\n channel: ChannelLike,\n posts: readonly unknown[],\n cdnOrigin?: string,\n): WebBuilderProject | null {\n const channelId = str(channel.id);\n if (!channelId) return null;\n const builds = buildsFromPosts(posts, '', cdnOrigin);\n const latest = builds[0];\n if (!latest) return null;\n const userPrompts = chronological(posts)\n .filter((post) => isUserPost(post) && str((post as Loose).message))\n .map((post) => String((post as Loose).message));\n // The brief names the product (\"Build me: …\"); a later message (\"the live preview is\n // not loading\") never does, so only the brief - or failing that the first ask - counts.\n const brief = userPrompts.find((m) => /build\\s*me\\s*:/i.test(m)) ?? userPrompts[0];\n const rawChannelTitle = [channel.displayName, channel.title]\n .map((t) => str(t))\n .find((t) => t && !isGenericTitle(t));\n // A chat named after its brief (\"Build simple calculator app\") gives the product name, not the sentence.\n const channelTitle =\n rawChannelTitle && /^(build|create|make)\\b/i.test(rawChannelTitle)\n ? (titleFromPrompt(rawChannelTitle) ?? rawChannelTitle)\n : rawChannelTitle;\n const title = resolveSiteTitle({\n fragmentTitle: latest.title,\n channelTitle,\n userPrompt: brief,\n files: latest.files,\n });\n const updated = Date.parse(String(channel.updatedAt ?? channel.createdAt ?? ''));\n return {\n channelId,\n title,\n updatedAt: Math.max(Number.isFinite(updated) ? updated : 0, latest.updatedAt),\n previewUrl: latest.previewUrl,\n liveUrl: builds.find((b) => b.liveUrl)?.liveUrl ?? null,\n coverUrl: builds.find((b) => b.coverUrl)?.coverUrl ?? null,\n templateId: latest.templateId,\n };\n}\n\n/** `?wb=<n>` on the preview so a rebuilt sandbox is fetched again, not served from cache. */\nexport function cacheBustedUrl(url: string, nonce: number | string): string {\n const [base, hash = ''] = url.split('#');\n const clean = base.replace(/([?&])wb=[^&]*(&|$)/, '$1').replace(/[?&]$/, '');\n const sep = clean.includes('?') ? '&' : '?';\n return `${clean}${sep}wb=${nonce}${hash ? `#${hash}` : ''}`;\n}\n\n/**\n * The publish name the web dialog suggests: the site's title as a slug,\n * `[a-z0-9-]`, at most 58 characters (`<name>.yarntra.com`).\n */\nexport function publishSlug(title: string): string {\n const slug = title\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 58)\n .replace(/-+$/, '');\n return slug || 'my-site';\n}\n\nexport function isValidPublishSlug(value: string): boolean {\n return /^[a-z0-9](?:[a-z0-9-]{0,56}[a-z0-9])?$/.test(value);\n}\n\n/** Display host of a URL: `https://bakery.pages.dev/` -> `bakery.pages.dev`. */\nexport function displayHost(url: string | null | undefined): string {\n const match = /^https?:\\/\\/([^/?#]+)/i.exec((url ?? '').trim());\n return match ? match[1] : (url ?? '').trim();\n}\n\n/** \"just now\", \"5 min ago\", \"3 h ago\", \"Yesterday\", \"12 Oct\". */\nexport function relativeTime(ms: number, now = Date.now()): string {\n if (!ms) return '';\n const diff = Math.max(0, now - ms);\n const min = Math.floor(diff / 60_000);\n if (min < 1) return 'just now';\n if (min < 60) return `${min} min ago`;\n const hours = Math.floor(min / 60);\n if (hours < 24) return `${hours} h ago`;\n if (hours < 48) return 'Yesterday';\n const d = new Date(ms);\n const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n return `${d.getDate()} ${months[d.getMonth()]}`;\n}\n\n// ── The agent transcript: the build chat's posts, as the web Agent pane shows them ──\n\n/** A live progress row (web `isThinkingPost`): shown as the agent's status, never kept. */\nexport function isThinkingPost(post: unknown): boolean {\n const p = (post ?? {}) as Loose;\n const props = asObject(p.props) || {};\n const attachment = asObject(props.attachment) || {};\n const msg = String(p.message ?? '')\n .trim()\n .toLowerCase();\n return (\n String(p.type ?? '').toUpperCase() === 'THINKING' ||\n Boolean(props.thinking ?? props.isThinking) ||\n props.kind === 'thinking' ||\n Boolean(attachment.isThinking) ||\n msg === 'thinking...' ||\n msg === 'initializing...' ||\n msg === 'initializing…'\n );\n}\n\nfunction readFragmentStatus(p: Loose): string | undefined {\n const contents = asObject(p.propsConfiguration?.contents) || {};\n return (\n str(asObject(asObject(contents.props)?.fragment)?.statusText) || str(asObject(contents.fragment)?.statusText)\n );\n}\n\n/** The workflow's progress line on a post: its thought, else the fragment's status. */\nexport function progressText(post: unknown): string | null {\n const p = (post ?? {}) as Loose;\n const props = asObject(p.props) || {};\n const thought = str(asObject(props.attachment)?.thought);\n if (thought) return thought;\n const status = str(asObject(props.fragment)?.statusText) || str(readFragmentStatus(p));\n if (status) return status;\n return isThinkingPost(post) ? (str(p.message) ?? null) : null;\n}\n\n/** A post the workflow wrote when the build failed (`fragment.isError` / `type: 'error'`). */\nexport function isErrorPost(post: unknown): boolean {\n const p = (post ?? {}) as Loose;\n const props = asObject(p.props) || {};\n const contents = asObject(p.propsConfiguration?.contents) || {};\n const f =\n asObject(props.fragment) || asObject(asObject(contents.props)?.fragment) || asObject(contents.fragment) || {};\n return f.isError === true || f.type === 'error';\n}\n\nexport interface TranscriptMessage {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n createdAt: number;\n}\n\n/**\n * The conversation in a build chat: the person's turns and the agent's replies,\n * oldest first, without progress rows or empty build markers.\n */\nexport function transcriptFromPosts(posts: readonly unknown[]): TranscriptMessage[] {\n const out: TranscriptMessage[] = [];\n for (const post of chronological(posts)) {\n const p = post as Loose;\n const text = str(p.message);\n if (text && !isThinkingPost(post)) {\n const user = isUserPost(post);\n out.push({\n id: String(p.id ?? `${user ? 'u' : 'a'}-${out.length}`),\n role: user ? 'user' : 'assistant',\n content: user ? cleanPrompt(text) || text : text,\n createdAt: postTime(post),\n });\n }\n }\n return out;\n}\n\n/**\n * How a turn started at `since` is going, read from the posts that arrived after it.\n * `heard` is whether the build posted anything back yet (a progress row, an answer).\n */\nexport function turnState(\n posts: readonly unknown[],\n since: number,\n): { status: 'running' | 'done' | 'failed'; progress: string | null; error: string | null; heard: boolean } {\n // A clock skew allowance, as the web ignores posts older than start - 2 s.\n const after = chronological(posts).filter((post) => postTime(post) >= since - 2_000);\n let progress: string | null = null;\n for (const post of after) {\n if (!isUserPost(post)) {\n if (isErrorPost(post)) {\n const p = post as Loose;\n return { status: 'failed', progress: null, error: str(p.message) ?? 'The build failed.', heard: true };\n }\n const fragment = readFragment(post);\n if (fragment && (fragment.sandboxUrl || fragment.liveUrl) && !isThinkingPost(post)) {\n return { status: 'done', progress: null, error: null, heard: true };\n }\n progress = progressText(post) ?? progress;\n }\n }\n // A plain answer (the agent asked a question, or replied without building) ends\n // the turn too - unless progress rows keep arriving after it.\n const newest = after.filter((post) => !isUserPost(post)).pop() as Loose | undefined;\n if (newest && !isThinkingPost(newest) && !progressText(newest) && str(newest.message)) {\n return { status: 'done', progress: null, error: null, heard: true };\n }\n return { status: 'running', progress, error: null, heard: Boolean(newest) };\n}\n\n/**\n * A turn sent through the build workflow: its USER post carries the workflow's\n * route (`templateTarget`). A blank build sends an empty fragment, which\n * the server drops, so this post is the only workflow mark until a build lands.\n */\nfunction isWorkflowTurnPost(post: unknown): boolean {\n if (!post || typeof post !== 'object') return false;\n const p = post as Loose;\n const contents = asObject(p.propsConfiguration?.contents) || {};\n return Boolean(str(asObject(p.props)?.templateTarget) || str(asObject(contents.props)?.templateTarget));\n}\n\n/**\n * The chat was built through the build workflow (its posts carry fragments or\n * the workflow's route): edits go back through the workflow. A chat without\n * any is an agent-chat site (a template remix), and its turns stay in the\n * agent chat.\n */\nexport function hasWorkflowPosts(posts: readonly unknown[]): boolean {\n return posts.some((post) => readFragment(post) !== null || isWorkflowTurnPost(post));\n}\n\n/** The person's words, without the agent-only template note a remix turn carries. */\nexport function stripAgentNote(content: string): string {\n return content.replace(/\\n*\\[(?:Template|Open build)\\][\\s\\S]*$/, '').trim();\n}\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -75,7 +75,7 @@ import {jsx,jsxs}from'react/jsx-runtime';import {useState,useEffect}from'react';
|
|
|
75
75
|
}], accessibilityLabel: "Site name", testID: "webbuilder-publish-name" }),
|
|
76
76
|
/* @__PURE__ */ jsx(Text, { style: [styles.suffix, {
|
|
77
77
|
color: theme.muted
|
|
78
|
-
}], children: ".
|
|
78
|
+
}], children: ".yarntra.com" })
|
|
79
79
|
] }),
|
|
80
80
|
!valid && name ? /* @__PURE__ */ jsx(Text, { style: [styles.help, {
|
|
81
81
|
color: theme.crit
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublishSheet.js","sources":["../../../../src/features/webbuilder/components/PublishSheet.tsx"],"sourcesContent":["/**\n * Publish a build: the web PublishControls dialog on a sheet. The person\n * picks the site's name (`<name>.pages.dev`), the host starts the deploy, and\n * the live address arrives later on a chat post - so the sheet says\n * \"Publishing…\" until the build carries it, then shows it with Open / Share.\n */\nimport React, { useEffect, useState } from 'react';\nimport { Linking, Share, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { displayHost, isValidPublishSlug, publishSlug } from '../buildFragments';\nimport type { WebBuilderBuild, WebBuilderPublishResult } from '../types';\nimport type { WebBuilderTheme } from '../webbuilderTheme';\nimport { PrimaryButton, SecondaryButton, Sheet } from './ui';\n\nexport function PublishSheet({\n visible,\n build,\n publishing,\n onPublish,\n onClose,\n theme,\n}: {\n visible: boolean;\n build: WebBuilderBuild | null;\n /** A deploy is running on this site (started here, or seen on the chat). */\n publishing: boolean;\n onPublish?: (build: WebBuilderBuild, projectName: string) => Promise<WebBuilderPublishResult>;\n onClose: () => void;\n theme: WebBuilderTheme;\n}) {\n const [name, setName] = useState('');\n const [starting, setStarting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (!visible || !build) return;\n setName((prev) => prev || publishSlug(build.title));\n setError(null);\n }, [visible, build]);\n\n const live = build?.liveUrl ?? null;\n const valid = isValidPublishSlug(name);\n\n const publish = async () => {\n if (!build || !onPublish || !valid) return;\n setStarting(true);\n setError(null);\n try {\n const result = await onPublish(build, name);\n if (!result.ok) setError(result.message || \"Publishing didn't start. Try again.\");\n } catch {\n setError(\"Publishing didn't start. Check your connection and try again.\");\n } finally {\n setStarting(false);\n }\n };\n\n let body: React.ReactNode;\n if (!build?.sandboxId) {\n body = (\n <Text style={[styles.note, { color: theme.muted }]}>\n There is nothing to publish yet. Build the site first, then publish it here.\n </Text>\n );\n } else if (publishing && !starting) {\n body = (\n <View style={styles.block} testID=\"webbuilder-publishing\">\n <PrimaryButton label=\"Publishing…\" onPress={() => undefined} theme={theme} busy />\n <Text style={[styles.note, { color: theme.muted }]}>\n This takes a minute or two. You can keep editing; the address appears here when it is live.\n </Text>\n </View>\n );\n } else {\n body = (\n <View style={styles.block}>\n {live ? (\n <View style={[styles.liveCard, { backgroundColor: theme.goodSoft }]} testID=\"webbuilder-live\">\n <MaterialCommunityIcons name=\"earth\" size={20} color={theme.good} />\n <Text style={[styles.liveHost, { color: theme.good }]} numberOfLines={1}>\n {displayHost(live)}\n </Text>\n </View>\n ) : null}\n {live ? (\n <View style={styles.row}>\n <SecondaryButton\n label=\"Open\"\n icon=\"open-in-new\"\n onPress={() => {\n Linking.openURL(live).catch(() => undefined);\n }}\n theme={theme}\n />\n <SecondaryButton\n label=\"Share\"\n icon=\"share-variant-outline\"\n onPress={() => {\n Share.share({ message: live, url: live }).catch(() => undefined);\n }}\n theme={theme}\n />\n </View>\n ) : null}\n <Text style={[styles.label, { color: theme.muted }]}>\n {live ? 'Publish the latest version' : 'Site address'}\n </Text>\n <View\n style={[\n styles.field,\n { backgroundColor: theme.chip, borderColor: valid ? theme.border : theme.crit },\n ]}\n >\n <TextInput\n value={name}\n onChangeText={(text) =>\n setName(\n text\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '')\n .slice(0, 58),\n )\n }\n autoCapitalize=\"none\"\n autoCorrect={false}\n placeholder=\"my-site\"\n placeholderTextColor={theme.faint}\n style={[styles.input, { color: theme.ink }]}\n accessibilityLabel=\"Site name\"\n testID=\"webbuilder-publish-name\"\n />\n <Text style={[styles.suffix, { color: theme.muted }]}>.pages.dev</Text>\n </View>\n {!valid && name ? (\n <Text style={[styles.help, { color: theme.crit }]}>\n Letters, numbers and dashes; it cannot start or end with a dash.\n </Text>\n ) : null}\n {error ? <Text style={[styles.help, { color: theme.crit }]}>{error}</Text> : null}\n <PrimaryButton\n label={live ? 'Publish update' : 'Publish'}\n icon=\"rocket-launch-outline\"\n onPress={() => {\n publish().catch(() => undefined);\n }}\n theme={theme}\n busy={starting}\n disabled={!valid || !onPublish}\n testID=\"webbuilder-publish-submit\"\n />\n </View>\n );\n }\n\n return (\n <Sheet visible={visible} title=\"Publish\" onClose={onClose} theme={theme} testID=\"webbuilder-publish-sheet\">\n {body}\n </Sheet>\n );\n}\n\nconst styles = StyleSheet.create({\n block: { gap: 12, paddingTop: 4 },\n row: { flexDirection: 'row', gap: 10 },\n liveCard: { flexDirection: 'row', alignItems: 'center', gap: 10, padding: 14, borderRadius: 12 },\n liveHost: { flex: 1, fontSize: 15, fontWeight: '700' },\n label: { fontSize: 13, fontWeight: '600', marginTop: 4 },\n field: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 12,\n borderWidth: StyleSheet.hairlineWidth,\n paddingHorizontal: 14,\n minHeight: 48,\n },\n input: { flex: 1, fontSize: 16, paddingVertical: 10 },\n suffix: { fontSize: 15 },\n help: { fontSize: 13 },\n note: { fontSize: 14, lineHeight: 20, paddingVertical: 8 },\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PublishSheet.js","sources":["../../../../src/features/webbuilder/components/PublishSheet.tsx"],"sourcesContent":["/**\n * Publish a build: the web PublishControls dialog on a sheet. The person\n * picks the site's name (`<name>.yarntra.com`), the host starts the deploy, and\n * the live address arrives later on a chat post - so the sheet says\n * \"Publishing…\" until the build carries it, then shows it with Open / Share.\n */\nimport React, { useEffect, useState } from 'react';\nimport { Linking, Share, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { displayHost, isValidPublishSlug, publishSlug } from '../buildFragments';\nimport type { WebBuilderBuild, WebBuilderPublishResult } from '../types';\nimport type { WebBuilderTheme } from '../webbuilderTheme';\nimport { PrimaryButton, SecondaryButton, Sheet } from './ui';\n\nexport function PublishSheet({\n visible,\n build,\n publishing,\n onPublish,\n onClose,\n theme,\n}: {\n visible: boolean;\n build: WebBuilderBuild | null;\n /** A deploy is running on this site (started here, or seen on the chat). */\n publishing: boolean;\n onPublish?: (build: WebBuilderBuild, projectName: string) => Promise<WebBuilderPublishResult>;\n onClose: () => void;\n theme: WebBuilderTheme;\n}) {\n const [name, setName] = useState('');\n const [starting, setStarting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (!visible || !build) return;\n setName((prev) => prev || publishSlug(build.title));\n setError(null);\n }, [visible, build]);\n\n const live = build?.liveUrl ?? null;\n const valid = isValidPublishSlug(name);\n\n const publish = async () => {\n if (!build || !onPublish || !valid) return;\n setStarting(true);\n setError(null);\n try {\n const result = await onPublish(build, name);\n if (!result.ok) setError(result.message || \"Publishing didn't start. Try again.\");\n } catch {\n setError(\"Publishing didn't start. Check your connection and try again.\");\n } finally {\n setStarting(false);\n }\n };\n\n let body: React.ReactNode;\n if (!build?.sandboxId) {\n body = (\n <Text style={[styles.note, { color: theme.muted }]}>\n There is nothing to publish yet. Build the site first, then publish it here.\n </Text>\n );\n } else if (publishing && !starting) {\n body = (\n <View style={styles.block} testID=\"webbuilder-publishing\">\n <PrimaryButton label=\"Publishing…\" onPress={() => undefined} theme={theme} busy />\n <Text style={[styles.note, { color: theme.muted }]}>\n This takes a minute or two. You can keep editing; the address appears here when it is live.\n </Text>\n </View>\n );\n } else {\n body = (\n <View style={styles.block}>\n {live ? (\n <View style={[styles.liveCard, { backgroundColor: theme.goodSoft }]} testID=\"webbuilder-live\">\n <MaterialCommunityIcons name=\"earth\" size={20} color={theme.good} />\n <Text style={[styles.liveHost, { color: theme.good }]} numberOfLines={1}>\n {displayHost(live)}\n </Text>\n </View>\n ) : null}\n {live ? (\n <View style={styles.row}>\n <SecondaryButton\n label=\"Open\"\n icon=\"open-in-new\"\n onPress={() => {\n Linking.openURL(live).catch(() => undefined);\n }}\n theme={theme}\n />\n <SecondaryButton\n label=\"Share\"\n icon=\"share-variant-outline\"\n onPress={() => {\n Share.share({ message: live, url: live }).catch(() => undefined);\n }}\n theme={theme}\n />\n </View>\n ) : null}\n <Text style={[styles.label, { color: theme.muted }]}>\n {live ? 'Publish the latest version' : 'Site address'}\n </Text>\n <View\n style={[\n styles.field,\n { backgroundColor: theme.chip, borderColor: valid ? theme.border : theme.crit },\n ]}\n >\n <TextInput\n value={name}\n onChangeText={(text) =>\n setName(\n text\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '')\n .slice(0, 58),\n )\n }\n autoCapitalize=\"none\"\n autoCorrect={false}\n placeholder=\"my-site\"\n placeholderTextColor={theme.faint}\n style={[styles.input, { color: theme.ink }]}\n accessibilityLabel=\"Site name\"\n testID=\"webbuilder-publish-name\"\n />\n <Text style={[styles.suffix, { color: theme.muted }]}>.yarntra.com</Text>\n </View>\n {!valid && name ? (\n <Text style={[styles.help, { color: theme.crit }]}>\n Letters, numbers and dashes; it cannot start or end with a dash.\n </Text>\n ) : null}\n {error ? <Text style={[styles.help, { color: theme.crit }]}>{error}</Text> : null}\n <PrimaryButton\n label={live ? 'Publish update' : 'Publish'}\n icon=\"rocket-launch-outline\"\n onPress={() => {\n publish().catch(() => undefined);\n }}\n theme={theme}\n busy={starting}\n disabled={!valid || !onPublish}\n testID=\"webbuilder-publish-submit\"\n />\n </View>\n );\n }\n\n return (\n <Sheet visible={visible} title=\"Publish\" onClose={onClose} theme={theme} testID=\"webbuilder-publish-sheet\">\n {body}\n </Sheet>\n );\n}\n\nconst styles = StyleSheet.create({\n block: { gap: 12, paddingTop: 4 },\n row: { flexDirection: 'row', gap: 10 },\n liveCard: { flexDirection: 'row', alignItems: 'center', gap: 10, padding: 14, borderRadius: 12 },\n liveHost: { flex: 1, fontSize: 15, fontWeight: '700' },\n label: { fontSize: 13, fontWeight: '600', marginTop: 4 },\n field: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 12,\n borderWidth: StyleSheet.hairlineWidth,\n paddingHorizontal: 14,\n minHeight: 48,\n },\n input: { flex: 1, fontSize: 16, paddingVertical: 10 },\n suffix: { fontSize: 15 },\n help: { fontSize: 13 },\n note: { fontSize: 14, lineHeight: 20, paddingVertical: 8 },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -36,11 +36,8 @@ function webbuilderAgentSuggestions(hasBuild, siteTitle) {
|
|
|
36
36
|
prompt: "Check the site for errors and fix anything broken."
|
|
37
37
|
}];
|
|
38
38
|
}
|
|
39
|
-
function wakePreviewPrompt(
|
|
40
|
-
|
|
41
|
-
return "The live preview is not responding. Restart the dev server for this site so the preview loads again.";
|
|
42
|
-
}
|
|
43
|
-
return [`The live preview of this site${build.title ? ` ("${build.title}")` : ""} is not responding`, build.previewUrl ? ` at ${build.previewUrl}` : "", build.sandboxId ? ` (sandbox ${build.sandboxId})` : "", ". Reconnect that sandbox and restart its dev server.", build.snapshotId ? ` If that sandbox is gone, boot from its latest restore point (snapshotId ${build.snapshotId}).` : " If the sandbox no longer exists, recreate the site in a new sandbox from its latest saved version.", " Then send me the preview link."].join("");
|
|
39
|
+
function wakePreviewPrompt() {
|
|
40
|
+
return "Open a live preview of my latest build.";
|
|
44
41
|
}
|
|
45
42
|
function agentEditNote(build) {
|
|
46
43
|
return `[Open build] The user is looking at the live preview of "${build.title || "this site"}" that you built${build.sandboxId ? ` (sandbox ${build.sandboxId}${build.previewUrl ? `, ${build.previewUrl}` : ""})` : ""}. Apply their request to that site in that sandbox - do not start a new one - and reply with the preview link.${build.snapshotId ? ` If that sandbox is gone, boot from its latest restore point (snapshotId ${build.snapshotId}).` : ""}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webbuilderPrompts.js","sources":["../../../src/features/webbuilder/webbuilderPrompts.ts"],"sourcesContent":["/**\n * Follow-ups for the Web Builder agent: the first asks of a site with nothing\n * built yet, and the edits people make most after a first build.\n */\nimport type { AgentChatSuggestion } from '../agent-chat';\n\n/**\n * Starter prompts in an empty chat (web `CHAT_STARTERS`, Lovable): complete briefs\n * that build on one tap - specific enough that the agent asks nothing.\n */\nexport const CHAT_STARTERS: readonly AgentChatSuggestion[] = [\n {\n id: 'cafe',\n label: 'Café website with menu',\n prompt: 'Build a website for a neighbourhood specialty coffee shop: hero, menu with prices, opening hours, location map and an Instagram-style gallery. Warm, modern look.',\n },\n {\n id: 'saas',\n label: 'SaaS landing page',\n prompt: 'Build a landing page for a project-management SaaS: hero with product screenshot, features, pricing (3 tiers), testimonials, FAQ and a sign-up call to action.',\n },\n {\n id: 'portfolio',\n label: 'Photographer portfolio',\n prompt: 'Build a portfolio for a wedding photographer: full-bleed gallery, about, packages with prices, and a contact form for booking enquiries. Elegant, minimal.',\n },\n {\n id: 'booking',\n label: 'Booking app with database',\n prompt: 'Build a booking app for a yoga studio: class schedule, book a spot (saved in a database), and an admin page listing bookings.',\n },\n];\n\nexport function webbuilderAgentSuggestions(hasBuild: boolean, siteTitle: string | null): AgentChatSuggestion[] {\n if (!hasBuild) return [...CHAT_STARTERS];\n const name = siteTitle ? ` on ${siteTitle}` : '';\n return [\n { id: 'mobile', label: 'Make it great on phones', prompt: `Make every page${name} look great on phones.` },\n { id: 'colors', label: 'New color scheme', prompt: 'Give the site a fresh, modern color scheme.' },\n { id: 'section', label: 'Add a section', prompt: 'Add a testimonials section above the footer.' },\n { id: 'fix', label: 'Fix what is broken', prompt: 'Check the site for errors and fix anything broken.' },\n ];\n}\n\ntype BuildRef = {\n title?: string;\n previewUrl: string | null;\n sandboxId: string | null;\n snapshotId?: string | null;\n};\n\n/**\n * Sent when the preview does not answer: the sandbox slept or was reclaimed (E2B
|
|
1
|
+
{"version":3,"file":"webbuilderPrompts.js","sources":["../../../src/features/webbuilder/webbuilderPrompts.ts"],"sourcesContent":["/**\n * Follow-ups for the Web Builder agent: the first asks of a site with nothing\n * built yet, and the edits people make most after a first build.\n */\nimport type { AgentChatSuggestion } from '../agent-chat';\n\n/**\n * Starter prompts in an empty chat (web `CHAT_STARTERS`, Lovable): complete briefs\n * that build on one tap - specific enough that the agent asks nothing.\n */\nexport const CHAT_STARTERS: readonly AgentChatSuggestion[] = [\n {\n id: 'cafe',\n label: 'Café website with menu',\n prompt: 'Build a website for a neighbourhood specialty coffee shop: hero, menu with prices, opening hours, location map and an Instagram-style gallery. Warm, modern look.',\n },\n {\n id: 'saas',\n label: 'SaaS landing page',\n prompt: 'Build a landing page for a project-management SaaS: hero with product screenshot, features, pricing (3 tiers), testimonials, FAQ and a sign-up call to action.',\n },\n {\n id: 'portfolio',\n label: 'Photographer portfolio',\n prompt: 'Build a portfolio for a wedding photographer: full-bleed gallery, about, packages with prices, and a contact form for booking enquiries. Elegant, minimal.',\n },\n {\n id: 'booking',\n label: 'Booking app with database',\n prompt: 'Build a booking app for a yoga studio: class schedule, book a spot (saved in a database), and an admin page listing bookings.',\n },\n];\n\nexport function webbuilderAgentSuggestions(hasBuild: boolean, siteTitle: string | null): AgentChatSuggestion[] {\n if (!hasBuild) return [...CHAT_STARTERS];\n const name = siteTitle ? ` on ${siteTitle}` : '';\n return [\n { id: 'mobile', label: 'Make it great on phones', prompt: `Make every page${name} look great on phones.` },\n { id: 'colors', label: 'New color scheme', prompt: 'Give the site a fresh, modern color scheme.' },\n { id: 'section', label: 'Add a section', prompt: 'Add a testimonials section above the footer.' },\n { id: 'fix', label: 'Fix what is broken', prompt: 'Check the site for errors and fix anything broken.' },\n ];\n}\n\ntype BuildRef = {\n title?: string;\n previewUrl: string | null;\n sandboxId: string | null;\n snapshotId?: string | null;\n};\n\n/**\n * Sent when the preview does not answer and the app could not bring it back\n * itself: the sandbox slept or was reclaimed (E2B sandboxes live about an hour\n * after the last change). The words are the web's (#428); the host's\n * `[Open build]` note names this build's sandbox and restore point, so the agent\n * reopens THIS site, booting the snapshot when the sandbox is gone.\n */\nexport function wakePreviewPrompt(): string {\n return 'Open a live preview of my latest build.';\n}\n\n/**\n * The note a change to an agent-chat build carries (web `agentEditForChat`): the\n * site lives in the agent's sandbox, so the change goes to that sandbox - never a\n * new one - with the restore point for when it expired.\n */\nexport function agentEditNote(build: BuildRef): string {\n return `[Open build] The user is looking at the live preview of \"${build.title || 'this site'}\" that you built${\n build.sandboxId ? ` (sandbox ${build.sandboxId}${build.previewUrl ? `, ${build.previewUrl}` : ''})` : ''\n }. Apply their request to that site in that sandbox - do not start a new one - and reply with the preview link.${\n build.snapshotId\n ? ` If that sandbox is gone, boot from its latest restore point (snapshotId ${build.snapshotId}).`\n : ''\n }`;\n}\n\n/** What Publish asks the agent for an agent-chat build (web `agentPublishMessage`). */\nexport function agentPublishMessage(build: BuildRef, projectName: string, customDomain?: string): string {\n return `Publish \"${build.title || 'this site'}\" as ${projectName}${customDomain ? ` on ${customDomain}` : ''}.`;\n}\n"],"names":[],"mappings":"AAUO,MAAM,gBAAgD,CAAC;AAAA,EAC5D,EAAI,EAAA,MAAA;AAAA,EACJ,KAAO,EAAA,2BAAA;AAAA,EACP,MAAQ,EAAA;AACV,CAAG,EAAA;AAAA,EACD,EAAI,EAAA,MAAA;AAAA,EACJ,KAAO,EAAA,mBAAA;AAAA,EACP,MAAQ,EAAA;AACV,CAAG,EAAA;AAAA,EACD,EAAI,EAAA,WAAA;AAAA,EACJ,KAAO,EAAA,wBAAA;AAAA,EACP,MAAQ,EAAA;AACV,CAAG,EAAA;AAAA,EACD,EAAI,EAAA,SAAA;AAAA,EACJ,KAAO,EAAA,2BAAA;AAAA,EACP,MAAQ,EAAA;AACV,CAAC;AACe,SAAA,0BAAA,CAA2B,UAAmB,SAAiD,EAAA;AAC7G,EAAA,IAAI,CAAC,QAAA,EAAiB,OAAA,CAAC,GAAG,aAAa,CAAA;AACvC,EAAA,MAAM,IAAO,GAAA,SAAA,GAAY,CAAO,IAAA,EAAA,SAAS,CAAK,CAAA,GAAA,EAAA;AAC9C,EAAA,OAAO,CAAC;AAAA,IACN,EAAI,EAAA,QAAA;AAAA,IACJ,KAAO,EAAA,yBAAA;AAAA,IACP,MAAA,EAAQ,kBAAkB,IAAI,CAAA,sBAAA;AAAA,GAC7B,EAAA;AAAA,IACD,EAAI,EAAA,QAAA;AAAA,IACJ,KAAO,EAAA,kBAAA;AAAA,IACP,MAAQ,EAAA;AAAA,GACP,EAAA;AAAA,IACD,EAAI,EAAA,SAAA;AAAA,IACJ,KAAO,EAAA,eAAA;AAAA,IACP,MAAQ,EAAA;AAAA,GACP,EAAA;AAAA,IACD,EAAI,EAAA,KAAA;AAAA,IACJ,KAAO,EAAA,oBAAA;AAAA,IACP,MAAQ,EAAA;AAAA,GACT,CAAA;AACH;AAeO,SAAS,iBAA4B,GAAA;AAC1C,EAAO,OAAA,yCAAA;AACT;AAOO,SAAS,cAAc,KAAyB,EAAA;AACrD,EAAO,OAAA,CAAA,yDAAA,EAA4D,KAAM,CAAA,KAAA,IAAS,WAAW,CAAA,gBAAA,EAAmB,KAAM,CAAA,SAAA,GAAY,CAAa,UAAA,EAAA,KAAA,CAAM,SAAS,CAAA,EAAG,KAAM,CAAA,UAAA,GAAa,CAAK,EAAA,EAAA,KAAA,CAAM,UAAU,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,8GAAA,EAAiH,KAAM,CAAA,UAAA,GAAa,CAA4E,yEAAA,EAAA,KAAA,CAAM,UAAU,CAAA,EAAA,CAAA,GAAO,EAAE,CAAA,CAAA;AACnc;AAGgB,SAAA,mBAAA,CAAoB,KAAiB,EAAA,WAAA,EAAqB,YAA+B,EAAA;AACvG,EAAO,OAAA,CAAA,SAAA,EAAY,KAAM,CAAA,KAAA,IAAS,WAAW,CAAA,KAAA,EAAQ,WAAW,CAAA,EAA0C,EAAE,CAAA,CAAA,CAAA;AAC9G"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {useRef,useCallback,useMemo}from'react';import {useApolloClient,gql}from'@apollo/client/index.js';import {OUTDATED_SERVER_RE,proxyResult}from'./webbuilderTransport.js';const SANDBOX_ACTION_MUTATION = gql`
|
|
2
|
+
mutation aiCodeSandboxAction($channelId: String!, $sandboxId: String!, $action: String!, $params: JSON) {
|
|
3
|
+
aiCodeSandboxAction(channelId: $channelId, sandboxId: $sandboxId, action: $action, params: $params)
|
|
4
|
+
}
|
|
5
|
+
`;
|
|
6
|
+
const PERSIST_SANDBOX_MUTATION = gql`
|
|
7
|
+
mutation aiCodePersistSandboxIdentity(
|
|
8
|
+
$channelId: String!
|
|
9
|
+
$sandboxId: String!
|
|
10
|
+
$sandboxUrl: String
|
|
11
|
+
$snapshotId: String
|
|
12
|
+
$previousSandboxId: String
|
|
13
|
+
) {
|
|
14
|
+
aiCodePersistSandboxIdentity(
|
|
15
|
+
channelId: $channelId
|
|
16
|
+
sandboxId: $sandboxId
|
|
17
|
+
sandboxUrl: $sandboxUrl
|
|
18
|
+
snapshotId: $snapshotId
|
|
19
|
+
previousSandboxId: $previousSandboxId
|
|
20
|
+
) {
|
|
21
|
+
success
|
|
22
|
+
message
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
function messageOf(err) {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
const e = err;
|
|
29
|
+
return ((_b = (_a = e == null ? void 0 : e.graphQLErrors) == null ? void 0 : _a.find((g) => g == null ? void 0 : g.message)) == null ? void 0 : _b.message) || (e == null ? void 0 : e.message) || String(err);
|
|
30
|
+
}
|
|
31
|
+
function useSandboxProxyApi() {
|
|
32
|
+
const client = useApolloClient();
|
|
33
|
+
const proxyMissing = useRef(false);
|
|
34
|
+
const proxy = useCallback(async (variables, timeoutMs) => {
|
|
35
|
+
var _a, _b, _c;
|
|
36
|
+
const controller = new AbortController();
|
|
37
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs + 3e4);
|
|
38
|
+
try {
|
|
39
|
+
const result = await client.mutate({
|
|
40
|
+
mutation: SANDBOX_ACTION_MUTATION,
|
|
41
|
+
variables,
|
|
42
|
+
fetchPolicy: "no-cache",
|
|
43
|
+
errorPolicy: "all",
|
|
44
|
+
context: {
|
|
45
|
+
fetchOptions: {
|
|
46
|
+
signal: controller.signal
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const first = (_b = (_a = result.errors) == null ? void 0 : _a.find((e) => e == null ? void 0 : e.message)) == null ? void 0 : _b.message;
|
|
51
|
+
if (first) {
|
|
52
|
+
if (OUTDATED_SERVER_RE.test(first)) return {
|
|
53
|
+
outdated: true
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
outdated: false,
|
|
57
|
+
result: {
|
|
58
|
+
successful: false,
|
|
59
|
+
error: first
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
outdated: false,
|
|
65
|
+
result: proxyResult((_c = result.data) == null ? void 0 : _c.aiCodeSandboxAction)
|
|
66
|
+
};
|
|
67
|
+
} catch (err) {
|
|
68
|
+
const message = messageOf(err);
|
|
69
|
+
if (OUTDATED_SERVER_RE.test(message)) return {
|
|
70
|
+
outdated: true
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
outdated: false,
|
|
74
|
+
result: {
|
|
75
|
+
successful: false,
|
|
76
|
+
error: message
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
} finally {
|
|
80
|
+
clearTimeout(timer);
|
|
81
|
+
}
|
|
82
|
+
}, [client]);
|
|
83
|
+
const persist = useCallback(async (input) => {
|
|
84
|
+
var _a, _b, _c;
|
|
85
|
+
try {
|
|
86
|
+
const result = await client.mutate({
|
|
87
|
+
mutation: PERSIST_SANDBOX_MUTATION,
|
|
88
|
+
variables: {
|
|
89
|
+
channelId: input.channelId,
|
|
90
|
+
sandboxId: input.sandboxId,
|
|
91
|
+
sandboxUrl: input.sandboxUrl || void 0,
|
|
92
|
+
snapshotId: input.snapshotId || void 0,
|
|
93
|
+
previousSandboxId: input.previousSandboxId || void 0
|
|
94
|
+
},
|
|
95
|
+
fetchPolicy: "no-cache",
|
|
96
|
+
errorPolicy: "all"
|
|
97
|
+
});
|
|
98
|
+
const first = (_b = (_a = result.errors) == null ? void 0 : _a.find((e) => e == null ? void 0 : e.message)) == null ? void 0 : _b.message;
|
|
99
|
+
if (first) return {
|
|
100
|
+
ok: false,
|
|
101
|
+
message: first
|
|
102
|
+
};
|
|
103
|
+
const payload = (_c = result.data) == null ? void 0 : _c.aiCodePersistSandboxIdentity;
|
|
104
|
+
return {
|
|
105
|
+
ok: (payload == null ? void 0 : payload.success) !== false,
|
|
106
|
+
message: payload == null ? void 0 : payload.message
|
|
107
|
+
};
|
|
108
|
+
} catch (err) {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
message: messageOf(err)
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}, [client]);
|
|
115
|
+
return useMemo(() => ({
|
|
116
|
+
proxy,
|
|
117
|
+
persist,
|
|
118
|
+
proxyMissing
|
|
119
|
+
}), [proxy, persist]);
|
|
120
|
+
}export{useSandboxProxyApi};//# sourceMappingURL=sandboxProxyApi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandboxProxyApi.js","sources":["../../../src/screens/WebBuilderNative/sandboxProxyApi.ts"],"sourcesContent":["/**\n * The two backend fields a preview restore goes through (web `sandbox/sandboxProxy.ts`,\n * `previewDeployApi.persistSandboxIdentity`), on the app's Apollo client - the\n * backend that owns the build channels:\n *\n * - `aiCodeSandboxAction`: one connector action on a project's sandbox. The server\n * adds the sandbox key from the channel's settings (an agent build's too), so\n * the app never holds a key; a CREATE through it records the new sandbox.\n * - `aiCodePersistSandboxIdentity`: the new sandbox (and its preview) after a\n * restore, so the web and other devices open it instead of the expired one.\n *\n * Neither has a generated hook in `common/graphql`, so the documents live here.\n */\nimport { useCallback, useMemo, useRef } from 'react';\nimport { gql, useApolloClient } from '@apollo/client';\nimport { OUTDATED_SERVER_RE, proxyResult, type SandboxProxyCall } from './webbuilderTransport';\n\nconst SANDBOX_ACTION_MUTATION = gql`\n mutation aiCodeSandboxAction($channelId: String!, $sandboxId: String!, $action: String!, $params: JSON) {\n aiCodeSandboxAction(channelId: $channelId, sandboxId: $sandboxId, action: $action, params: $params)\n }\n`;\n\nconst PERSIST_SANDBOX_MUTATION = gql`\n mutation aiCodePersistSandboxIdentity(\n $channelId: String!\n $sandboxId: String!\n $sandboxUrl: String\n $snapshotId: String\n $previousSandboxId: String\n ) {\n aiCodePersistSandboxIdentity(\n channelId: $channelId\n sandboxId: $sandboxId\n sandboxUrl: $sandboxUrl\n snapshotId: $snapshotId\n previousSandboxId: $previousSandboxId\n ) {\n success\n message\n }\n }\n`;\n\nfunction messageOf(err: unknown): string {\n const e = err as { graphQLErrors?: Array<{ message?: string }>; message?: string } | null;\n return e?.graphQLErrors?.find((g) => g?.message)?.message || e?.message || String(err);\n}\n\nexport interface PersistSandboxInput {\n channelId: string;\n sandboxId: string;\n sandboxUrl?: string | null;\n snapshotId?: string | null;\n previousSandboxId?: string | null;\n}\n\nexport function useSandboxProxyApi() {\n const client = useApolloClient();\n /** Set once a server answers without the proxy: the session stays direct (web router `missing`). */\n const proxyMissing = useRef(false);\n\n const proxy = useCallback<SandboxProxyCall>(\n async (variables, timeoutMs) => {\n const controller = new AbortController();\n // The proxy waits for the connector: allow its timeout plus a margin (web: +30 s).\n const timer = setTimeout(() => controller.abort(), timeoutMs + 30_000);\n try {\n const result = await client.mutate({\n mutation: SANDBOX_ACTION_MUTATION,\n variables,\n fetchPolicy: 'no-cache',\n errorPolicy: 'all',\n context: { fetchOptions: { signal: controller.signal } },\n });\n const first = result.errors?.find((e) => e?.message)?.message;\n if (first) {\n if (OUTDATED_SERVER_RE.test(first)) return { outdated: true };\n return { outdated: false, result: { successful: false, error: first } };\n }\n return {\n outdated: false,\n result: proxyResult((result.data as { aiCodeSandboxAction?: unknown } | null)?.aiCodeSandboxAction),\n };\n } catch (err) {\n const message = messageOf(err);\n if (OUTDATED_SERVER_RE.test(message)) return { outdated: true };\n return { outdated: false, result: { successful: false, error: message } };\n } finally {\n clearTimeout(timer);\n }\n },\n [client],\n );\n\n const persist = useCallback(\n async (input: PersistSandboxInput): Promise<{ ok: boolean; message?: string }> => {\n try {\n const result = await client.mutate({\n mutation: PERSIST_SANDBOX_MUTATION,\n variables: {\n channelId: input.channelId,\n sandboxId: input.sandboxId,\n sandboxUrl: input.sandboxUrl || undefined,\n snapshotId: input.snapshotId || undefined,\n previousSandboxId: input.previousSandboxId || undefined,\n },\n fetchPolicy: 'no-cache',\n errorPolicy: 'all',\n });\n const first = result.errors?.find((e) => e?.message)?.message;\n if (first) return { ok: false, message: first };\n const payload = (\n result.data as { aiCodePersistSandboxIdentity?: { success?: boolean; message?: string } } | null\n )?.aiCodePersistSandboxIdentity;\n return { ok: payload?.success !== false, message: payload?.message };\n } catch (err) {\n return { ok: false, message: messageOf(err) };\n }\n },\n [client],\n );\n\n return useMemo(() => ({ proxy, persist, proxyMissing }), [proxy, persist]);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRestoredSandboxes.js","sources":["../../../src/screens/WebBuilderNative/useRestoredSandboxes.ts"],"sourcesContent":["/**\n * The sandboxes a build's restore point was booted into on this device (web\n * `writeRestoredSandbox`/`readRestoredSandbox`). The chat's posts still name the\n * expired sandbox, and
|
|
1
|
+
{"version":3,"file":"useRestoredSandboxes.js","sources":["../../../src/screens/WebBuilderNative/useRestoredSandboxes.ts"],"sourcesContent":["/**\n * The sandboxes a build's restore point was booted into on this device (web\n * `writeRestoredSandbox`/`readRestoredSandbox`). The chat's posts still name the\n * expired sandbox, so the new id and preview are laid over the builds read from\n * them at once. The host also records the new sandbox on the project\n * (`aiCodePersistSandboxIdentity`) for the web and other devices; this copy\n * covers the moment until that lands and a server without it.\n */\nimport { useCallback, useEffect, useState } from 'react';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport type { WebBuilderBuild } from '../../features/webbuilder/types';\n\nconst STORAGE_KEY = 'yantra.webbuilder.restored.v1';\n/** Restored sandboxes expire too; older entries are not worth keeping. */\nconst MAX_ENTRIES = 50;\n\nexport interface RestoredSandbox {\n sandboxId: string;\n previewUrl: string;\n at: number;\n}\n\ntype RestoredMap = Record<string, RestoredSandbox>;\n\nexport function applyRestored(builds: WebBuilderBuild[], restored: RestoredMap): WebBuilderBuild[] {\n if (!Object.keys(restored).length) return builds;\n return builds.map((build) => {\n const next = restored[build.key];\n return next ? { ...build, sandboxId: next.sandboxId, previewUrl: next.previewUrl } : build;\n });\n}\n\nexport function useRestoredSandboxes() {\n const [restored, setRestored] = useState<RestoredMap>({});\n useEffect(() => {\n let alive = true;\n AsyncStorage.getItem(STORAGE_KEY)\n .then((raw) => {\n if (!alive || !raw) return;\n const parsed = JSON.parse(raw) as RestoredMap;\n if (parsed && typeof parsed === 'object') setRestored((cur) => ({ ...parsed, ...cur }));\n })\n .catch(() => undefined);\n return () => {\n alive = false;\n };\n }, []);\n\n const remember = useCallback((buildKey: string, sandboxId: string, previewUrl: string) => {\n setRestored((cur) => {\n const entries = Object.entries({ ...cur, [buildKey]: { sandboxId, previewUrl, at: Date.now() } })\n .sort((a, b) => b[1].at - a[1].at)\n .slice(0, MAX_ENTRIES);\n const next = Object.fromEntries(entries);\n AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(next)).catch(() => undefined);\n return next;\n });\n }, []);\n\n return { restored, remember };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAWA,MAAM,WAAc,GAAA,+BAAA;AAEpB,MAAM,WAAc,GAAA,EAAA;AAOJ,SAAA,aAAA,CAAc,QAA2B,QAA0C,EAAA;AACjG,EAAA,IAAI,CAAC,MAAO,CAAA,IAAA,CAAK,QAAQ,CAAA,CAAE,QAAe,OAAA,MAAA;AAC1C,EAAO,OAAA,MAAA,CAAO,IAAI,CAAS,KAAA,KAAA;AACzB,IAAM,MAAA,IAAA,GAAO,QAAS,CAAA,KAAA,CAAM,GAAG,CAAA;AAC/B,IAAO,OAAA,IAAA,GAAO,iCACT,KADS,CAAA,EAAA;AAAA,MAEZ,WAAW,IAAK,CAAA,SAAA;AAAA,MAChB,YAAY,IAAK,CAAA;AAAA,KACf,CAAA,GAAA,KAAA;AAAA,GACL,CAAA;AACH;AACO,SAAS,oBAAuB,GAAA;AACrC,EAAA,MAAM,CAAC,QAAU,EAAA,WAAW,CAAI,GAAA,QAAA,CAAsB,EAAE,CAAA;AACxD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAQ,GAAA,IAAA;AACZ,IAAA,YAAA,CAAa,OAAQ,CAAA,WAAW,CAAE,CAAA,IAAA,CAAK,CAAO,GAAA,KAAA;AAC5C,MAAI,IAAA,CAAC,KAAS,IAAA,CAAC,GAAK,EAAA;AACpB,MAAM,MAAA,MAAA,GAAS,IAAK,CAAA,KAAA,CAAM,GAAG,CAAA;AAC7B,MAAI,IAAA,MAAA,IAAU,OAAO,MAAW,KAAA,QAAA,cAAsB,CAAQ,GAAA,KAAA,cAAA,CAAA,cAAA,CAAA,EAAA,EACzD,SACA,GACH,CAAA,CAAA;AAAA,KACH,CAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AACxB,IAAA,OAAO,MAAM;AACX,MAAQ,KAAA,GAAA,KAAA;AAAA,KACV;AAAA,GACF,EAAG,EAAE,CAAA;AACL,EAAA,MAAM,QAAW,GAAA,WAAA,CAAY,CAAC,QAAA,EAAkB,WAAmB,UAAuB,KAAA;AACxF,IAAA,WAAA,CAAY,CAAO,GAAA,KAAA;AACjB,MAAA,MAAM,OAAU,GAAA,MAAA,CAAO,OAAQ,CAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EAC1B,GAD0B,CAAA,EAAA;AAAA,QAE7B,CAAC,QAAQ,GAAG;AAAA,UACV,SAAA;AAAA,UACA,UAAA;AAAA,UACA,EAAA,EAAI,KAAK,GAAI;AAAA;AACf,QACD,CAAE,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,MAAM,CAAE,CAAA,CAAC,CAAE,CAAA,EAAA,GAAK,EAAE,CAAC,CAAA,CAAE,EAAE,CAAE,CAAA,KAAA,CAAM,GAAG,WAAW,CAAA;AACzD,MAAM,MAAA,IAAA,GAAO,MAAO,CAAA,WAAA,CAAY,OAAO,CAAA;AACvC,MAAa,YAAA,CAAA,OAAA,CAAQ,aAAa,IAAK,CAAA,SAAA,CAAU,IAAI,CAAC,CAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AAC7E,MAAO,OAAA,IAAA;AAAA,KACR,CAAA;AAAA,GACH,EAAG,EAAE,CAAA;AACL,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA;AAAA,GACF;AACF"}
|