@agent-native/core 0.8.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +5 -4
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +6 -3
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +8 -17
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +28 -11
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +10 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +89 -7
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +4 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +6 -5
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +12 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +96 -0
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/cli/create.d.ts +9 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +29 -11
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +177 -22
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/workspace-dev.js +66 -5
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -20
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +146 -107
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +143 -22
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +3 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -0
- package/dist/client/agent-sidebar-state.js +24 -0
- package/dist/client/agent-sidebar-state.js.map +1 -0
- package/dist/client/analytics.d.ts +39 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +74 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/components/PresenceBar.d.ts.map +1 -1
- package/dist/client/components/PresenceBar.js +21 -15
- package/dist/client/components/PresenceBar.js.map +1 -1
- package/dist/client/components/ui/tooltip.d.ts +2 -1
- package/dist/client/components/ui/tooltip.d.ts.map +1 -1
- package/dist/client/components/ui/tooltip.js +9 -2
- package/dist/client/components/ui/tooltip.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +51 -17
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +30 -0
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +31 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +9 -8
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -1
- package/dist/client/dev-overlay/DevOverlay.js +4 -3
- package/dist/client/dev-overlay/DevOverlay.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +6 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +14 -3
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionEditor.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionEditor.js +6 -5
- package/dist/client/extensions/ExtensionEditor.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +2 -1
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +40 -19
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js +52 -51
- package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationCard.js +2 -1
- package/dist/client/integrations/IntegrationCard.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +3 -2
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +42 -6
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +3 -2
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -1
- package/dist/client/onboarding/SetupButton.js +14 -13
- package/dist/client/onboarding/SetupButton.js.map +1 -1
- package/dist/client/org/InvitationBanner.d.ts +8 -2
- package/dist/client/org/InvitationBanner.d.ts.map +1 -1
- package/dist/client/org/InvitationBanner.js +28 -7
- package/dist/client/org/InvitationBanner.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +29 -5
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +9 -7
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +2 -1
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +48 -14
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +2 -0
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
- package/dist/client/resources/use-mcp-servers.js +59 -3
- package/dist/client/resources/use-mcp-servers.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +8 -7
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
- package/dist/client/settings/AutomationsSection.js +4 -3
- package/dist/client/settings/AutomationsSection.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts.map +1 -1
- package/dist/client/settings/SecretsSection.js +11 -1
- package/dist/client/settings/SecretsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +15 -12
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js +13 -30
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/client/settings/index.d.ts +1 -1
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +27 -1
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +4 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +5 -1
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +59 -11
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +100 -19
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +14 -2
- package/dist/client/use-session.js.map +1 -1
- package/dist/collab/client.d.ts +1 -0
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +18 -1
- package/dist/collab/client.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +5 -0
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +1 -0
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/deploy/workspace-core.d.ts +1 -1
- package/dist/deploy/workspace-core.d.ts.map +1 -1
- package/dist/deploy/workspace-core.js +1 -0
- package/dist/deploy/workspace-core.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +17 -3
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/routes.js +1 -1
- package/dist/extensions/routes.js.map +1 -1
- package/dist/extensions/schema.d.ts +14 -14
- package/dist/extensions/schema.d.ts.map +1 -1
- package/dist/extensions/schema.js +4 -4
- package/dist/extensions/schema.js.map +1 -1
- package/dist/extensions/store.d.ts.map +1 -1
- package/dist/extensions/store.js +23 -0
- package/dist/extensions/store.js.map +1 -1
- package/dist/extensions/theme.d.ts +8 -1
- package/dist/extensions/theme.d.ts.map +1 -1
- package/dist/extensions/theme.js +43 -34
- package/dist/extensions/theme.js.map +1 -1
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +28 -1
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/org/auto-join-domain.d.ts +28 -0
- package/dist/org/auto-join-domain.d.ts.map +1 -0
- package/dist/org/auto-join-domain.js +92 -0
- package/dist/org/auto-join-domain.js.map +1 -0
- package/dist/org/index.d.ts +2 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +27 -1
- package/dist/scripts/db/exec.js.map +1 -1
- package/dist/scripts/db/index.d.ts.map +1 -1
- package/dist/scripts/db/index.js +1 -0
- package/dist/scripts/db/index.js.map +1 -1
- package/dist/scripts/db/reset-dev-owner.d.ts +27 -0
- package/dist/scripts/db/reset-dev-owner.d.ts.map +1 -0
- package/dist/scripts/db/reset-dev-owner.js +225 -0
- package/dist/scripts/db/reset-dev-owner.js.map +1 -0
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +15 -30
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/dev-session.d.ts +46 -0
- package/dist/scripts/dev-session.d.ts.map +1 -0
- package/dist/scripts/dev-session.js +81 -0
- package/dist/scripts/dev-session.js.map +1 -0
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +21 -0
- package/dist/scripts/runner.js.map +1 -1
- package/dist/secrets/register.d.ts +1 -1
- package/dist/secrets/register.d.ts.map +1 -1
- package/dist/secrets/register.js +4 -2
- package/dist/secrets/register.js.map +1 -1
- package/dist/secrets/routes.d.ts.map +1 -1
- package/dist/secrets/routes.js +32 -0
- package/dist/secrets/routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +77 -102
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +33 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +11 -0
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +169 -68
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +56 -13
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +49 -6
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +133 -38
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/design-token-utils.d.ts +13 -2
- package/dist/server/design-token-utils.d.ts.map +1 -1
- package/dist/server/design-token-utils.js +48 -16
- package/dist/server/design-token-utils.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +31 -0
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-realtime-session.d.ts.map +1 -1
- package/dist/server/google-realtime-session.js +19 -6
- package/dist/server/google-realtime-session.js.map +1 -1
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +142 -14
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/request-context.d.ts +17 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +40 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/sentry-plugin.d.ts +11 -0
- package/dist/server/sentry-plugin.d.ts.map +1 -0
- package/dist/server/sentry-plugin.js +116 -0
- package/dist/server/sentry-plugin.js.map +1 -0
- package/dist/server/sentry.d.ts +92 -0
- package/dist/server/sentry.d.ts.map +1 -0
- package/dist/server/sentry.js +287 -0
- package/dist/server/sentry.js.map +1 -0
- package/dist/server/transcribe-voice.d.ts +2 -4
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +4 -16
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts.map +1 -1
- package/dist/server/voice-providers-status.js +19 -35
- package/dist/server/voice-providers-status.js.map +1 -1
- package/dist/styles/agent-native.css +15 -0
- package/docs/content/cloneable-saas.md +7 -9
- package/docs/content/deployment.md +6 -2
- package/docs/content/dispatch.md +1 -1
- package/docs/content/extensions.md +177 -142
- package/docs/content/faq.md +2 -2
- package/docs/content/getting-started.md +13 -11
- package/docs/content/multi-app-workspace.md +2 -2
- package/docs/content/observability.md +47 -0
- package/docs/content/pure-agent-apps.md +1 -1
- package/docs/content/template-clips.md +3 -3
- package/docs/content/template-design.md +3 -3
- package/docs/content/template-dispatch.md +1 -1
- package/docs/content/template-forms.md +1 -1
- package/docs/content/template-mail.md +1 -1
- package/docs/content/what-is-agent-native.md +4 -4
- package/docs/content/workspace.md +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceButton.js","sourceRoot":"","sources":["../../../src/client/composer/VoiceButton.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Voice dictation button + recording overlay for the agent composer.\n *\n * UX mirrors Lovable: click-to-toggle record, a live amplitude bar and\n * MM:SS timer replace the editor area while recording, and a cancel X\n * discards without transcribing. The mic is always visible alongside the\n * send button (Cursor replaces send with mic; their users complain — we\n * don't copy that).\n */\n\nimport React from \"react\";\nimport {\n IconMicrophone,\n IconPlayerStopFilled,\n IconLoader2,\n IconX,\n} from \"@tabler/icons-react\";\nimport type { VoiceDictationApi } from \"./useVoiceDictation.js\";\n\nexport interface VoiceButtonProps {\n voice: VoiceDictationApi;\n isMac: boolean;\n disabled?: boolean;\n}\n\nexport function VoiceButton({ voice, isMac, disabled }: VoiceButtonProps) {\n const { state, start, stop, supported } = voice;\n\n if (!supported) return null;\n\n const recording = state === \"recording\" || state === \"starting\";\n const transcribing = state === \"transcribing\";\n\n const label = recording\n ? \"Stop recording\"\n : transcribing\n ? \"Transcribing…\"\n : `Dictate (${isMac ? \"⌘⇧M\" : \"Ctrl+Shift+M\"})`;\n\n const onClick = () => {\n if (recording) stop();\n else if (!transcribing) void start();\n };\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled || transcribing}\n title={label}\n aria-label={label}\n aria-pressed={recording}\n className={`shrink-0 flex h-7 w-7 items-center justify-center rounded-md disabled:opacity-30 disabled:cursor-not-allowed ${\n recording\n ? \"text-[#625DF5] bg-[#625DF5]/10 hover:bg-[#625DF5]/20\"\n : \"text-muted-foreground hover:text-foreground hover:bg-accent/50\"\n }`}\n >\n {transcribing ? (\n <IconLoader2 className=\"h-4 w-4 animate-spin\" />\n ) : recording ? (\n <IconPlayerStopFilled className=\"h-3.5 w-3.5\" />\n ) : (\n <IconMicrophone className=\"h-4 w-4\" />\n )}\n </button>\n );\n}\n\nexport interface VoiceRecordingOverlayProps {\n voice: VoiceDictationApi;\n}\n\nexport function VoiceRecordingOverlay({ voice }: VoiceRecordingOverlayProps) {\n const { state, amplitude, durationMs, errorMessage, cancel } = voice;\n const { dismissError, start } = voice;\n\n if (state === \"error\" && errorMessage) {\n return (\n <div\n role=\"alert\"\n className=\"mx-2 mt-1 flex items-start gap-2 rounded-md border border-red-500/40 bg-red-500/10 px-2 py-1.5 text-[11px] text-red-500\"\n >\n <span className=\"flex-1 min-w-0\">{errorMessage}</span>\n <button\n type=\"button\"\n onClick={() => {\n dismissError();\n void start();\n }}\n className=\"shrink-0 cursor-pointer rounded px-1.5 py-0.5 text-[11px] font-medium text-red-500 hover:bg-red-500/20\"\n title=\"Try again\"\n aria-label=\"Try again\"\n >\n Try again\n </button>\n <button\n type=\"button\"\n onClick={dismissError}\n className=\"shrink-0 flex h-4 w-4 cursor-pointer items-center justify-center rounded text-red-500 hover:bg-red-500/20\"\n title=\"Dismiss\"\n aria-label=\"Dismiss\"\n >\n <IconX className=\"h-3 w-3\" />\n </button>\n </div>\n );\n }\n\n if (state !== \"recording\" && state !== \"starting\" && state !== \"transcribing\")\n return null;\n\n return (\n <div\n className=\"flex items-center gap-2 mx-2 mt-2 mb-1 h-[2rem] rounded-md border border-[#625DF5]/40 bg-[#625DF5]/10 px-2\"\n aria-live=\"polite\"\n >\n <button\n type=\"button\"\n onClick={cancel}\n className=\"shrink-0 flex h-5 w-5 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n title=\"Cancel (Esc)\"\n aria-label=\"Cancel recording\"\n >\n <IconX className=\"h-3 w-3\" />\n </button>\n\n <div className=\"flex-1 flex items-center gap-[2px] min-w-0 h-4\">\n {state === \"transcribing\" ? (\n <span className=\"text-[11px] text-muted-foreground\">\n Transcribing…\n </span>\n ) : (\n <AmplitudeBars amplitude={amplitude} />\n )}\n </div>\n\n <span className=\"shrink-0 text-[11px] font-medium tabular-nums text-muted-foreground\">\n {state === \"transcribing\" ? (\n <IconLoader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n formatDuration(durationMs)\n )}\n </span>\n </div>\n );\n}\n\nconst BAR_COUNT = 24;\n\nfunction AmplitudeBars({ amplitude }: { amplitude: number }) {\n // Render a symmetric meter — the middle bars peak first so the visual\n // matches what voice input looks like in Lovable / iOS dictation.\n const bars = [];\n for (let i = 0; i < BAR_COUNT; i++) {\n const centerDistance =\n Math.abs(i - (BAR_COUNT - 1) / 2) / ((BAR_COUNT - 1) / 2);\n const heightPct =\n Math.max(0.1, amplitude * (1 - centerDistance * 0.6)) * 100;\n bars.push(\n <span\n key={i}\n className=\"flex-1 rounded-full bg-[#625DF5]\"\n style={{ height: `${heightPct}%`, minHeight: 2 }}\n />,\n );\n }\n return <>{bars}</>;\n}\n\nfunction formatDuration(ms: number): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"VoiceButton.js","sourceRoot":"","sources":["../../../src/client/composer/VoiceButton.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Voice dictation button + recording overlay for the agent composer.\n *\n * UX mirrors Lovable: click-to-toggle record, a live amplitude bar and\n * MM:SS timer replace the editor area while recording, and a cancel X\n * discards without transcribing. The mic is always visible alongside the\n * send button (Cursor replaces send with mic; their users complain — we\n * don't copy that).\n */\n\nimport React from \"react\";\nimport {\n IconMicrophone,\n IconPlayerStopFilled,\n IconLoader2,\n IconX,\n} from \"@tabler/icons-react\";\nimport type { VoiceDictationApi } from \"./useVoiceDictation.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\nexport interface VoiceButtonProps {\n voice: VoiceDictationApi;\n isMac: boolean;\n disabled?: boolean;\n}\n\nexport function VoiceButton({ voice, isMac, disabled }: VoiceButtonProps) {\n const { state, start, stop, supported } = voice;\n\n if (!supported) return null;\n\n const recording = state === \"recording\" || state === \"starting\";\n const transcribing = state === \"transcribing\";\n\n const label = recording\n ? \"Stop recording\"\n : transcribing\n ? \"Transcribing…\"\n : `Dictate (${isMac ? \"⌘⇧M\" : \"Ctrl+Shift+M\"})`;\n\n const onClick = () => {\n if (recording) stop();\n else if (!transcribing) void start();\n };\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled || transcribing}\n aria-label={label}\n aria-pressed={recording}\n className={`shrink-0 flex h-7 w-7 items-center justify-center rounded-md disabled:opacity-30 disabled:cursor-not-allowed ${\n recording\n ? \"text-[#625DF5] bg-[#625DF5]/10 hover:bg-[#625DF5]/20\"\n : \"text-muted-foreground hover:text-foreground hover:bg-accent/50\"\n }`}\n >\n {transcribing ? (\n <IconLoader2 className=\"h-4 w-4 animate-spin\" />\n ) : recording ? (\n <IconPlayerStopFilled className=\"h-3.5 w-3.5\" />\n ) : (\n <IconMicrophone className=\"h-4 w-4\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent>{label}</TooltipContent>\n </Tooltip>\n );\n}\n\nexport interface VoiceRecordingOverlayProps {\n voice: VoiceDictationApi;\n}\n\nexport function VoiceRecordingOverlay({ voice }: VoiceRecordingOverlayProps) {\n const { state, amplitude, durationMs, errorMessage, cancel } = voice;\n const { dismissError, start } = voice;\n\n if (state === \"error\" && errorMessage) {\n return (\n <div\n role=\"alert\"\n className=\"mx-2 mt-1 flex items-start gap-2 rounded-md border border-red-500/40 bg-red-500/10 px-2 py-1.5 text-[11px] text-red-500\"\n >\n <span className=\"flex-1 min-w-0\">{errorMessage}</span>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => {\n dismissError();\n void start();\n }}\n className=\"shrink-0 cursor-pointer rounded px-1.5 py-0.5 text-[11px] font-medium text-red-500 hover:bg-red-500/20\"\n aria-label=\"Try again\"\n >\n Try again\n </button>\n </TooltipTrigger>\n <TooltipContent>Try again</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={dismissError}\n className=\"shrink-0 flex h-4 w-4 cursor-pointer items-center justify-center rounded text-red-500 hover:bg-red-500/20\"\n aria-label=\"Dismiss\"\n >\n <IconX className=\"h-3 w-3\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Dismiss</TooltipContent>\n </Tooltip>\n </div>\n );\n }\n\n if (state !== \"recording\" && state !== \"starting\" && state !== \"transcribing\")\n return null;\n\n return (\n <div\n className=\"flex items-center gap-2 mx-2 mt-2 mb-1 h-[2rem] rounded-md border border-[#625DF5]/40 bg-[#625DF5]/10 px-2\"\n aria-live=\"polite\"\n >\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={cancel}\n className=\"shrink-0 flex h-5 w-5 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n aria-label=\"Cancel recording\"\n >\n <IconX className=\"h-3 w-3\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Cancel (Esc)</TooltipContent>\n </Tooltip>\n\n <div className=\"flex-1 flex items-center gap-[2px] min-w-0 h-4\">\n {state === \"transcribing\" ? (\n <span className=\"text-[11px] text-muted-foreground\">\n Transcribing…\n </span>\n ) : (\n <AmplitudeBars amplitude={amplitude} />\n )}\n </div>\n\n <span className=\"shrink-0 text-[11px] font-medium tabular-nums text-muted-foreground\">\n {state === \"transcribing\" ? (\n <IconLoader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n formatDuration(durationMs)\n )}\n </span>\n </div>\n );\n}\n\nconst BAR_COUNT = 24;\n\nfunction AmplitudeBars({ amplitude }: { amplitude: number }) {\n // Render a symmetric meter — the middle bars peak first so the visual\n // matches what voice input looks like in Lovable / iOS dictation.\n const bars = [];\n for (let i = 0; i < BAR_COUNT; i++) {\n const centerDistance =\n Math.abs(i - (BAR_COUNT - 1) / 2) / ((BAR_COUNT - 1) / 2);\n const heightPct =\n Math.max(0.1, amplitude * (1 - centerDistance * 0.6)) * 100;\n bars.push(\n <span\n key={i}\n className=\"flex-1 rounded-full bg-[#625DF5]\"\n style={{ height: `${heightPct}%`, minHeight: 2 }}\n />,\n );\n }\n return <>{bars}</>;\n}\n\nfunction formatDuration(ms: number): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DevOverlay.d.ts","sourceRoot":"","sources":["../../../src/client/dev-overlay/DevOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAwBf,OAAO,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"DevOverlay.d.ts","sourceRoot":"","sources":["../../../src/client/dev-overlay/DevOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAwBf,OAAO,eAAe,CAAC;AAWvB,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAE,eAAoB,2CAqCtE;AA6dD,YAAY,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -18,6 +18,7 @@ import { listDevPanels, subscribeDevPanels } from "./registry.js";
|
|
|
18
18
|
import { clearAllDevOverlayStorage, useDevOption, DEV_OVERLAY_STORAGE_PREFIX, } from "./use-dev-option.js";
|
|
19
19
|
import { useDevOverlayShortcut } from "./use-dev-overlay-shortcut.js";
|
|
20
20
|
import "./builtins.js";
|
|
21
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
21
22
|
const PANEL_OPEN_KEY = `${DEV_OVERLAY_STORAGE_PREFIX}open`;
|
|
22
23
|
const COLLAPSED_KEY_PREFIX = `${DEV_OVERLAY_STORAGE_PREFIX}collapsed-`;
|
|
23
24
|
export function DevOverlay({ open, onOpenChange } = {}) {
|
|
@@ -55,9 +56,9 @@ export function DevOverlay({ open, onOpenChange } = {}) {
|
|
|
55
56
|
}
|
|
56
57
|
function DevOverlayPanel({ onClose }) {
|
|
57
58
|
const panels = useSyncExternalStore(subscribeDevPanels, listDevPanels, listDevPanels);
|
|
58
|
-
return (_jsxs("div", { style: styles.shell, role: "dialog", "aria-label": "Dev overlay", children: [_jsxs("div", { style: styles.header, children: [_jsxs("div", { children: [_jsx("div", { style: styles.headerTitle, children: "Dev Overlay" }), _jsx("div", { style: styles.headerSub, children: "Cmd+Ctrl+A \u00B7 localStorage-backed" })] }), _jsx("button", { type: "button", style: styles.iconBtn, onClick: onClose, "aria-label": "Close",
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
return (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs("div", { style: styles.shell, role: "dialog", "aria-label": "Dev overlay", children: [_jsxs("div", { style: styles.header, children: [_jsxs("div", { children: [_jsx("div", { style: styles.headerTitle, children: "Dev Overlay" }), _jsx("div", { style: styles.headerSub, children: "Cmd+Ctrl+A \u00B7 localStorage-backed" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", style: styles.iconBtn, onClick: onClose, "aria-label": "Close", children: _jsx(IconX, { size: 16 }) }) }), _jsx(TooltipContent, { children: "Close (Esc)" })] })] }), _jsx("div", { style: styles.body, children: panels.length === 0 ? (_jsxs("div", { style: styles.empty, children: ["No panels registered. Call ", _jsx("code", { children: "registerDevPanel(...)" }), " from your template to add options here."] })) : (panels.map((panel) => _jsx(DevPanelCard, { panel: panel }, panel.id))) }), _jsx("div", { style: styles.footer, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", style: { ...styles.footerBtn, ...styles.footerBtnDanger }, onClick: () => {
|
|
60
|
+
clearAllDevOverlayStorage();
|
|
61
|
+
}, children: [_jsx(IconTrash, { size: 13 }), "Clear all dev-overlay values"] }) }), _jsx(TooltipContent, { children: "Reset every dev-overlay value back to its default" })] }) })] }) }));
|
|
61
62
|
}
|
|
62
63
|
function DevPanelCard({ panel }) {
|
|
63
64
|
const [collapsedRaw, setCollapsedRaw] = useState(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DevOverlay.js","sourceRoot":"","sources":["../../../src/client/dev-overlay/DevOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <DevOverlay /> — the framework dev/configuration panel.\n *\n * Templates render this once at the root of their app. The user toggles it\n * with Cmd+Ctrl+A (also exposed as `useDevOverlayShortcut`). Panels register\n * via `registerDevPanel`; values for option-style controls persist to\n * localStorage via `useDevOption`.\n *\n * Visibility note: the overlay only mounts when the host explicitly opens it\n * via the keybinding (or the `open` prop). It is dev-only by convention —\n * shipping with the keybinding active in prod is fine because nothing renders\n * unless invoked.\n */\n\nimport {\n useCallback,\n useEffect,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport {\n IconChevronDown,\n IconChevronRight,\n IconLoader2,\n IconRefresh,\n IconTrash,\n IconX,\n} from \"@tabler/icons-react\";\nimport { listDevPanels, subscribeDevPanels } from \"./registry.js\";\nimport {\n clearAllDevOverlayStorage,\n useDevOption,\n DEV_OVERLAY_STORAGE_PREFIX,\n} from \"./use-dev-option.js\";\nimport { useDevOverlayShortcut } from \"./use-dev-overlay-shortcut.js\";\nimport type {\n DevActionOption,\n DevBooleanOption,\n DevOption,\n DevPanel,\n DevSelectOption,\n DevStringOption,\n} from \"./types.js\";\nimport \"./builtins.js\";\n\nconst PANEL_OPEN_KEY = `${DEV_OVERLAY_STORAGE_PREFIX}open`;\nconst COLLAPSED_KEY_PREFIX = `${DEV_OVERLAY_STORAGE_PREFIX}collapsed-`;\n\nexport interface DevOverlayProps {\n /**\n * Force-control the overlay's visibility. When omitted the overlay manages\n * its own state and listens to Cmd+Ctrl+A.\n */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function DevOverlay({ open, onOpenChange }: DevOverlayProps = {}) {\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = open !== undefined;\n const isOpen = isControlled ? open : internalOpen;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange],\n );\n\n useDevOverlayShortcut(useCallback(() => setOpen(!isOpen), [isOpen, setOpen]));\n\n // Esc closes (only when overlay is the topmost UI — skip when typing).\n useEffect(() => {\n if (!isOpen) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\") return;\n const target = e.target as HTMLElement | null;\n if (\n target &&\n (target.tagName === \"INPUT\" ||\n target.tagName === \"TEXTAREA\" ||\n target.isContentEditable)\n ) {\n return;\n }\n setOpen(false);\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [isOpen, setOpen]);\n\n if (!isOpen) return null;\n return <DevOverlayPanel onClose={() => setOpen(false)} />;\n}\n\nfunction DevOverlayPanel({ onClose }: { onClose: () => void }) {\n const panels = useSyncExternalStore(\n subscribeDevPanels,\n listDevPanels,\n listDevPanels,\n );\n\n return (\n <div style={styles.shell} role=\"dialog\" aria-label=\"Dev overlay\">\n <div style={styles.header}>\n <div>\n <div style={styles.headerTitle}>Dev Overlay</div>\n <div style={styles.headerSub}>Cmd+Ctrl+A · localStorage-backed</div>\n </div>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={onClose}\n aria-label=\"Close\"\n title=\"Close (Esc)\"\n >\n <IconX size={16} />\n </button>\n </div>\n\n <div style={styles.body}>\n {panels.length === 0 ? (\n <div style={styles.empty}>\n No panels registered. Call <code>registerDevPanel(...)</code> from\n your template to add options here.\n </div>\n ) : (\n panels.map((panel) => <DevPanelCard key={panel.id} panel={panel} />)\n )}\n </div>\n\n <div style={styles.footer}>\n <button\n type=\"button\"\n style={{ ...styles.footerBtn, ...styles.footerBtnDanger }}\n onClick={() => {\n clearAllDevOverlayStorage();\n }}\n title=\"Reset every dev-overlay value back to its default\"\n >\n <IconTrash size={13} />\n Clear all dev-overlay values\n </button>\n </div>\n </div>\n );\n}\n\nfunction DevPanelCard({ panel }: { panel: DevPanel }) {\n const [collapsedRaw, setCollapsedRaw] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n try {\n return (\n window.localStorage.getItem(`${COLLAPSED_KEY_PREFIX}${panel.id}`) ===\n \"1\"\n );\n } catch {\n return false;\n }\n });\n const setCollapsed = (next: boolean) => {\n setCollapsedRaw(next);\n try {\n window.localStorage.setItem(\n `${COLLAPSED_KEY_PREFIX}${panel.id}`,\n next ? \"1\" : \"0\",\n );\n } catch {\n // ignore — collapsed state is just UX sugar\n }\n };\n\n return (\n <div style={styles.panel}>\n <button\n type=\"button\"\n style={styles.panelHeader}\n onClick={() => setCollapsed(!collapsedRaw)}\n >\n {collapsedRaw ? (\n <IconChevronRight size={14} />\n ) : (\n <IconChevronDown size={14} />\n )}\n <span style={styles.panelLabel}>{panel.label}</span>\n </button>\n {!collapsedRaw && (\n <div style={styles.panelBody}>\n {panel.description && (\n <div style={styles.panelDesc}>{panel.description}</div>\n )}\n {(panel.options ?? []).map((option) => (\n <DevOptionRow key={option.id} panelId={panel.id} option={option} />\n ))}\n {panel.render ? (\n <div style={styles.customRender}>{panel.render()}</div>\n ) : null}\n </div>\n )}\n </div>\n );\n}\n\nfunction DevOptionRow({\n panelId,\n option,\n}: {\n panelId: string;\n option: DevOption;\n}) {\n if (option.type === \"boolean\") {\n return <DevBooleanRow panelId={panelId} option={option} />;\n }\n if (option.type === \"select\") {\n return <DevSelectRow panelId={panelId} option={option} />;\n }\n if (option.type === \"string\") {\n return <DevStringRow panelId={panelId} option={option} />;\n }\n return <DevActionRow option={option} />;\n}\n\nfunction DevBooleanRow({\n panelId,\n option,\n}: {\n panelId: string;\n option: DevBooleanOption;\n}) {\n const [value, setValue] = useDevOption(\n panelId,\n option.id,\n option.default ?? false,\n );\n return (\n <label style={styles.row}>\n <div style={styles.rowLabels}>\n <div style={styles.rowLabel}>{option.label}</div>\n {option.description && (\n <div style={styles.rowDesc}>{option.description}</div>\n )}\n </div>\n <input\n type=\"checkbox\"\n checked={!!value}\n onChange={(e) => {\n const next = e.target.checked;\n setValue(next);\n option.onChange?.(next);\n }}\n style={styles.checkbox}\n />\n </label>\n );\n}\n\nfunction DevSelectRow({\n panelId,\n option,\n}: {\n panelId: string;\n option: DevSelectOption;\n}) {\n const [value, setValue] = useDevOption(\n panelId,\n option.id,\n option.default ?? option.choices[0]?.value ?? \"\",\n );\n return (\n <div style={styles.row}>\n <div style={styles.rowLabels}>\n <div style={styles.rowLabel}>{option.label}</div>\n {option.description && (\n <div style={styles.rowDesc}>{option.description}</div>\n )}\n </div>\n <select\n value={value}\n onChange={(e) => {\n const next = e.target.value;\n setValue(next);\n option.onChange?.(next);\n }}\n style={styles.select}\n >\n {option.choices.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n );\n}\n\nfunction DevStringRow({\n panelId,\n option,\n}: {\n panelId: string;\n option: DevStringOption;\n}) {\n const [value, setValue] = useDevOption(\n panelId,\n option.id,\n option.default ?? \"\",\n );\n return (\n <div\n style={{ ...styles.row, alignItems: \"stretch\", flexDirection: \"column\" }}\n >\n <div style={styles.rowLabels}>\n <div style={styles.rowLabel}>{option.label}</div>\n {option.description && (\n <div style={styles.rowDesc}>{option.description}</div>\n )}\n </div>\n <input\n type=\"text\"\n value={value}\n placeholder={option.placeholder}\n onChange={(e) => {\n const next = e.target.value;\n setValue(next);\n option.onChange?.(next);\n }}\n style={styles.input}\n />\n </div>\n );\n}\n\nfunction DevActionRow({ option }: { option: DevActionOption }) {\n const [busy, setBusy] = useState(false);\n return (\n <div style={styles.row}>\n <div style={styles.rowLabels}>\n <div style={styles.rowLabel}>{option.label}</div>\n {option.description && (\n <div style={styles.rowDesc}>{option.description}</div>\n )}\n </div>\n <button\n type=\"button\"\n disabled={busy}\n onClick={async () => {\n setBusy(true);\n try {\n await option.onClick();\n } finally {\n setBusy(false);\n }\n }}\n style={{\n ...styles.actionBtn,\n ...(option.destructive ? styles.actionBtnDanger : {}),\n }}\n >\n {busy ? (\n <IconLoader2\n size={13}\n style={{ animation: \"spin 1s linear infinite\" }}\n />\n ) : (\n <IconRefresh size={13} />\n )}\n {option.buttonLabel ?? option.label}\n </button>\n </div>\n );\n}\n\n// Shadow / border styles tuned to read well over both light and dark app\n// chrome — the overlay is dev-only so we don't bother with theme tokens.\nconst styles: Record<string, React.CSSProperties> = {\n shell: {\n position: \"fixed\",\n top: 16,\n right: 16,\n width: 380,\n maxWidth: \"calc(100vw - 32px)\",\n // Sized to content; capped so it never spills off-screen on small windows.\n maxHeight: \"calc(100vh - 32px)\",\n background: \"rgba(20, 20, 23, 0.96)\",\n color: \"#f4f4f5\",\n border: \"1px solid rgba(255,255,255,0.08)\",\n borderRadius: 12,\n boxShadow: \"0 24px 60px rgba(0,0,0,0.5)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', sans-serif\",\n fontSize: 13,\n zIndex: 2147483646,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n },\n header: {\n display: \"flex\",\n alignItems: \"flex-start\",\n justifyContent: \"space-between\",\n padding: \"14px 16px\",\n borderBottom: \"1px solid rgba(255,255,255,0.06)\",\n },\n headerTitle: { fontWeight: 600, fontSize: 14 },\n headerSub: { fontSize: 11, opacity: 0.55, marginTop: 2 },\n iconBtn: {\n background: \"transparent\",\n border: \"none\",\n color: \"inherit\",\n cursor: \"pointer\",\n padding: 4,\n borderRadius: 6,\n display: \"inline-flex\",\n alignItems: \"center\",\n },\n body: {\n padding: 12,\n overflowY: \"auto\",\n flex: 1,\n // Required to let `overflow-y: auto` actually scroll inside a flex column.\n // Without this, flex children grow to fit content and the scroll never\n // engages.\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n },\n empty: {\n padding: 16,\n fontSize: 12,\n opacity: 0.7,\n background: \"rgba(255,255,255,0.03)\",\n borderRadius: 8,\n border: \"1px dashed rgba(255,255,255,0.1)\",\n },\n panel: {\n background: \"rgba(255,255,255,0.03)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n borderRadius: 8,\n overflow: \"hidden\",\n },\n panelHeader: {\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n width: \"100%\",\n background: \"transparent\",\n border: \"none\",\n color: \"inherit\",\n padding: \"10px 12px\",\n cursor: \"pointer\",\n fontSize: 13,\n textAlign: \"left\",\n },\n panelLabel: { fontWeight: 600 },\n panelBody: {\n padding: \"0 12px 12px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 10,\n },\n panelDesc: { fontSize: 11, opacity: 0.65, lineHeight: 1.4 },\n customRender: { marginTop: 4 },\n row: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 12,\n },\n rowLabels: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n flex: 1,\n minWidth: 0,\n },\n rowLabel: { fontSize: 13 },\n rowDesc: { fontSize: 11, opacity: 0.6, lineHeight: 1.4 },\n checkbox: {\n width: 16,\n height: 16,\n cursor: \"pointer\",\n accentColor: \"#3b82f6\",\n },\n select: {\n background: \"rgba(255,255,255,0.06)\",\n color: \"inherit\",\n border: \"1px solid rgba(255,255,255,0.1)\",\n borderRadius: 6,\n padding: \"4px 8px\",\n fontSize: 12,\n minWidth: 120,\n cursor: \"pointer\",\n },\n input: {\n background: \"rgba(255,255,255,0.06)\",\n color: \"inherit\",\n border: \"1px solid rgba(255,255,255,0.1)\",\n borderRadius: 6,\n padding: \"6px 8px\",\n fontSize: 12,\n width: \"100%\",\n boxSizing: \"border-box\",\n },\n actionBtn: {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n background: \"rgba(59,130,246,0.15)\",\n color: \"#bfdbfe\",\n border: \"1px solid rgba(59,130,246,0.3)\",\n borderRadius: 6,\n padding: \"5px 10px\",\n fontSize: 12,\n cursor: \"pointer\",\n fontWeight: 500,\n },\n actionBtnDanger: {\n background: \"rgba(239,68,68,0.15)\",\n color: \"#fecaca\",\n border: \"1px solid rgba(239,68,68,0.3)\",\n },\n footer: {\n padding: 10,\n borderTop: \"1px solid rgba(255,255,255,0.06)\",\n display: \"flex\",\n justifyContent: \"flex-end\",\n },\n footerBtn: {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n background: \"transparent\",\n color: \"inherit\",\n border: \"1px solid rgba(255,255,255,0.12)\",\n borderRadius: 6,\n padding: \"5px 10px\",\n fontSize: 11,\n cursor: \"pointer\",\n },\n footerBtnDanger: { color: \"#fecaca\", borderColor: \"rgba(239,68,68,0.3)\" },\n};\n\n// Inject keyframes for the spinner once.\nif (\n typeof document !== \"undefined\" &&\n !document.getElementById(\"agent-native-dev-overlay-keyframes\")\n) {\n const styleEl = document.createElement(\"style\");\n styleEl.id = \"agent-native-dev-overlay-keyframes\";\n styleEl.textContent = \"@keyframes spin { to { transform: rotate(360deg); } }\";\n document.head.appendChild(styleEl);\n}\n\n// `ReactNode` is intentionally re-imported here so the file is self-contained\n// when consumed via the package's exports map.\nexport type { ReactNode };\n"]}
|
|
1
|
+
{"version":3,"file":"DevOverlay.js","sourceRoot":"","sources":["../../../src/client/dev-overlay/DevOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <DevOverlay /> — the framework dev/configuration panel.\n *\n * Templates render this once at the root of their app. The user toggles it\n * with Cmd+Ctrl+A (also exposed as `useDevOverlayShortcut`). Panels register\n * via `registerDevPanel`; values for option-style controls persist to\n * localStorage via `useDevOption`.\n *\n * Visibility note: the overlay only mounts when the host explicitly opens it\n * via the keybinding (or the `open` prop). It is dev-only by convention —\n * shipping with the keybinding active in prod is fine because nothing renders\n * unless invoked.\n */\n\nimport {\n useCallback,\n useEffect,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport {\n IconChevronDown,\n IconChevronRight,\n IconLoader2,\n IconRefresh,\n IconTrash,\n IconX,\n} from \"@tabler/icons-react\";\nimport { listDevPanels, subscribeDevPanels } from \"./registry.js\";\nimport {\n clearAllDevOverlayStorage,\n useDevOption,\n DEV_OVERLAY_STORAGE_PREFIX,\n} from \"./use-dev-option.js\";\nimport { useDevOverlayShortcut } from \"./use-dev-overlay-shortcut.js\";\nimport type {\n DevActionOption,\n DevBooleanOption,\n DevOption,\n DevPanel,\n DevSelectOption,\n DevStringOption,\n} from \"./types.js\";\nimport \"./builtins.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\nconst PANEL_OPEN_KEY = `${DEV_OVERLAY_STORAGE_PREFIX}open`;\nconst COLLAPSED_KEY_PREFIX = `${DEV_OVERLAY_STORAGE_PREFIX}collapsed-`;\n\nexport interface DevOverlayProps {\n /**\n * Force-control the overlay's visibility. When omitted the overlay manages\n * its own state and listens to Cmd+Ctrl+A.\n */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function DevOverlay({ open, onOpenChange }: DevOverlayProps = {}) {\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = open !== undefined;\n const isOpen = isControlled ? open : internalOpen;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange],\n );\n\n useDevOverlayShortcut(useCallback(() => setOpen(!isOpen), [isOpen, setOpen]));\n\n // Esc closes (only when overlay is the topmost UI — skip when typing).\n useEffect(() => {\n if (!isOpen) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\") return;\n const target = e.target as HTMLElement | null;\n if (\n target &&\n (target.tagName === \"INPUT\" ||\n target.tagName === \"TEXTAREA\" ||\n target.isContentEditable)\n ) {\n return;\n }\n setOpen(false);\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [isOpen, setOpen]);\n\n if (!isOpen) return null;\n return <DevOverlayPanel onClose={() => setOpen(false)} />;\n}\n\nfunction DevOverlayPanel({ onClose }: { onClose: () => void }) {\n const panels = useSyncExternalStore(\n subscribeDevPanels,\n listDevPanels,\n listDevPanels,\n );\n\n return (\n <TooltipProvider delayDuration={200}>\n <div style={styles.shell} role=\"dialog\" aria-label=\"Dev overlay\">\n <div style={styles.header}>\n <div>\n <div style={styles.headerTitle}>Dev Overlay</div>\n <div style={styles.headerSub}>Cmd+Ctrl+A · localStorage-backed</div>\n </div>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={onClose}\n aria-label=\"Close\"\n >\n <IconX size={16} />\n </button>\n </TooltipTrigger>\n <TooltipContent>Close (Esc)</TooltipContent>\n </Tooltip>\n </div>\n\n <div style={styles.body}>\n {panels.length === 0 ? (\n <div style={styles.empty}>\n No panels registered. Call <code>registerDevPanel(...)</code> from\n your template to add options here.\n </div>\n ) : (\n panels.map((panel) => <DevPanelCard key={panel.id} panel={panel} />)\n )}\n </div>\n\n <div style={styles.footer}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n style={{ ...styles.footerBtn, ...styles.footerBtnDanger }}\n onClick={() => {\n clearAllDevOverlayStorage();\n }}\n >\n <IconTrash size={13} />\n Clear all dev-overlay values\n </button>\n </TooltipTrigger>\n <TooltipContent>\n Reset every dev-overlay value back to its default\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n </TooltipProvider>\n );\n}\n\nfunction DevPanelCard({ panel }: { panel: DevPanel }) {\n const [collapsedRaw, setCollapsedRaw] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n try {\n return (\n window.localStorage.getItem(`${COLLAPSED_KEY_PREFIX}${panel.id}`) ===\n \"1\"\n );\n } catch {\n return false;\n }\n });\n const setCollapsed = (next: boolean) => {\n setCollapsedRaw(next);\n try {\n window.localStorage.setItem(\n `${COLLAPSED_KEY_PREFIX}${panel.id}`,\n next ? \"1\" : \"0\",\n );\n } catch {\n // ignore — collapsed state is just UX sugar\n }\n };\n\n return (\n <div style={styles.panel}>\n <button\n type=\"button\"\n style={styles.panelHeader}\n onClick={() => setCollapsed(!collapsedRaw)}\n >\n {collapsedRaw ? (\n <IconChevronRight size={14} />\n ) : (\n <IconChevronDown size={14} />\n )}\n <span style={styles.panelLabel}>{panel.label}</span>\n </button>\n {!collapsedRaw && (\n <div style={styles.panelBody}>\n {panel.description && (\n <div style={styles.panelDesc}>{panel.description}</div>\n )}\n {(panel.options ?? []).map((option) => (\n <DevOptionRow key={option.id} panelId={panel.id} option={option} />\n ))}\n {panel.render ? (\n <div style={styles.customRender}>{panel.render()}</div>\n ) : null}\n </div>\n )}\n </div>\n );\n}\n\nfunction DevOptionRow({\n panelId,\n option,\n}: {\n panelId: string;\n option: DevOption;\n}) {\n if (option.type === \"boolean\") {\n return <DevBooleanRow panelId={panelId} option={option} />;\n }\n if (option.type === \"select\") {\n return <DevSelectRow panelId={panelId} option={option} />;\n }\n if (option.type === \"string\") {\n return <DevStringRow panelId={panelId} option={option} />;\n }\n return <DevActionRow option={option} />;\n}\n\nfunction DevBooleanRow({\n panelId,\n option,\n}: {\n panelId: string;\n option: DevBooleanOption;\n}) {\n const [value, setValue] = useDevOption(\n panelId,\n option.id,\n option.default ?? false,\n );\n return (\n <label style={styles.row}>\n <div style={styles.rowLabels}>\n <div style={styles.rowLabel}>{option.label}</div>\n {option.description && (\n <div style={styles.rowDesc}>{option.description}</div>\n )}\n </div>\n <input\n type=\"checkbox\"\n checked={!!value}\n onChange={(e) => {\n const next = e.target.checked;\n setValue(next);\n option.onChange?.(next);\n }}\n style={styles.checkbox}\n />\n </label>\n );\n}\n\nfunction DevSelectRow({\n panelId,\n option,\n}: {\n panelId: string;\n option: DevSelectOption;\n}) {\n const [value, setValue] = useDevOption(\n panelId,\n option.id,\n option.default ?? option.choices[0]?.value ?? \"\",\n );\n return (\n <div style={styles.row}>\n <div style={styles.rowLabels}>\n <div style={styles.rowLabel}>{option.label}</div>\n {option.description && (\n <div style={styles.rowDesc}>{option.description}</div>\n )}\n </div>\n <select\n value={value}\n onChange={(e) => {\n const next = e.target.value;\n setValue(next);\n option.onChange?.(next);\n }}\n style={styles.select}\n >\n {option.choices.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n );\n}\n\nfunction DevStringRow({\n panelId,\n option,\n}: {\n panelId: string;\n option: DevStringOption;\n}) {\n const [value, setValue] = useDevOption(\n panelId,\n option.id,\n option.default ?? \"\",\n );\n return (\n <div\n style={{ ...styles.row, alignItems: \"stretch\", flexDirection: \"column\" }}\n >\n <div style={styles.rowLabels}>\n <div style={styles.rowLabel}>{option.label}</div>\n {option.description && (\n <div style={styles.rowDesc}>{option.description}</div>\n )}\n </div>\n <input\n type=\"text\"\n value={value}\n placeholder={option.placeholder}\n onChange={(e) => {\n const next = e.target.value;\n setValue(next);\n option.onChange?.(next);\n }}\n style={styles.input}\n />\n </div>\n );\n}\n\nfunction DevActionRow({ option }: { option: DevActionOption }) {\n const [busy, setBusy] = useState(false);\n return (\n <div style={styles.row}>\n <div style={styles.rowLabels}>\n <div style={styles.rowLabel}>{option.label}</div>\n {option.description && (\n <div style={styles.rowDesc}>{option.description}</div>\n )}\n </div>\n <button\n type=\"button\"\n disabled={busy}\n onClick={async () => {\n setBusy(true);\n try {\n await option.onClick();\n } finally {\n setBusy(false);\n }\n }}\n style={{\n ...styles.actionBtn,\n ...(option.destructive ? styles.actionBtnDanger : {}),\n }}\n >\n {busy ? (\n <IconLoader2\n size={13}\n style={{ animation: \"spin 1s linear infinite\" }}\n />\n ) : (\n <IconRefresh size={13} />\n )}\n {option.buttonLabel ?? option.label}\n </button>\n </div>\n );\n}\n\n// Shadow / border styles tuned to read well over both light and dark app\n// chrome — the overlay is dev-only so we don't bother with theme tokens.\nconst styles: Record<string, React.CSSProperties> = {\n shell: {\n position: \"fixed\",\n top: 16,\n right: 16,\n width: 380,\n maxWidth: \"calc(100vw - 32px)\",\n // Sized to content; capped so it never spills off-screen on small windows.\n maxHeight: \"calc(100vh - 32px)\",\n background: \"rgba(20, 20, 23, 0.96)\",\n color: \"#f4f4f5\",\n border: \"1px solid rgba(255,255,255,0.08)\",\n borderRadius: 12,\n boxShadow: \"0 24px 60px rgba(0,0,0,0.5)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', sans-serif\",\n fontSize: 13,\n zIndex: 2147483646,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n },\n header: {\n display: \"flex\",\n alignItems: \"flex-start\",\n justifyContent: \"space-between\",\n padding: \"14px 16px\",\n borderBottom: \"1px solid rgba(255,255,255,0.06)\",\n },\n headerTitle: { fontWeight: 600, fontSize: 14 },\n headerSub: { fontSize: 11, opacity: 0.55, marginTop: 2 },\n iconBtn: {\n background: \"transparent\",\n border: \"none\",\n color: \"inherit\",\n cursor: \"pointer\",\n padding: 4,\n borderRadius: 6,\n display: \"inline-flex\",\n alignItems: \"center\",\n },\n body: {\n padding: 12,\n overflowY: \"auto\",\n flex: 1,\n // Required to let `overflow-y: auto` actually scroll inside a flex column.\n // Without this, flex children grow to fit content and the scroll never\n // engages.\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n },\n empty: {\n padding: 16,\n fontSize: 12,\n opacity: 0.7,\n background: \"rgba(255,255,255,0.03)\",\n borderRadius: 8,\n border: \"1px dashed rgba(255,255,255,0.1)\",\n },\n panel: {\n background: \"rgba(255,255,255,0.03)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n borderRadius: 8,\n overflow: \"hidden\",\n },\n panelHeader: {\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n width: \"100%\",\n background: \"transparent\",\n border: \"none\",\n color: \"inherit\",\n padding: \"10px 12px\",\n cursor: \"pointer\",\n fontSize: 13,\n textAlign: \"left\",\n },\n panelLabel: { fontWeight: 600 },\n panelBody: {\n padding: \"0 12px 12px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 10,\n },\n panelDesc: { fontSize: 11, opacity: 0.65, lineHeight: 1.4 },\n customRender: { marginTop: 4 },\n row: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 12,\n },\n rowLabels: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n flex: 1,\n minWidth: 0,\n },\n rowLabel: { fontSize: 13 },\n rowDesc: { fontSize: 11, opacity: 0.6, lineHeight: 1.4 },\n checkbox: {\n width: 16,\n height: 16,\n cursor: \"pointer\",\n accentColor: \"#3b82f6\",\n },\n select: {\n background: \"rgba(255,255,255,0.06)\",\n color: \"inherit\",\n border: \"1px solid rgba(255,255,255,0.1)\",\n borderRadius: 6,\n padding: \"4px 8px\",\n fontSize: 12,\n minWidth: 120,\n cursor: \"pointer\",\n },\n input: {\n background: \"rgba(255,255,255,0.06)\",\n color: \"inherit\",\n border: \"1px solid rgba(255,255,255,0.1)\",\n borderRadius: 6,\n padding: \"6px 8px\",\n fontSize: 12,\n width: \"100%\",\n boxSizing: \"border-box\",\n },\n actionBtn: {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n background: \"rgba(59,130,246,0.15)\",\n color: \"#bfdbfe\",\n border: \"1px solid rgba(59,130,246,0.3)\",\n borderRadius: 6,\n padding: \"5px 10px\",\n fontSize: 12,\n cursor: \"pointer\",\n fontWeight: 500,\n },\n actionBtnDanger: {\n background: \"rgba(239,68,68,0.15)\",\n color: \"#fecaca\",\n border: \"1px solid rgba(239,68,68,0.3)\",\n },\n footer: {\n padding: 10,\n borderTop: \"1px solid rgba(255,255,255,0.06)\",\n display: \"flex\",\n justifyContent: \"flex-end\",\n },\n footerBtn: {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n background: \"transparent\",\n color: \"inherit\",\n border: \"1px solid rgba(255,255,255,0.12)\",\n borderRadius: 6,\n padding: \"5px 10px\",\n fontSize: 11,\n cursor: \"pointer\",\n },\n footerBtnDanger: { color: \"#fecaca\", borderColor: \"rgba(239,68,68,0.3)\" },\n};\n\n// Inject keyframes for the spinner once.\nif (\n typeof document !== \"undefined\" &&\n !document.getElementById(\"agent-native-dev-overlay-keyframes\")\n) {\n const styleEl = document.createElement(\"style\");\n styleEl.id = \"agent-native-dev-overlay-keyframes\";\n styleEl.textContent = \"@keyframes spin { to { transform: rotate(360deg); } }\";\n document.head.appendChild(styleEl);\n}\n\n// `ReactNode` is intentionally re-imported here so the file is self-contained\n// when consumed via the package's exports map.\nexport type { ReactNode };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-format.d.ts","sourceRoot":"","sources":["../../src/client/error-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0BAA0B,qCAAqC,CAAC;AAY7E,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAYR;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"error-format.d.ts","sourceRoot":"","sources":["../../src/client/error-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0BAA0B,qCAAqC,CAAC;AAY7E,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAYR;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,CAsC5E"}
|
|
@@ -38,6 +38,12 @@ export function normalizeChatError(errorMessage) {
|
|
|
38
38
|
const raw = String(errorMessage || "Unknown error");
|
|
39
39
|
const looksHtml = /<html[\s>]|<body[\s>]|<head[\s>]/i.test(raw);
|
|
40
40
|
const text = looksHtml ? htmlToText(raw) : raw.trim();
|
|
41
|
+
if (/^Gateway error \(no detail; raw event:/i.test(text)) {
|
|
42
|
+
return {
|
|
43
|
+
message: "The model gateway stopped without a specific error. The chat will try to recover automatically; if it keeps happening, retry with another model.",
|
|
44
|
+
details: text,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
41
47
|
if (/inactivity timeout/i.test(text)) {
|
|
42
48
|
return {
|
|
43
49
|
message: "The agent connection timed out before it could finish. You can continue from the partial work or retry.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-format.js","sourceRoot":"","sources":["../../src/client/error-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Append a Builder CTA markdown link to gateway errors that users can fix\n * outside the app. Used by both\n * chat SSE consumers (`sse-event-processor.ts` and `useProductionAgent.ts`)\n * to keep the copy in lockstep.\n *\n * `upgradeUrl` comes from the gateway response body and ends up interpolated\n * into markdown, so we validate it's a plain https URL with no characters\n * that would escape the `[...](url)` link target. Only `)` and whitespace\n * terminate the link target — `(`, `<`, `>` are fine inside it — so the\n * regex stays narrow; `buildUpgradeUrl` emits org-name URLs that may\n * contain `(` (e.g. `Acme%20(staging)`) and we don't want to reject them.\n */\nexport const BUILDER_SPACE_SETTINGS_URL = \"https://builder.io/account/space\";\n\nfunction isSafeUpgradeUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== \"https:\") return false;\n return !/[\\s)]/.test(url);\n } catch {\n return false;\n }\n}\n\nexport function formatChatErrorText(\n errorMessage: string,\n upgradeUrl?: string,\n errorCode?: string,\n): string {\n const normalized = normalizeChatError(errorMessage);\n if (\n errorCode === \"gateway_not_enabled\" ||\n /space has not enabled the LLM gateway/i.test(normalized.message)\n ) {\n return `Error: ${normalized.message}\\n\\n[Open Builder space settings](${BUILDER_SPACE_SETTINGS_URL})`;\n }\n if (!upgradeUrl || !isSafeUpgradeUrl(upgradeUrl)) {\n return `Error: ${normalized.message}`;\n }\n return `Error: ${normalized.message}\\n\\n[Upgrade at builder.io](${upgradeUrl})`;\n}\n\nexport interface NormalizedChatError {\n message: string;\n details?: string;\n}\n\nexport function normalizeChatError(errorMessage: string): NormalizedChatError {\n const raw = String(errorMessage || \"Unknown error\");\n const looksHtml = /<html[\\s>]|<body[\\s>]|<head[\\s>]/i.test(raw);\n const text = looksHtml ? htmlToText(raw) : raw.trim();\n\n if (/inactivity timeout/i.test(text)) {\n return {\n message:\n \"The agent connection timed out before it could finish. You can continue from the partial work or retry.\",\n details: text,\n };\n }\n\n if (/Invalid request body:\\s*tools\\.\\d+\\.input_schema\\.type/i.test(text)) {\n return {\n message:\n \"A tool schema was invalid, so the model rejected the request before it started. The invalid tool can be skipped and the request retried.\",\n details: text,\n };\n }\n\n if (looksHtml) {\n return {\n message:\n text.slice(0, 240) || \"The provider returned an HTML error page.\",\n details: text,\n };\n }\n\n return { message: text };\n}\n\nfunction htmlToText(html: string): string {\n return html\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \" \")\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \" \")\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/(p|div|h1|h2|h3|li|tr)>/gi, \"\\n\")\n .replace(/<[^>]+>/g, \" \")\n .replace(/ /gi, \" \")\n .replace(/</gi, \"<\")\n .replace(/>/gi, \">\")\n .replace(/&/gi, \"&\")\n .replace(/"/gi, '\"')\n .replace(/'/gi, \"'\")\n .replace(/[ \\t]+/g, \" \")\n .replace(/\\n\\s+/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"error-format.js","sourceRoot":"","sources":["../../src/client/error-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Append a Builder CTA markdown link to gateway errors that users can fix\n * outside the app. Used by both\n * chat SSE consumers (`sse-event-processor.ts` and `useProductionAgent.ts`)\n * to keep the copy in lockstep.\n *\n * `upgradeUrl` comes from the gateway response body and ends up interpolated\n * into markdown, so we validate it's a plain https URL with no characters\n * that would escape the `[...](url)` link target. Only `)` and whitespace\n * terminate the link target — `(`, `<`, `>` are fine inside it — so the\n * regex stays narrow; `buildUpgradeUrl` emits org-name URLs that may\n * contain `(` (e.g. `Acme%20(staging)`) and we don't want to reject them.\n */\nexport const BUILDER_SPACE_SETTINGS_URL = \"https://builder.io/account/space\";\n\nfunction isSafeUpgradeUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== \"https:\") return false;\n return !/[\\s)]/.test(url);\n } catch {\n return false;\n }\n}\n\nexport function formatChatErrorText(\n errorMessage: string,\n upgradeUrl?: string,\n errorCode?: string,\n): string {\n const normalized = normalizeChatError(errorMessage);\n if (\n errorCode === \"gateway_not_enabled\" ||\n /space has not enabled the LLM gateway/i.test(normalized.message)\n ) {\n return `Error: ${normalized.message}\\n\\n[Open Builder space settings](${BUILDER_SPACE_SETTINGS_URL})`;\n }\n if (!upgradeUrl || !isSafeUpgradeUrl(upgradeUrl)) {\n return `Error: ${normalized.message}`;\n }\n return `Error: ${normalized.message}\\n\\n[Upgrade at builder.io](${upgradeUrl})`;\n}\n\nexport interface NormalizedChatError {\n message: string;\n details?: string;\n}\n\nexport function normalizeChatError(errorMessage: string): NormalizedChatError {\n const raw = String(errorMessage || \"Unknown error\");\n const looksHtml = /<html[\\s>]|<body[\\s>]|<head[\\s>]/i.test(raw);\n const text = looksHtml ? htmlToText(raw) : raw.trim();\n\n if (/^Gateway error \\(no detail; raw event:/i.test(text)) {\n return {\n message:\n \"The model gateway stopped without a specific error. The chat will try to recover automatically; if it keeps happening, retry with another model.\",\n details: text,\n };\n }\n\n if (/inactivity timeout/i.test(text)) {\n return {\n message:\n \"The agent connection timed out before it could finish. You can continue from the partial work or retry.\",\n details: text,\n };\n }\n\n if (/Invalid request body:\\s*tools\\.\\d+\\.input_schema\\.type/i.test(text)) {\n return {\n message:\n \"A tool schema was invalid, so the model rejected the request before it started. The invalid tool can be skipped and the request retried.\",\n details: text,\n };\n }\n\n if (looksHtml) {\n return {\n message:\n text.slice(0, 240) || \"The provider returned an HTML error page.\",\n details: text,\n };\n }\n\n return { message: text };\n}\n\nfunction htmlToText(html: string): string {\n return html\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \" \")\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \" \")\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/(p|div|h1|h2|h3|li|tr)>/gi, \"\\n\")\n .replace(/<[^>]+>/g, \" \")\n .replace(/ /gi, \" \")\n .replace(/</gi, \"<\")\n .replace(/>/gi, \">\")\n .replace(/&/gi, \"&\")\n .replace(/"/gi, '\"')\n .replace(/'/gi, \"'\")\n .replace(/[ \\t]+/g, \" \")\n .replace(/\\n\\s+/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbeddedExtension.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/EmbeddedExtension.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EmbeddedExtension.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/EmbeddedExtension.tsx"],"names":[],"mappings":"AAoCA,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB;2CACuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf;iDAC6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,WAAW,EACX,MAAM,EACN,OAAO,EACP,SAAS,EACT,aAAkB,GACnB,EAAE,sBAAsB,2CA2MxB"}
|
|
@@ -6,6 +6,7 @@ import { useNavigate } from "react-router";
|
|
|
6
6
|
import { IconDots, IconExternalLink, IconLayoutSidebarRightCollapse, IconTrash, } from "@tabler/icons-react";
|
|
7
7
|
import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
|
|
8
8
|
import { isAllowedExtensionPath, sanitizeExtensionRequestOptions, checkBridgePolicy, } from "./iframe-bridge.js";
|
|
9
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
9
10
|
/**
|
|
10
11
|
* Renders a extension inline as a small auto-sized iframe — for use inside an
|
|
11
12
|
* `<ExtensionSlot>`. Different from `<ExtensionViewer>` (which is full-page with a
|
|
@@ -41,10 +42,20 @@ export function EmbeddedExtension({ extensionId, slotId, context, className, ini
|
|
|
41
42
|
return res.json();
|
|
42
43
|
},
|
|
43
44
|
});
|
|
45
|
+
// Initial dark state is baked into the URL on first load only; subsequent
|
|
46
|
+
// theme toggles update the iframe's <html class="dark"> via postMessage so
|
|
47
|
+
// the user's interaction state inside the extension survives the toggle.
|
|
48
|
+
const initialDarkRef = useRef(isDark);
|
|
44
49
|
const iframeSrc = useMemo(() => {
|
|
45
50
|
const v = encodeURIComponent(extension?.updatedAt ?? "");
|
|
46
|
-
return agentNativePath(`/_agent-native/extensions/${extensionId}/render?slot=${encodeURIComponent(slotId)}&dark=${
|
|
47
|
-
}, [extensionId, slotId,
|
|
51
|
+
return agentNativePath(`/_agent-native/extensions/${extensionId}/render?slot=${encodeURIComponent(slotId)}&dark=${initialDarkRef.current}&v=${v}`);
|
|
52
|
+
}, [extensionId, slotId, extension?.updatedAt]);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
const win = iframeRef.current?.contentWindow;
|
|
55
|
+
if (!win)
|
|
56
|
+
return;
|
|
57
|
+
win.postMessage({ type: "agent-native-theme-update", isDark }, "*");
|
|
58
|
+
}, [isDark]);
|
|
48
59
|
// Forward slot context whenever it changes. The iframe's own load handler
|
|
49
60
|
// posts the initial value once it's ready; this effect handles updates.
|
|
50
61
|
const contextJson = JSON.stringify(context ?? {});
|
|
@@ -191,7 +202,7 @@ function EmbeddedToolMenu({ extensionId, slotId, toolName, }) {
|
|
|
191
202
|
setOpen(o);
|
|
192
203
|
if (!o)
|
|
193
204
|
setConfirmingDelete(false);
|
|
194
|
-
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "absolute top-1 right-1 flex h-6 w-6 items-center justify-center rounded-md bg-background/60 text-muted-foreground/60 opacity-0 hover:bg-accent hover:text-foreground hover:opacity-100 group-hover/embedded-extension:opacity-100 cursor-pointer transition-opacity",
|
|
205
|
+
}, children: [_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "absolute top-1 right-1 flex h-6 w-6 items-center justify-center rounded-md bg-background/60 text-muted-foreground/60 opacity-0 hover:bg-accent hover:text-foreground hover:opacity-100 group-hover/embedded-extension:opacity-100 cursor-pointer transition-opacity", "aria-label": `${toolName} options`, children: _jsx(IconDots, { className: "h-3.5 w-3.5" }) }) }) }), _jsx(TooltipContent, { children: `${toolName} options` })] }) }), _jsx(PopoverContent, { align: "end", sideOffset: 4, className: "w-56 p-1", children: !confirmingDelete ? (_jsxs("div", { className: "flex flex-col", children: [_jsxs("button", { type: "button", onClick: () => {
|
|
195
206
|
closeMenu();
|
|
196
207
|
navigate(`/extensions/${extensionId}`);
|
|
197
208
|
}, className: "flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] hover:bg-accent cursor-pointer text-left", children: [_jsx(IconExternalLink, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Open full view" })] }), _jsxs("button", { type: "button", onClick: removeFromSlot, className: "flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] hover:bg-accent cursor-pointer text-left", children: [_jsx(IconLayoutSidebarRightCollapse, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Remove from this widget area" })] }), _jsx("div", { className: "my-1 h-px bg-border/40" }), _jsxs("button", { type: "button", onClick: () => setConfirmingDelete(true), className: "flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] text-destructive hover:bg-destructive/10 cursor-pointer text-left", children: [_jsx(IconTrash, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Delete extension\u2026" })] })] })) : (_jsxs("div", { className: "flex flex-col gap-2 p-2", children: [_jsxs("p", { className: "text-[12px]", children: ["Delete ", _jsx("span", { className: "font-medium", children: toolName }), "? This removes the extension everywhere, for everyone it's shared with."] }), _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), className: "rounded-md px-2 py-1 text-[12px] hover:bg-accent cursor-pointer", children: "Cancel" }), _jsx("button", { type: "button", onClick: deleteExtension, className: "rounded-md bg-destructive px-2 py-1 text-[12px] text-destructive-foreground hover:bg-destructive/90 cursor-pointer", children: "Delete" })] })] })) })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbeddedExtension.js","sourceRoot":"","sources":["../../../src/client/extensions/EmbeddedExtension.tsx"],"names":[],"mappings":"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","sourcesContent":["import { agentNativePath } from \"../api-path.js\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useNavigate } from \"react-router\";\nimport {\n IconDots,\n IconExternalLink,\n IconLayoutSidebarRightCollapse,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport {\n isAllowedExtensionPath,\n sanitizeExtensionRequestOptions,\n checkBridgePolicy,\n type ExtensionBridgeRole,\n} from \"./iframe-bridge.js\";\n\ninterface Extension {\n id: string;\n name: string;\n description?: string;\n content?: string;\n updatedAt?: string;\n}\n\nexport interface EmbeddedExtensionProps {\n extensionId: string;\n /** Slot identifier passed via the iframe URL so the extension runtime knows it's\n * embedded and enables auto-resize. */\n slotId: string;\n /** Object pushed into the extension as `window.slotContext`. Re-posted whenever\n * the host re-renders with a new context. */\n context?: Record<string, unknown> | null;\n /** Optional className applied to the iframe container. */\n className?: string;\n /** Initial iframe height before content reports a real height. */\n initialHeight?: number;\n}\n\n/**\n * Renders a extension inline as a small auto-sized iframe — for use inside an\n * `<ExtensionSlot>`. Different from `<ExtensionViewer>` (which is full-page with a\n * toolbar): no header, sized to content, receives a `slotContext`.\n */\nexport function EmbeddedExtension({\n extensionId,\n slotId,\n context,\n className,\n initialHeight = 80,\n}: EmbeddedExtensionProps) {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const [height, setHeight] = useState<number>(initialHeight);\n const [isDark, setIsDark] = useState(false);\n // (audit H4) Mirror ExtensionViewer's role-aware gating; deny-by-default until\n // the iframe's render binding announcement arrives.\n const bridgeContextRef = useRef<{\n role: ExtensionBridgeRole;\n isAuthor: boolean;\n }>({\n role: \"viewer\",\n isAuthor: false,\n });\n\n useEffect(() => {\n setIsDark(document.documentElement.classList.contains(\"dark\"));\n const observer = new MutationObserver(() => {\n setIsDark(document.documentElement.classList.contains(\"dark\"));\n });\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\"],\n });\n return () => observer.disconnect();\n }, []);\n\n const { data: extension } = useQuery<Extension>({\n queryKey: [\"extension\", extensionId],\n queryFn: async () => {\n const res = await fetch(\n agentNativePath(`/_agent-native/extensions/${extensionId}`),\n );\n if (!res.ok) throw new Error(\"Failed to fetch extension\");\n return res.json();\n },\n });\n\n const iframeSrc = useMemo(() => {\n const v = encodeURIComponent(extension?.updatedAt ?? \"\");\n return agentNativePath(\n `/_agent-native/extensions/${extensionId}/render?slot=${encodeURIComponent(slotId)}&dark=${isDark}&v=${v}`,\n );\n }, [extensionId, slotId, isDark, extension?.updatedAt]);\n\n // Forward slot context whenever it changes. The iframe's own load handler\n // posts the initial value once it's ready; this effect handles updates.\n const contextJson = JSON.stringify(context ?? {});\n useEffect(() => {\n const win = iframeRef.current?.contentWindow;\n if (!win) return;\n win.postMessage(\n { type: \"agent-native-slot-context\", context: context ?? {} },\n \"*\",\n );\n }, [contextJson]);\n\n // Bridge extension requests + height reports.\n useEffect(() => {\n const handleMessage = async (event: MessageEvent) => {\n if (event.source !== iframeRef.current?.contentWindow) return;\n const message = event.data;\n if (!message || typeof message !== \"object\") return;\n\n if (message.type === \"agent-native-extension-binding\") {\n const binding = (message as any).binding ?? {};\n const role: ExtensionBridgeRole =\n binding.role === \"owner\" ||\n binding.role === \"admin\" ||\n binding.role === \"editor\" ||\n binding.role === \"viewer\"\n ? binding.role\n : \"viewer\";\n bridgeContextRef.current = {\n role,\n isAuthor: !!binding.isAuthor,\n };\n return;\n }\n\n if (message.type === \"agent-native-extension-resize\") {\n const h = Number(message.height);\n if (Number.isFinite(h) && h > 0) {\n setHeight(Math.ceil(h));\n }\n return;\n }\n\n if (message.type !== \"agent-native-extension-request\") return;\n\n const requestId = String(message.requestId ?? \"\");\n const path = String(message.path ?? \"\");\n const respond = (payload: Record<string, unknown>) => {\n iframeRef.current?.contentWindow?.postMessage(\n { type: \"agent-native-extension-response\", requestId, ...payload },\n \"*\",\n );\n };\n\n if (!requestId || !isAllowedExtensionPath(path, extensionId)) {\n respond({ error: \"Extension request path is not allowed\" });\n return;\n }\n\n try {\n const options = sanitizeExtensionRequestOptions(message.options);\n // (audit H4) Role-aware gating: viewer-shared extensions can read but not\n // write. The bridge policy is decided here in the parent before the\n // request leaves; the server enforces a second layer.\n const policy = checkBridgePolicy(\n path,\n options.method ?? \"GET\",\n bridgeContextRef.current,\n );\n if (!policy.ok) {\n respond({\n response: {\n ok: false,\n status: 403,\n statusText: \"Forbidden\",\n body: { error: policy.error },\n },\n });\n return;\n }\n // (audit H5) Same extension-bridge tagging as <ExtensionViewer>. action-routes\n // uses these headers to enforce per-action `toolCallable` opt-in.\n const finalHeaders = new Headers(options.headers ?? undefined);\n finalHeaders.set(\"X-Agent-Native-Extension-Bridge\", \"1\");\n finalHeaders.set(\"X-Agent-Native-Extension-Id\", extensionId);\n const res = await fetch(agentNativePath(path), {\n ...options,\n headers: finalHeaders,\n credentials: \"same-origin\",\n });\n const text = await res.text();\n let body: unknown = text;\n if (text) {\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n }\n respond({\n response: {\n ok: res.ok,\n status: res.status,\n statusText: res.statusText,\n body,\n },\n });\n } catch (err: any) {\n respond({ error: err?.message ?? \"Extension host request failed\" });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [extensionId]);\n\n if (!extension) {\n return (\n <div\n className={className}\n style={{ height: initialHeight }}\n aria-busy=\"true\"\n />\n );\n }\n\n return (\n <div className={`relative group/embedded-extension ${className ?? \"\"}`}>\n <iframe\n ref={iframeRef}\n key={`${extensionId}-${extension.updatedAt ?? \"\"}`}\n src={iframeSrc}\n title={extension.name}\n sandbox=\"allow-scripts allow-forms\"\n style={{ width: \"100%\", border: 0, height, display: \"block\" }}\n onLoad={() => {\n iframeRef.current?.contentWindow?.postMessage(\n { type: \"agent-native-slot-context\", context: context ?? {} },\n \"*\",\n );\n }}\n />\n <EmbeddedToolMenu\n extensionId={extensionId}\n slotId={slotId}\n toolName={extension.name}\n />\n </div>\n );\n}\n\nfunction EmbeddedToolMenu({\n extensionId,\n slotId,\n toolName,\n}: {\n extensionId: string;\n slotId: string;\n toolName: string;\n}) {\n const [open, setOpen] = useState(false);\n const [confirmingDelete, setConfirmingDelete] = useState(false);\n const queryClient = useQueryClient();\n const navigate = useNavigate();\n\n const closeMenu = () => {\n setOpen(false);\n setConfirmingDelete(false);\n };\n\n const removeFromSlot = async () => {\n closeMenu();\n queryClient.setQueryData<any[]>([\"slot-installs\", slotId], (old) =>\n (old ?? []).filter((i) => i.extensionId !== extensionId),\n );\n try {\n await fetch(\n agentNativePath(\n `/_agent-native/slots/${encodeURIComponent(slotId)}/install/${encodeURIComponent(extensionId)}`,\n ),\n { method: \"DELETE\" },\n );\n } finally {\n queryClient.invalidateQueries({ queryKey: [\"slot-installs\", slotId] });\n }\n };\n\n const deleteExtension = async () => {\n closeMenu();\n queryClient.setQueryData<any[]>([\"slot-installs\", slotId], (old) =>\n (old ?? []).filter((i) => i.extensionId !== extensionId),\n );\n try {\n await fetch(agentNativePath(`/_agent-native/extensions/${extensionId}`), {\n method: \"DELETE\",\n });\n } finally {\n queryClient.invalidateQueries({ queryKey: [\"slot-installs\", slotId] });\n queryClient.invalidateQueries({ queryKey: [\"extension\", extensionId] });\n queryClient.invalidateQueries({ queryKey: [\"extensions\"] });\n }\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n if (!o) setConfirmingDelete(false);\n }}\n >\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"absolute top-1 right-1 flex h-6 w-6 items-center justify-center rounded-md bg-background/60 text-muted-foreground/60 opacity-0 hover:bg-accent hover:text-foreground hover:opacity-100 group-hover/embedded-extension:opacity-100 cursor-pointer transition-opacity\"\n title={`${toolName} options`}\n aria-label={`${toolName} options`}\n >\n <IconDots className=\"h-3.5 w-3.5\" />\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" sideOffset={4} className=\"w-56 p-1\">\n {!confirmingDelete ? (\n <div className=\"flex flex-col\">\n <button\n type=\"button\"\n onClick={() => {\n closeMenu();\n navigate(`/extensions/${extensionId}`);\n }}\n className=\"flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] hover:bg-accent cursor-pointer text-left\"\n >\n <IconExternalLink className=\"h-3.5 w-3.5\" />\n <span>Open full view</span>\n </button>\n <button\n type=\"button\"\n onClick={removeFromSlot}\n className=\"flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] hover:bg-accent cursor-pointer text-left\"\n >\n <IconLayoutSidebarRightCollapse className=\"h-3.5 w-3.5\" />\n <span>Remove from this widget area</span>\n </button>\n <div className=\"my-1 h-px bg-border/40\" />\n <button\n type=\"button\"\n onClick={() => setConfirmingDelete(true)}\n className=\"flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] text-destructive hover:bg-destructive/10 cursor-pointer text-left\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n <span>Delete extension…</span>\n </button>\n </div>\n ) : (\n <div className=\"flex flex-col gap-2 p-2\">\n <p className=\"text-[12px]\">\n Delete <span className=\"font-medium\">{toolName}</span>? This\n removes the extension everywhere, for everyone it's shared with.\n </p>\n <div className=\"flex justify-end gap-1\">\n <button\n type=\"button\"\n onClick={() => setConfirmingDelete(false)}\n className=\"rounded-md px-2 py-1 text-[12px] hover:bg-accent cursor-pointer\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={deleteExtension}\n className=\"rounded-md bg-destructive px-2 py-1 text-[12px] text-destructive-foreground hover:bg-destructive/90 cursor-pointer\"\n >\n Delete\n </button>\n </div>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"EmbeddedExtension.js","sourceRoot":"","sources":["../../../src/client/extensions/EmbeddedExtension.tsx"],"names":[],"mappings":"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","sourcesContent":["import { agentNativePath } from \"../api-path.js\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useNavigate } from \"react-router\";\nimport {\n IconDots,\n IconExternalLink,\n IconLayoutSidebarRightCollapse,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport {\n isAllowedExtensionPath,\n sanitizeExtensionRequestOptions,\n checkBridgePolicy,\n type ExtensionBridgeRole,\n} from \"./iframe-bridge.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\ninterface Extension {\n id: string;\n name: string;\n description?: string;\n content?: string;\n updatedAt?: string;\n}\n\nexport interface EmbeddedExtensionProps {\n extensionId: string;\n /** Slot identifier passed via the iframe URL so the extension runtime knows it's\n * embedded and enables auto-resize. */\n slotId: string;\n /** Object pushed into the extension as `window.slotContext`. Re-posted whenever\n * the host re-renders with a new context. */\n context?: Record<string, unknown> | null;\n /** Optional className applied to the iframe container. */\n className?: string;\n /** Initial iframe height before content reports a real height. */\n initialHeight?: number;\n}\n\n/**\n * Renders a extension inline as a small auto-sized iframe — for use inside an\n * `<ExtensionSlot>`. Different from `<ExtensionViewer>` (which is full-page with a\n * toolbar): no header, sized to content, receives a `slotContext`.\n */\nexport function EmbeddedExtension({\n extensionId,\n slotId,\n context,\n className,\n initialHeight = 80,\n}: EmbeddedExtensionProps) {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const [height, setHeight] = useState<number>(initialHeight);\n const [isDark, setIsDark] = useState(false);\n // (audit H4) Mirror ExtensionViewer's role-aware gating; deny-by-default until\n // the iframe's render binding announcement arrives.\n const bridgeContextRef = useRef<{\n role: ExtensionBridgeRole;\n isAuthor: boolean;\n }>({\n role: \"viewer\",\n isAuthor: false,\n });\n\n useEffect(() => {\n setIsDark(document.documentElement.classList.contains(\"dark\"));\n const observer = new MutationObserver(() => {\n setIsDark(document.documentElement.classList.contains(\"dark\"));\n });\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\"],\n });\n return () => observer.disconnect();\n }, []);\n\n const { data: extension } = useQuery<Extension>({\n queryKey: [\"extension\", extensionId],\n queryFn: async () => {\n const res = await fetch(\n agentNativePath(`/_agent-native/extensions/${extensionId}`),\n );\n if (!res.ok) throw new Error(\"Failed to fetch extension\");\n return res.json();\n },\n });\n\n // Initial dark state is baked into the URL on first load only; subsequent\n // theme toggles update the iframe's <html class=\"dark\"> via postMessage so\n // the user's interaction state inside the extension survives the toggle.\n const initialDarkRef = useRef(isDark);\n const iframeSrc = useMemo(() => {\n const v = encodeURIComponent(extension?.updatedAt ?? \"\");\n return agentNativePath(\n `/_agent-native/extensions/${extensionId}/render?slot=${encodeURIComponent(slotId)}&dark=${initialDarkRef.current}&v=${v}`,\n );\n }, [extensionId, slotId, extension?.updatedAt]);\n\n useEffect(() => {\n const win = iframeRef.current?.contentWindow;\n if (!win) return;\n win.postMessage({ type: \"agent-native-theme-update\", isDark }, \"*\");\n }, [isDark]);\n\n // Forward slot context whenever it changes. The iframe's own load handler\n // posts the initial value once it's ready; this effect handles updates.\n const contextJson = JSON.stringify(context ?? {});\n useEffect(() => {\n const win = iframeRef.current?.contentWindow;\n if (!win) return;\n win.postMessage(\n { type: \"agent-native-slot-context\", context: context ?? {} },\n \"*\",\n );\n }, [contextJson]);\n\n // Bridge extension requests + height reports.\n useEffect(() => {\n const handleMessage = async (event: MessageEvent) => {\n if (event.source !== iframeRef.current?.contentWindow) return;\n const message = event.data;\n if (!message || typeof message !== \"object\") return;\n\n if (message.type === \"agent-native-extension-binding\") {\n const binding = (message as any).binding ?? {};\n const role: ExtensionBridgeRole =\n binding.role === \"owner\" ||\n binding.role === \"admin\" ||\n binding.role === \"editor\" ||\n binding.role === \"viewer\"\n ? binding.role\n : \"viewer\";\n bridgeContextRef.current = {\n role,\n isAuthor: !!binding.isAuthor,\n };\n return;\n }\n\n if (message.type === \"agent-native-extension-resize\") {\n const h = Number(message.height);\n if (Number.isFinite(h) && h > 0) {\n setHeight(Math.ceil(h));\n }\n return;\n }\n\n if (message.type !== \"agent-native-extension-request\") return;\n\n const requestId = String(message.requestId ?? \"\");\n const path = String(message.path ?? \"\");\n const respond = (payload: Record<string, unknown>) => {\n iframeRef.current?.contentWindow?.postMessage(\n { type: \"agent-native-extension-response\", requestId, ...payload },\n \"*\",\n );\n };\n\n if (!requestId || !isAllowedExtensionPath(path, extensionId)) {\n respond({ error: \"Extension request path is not allowed\" });\n return;\n }\n\n try {\n const options = sanitizeExtensionRequestOptions(message.options);\n // (audit H4) Role-aware gating: viewer-shared extensions can read but not\n // write. The bridge policy is decided here in the parent before the\n // request leaves; the server enforces a second layer.\n const policy = checkBridgePolicy(\n path,\n options.method ?? \"GET\",\n bridgeContextRef.current,\n );\n if (!policy.ok) {\n respond({\n response: {\n ok: false,\n status: 403,\n statusText: \"Forbidden\",\n body: { error: policy.error },\n },\n });\n return;\n }\n // (audit H5) Same extension-bridge tagging as <ExtensionViewer>. action-routes\n // uses these headers to enforce per-action `toolCallable` opt-in.\n const finalHeaders = new Headers(options.headers ?? undefined);\n finalHeaders.set(\"X-Agent-Native-Extension-Bridge\", \"1\");\n finalHeaders.set(\"X-Agent-Native-Extension-Id\", extensionId);\n const res = await fetch(agentNativePath(path), {\n ...options,\n headers: finalHeaders,\n credentials: \"same-origin\",\n });\n const text = await res.text();\n let body: unknown = text;\n if (text) {\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n }\n respond({\n response: {\n ok: res.ok,\n status: res.status,\n statusText: res.statusText,\n body,\n },\n });\n } catch (err: any) {\n respond({ error: err?.message ?? \"Extension host request failed\" });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [extensionId]);\n\n if (!extension) {\n return (\n <div\n className={className}\n style={{ height: initialHeight }}\n aria-busy=\"true\"\n />\n );\n }\n\n return (\n <div className={`relative group/embedded-extension ${className ?? \"\"}`}>\n <iframe\n ref={iframeRef}\n key={`${extensionId}-${extension.updatedAt ?? \"\"}`}\n src={iframeSrc}\n title={extension.name}\n sandbox=\"allow-scripts allow-forms\"\n style={{ width: \"100%\", border: 0, height, display: \"block\" }}\n onLoad={() => {\n iframeRef.current?.contentWindow?.postMessage(\n { type: \"agent-native-slot-context\", context: context ?? {} },\n \"*\",\n );\n }}\n />\n <EmbeddedToolMenu\n extensionId={extensionId}\n slotId={slotId}\n toolName={extension.name}\n />\n </div>\n );\n}\n\nfunction EmbeddedToolMenu({\n extensionId,\n slotId,\n toolName,\n}: {\n extensionId: string;\n slotId: string;\n toolName: string;\n}) {\n const [open, setOpen] = useState(false);\n const [confirmingDelete, setConfirmingDelete] = useState(false);\n const queryClient = useQueryClient();\n const navigate = useNavigate();\n\n const closeMenu = () => {\n setOpen(false);\n setConfirmingDelete(false);\n };\n\n const removeFromSlot = async () => {\n closeMenu();\n queryClient.setQueryData<any[]>([\"slot-installs\", slotId], (old) =>\n (old ?? []).filter((i) => i.extensionId !== extensionId),\n );\n try {\n await fetch(\n agentNativePath(\n `/_agent-native/slots/${encodeURIComponent(slotId)}/install/${encodeURIComponent(extensionId)}`,\n ),\n { method: \"DELETE\" },\n );\n } finally {\n queryClient.invalidateQueries({ queryKey: [\"slot-installs\", slotId] });\n }\n };\n\n const deleteExtension = async () => {\n closeMenu();\n queryClient.setQueryData<any[]>([\"slot-installs\", slotId], (old) =>\n (old ?? []).filter((i) => i.extensionId !== extensionId),\n );\n try {\n await fetch(agentNativePath(`/_agent-native/extensions/${extensionId}`), {\n method: \"DELETE\",\n });\n } finally {\n queryClient.invalidateQueries({ queryKey: [\"slot-installs\", slotId] });\n queryClient.invalidateQueries({ queryKey: [\"extension\", extensionId] });\n queryClient.invalidateQueries({ queryKey: [\"extensions\"] });\n }\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n if (!o) setConfirmingDelete(false);\n }}\n >\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"absolute top-1 right-1 flex h-6 w-6 items-center justify-center rounded-md bg-background/60 text-muted-foreground/60 opacity-0 hover:bg-accent hover:text-foreground hover:opacity-100 group-hover/embedded-extension:opacity-100 cursor-pointer transition-opacity\"\n aria-label={`${toolName} options`}\n >\n <IconDots className=\"h-3.5 w-3.5\" />\n </button>\n </PopoverTrigger>\n </TooltipTrigger>\n <TooltipContent>{`${toolName} options`}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <PopoverContent align=\"end\" sideOffset={4} className=\"w-56 p-1\">\n {!confirmingDelete ? (\n <div className=\"flex flex-col\">\n <button\n type=\"button\"\n onClick={() => {\n closeMenu();\n navigate(`/extensions/${extensionId}`);\n }}\n className=\"flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] hover:bg-accent cursor-pointer text-left\"\n >\n <IconExternalLink className=\"h-3.5 w-3.5\" />\n <span>Open full view</span>\n </button>\n <button\n type=\"button\"\n onClick={removeFromSlot}\n className=\"flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] hover:bg-accent cursor-pointer text-left\"\n >\n <IconLayoutSidebarRightCollapse className=\"h-3.5 w-3.5\" />\n <span>Remove from this widget area</span>\n </button>\n <div className=\"my-1 h-px bg-border/40\" />\n <button\n type=\"button\"\n onClick={() => setConfirmingDelete(true)}\n className=\"flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] text-destructive hover:bg-destructive/10 cursor-pointer text-left\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n <span>Delete extension…</span>\n </button>\n </div>\n ) : (\n <div className=\"flex flex-col gap-2 p-2\">\n <p className=\"text-[12px]\">\n Delete <span className=\"font-medium\">{toolName}</span>? This\n removes the extension everywhere, for everyone it's shared with.\n </p>\n <div className=\"flex justify-end gap-1\">\n <button\n type=\"button\"\n onClick={() => setConfirmingDelete(false)}\n className=\"rounded-md px-2 py-1 text-[12px] hover:bg-accent cursor-pointer\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={deleteExtension}\n className=\"rounded-md bg-destructive px-2 py-1 text-[12px] text-destructive-foreground hover:bg-destructive/90 cursor-pointer\"\n >\n Delete\n </button>\n </div>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExtensionEditor.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/ExtensionEditor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExtensionEditor.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/ExtensionEditor.tsx"],"names":[],"mappings":"AAqCA,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,EAAE,WAAW,EAAE,EAAE,oBAAoB,2CAkVpE"}
|
|
@@ -6,6 +6,7 @@ import { Link, useNavigate } from "react-router";
|
|
|
6
6
|
import { IconArrowLeft, IconDeviceFloppy, IconDots, IconTrash, IconX, } from "@tabler/icons-react";
|
|
7
7
|
import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
|
|
8
8
|
import { cn } from "../utils.js";
|
|
9
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
9
10
|
export function ExtensionEditor({ extensionId }) {
|
|
10
11
|
const navigate = useNavigate();
|
|
11
12
|
const queryClient = useQueryClient();
|
|
@@ -120,10 +121,10 @@ export function ExtensionEditor({ extensionId }) {
|
|
|
120
121
|
queryClient.invalidateQueries({ queryKey: ["slot-installs", slotId] });
|
|
121
122
|
}
|
|
122
123
|
};
|
|
123
|
-
return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("header", { className: "flex items-center justify-between border-b px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Link, { to: isEdit ? `/extensions/${extensionId}` : "/extensions", className: "inline-flex cursor-pointer items-center justify-center rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground", "aria-label": "Back", children: _jsx(IconArrowLeft, { className: "h-4 w-4" }) }), _jsx("h1", { className: "text-sm font-semibold", children: isEdit ? "Edit Extension" : "New Extension" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: handleSave, disabled: saving || !name.trim(), className: cn("inline-flex cursor-pointer items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-sm text-primary-foreground hover:bg-primary/90", (saving || !name.trim()) && "opacity-60"), children: [_jsx(IconDeviceFloppy, { className: "h-3.5 w-3.5" }), saving ? "Saving..." : isEdit ? "Save" : "Create"] }), isEdit && (_jsxs(Popover, { open: menuOpen, onOpenChange: (o) => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
return (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("header", { className: "flex items-center justify-between border-b px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Link, { to: isEdit ? `/extensions/${extensionId}` : "/extensions", className: "inline-flex cursor-pointer items-center justify-center rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground", "aria-label": "Back", children: _jsx(IconArrowLeft, { className: "h-4 w-4" }) }), _jsx("h1", { className: "text-sm font-semibold", children: isEdit ? "Edit Extension" : "New Extension" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: handleSave, disabled: saving || !name.trim(), className: cn("inline-flex cursor-pointer items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-sm text-primary-foreground hover:bg-primary/90", (saving || !name.trim()) && "opacity-60"), children: [_jsx(IconDeviceFloppy, { className: "h-3.5 w-3.5" }), saving ? "Saving..." : isEdit ? "Save" : "Create"] }), isEdit && (_jsxs(Popover, { open: menuOpen, onOpenChange: (o) => {
|
|
125
|
+
setMenuOpen(o);
|
|
126
|
+
if (!o)
|
|
127
|
+
setConfirmingDelete(false);
|
|
128
|
+
}, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-accent-foreground", "aria-label": "More options", children: _jsx(IconDots, { className: "h-4 w-4" }) }) }) }), _jsx(TooltipContent, { children: "More options" })] }), _jsx(PopoverContent, { align: "end", sideOffset: 4, className: "w-72 p-0", children: !confirmingDelete ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "px-3 py-2 border-b border-border/40", children: [_jsx("p", { className: "text-[12px] font-medium", children: "Appears in" }), slots.length === 0 ? (_jsx("p", { className: "text-[11px] text-muted-foreground/70 mt-0.5", children: "Not installed in any widget areas. Ask the agent to add it somewhere." })) : (_jsxs("p", { className: "text-[11px] text-muted-foreground/70 mt-0.5", children: ["This extension can render in ", slots.length, " widget area", slots.length === 1 ? "" : "s", "."] }))] }), slots.length > 0 && (_jsx("div", { className: "max-h-48 overflow-y-auto py-1", children: slots.map((s) => (_jsxs("div", { className: "flex items-center gap-2 px-3 py-1.5 text-[12px]", children: [_jsx("span", { className: "flex-1 truncate font-mono text-[11px] text-muted-foreground", children: s.slotId }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => handleRemoveFromSlot(s.slotId), className: "rounded p-1 text-muted-foreground/60 hover:bg-accent hover:text-foreground cursor-pointer", "aria-label": "Remove from this widget area", children: _jsx(IconX, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Remove from this widget area (for me)" })] })] }, s.id))) })), _jsx("div", { className: "border-t border-border/40 p-1", children: _jsxs("button", { type: "button", onClick: () => setConfirmingDelete(true), className: "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] text-destructive hover:bg-destructive/10 cursor-pointer text-left", children: [_jsx(IconTrash, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Delete extension\u2026" })] }) })] })) : (_jsxs("div", { className: "flex flex-col gap-2 p-3", children: [_jsxs("p", { className: "text-[12px]", children: ["Delete ", _jsx("span", { className: "font-medium", children: name }), "? This removes the extension everywhere, for everyone it's shared with."] }), _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), className: "rounded-md px-2 py-1 text-[12px] hover:bg-accent cursor-pointer", children: "Cancel" }), _jsx("button", { type: "button", onClick: handleDelete, disabled: deleting, className: cn("rounded-md bg-destructive px-2 py-1 text-[12px] text-destructive-foreground hover:bg-destructive/90 cursor-pointer", deleting && "opacity-60"), children: deleting ? "Deleting…" : "Delete" })] })] })) })] }))] })] }), _jsxs("div", { className: "flex flex-1 overflow-hidden", children: [_jsxs("div", { className: "flex w-1/2 flex-col gap-4 overflow-auto border-r p-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1.5 block text-sm font-medium text-foreground", children: "Name" }), _jsx("input", { type: "text", value: name, onChange: (e) => setName(e.target.value), placeholder: "My Extension", className: "h-9 w-full rounded-md border border-input bg-background px-3 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1.5 block text-sm font-medium text-foreground", children: "Description" }), _jsx("textarea", { value: description, onChange: (e) => setDescription(e.target.value), placeholder: "What does this extension do?", rows: 2, className: "w-full resize-none rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background" })] }), _jsxs("div", { className: "flex flex-1 flex-col", children: [_jsx("label", { className: "mb-1.5 block text-sm font-medium text-foreground", children: "Content" }), _jsx("textarea", { value: content, onChange: (e) => setContent(e.target.value), placeholder: "<html>...</html>", className: "flex-1 resize-none rounded-md border border-input bg-background p-3 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background", spellCheck: false })] })] }), _jsx("div", { className: "w-1/2", children: content ? (_jsx("iframe", { srcDoc: content, className: "h-full w-full border-0", sandbox: "allow-scripts allow-forms", title: "Extension preview" })) : (_jsx("div", { className: "flex h-full items-center justify-center text-sm text-muted-foreground", children: "Preview will appear here" })) })] })] }) }));
|
|
128
129
|
}
|
|
129
130
|
//# sourceMappingURL=ExtensionEditor.js.map
|