@agent-native/core 0.30.6 → 0.31.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/dist/a2a/client.d.ts +2 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +6 -4
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +3 -0
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +0 -7
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.js +5 -3
- package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
- package/dist/agent/production-agent.js +7 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +14 -6
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js.map +1 -1
- package/dist/brand-kit/brand-signals.d.ts +31 -0
- package/dist/brand-kit/brand-signals.d.ts.map +1 -0
- package/dist/brand-kit/brand-signals.js +101 -0
- package/dist/brand-kit/brand-signals.js.map +1 -0
- package/dist/brand-kit/index.d.ts +21 -0
- package/dist/brand-kit/index.d.ts.map +1 -0
- package/dist/brand-kit/index.js +34 -0
- package/dist/brand-kit/index.js.map +1 -0
- package/dist/brand-kit/types.d.ts +103 -0
- package/dist/brand-kit/types.d.ts.map +1 -0
- package/dist/brand-kit/types.js +17 -0
- package/dist/brand-kit/types.js.map +1 -0
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +0 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/client/AgentNative.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +0 -2
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +69 -17
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/IframeEmbed.d.ts.map +1 -1
- package/dist/client/IframeEmbed.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/builder-mark.d.ts.map +1 -1
- package/dist/client/builder-mark.js.map +1 -1
- package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
- package/dist/client/components/MissingKeyCard.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +6 -3
- 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 +5 -0
- 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 -0
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/extensions/FileReference.d.ts.map +1 -1
- package/dist/client/composer/extensions/FileReference.js.map +1 -1
- package/dist/client/composer/extensions/MentionReference.d.ts.map +1 -1
- package/dist/client/composer/extensions/MentionReference.js.map +1 -1
- package/dist/client/composer/extensions/SkillReference.d.ts.map +1 -1
- package/dist/client/composer/extensions/SkillReference.js.map +1 -1
- package/dist/client/conversation/AgentConversation.js +8 -6
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.js +133 -35
- package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
- package/dist/client/db-admin/DbAdminPage.js.map +1 -1
- package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -1
- package/dist/client/dev-overlay/DevOverlay.js +0 -1
- package/dist/client/dev-overlay/DevOverlay.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +19 -0
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +11 -3
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/mcp-app-host.d.ts.map +1 -1
- package/dist/client/mcp-app-host.js +6 -1
- package/dist/client/mcp-app-host.js.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.js +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -1
- package/dist/client/onboarding/SetupButton.js +6 -0
- package/dist/client/onboarding/SetupButton.js.map +1 -1
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/resources/McpServerDetail.d.ts.map +1 -1
- package/dist/client/resources/McpServerDetail.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +1 -1
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/AutomationsSection.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +0 -4
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
- package/dist/client/terminal/AgentTerminal.js +1 -1
- package/dist/client/terminal/AgentTerminal.js.map +1 -1
- package/dist/client/use-agent-chat.d.ts.map +1 -1
- package/dist/client/use-agent-chat.js +20 -4
- package/dist/client/use-agent-chat.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +39 -25
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +8 -0
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +25 -9
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/client/useProductionAgent.d.ts.map +1 -1
- package/dist/client/useProductionAgent.js +6 -2
- package/dist/client/useProductionAgent.js.map +1 -1
- package/dist/collab/agent-presence.d.ts.map +1 -1
- package/dist/collab/agent-presence.js +1 -1
- package/dist/collab/agent-presence.js.map +1 -1
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/awareness.js +8 -0
- package/dist/collab/awareness.js.map +1 -1
- package/dist/collab/client-struct.js.map +1 -1
- package/dist/deploy/build.js +0 -5
- package/dist/deploy/build.js.map +1 -1
- package/dist/extensions/fetch-tool.d.ts.map +1 -1
- package/dist/extensions/fetch-tool.js +4 -1
- package/dist/extensions/fetch-tool.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts.map +1 -1
- package/dist/file-upload/actions/upload-image.js +39 -4
- package/dist/file-upload/actions/upload-image.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +14 -1
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +10 -1
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +20 -8
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/connect-store.d.ts.map +1 -1
- package/dist/mcp/connect-store.js +1 -1
- package/dist/mcp/connect-store.js.map +1 -1
- package/dist/notifications/channels.d.ts.map +1 -1
- package/dist/notifications/channels.js +3 -2
- package/dist/notifications/channels.js.map +1 -1
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/observability/evals.d.ts.map +1 -1
- package/dist/observability/evals.js +7 -7
- package/dist/observability/evals.js.map +1 -1
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +15 -5
- package/dist/observability/traces.js.map +1 -1
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +3 -2
- package/dist/org/handlers.js.map +1 -1
- package/dist/resources/handlers.d.ts +5 -5
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js.map +1 -1
- package/dist/scripts/db/schema.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +0 -6
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- 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 +0 -3
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +1 -2
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +0 -23
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +0 -3
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +49 -18
- package/dist/server/poll.js.map +1 -1
- package/dist/settings/store.js.map +1 -1
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +25 -4
- package/dist/sharing/access.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/package.json +3 -2
- package/dist/client/conversation/AgentConversation.spec.d.ts +0 -2
- package/dist/client/conversation/AgentConversation.spec.d.ts.map +0 -1
- package/dist/client/conversation/AgentConversation.spec.js +0 -69
- package/dist/client/conversation/AgentConversation.spec.js.map +0 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts +0 -2
- package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts.map +0 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js +0 -110
- package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js.map +0 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts +0 -2
- package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts.map +0 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.spec.js +0 -68
- package/dist/client/extensions/AgentNativeExtensionFrame.spec.js.map +0 -1
- package/dist/client/extensions/ExtensionViewer.spec.d.ts +0 -2
- package/dist/client/extensions/ExtensionViewer.spec.d.ts.map +0 -1
- package/dist/client/extensions/ExtensionViewer.spec.js +0 -94
- package/dist/client/extensions/ExtensionViewer.spec.js.map +0 -1
- package/dist/client/guided-questions.flow.spec.d.ts +0 -2
- package/dist/client/guided-questions.flow.spec.d.ts.map +0 -1
- package/dist/client/guided-questions.flow.spec.js +0 -147
- package/dist/client/guided-questions.flow.spec.js.map +0 -1
- package/dist/client/settings/useBuilderStatus.spec.d.ts +0 -2
- package/dist/client/settings/useBuilderStatus.spec.d.ts.map +0 -1
- package/dist/client/settings/useBuilderStatus.spec.js +0 -487
- package/dist/client/settings/useBuilderStatus.spec.js.map +0 -1
- package/dist/client/sharing/ShareButton.spec.d.ts +0 -2
- package/dist/client/sharing/ShareButton.spec.d.ts.map +0 -1
- package/dist/client/sharing/ShareButton.spec.js +0 -196
- package/dist/client/sharing/ShareButton.spec.js.map +0 -1
- package/dist/client/use-chat-models.spec.d.ts +0 -2
- package/dist/client/use-chat-models.spec.d.ts.map +0 -1
- package/dist/client/use-chat-models.spec.js +0 -39
- package/dist/client/use-chat-models.spec.js.map +0 -1
- package/dist/client/use-chat-threads.spec.d.ts +0 -2
- package/dist/client/use-chat-threads.spec.d.ts.map +0 -1
- package/dist/client/use-chat-threads.spec.js +0 -760
- package/dist/client/use-chat-threads.spec.js.map +0 -1
- package/dist/client/use-db-sync.spec.d.ts +0 -2
- package/dist/client/use-db-sync.spec.d.ts.map +0 -1
- package/dist/client/use-db-sync.spec.js +0 -107
- package/dist/client/use-db-sync.spec.js.map +0 -1
- package/dist/server/script-discovery.d.ts +0 -6
- package/dist/server/script-discovery.d.ts.map +0 -1
- package/dist/server/script-discovery.js +0 -6
- package/dist/server/script-discovery.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DbAdminPage.js","sourceRoot":"","sources":["../../../src/client/db-admin/DbAdminPage.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Code-mode database admin page — the shell that hosts the table browser, the\n * table editor, and the SQL editor.\n *\n * Gated to Code mode: when the app cannot toggle into Code mode\n * (`canToggle` is false) we render a clean notice instead of the tool. The\n * backend also enforces this with a 403, so this is purely a friendlier UX.\n */\nimport { useEffect, useMemo, useState } from \"react\";\nimport { IconDatabase, IconLoader2 } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { useCodeMode } from \"../use-dev-mode.js\";\nimport type { DbAdminFilter, DbAdminColumn } from \"../../db-admin/types.js\";\nimport { useOverview } from \"./useDbAdmin.js\";\nimport { TableBrowser } from \"./TableBrowser.js\";\nimport { useDbAdminAgentSync, useNavigateConsumer } from \"./useAgentSync.js\";\nimport { TableEditor } from \"./TableEditor.js\";\nimport { SqlEditor } from \"./SqlEditor.js\";\n\nconst DIALECT_LABEL: Record<string, string> = {\n postgres: \"Postgres\",\n sqlite: \"SQLite\",\n d1: \"Cloudflare D1\",\n};\n\nexport function DbAdminPage() {\n const { canToggle, isLoading: devLoading } = useCodeMode();\n const { data: overview, isLoading: overviewLoading } = useOverview();\n\n const [selectedTable, setSelectedTable] = useState<string | null>(null);\n const [mode, setMode] = useState<\"table\" | \"sql\">(\"table\");\n const [fkFilters, setFkFilters] = useState<DbAdminFilter[] | undefined>(\n undefined,\n );\n\n const tables = overview?.tables ?? [];\n const dialect = overview?.dialect ?? \"sqlite\";\n\n // Default selection to the first table once the overview loads.\n useEffect(() => {\n if (selectedTable === null && tables.length > 0) {\n setSelectedTable(tables[0].name);\n }\n }, [selectedTable, tables]);\n\n // Keep the agent's <current-screen> in sync, and let it drive navigation.\n useDbAdminAgentSync({ table: selectedTable, mode });\n useNavigateConsumer((table) => {\n setSelectedTable(table);\n setMode(\"table\");\n setFkFilters(undefined);\n });\n\n const tableNames = useMemo(() => tables.map((t) => t.name), [tables]);\n // SqlEditor degrades gracefully without per-table columns; pass an empty map.\n // (Table-name autocomplete still works; column autocomplete fills in lazily.)\n const columnsByTable = useMemo<Record<string, string[]>>(() => ({}), []);\n\n // ─── Code mode gate ──────────────────────────────────────────────────────\n if (!devLoading && !canToggle) {\n return (\n <div className=\"flex h-full w-full items-center justify-center bg-background p-6\">\n <div className=\"flex max-w-md flex-col items-center rounded-lg border bg-card p-8 text-center shadow-sm\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <IconDatabase\n className=\"h-6 w-6 text-muted-foreground\"\n stroke={1.75}\n />\n </div>\n <h2 className=\"text-base font-semibold text-foreground\">\n Code mode only\n </h2>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">\n Database admin is available in Code mode only.\n </p>\n </div>\n </div>\n );\n }\n\n const showInitialLoading = (devLoading || overviewLoading) && !overview;\n\n return (\n <div className=\"flex h-full w-full flex-col bg-background text-foreground\">\n {/* Header */}\n <header className=\"flex h-12 shrink-0 items-center gap-3 border-b px-4\">\n <IconDatabase className=\"h-5 w-5 text-muted-foreground\" stroke={1.75} />\n <span className=\"text-sm font-semibold\">Database</span>\n <span className=\"inline-flex items-center rounded-full border bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground\">\n {DIALECT_LABEL[dialect] ?? dialect}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {tables.length} {tables.length === 1 ? \"table\" : \"tables\"}\n </span>\n </header>\n\n {/* Body: fixed sidebar + flexible main */}\n <div className=\"flex min-h-0 flex-1\">\n <aside className=\"w-[260px] shrink-0 border-r\">\n {showInitialLoading ? (\n <SidebarSkeleton />\n ) : (\n <TableBrowser\n tables={tables}\n selected={selectedTable}\n onSelect={(t) => {\n setSelectedTable(t);\n setFkFilters(undefined);\n }}\n mode={mode}\n onModeChange={setMode}\n />\n )}\n </aside>\n\n <main className=\"min-w-0 flex-1 overflow-hidden\">\n {showInitialLoading ? (\n <MainLoading />\n ) : mode === \"sql\" ? (\n <SqlEditor\n dialect={dialect}\n tableNames={tableNames}\n columnsByTable={columnsByTable}\n />\n ) : selectedTable ? (\n <TableEditor\n key={selectedTable}\n table={selectedTable}\n dialect={dialect}\n initialFilters={fkFilters}\n onNavigateToRow={(t, filters) => {\n setSelectedTable(t);\n setMode(\"table\");\n setFkFilters(filters);\n }}\n />\n ) : (\n <NoTableSelected />\n )}\n </main>\n </div>\n </div>\n );\n}\n\nfunction SidebarSkeleton() {\n return (\n <div className=\"flex h-full flex-col bg-card p-2\">\n <div className=\"mb-2 h-9 animate-pulse rounded-md bg-muted\" />\n <div className=\"mb-3 h-9 animate-pulse rounded-md bg-muted\" />\n <div className=\"space-y-1.5\">\n {Array.from({ length: 8 }).map((_, i) => (\n <div\n key={i}\n className=\"h-8 animate-pulse rounded-md bg-muted\"\n style={{ opacity: 1 - i * 0.08 }}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction MainLoading() {\n return (\n <div className=\"flex h-full w-full items-center justify-center\">\n <IconLoader2\n className={cn(\"h-5 w-5 animate-spin text-muted-foreground\")}\n />\n </div>\n );\n}\n\nfunction NoTableSelected() {\n return (\n <div className=\"flex h-full w-full items-center justify-center p-6 text-center\">\n <div className=\"flex flex-col items-center\">\n <IconDatabase\n className=\"mb-3 h-8 w-8 text-muted-foreground/50\"\n stroke={1.5}\n />\n <p className=\"text-sm font-medium text-foreground\">No table selected</p>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n Pick a table from the sidebar to browse and edit its rows.\n </p>\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DbAdminPage.js","sourceRoot":"","sources":["../../../src/client/db-admin/DbAdminPage.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Code-mode database admin page — the shell that hosts the table browser, the\n * table editor, and the SQL editor.\n *\n * Gated to Code mode: when the app cannot toggle into Code mode\n * (`canToggle` is false) we render a clean notice instead of the tool. The\n * backend also enforces this with a 403, so this is purely a friendlier UX.\n */\nimport { useEffect, useMemo, useState } from \"react\";\nimport { IconDatabase, IconLoader2 } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { useCodeMode } from \"../use-dev-mode.js\";\nimport type { DbAdminFilter } from \"../../db-admin/types.js\";\nimport { useOverview } from \"./useDbAdmin.js\";\nimport { TableBrowser } from \"./TableBrowser.js\";\nimport { useDbAdminAgentSync, useNavigateConsumer } from \"./useAgentSync.js\";\nimport { TableEditor } from \"./TableEditor.js\";\nimport { SqlEditor } from \"./SqlEditor.js\";\n\nconst DIALECT_LABEL: Record<string, string> = {\n postgres: \"Postgres\",\n sqlite: \"SQLite\",\n d1: \"Cloudflare D1\",\n};\n\nexport function DbAdminPage() {\n const { canToggle, isLoading: devLoading } = useCodeMode();\n const { data: overview, isLoading: overviewLoading } = useOverview();\n\n const [selectedTable, setSelectedTable] = useState<string | null>(null);\n const [mode, setMode] = useState<\"table\" | \"sql\">(\"table\");\n const [fkFilters, setFkFilters] = useState<DbAdminFilter[] | undefined>(\n undefined,\n );\n\n const tables = overview?.tables ?? [];\n const dialect = overview?.dialect ?? \"sqlite\";\n\n // Default selection to the first table once the overview loads.\n useEffect(() => {\n if (selectedTable === null && tables.length > 0) {\n setSelectedTable(tables[0].name);\n }\n }, [selectedTable, tables]);\n\n // Keep the agent's <current-screen> in sync, and let it drive navigation.\n useDbAdminAgentSync({ table: selectedTable, mode });\n useNavigateConsumer((table) => {\n setSelectedTable(table);\n setMode(\"table\");\n setFkFilters(undefined);\n });\n\n const tableNames = useMemo(() => tables.map((t) => t.name), [tables]);\n // SqlEditor degrades gracefully without per-table columns; pass an empty map.\n // (Table-name autocomplete still works; column autocomplete fills in lazily.)\n const columnsByTable = useMemo<Record<string, string[]>>(() => ({}), []);\n\n // ─── Code mode gate ──────────────────────────────────────────────────────\n if (!devLoading && !canToggle) {\n return (\n <div className=\"flex h-full w-full items-center justify-center bg-background p-6\">\n <div className=\"flex max-w-md flex-col items-center rounded-lg border bg-card p-8 text-center shadow-sm\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <IconDatabase\n className=\"h-6 w-6 text-muted-foreground\"\n stroke={1.75}\n />\n </div>\n <h2 className=\"text-base font-semibold text-foreground\">\n Code mode only\n </h2>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">\n Database admin is available in Code mode only.\n </p>\n </div>\n </div>\n );\n }\n\n const showInitialLoading = (devLoading || overviewLoading) && !overview;\n\n return (\n <div className=\"flex h-full w-full flex-col bg-background text-foreground\">\n {/* Header */}\n <header className=\"flex h-12 shrink-0 items-center gap-3 border-b px-4\">\n <IconDatabase className=\"h-5 w-5 text-muted-foreground\" stroke={1.75} />\n <span className=\"text-sm font-semibold\">Database</span>\n <span className=\"inline-flex items-center rounded-full border bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground\">\n {DIALECT_LABEL[dialect] ?? dialect}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {tables.length} {tables.length === 1 ? \"table\" : \"tables\"}\n </span>\n </header>\n\n {/* Body: fixed sidebar + flexible main */}\n <div className=\"flex min-h-0 flex-1\">\n <aside className=\"w-[260px] shrink-0 border-r\">\n {showInitialLoading ? (\n <SidebarSkeleton />\n ) : (\n <TableBrowser\n tables={tables}\n selected={selectedTable}\n onSelect={(t) => {\n setSelectedTable(t);\n setFkFilters(undefined);\n }}\n mode={mode}\n onModeChange={setMode}\n />\n )}\n </aside>\n\n <main className=\"min-w-0 flex-1 overflow-hidden\">\n {showInitialLoading ? (\n <MainLoading />\n ) : mode === \"sql\" ? (\n <SqlEditor\n dialect={dialect}\n tableNames={tableNames}\n columnsByTable={columnsByTable}\n />\n ) : selectedTable ? (\n <TableEditor\n key={selectedTable}\n table={selectedTable}\n dialect={dialect}\n initialFilters={fkFilters}\n onNavigateToRow={(t, filters) => {\n setSelectedTable(t);\n setMode(\"table\");\n setFkFilters(filters);\n }}\n />\n ) : (\n <NoTableSelected />\n )}\n </main>\n </div>\n </div>\n );\n}\n\nfunction SidebarSkeleton() {\n return (\n <div className=\"flex h-full flex-col bg-card p-2\">\n <div className=\"mb-2 h-9 animate-pulse rounded-md bg-muted\" />\n <div className=\"mb-3 h-9 animate-pulse rounded-md bg-muted\" />\n <div className=\"space-y-1.5\">\n {Array.from({ length: 8 }).map((_, i) => (\n <div\n key={i}\n className=\"h-8 animate-pulse rounded-md bg-muted\"\n style={{ opacity: 1 - i * 0.08 }}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction MainLoading() {\n return (\n <div className=\"flex h-full w-full items-center justify-center\">\n <IconLoader2\n className={cn(\"h-5 w-5 animate-spin text-muted-foreground\")}\n />\n </div>\n );\n}\n\nfunction NoTableSelected() {\n return (\n <div className=\"flex h-full w-full items-center justify-center p-6 text-center\">\n <div className=\"flex flex-col items-center\">\n <IconDatabase\n className=\"mb-3 h-8 w-8 text-muted-foreground/50\"\n stroke={1.5}\n />\n <p className=\"text-sm font-medium text-foreground\">No table selected</p>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n Pick a table from the sidebar to browse and edit its rows.\n </p>\n </div>\n </div>\n );\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;AAUvB,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;AAoeD,YAAY,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -19,7 +19,6 @@ import { clearAllDevOverlayStorage, useDevOption, DEV_OVERLAY_STORAGE_PREFIX, }
|
|
|
19
19
|
import { useDevOverlayShortcut } from "./use-dev-overlay-shortcut.js";
|
|
20
20
|
import "./builtins.js";
|
|
21
21
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
22
|
-
const PANEL_OPEN_KEY = `${DEV_OVERLAY_STORAGE_PREFIX}open`;
|
|
23
22
|
const COLLAPSED_KEY_PREFIX = `${DEV_OVERLAY_STORAGE_PREFIX}collapsed-`;
|
|
24
23
|
export function DevOverlay({ open, onOpenChange } = {}) {
|
|
25
24
|
const [internalOpen, setInternalOpen] = useState(false);
|
|
@@ -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\";\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 const shortcutHint =\n typeof navigator !== \"undefined\" &&\n /Mac|iPhone|iPad/.test(navigator.userAgent)\n ? \"Cmd+Ctrl+A\"\n : \"Ctrl+Alt+A\";\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}>\n {shortcutHint} · localStorage-backed\n </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
|
+
{"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 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 const shortcutHint =\n typeof navigator !== \"undefined\" &&\n /Mac|iPhone|iPad/.test(navigator.userAgent)\n ? \"Cmd+Ctrl+A\"\n : \"Ctrl+Alt+A\";\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}>\n {shortcutHint} · localStorage-backed\n </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":"EmbeddedExtension.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/EmbeddedExtension.tsx"],"names":[],"mappings":"AA0CA,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,
|
|
1
|
+
{"version":3,"file":"EmbeddedExtension.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/EmbeddedExtension.tsx"],"names":[],"mappings":"AA0CA,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,2CAmOxB"}
|
|
@@ -24,6 +24,12 @@ export function EmbeddedExtension({ extensionId, slotId, context, className, ini
|
|
|
24
24
|
role: "viewer",
|
|
25
25
|
isAuthor: false,
|
|
26
26
|
});
|
|
27
|
+
// (audit H4) Latch the render binding once per iframe instance. The shell
|
|
28
|
+
// posts the server-resolved binding BEFORE user content runs; any later
|
|
29
|
+
// agent-native-extension-binding message is attacker-controllable (it
|
|
30
|
+
// originates inside the same sandboxed realm as user code) and must be
|
|
31
|
+
// ignored so a viewer cannot self-escalate to owner.
|
|
32
|
+
const bindingLatchedRef = useRef(false);
|
|
27
33
|
useEffect(() => {
|
|
28
34
|
setIsDark(document.documentElement.classList.contains("dark"));
|
|
29
35
|
const observer = new MutationObserver(() => {
|
|
@@ -54,6 +60,13 @@ export function EmbeddedExtension({ extensionId, slotId, context, className, ini
|
|
|
54
60
|
const v = encodeURIComponent(extension?.updatedAt ?? "");
|
|
55
61
|
return agentNativePath(`/_agent-native/extensions/${extensionId}/render?slot=${encodeURIComponent(slotId)}&dark=${initialDarkRef.current}&v=${v}`);
|
|
56
62
|
}, [extensionId, slotId, extension?.updatedAt]);
|
|
63
|
+
// Reset role + binding latch to deny-by-default whenever the iframe is
|
|
64
|
+
// recreated (its key changes). The new render's first binding announcement
|
|
65
|
+
// re-establishes the role.
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
bridgeContextRef.current = { role: "viewer", isAuthor: false };
|
|
68
|
+
bindingLatchedRef.current = false;
|
|
69
|
+
}, [extensionId, extension?.updatedAt]);
|
|
57
70
|
useEffect(() => {
|
|
58
71
|
const win = iframeRef.current?.contentWindow;
|
|
59
72
|
if (!win)
|
|
@@ -78,6 +91,12 @@ export function EmbeddedExtension({ extensionId, slotId, context, className, ini
|
|
|
78
91
|
if (!message || typeof message !== "object")
|
|
79
92
|
return;
|
|
80
93
|
if (message.type === "agent-native-extension-binding") {
|
|
94
|
+
// Only the FIRST announcement (sent by the shell before user content
|
|
95
|
+
// runs) is trusted. Ignore re-announcements — a malicious extension
|
|
96
|
+
// body could otherwise postMessage a forged owner binding to escalate.
|
|
97
|
+
if (bindingLatchedRef.current)
|
|
98
|
+
return;
|
|
99
|
+
bindingLatchedRef.current = true;
|
|
81
100
|
const binding = message.binding ?? {};
|
|
82
101
|
const role = binding.role === "owner" ||
|
|
83
102
|
binding.role === "admin" ||
|
|
@@ -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\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\nimport {\n deleteOrHideExtension,\n invalidateExtensionRemoval,\n} from \"./delete-extension.js\";\nimport { extensionPath } from \"../../extensions/path.js\";\n\ninterface Extension {\n id: string;\n name: string;\n description?: string;\n content?: string;\n updatedAt?: string;\n canDelete?: boolean;\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, isLoading } = useQuery<Extension | null>({\n queryKey: [\"extension\", extensionId],\n queryFn: async () => {\n const res = await fetch(\n agentNativePath(`/_agent-native/extensions/${extensionId}`),\n );\n if (res.status === 403 || res.status === 404) return null;\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 finalHeaders.set(\"X-Agent-Native-Tool-Bridge\", \"1\");\n finalHeaders.set(\"X-Agent-Native-Tool-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 if (!isLoading) return null;\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 canDelete={extension.canDelete}\n />\n </div>\n );\n}\n\nfunction EmbeddedToolMenu({\n extensionId,\n slotId,\n toolName,\n canDelete,\n}: {\n extensionId: string;\n slotId: string;\n toolName: string;\n canDelete?: boolean;\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 try {\n await deleteOrHideExtension({ id: extensionId, canDelete });\n invalidateExtensionRemoval(queryClient, extensionId);\n } catch {\n queryClient.invalidateQueries({ queryKey: [\"extension\", extensionId] });\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(extensionPath(extensionId, toolName));\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 {canDelete !== false && (\n <>\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 </>\n )}\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\";\nimport {\n deleteOrHideExtension,\n invalidateExtensionRemoval,\n} from \"./delete-extension.js\";\nimport { extensionPath } from \"../../extensions/path.js\";\n\ninterface Extension {\n id: string;\n name: string;\n description?: string;\n content?: string;\n updatedAt?: string;\n canDelete?: boolean;\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 // (audit H4) Latch the render binding once per iframe instance. The shell\n // posts the server-resolved binding BEFORE user content runs; any later\n // agent-native-extension-binding message is attacker-controllable (it\n // originates inside the same sandboxed realm as user code) and must be\n // ignored so a viewer cannot self-escalate to owner.\n const bindingLatchedRef = useRef(false);\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, isLoading } = useQuery<Extension | null>({\n queryKey: [\"extension\", extensionId],\n queryFn: async () => {\n const res = await fetch(\n agentNativePath(`/_agent-native/extensions/${extensionId}`),\n );\n if (res.status === 403 || res.status === 404) return null;\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 // Reset role + binding latch to deny-by-default whenever the iframe is\n // recreated (its key changes). The new render's first binding announcement\n // re-establishes the role.\n useEffect(() => {\n bridgeContextRef.current = { role: \"viewer\", isAuthor: false };\n bindingLatchedRef.current = false;\n }, [extensionId, 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 // Only the FIRST announcement (sent by the shell before user content\n // runs) is trusted. Ignore re-announcements — a malicious extension\n // body could otherwise postMessage a forged owner binding to escalate.\n if (bindingLatchedRef.current) return;\n bindingLatchedRef.current = true;\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 finalHeaders.set(\"X-Agent-Native-Tool-Bridge\", \"1\");\n finalHeaders.set(\"X-Agent-Native-Tool-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 if (!isLoading) return null;\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 canDelete={extension.canDelete}\n />\n </div>\n );\n}\n\nfunction EmbeddedToolMenu({\n extensionId,\n slotId,\n toolName,\n canDelete,\n}: {\n extensionId: string;\n slotId: string;\n toolName: string;\n canDelete?: boolean;\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 try {\n await deleteOrHideExtension({ id: extensionId, canDelete });\n invalidateExtensionRemoval(queryClient, extensionId);\n } catch {\n queryClient.invalidateQueries({ queryKey: [\"extension\", extensionId] });\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(extensionPath(extensionId, toolName));\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 {canDelete !== false && (\n <>\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 </>\n )}\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":"ExtensionViewer.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/ExtensionViewer.tsx"],"names":[],"mappings":"AAoGA,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;CACrB;AAigBD,wBAAgB,eAAe,CAAC,EAAE,WAAW,EAAE,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"ExtensionViewer.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/ExtensionViewer.tsx"],"names":[],"mappings":"AAoGA,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;CACrB;AAigBD,wBAAgB,eAAe,CAAC,EAAE,WAAW,EAAE,EAAE,oBAAoB,2CA+hBpE"}
|
|
@@ -347,6 +347,9 @@ export function ExtensionViewer({ extensionId }) {
|
|
|
347
347
|
role: "viewer",
|
|
348
348
|
isAuthor: false,
|
|
349
349
|
});
|
|
350
|
+
// (audit H4) Latch the render binding once per iframe instance; later
|
|
351
|
+
// announcements are attacker-controllable and must be ignored.
|
|
352
|
+
const bindingLatchedRef = useRef(false);
|
|
350
353
|
useEffect(() => {
|
|
351
354
|
setIsDark(document.documentElement.classList.contains("dark"));
|
|
352
355
|
const observer = new MutationObserver(() => {
|
|
@@ -381,9 +384,13 @@ export function ExtensionViewer({ extensionId }) {
|
|
|
381
384
|
if (!message)
|
|
382
385
|
return;
|
|
383
386
|
if (message.type === "agent-native-extension-binding") {
|
|
384
|
-
// (audit H4)
|
|
385
|
-
//
|
|
386
|
-
//
|
|
387
|
+
// (audit H4) Trust only the FIRST announcement: the shell sends the
|
|
388
|
+
// server-resolved binding BEFORE user-authored content runs. Later
|
|
389
|
+
// announcements share the iframe realm with user code and could forge
|
|
390
|
+
// an owner role, so they are ignored.
|
|
391
|
+
if (bindingLatchedRef.current)
|
|
392
|
+
return;
|
|
393
|
+
bindingLatchedRef.current = true;
|
|
387
394
|
const binding = message.binding ?? {};
|
|
388
395
|
const role = binding.role === "owner" ||
|
|
389
396
|
binding.role === "admin" ||
|
|
@@ -594,6 +601,7 @@ export function ExtensionViewer({ extensionId }) {
|
|
|
594
601
|
// Reset role to deny-by-default on every reload — the new render's
|
|
595
602
|
// binding announcement re-establishes the role before any helper call.
|
|
596
603
|
bridgeContextRef.current = { role: "viewer", isAuthor: false };
|
|
604
|
+
bindingLatchedRef.current = false;
|
|
597
605
|
}, [extensionId, extension?.updatedAt, refreshKey]);
|
|
598
606
|
const startRename = useCallback(() => {
|
|
599
607
|
if (!extension)
|