@agent-native/core 0.103.0 → 0.104.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +36 -0
- package/corpus/core/package.json +9 -2
- package/corpus/core/src/agent/engine/credential-errors.ts +2 -2
- package/corpus/core/src/agent/production-agent.ts +30 -0
- package/corpus/core/src/agent/run-store.ts +12 -2
- package/corpus/core/src/cli/create.ts +1 -0
- package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +30 -11
- package/corpus/core/src/cli/templates-meta.ts +4 -3
- package/corpus/core/src/client/AgentAskPopover.tsx +89 -0
- package/corpus/core/src/client/AgentChatHome.tsx +4 -0
- package/corpus/core/src/client/AgentPanel.tsx +321 -223
- package/corpus/core/src/client/AssistantChat.tsx +6 -10
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +53 -372
- package/corpus/core/src/client/agent-chat-adapter.ts +13 -1
- package/corpus/core/src/client/agent-page/AgentContextTab.tsx +133 -149
- package/corpus/core/src/client/agent-page/AgentEmptyState.tsx +44 -0
- package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +153 -82
- package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +39 -0
- package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +368 -356
- package/corpus/core/src/client/agent-page/types.ts +1 -1
- package/corpus/core/src/client/analytics.ts +51 -5
- package/corpus/core/src/client/chat/run-recovery.tsx +12 -4
- package/corpus/core/src/client/composer/PromptComposer.tsx +5 -15
- package/corpus/core/src/client/composer/TiptapComposer.tsx +32 -3
- package/corpus/core/src/client/dynamic-suggestions.ts +3 -3
- package/corpus/core/src/client/index.ts +16 -1
- package/corpus/core/src/client/resources/ResourceTree.tsx +249 -38
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +307 -140
- package/corpus/core/src/client/session-replay.ts +158 -5
- package/corpus/core/src/client/settings/AutomationsSection.tsx +30 -10
- package/corpus/core/src/client/settings/SettingsPanel.tsx +3 -2
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +2 -0
- package/corpus/core/src/client/settings/agent-settings-search.ts +2 -2
- package/corpus/core/src/client/use-chat-threads.ts +2 -0
- package/corpus/core/src/connections/catalog.ts +49 -7
- package/corpus/core/src/db/index.ts +6 -1
- package/corpus/core/src/extensions/actions.ts +106 -16
- package/corpus/core/src/extensions/content-patch.ts +22 -0
- package/corpus/core/src/extensions/routes.ts +18 -0
- package/corpus/core/src/extensions/store.ts +8 -0
- package/corpus/core/src/index.ts +3 -0
- package/corpus/core/src/ingestion/docx.ts +158 -0
- package/corpus/core/src/ingestion/figma-node-to-html.ts +1860 -0
- package/corpus/core/src/ingestion/figma.ts +548 -0
- package/corpus/core/src/ingestion/index.ts +107 -0
- package/corpus/core/src/ingestion/media.ts +264 -0
- package/corpus/core/src/ingestion/notion.ts +121 -0
- package/corpus/core/src/ingestion/office.ts +214 -0
- package/corpus/core/src/ingestion/orchestration.ts +160 -0
- package/corpus/core/src/ingestion/pptx.ts +333 -0
- package/corpus/core/src/ingestion/selection.ts +81 -0
- package/corpus/core/src/ingestion/website.ts +151 -0
- package/corpus/core/src/integrations/plugin.ts +45 -37
- package/corpus/core/src/localization/default-messages.ts +35 -12
- package/corpus/core/src/observability/hosted-model-experiment.ts +118 -0
- package/corpus/core/src/observability/traces.ts +5 -3
- package/corpus/core/src/provider-api/index.ts +452 -8
- package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +18 -1
- package/corpus/core/src/search-utils/index.ts +112 -0
- package/corpus/core/src/secrets/register-framework-secrets.ts +61 -0
- package/corpus/core/src/server/action-discovery.ts +33 -8
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +2 -2
- package/corpus/core/src/server/agent-chat/prompt-resources.ts +144 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +6 -0
- package/corpus/core/src/server/core-routes-plugin.ts +12 -0
- package/corpus/core/src/server/index.ts +30 -0
- package/corpus/core/src/server/workspace-provider-oauth.ts +583 -0
- package/corpus/core/src/styles/agent-native.css +9 -0
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +3 -3
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
- package/corpus/core/src/templates/workspace-root/.env.example +12 -0
- package/corpus/core/src/vite/client.ts +2 -0
- package/corpus/core/src/workspace-connections/index.ts +6 -0
- package/corpus/core/src/workspace-connections/lifecycle.ts +43 -0
- package/corpus/core/src/workspace-connections/store.ts +16 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +46 -3
- package/corpus/templates/analytics/AGENTS.md +9 -0
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +120 -6
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +92 -30
- package/corpus/templates/analytics/actions/update-dashboard.ts +5 -5
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +313 -220
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +2 -2
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +9 -6
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +90 -64
- package/corpus/templates/analytics/app/i18n-data.ts +3 -3
- package/corpus/templates/analytics/app/lib/dashboard-list-loading.ts +25 -0
- package/corpus/templates/analytics/app/lib/item-popularity.ts +13 -4
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/pivot.ts +8 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +1 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +15 -3
- package/corpus/templates/analytics/changelog/2026-07-16-dashboard-filter-defaults-can-now-be-changed-reliably-withou.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-16-dashboard-lists-load-in-one-stable-order-without-popping-bet.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-16-fixed-dashboard-filter-dropdown-text-alignment.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-16-recurring-signed-in-users-can-now-be-viewed-as-weekly-bars-b.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-16-the-analytics-agent-can-now-duplicate-a-chart-and-place-the-.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +41 -1
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +1 -1
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +47 -1
- package/corpus/templates/analytics/server/lib/session-replay.ts +68 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/analytics/server/routes/sessions/lookup.get.ts +47 -0
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +16 -9
- package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +86 -0
- package/corpus/templates/assets/AGENTS.md +10 -0
- package/corpus/templates/assets/actions/create-generation-session.ts +59 -1
- package/corpus/templates/assets/actions/edit-image.ts +2 -0
- package/corpus/templates/assets/actions/generate-asset.ts +52 -0
- package/corpus/templates/assets/actions/generate-image-batch.ts +55 -0
- package/corpus/templates/assets/actions/generate-image.ts +219 -1
- package/corpus/templates/assets/actions/open-asset-picker.ts +14 -0
- package/corpus/templates/assets/actions/refine-image.ts +3 -0
- package/corpus/templates/assets/actions/restyle-image.ts +2 -0
- package/corpus/templates/assets/agent-native.app-skill.json +4 -0
- package/corpus/templates/assets/app/components/layout/Layout.tsx +2 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/assets/app/i18n-data.ts +29 -13
- package/corpus/templates/assets/app/routes/agent.tsx +7 -1
- package/corpus/templates/assets/app/routes/library.tsx +9 -0
- package/corpus/templates/assets/app/routes/settings.tsx +3 -0
- package/corpus/templates/assets/changelog/2026-07-16-creative-context-library.md +6 -0
- package/corpus/templates/assets/package.json +1 -0
- package/corpus/templates/assets/server/lib/image-processing.ts +1 -22
- package/corpus/templates/assets/server/plugins/creative-context.ts +205 -0
- package/corpus/templates/brain/app/i18n-data.ts +3 -3
- package/corpus/templates/brain/app/lib/brain.ts +1 -1
- package/corpus/templates/brain/server/lib/search.ts +17 -67
- package/corpus/templates/calendar/app/i18n-data.ts +3 -3
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +19 -18
- package/corpus/templates/chat/app/i18n/en-US.ts +3 -3
- package/corpus/templates/chat/app/lib/agent-page.tsx +10 -1
- package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +1 -1
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +35 -4
- package/corpus/templates/clips/actions/create-meeting.ts +6 -2
- package/corpus/templates/clips/actions/create-organization.ts +3 -2
- package/corpus/templates/clips/actions/create-recording.ts +4 -1
- package/corpus/templates/clips/actions/finalize-recording.ts +44 -7
- package/corpus/templates/clips/actions/import-loom-recording.ts +4 -1
- package/corpus/templates/clips/actions/lib/create-recording-schema.ts +2 -2
- package/corpus/templates/clips/actions/list-meetings.ts +23 -5
- package/corpus/templates/clips/actions/list-organization-state.ts +1 -1
- package/corpus/templates/clips/actions/remove-silences.ts +10 -1
- package/corpus/templates/clips/actions/request-transcript.ts +53 -11
- package/corpus/templates/clips/actions/search-recordings-utils.ts +7 -0
- package/corpus/templates/clips/actions/search-recordings.ts +5 -8
- package/corpus/templates/clips/actions/set-organization-branding.ts +2 -2
- package/corpus/templates/clips/actions/stitch-recordings.ts +10 -5
- package/corpus/templates/clips/actions/update-ai-request-status.ts +38 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +3 -4
- package/corpus/templates/clips/app/components/editor/editor-selection.ts +19 -0
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +10 -10
- package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +1 -2
- package/corpus/templates/clips/app/components/library/library-grid.tsx +101 -93
- package/corpus/templates/clips/app/components/player/video-player.tsx +11 -0
- package/corpus/templates/clips/app/components/workspace/branding-editor.tsx +53 -1
- package/corpus/templates/clips/app/i18n/ar-SA.ts +7 -1
- package/corpus/templates/clips/app/i18n/de-DE.ts +7 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +10 -4
- package/corpus/templates/clips/app/i18n/es-ES.ts +7 -1
- package/corpus/templates/clips/app/i18n/fr-FR.ts +7 -1
- package/corpus/templates/clips/app/i18n/hi-IN.ts +7 -1
- package/corpus/templates/clips/app/i18n/ja-JP.ts +7 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +7 -1
- package/corpus/templates/clips/app/i18n/pt-BR.ts +7 -1
- package/corpus/templates/clips/app/i18n/zh-CN.ts +6 -1
- package/corpus/templates/clips/app/i18n/zh-TW.ts +6 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +5 -9
- package/corpus/templates/clips/app/routes/_app.settings.organization.tsx +6 -2
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +129 -27
- package/corpus/templates/clips/app/routes/record.tsx +23 -2
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -2
- package/corpus/templates/clips/changelog/2026-07-16-authorized-viewers-can-open-shared-private-clips-without-a-m.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-camera-bubble-hover-controls-appear-above-the-face.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-chrome-extension-recovers-stale-recorder-state.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-clips-agent-chat-no-longer-shows-a-separate-workspace-header.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-clips-search-now-matches-recording-content-without-requiring.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-declined-meetings-no-longer-show-desktop-reminders.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-failed-desktop-saves-now-show-their-local-recovery-copy.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-long-desktop-clips-now-preserve-complete-playback-synced-aud.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-long-recording-lists-keep-stitch-and-library-actions-visible.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-organization-admins-can-choose-new-recording-visibility.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-remove-silences-now-shows-queued-active-completed-and-failed.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-settings-no-longer-repeats-the-builder-connection-status-in-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-16-transcripts-now-appear-from-native-browser-speech-sooner-wit.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/chrome-extension/src/background.ts +73 -1
- package/corpus/templates/clips/chrome-extension/src/native-recording-state.ts +32 -0
- package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +248 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +106 -0
- package/corpus/templates/clips/desktop/src/app.tsx +66 -28
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +335 -285
- package/corpus/templates/clips/desktop/src/lib/single-flight.ts +7 -0
- package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +51 -0
- package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +2 -2
- package/corpus/templates/clips/desktop/src/overlays/finalizing.tsx +10 -2
- package/corpus/templates/clips/desktop/src/styles.css +13 -11
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +8 -9
- package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +88 -13
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +13 -2
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +241 -6
- package/corpus/templates/clips/server/db/schema.ts +2 -2
- package/corpus/templates/clips/server/lib/builder-media-compression.ts +64 -67
- package/corpus/templates/clips/server/lib/calendar-event-classification.ts +19 -0
- package/corpus/templates/clips/server/lib/google-calendar-client.ts +1 -0
- package/corpus/templates/clips/server/lib/recordings.ts +40 -1
- package/corpus/templates/clips/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/clips/server/plugins/db.ts +2 -2
- package/corpus/templates/clips/server/routes/api/auth/google-calendar.get.ts +1 -1
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +14 -5
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +51 -1
- package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +1 -64
- package/corpus/templates/clips/shared/media-worker-contract.ts +32 -15
- package/corpus/templates/content/.agents/skills/content/SKILL.md +16 -0
- package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +85 -0
- package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +8 -0
- package/corpus/templates/content/AGENTS.md +9 -0
- package/corpus/templates/content/actions/create-document.ts +94 -0
- package/corpus/templates/content/actions/edit-document.ts +144 -4
- package/corpus/templates/content/actions/update-document.ts +138 -0
- package/corpus/templates/content/agent-native.app-skill.json +4 -0
- package/corpus/templates/content/app/components/layout/Layout.tsx +2 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/content/app/i18n-data.ts +13 -4
- package/corpus/templates/content/app/routes/_app.agent.tsx +2 -1
- package/corpus/templates/content/app/routes/_app.settings.tsx +3 -0
- package/corpus/templates/content/changelog/2026-07-16-creative-context-library.md +6 -0
- package/corpus/templates/content/package.json +1 -0
- package/corpus/templates/content/server/plugins/creative-context.ts +31 -0
- package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +116 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +16 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -0
- package/corpus/templates/design/AGENTS.md +6 -0
- package/corpus/templates/design/actions/clone-creative-context-design.ts +176 -0
- package/corpus/templates/design/actions/edit-design.ts +128 -0
- package/corpus/templates/design/actions/generate-design.ts +278 -14
- package/corpus/templates/design/actions/generate-screens.ts +42 -1
- package/corpus/templates/design/agent-native.app-skill.json +4 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +7 -3
- package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/design/app/i18n-data.ts +10 -4
- package/corpus/templates/design/app/routes/agent.tsx +2 -1
- package/corpus/templates/design/app/routes/settings.tsx +3 -0
- package/corpus/templates/design/changelog/2026-07-16-creative-context-library.md +6 -0
- package/corpus/templates/design/changelog/2026-07-16-design-agent-chat-no-longer-shows-a-separate-workspace-header.md +6 -0
- package/corpus/templates/design/package.json +1 -0
- package/corpus/templates/design/server/lib/figma-design-context.ts +5 -335
- package/corpus/templates/design/server/lib/figma-node-to-html.ts +1 -1859
- package/corpus/templates/design/server/lib/import-design-files.ts +6 -8
- package/corpus/templates/design/server/plugins/creative-context.ts +31 -0
- package/corpus/templates/design/shared/generation-session.ts +7 -0
- package/corpus/templates/dispatch/app/i18n-data.ts +3 -3
- package/corpus/templates/forms/app/i18n/en-US.ts +3 -3
- package/corpus/templates/macros/app/i18n/en-US.ts +3 -3
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +35 -5
- package/corpus/templates/mail/app/i18n/en-US.ts +3 -3
- package/corpus/templates/mail/changelog/2026-07-16-mail-previews-now-expand-to-show-the-full-message-without-an.md +6 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +30 -11
- package/corpus/templates/plan/AGENTS.md +21 -1
- package/corpus/templates/plan/actions/get-visual-plan.ts +1 -1
- package/corpus/templates/plan/actions/patch-visual-plan-source.ts +161 -0
- package/corpus/templates/plan/actions/read-visual-plan-source.ts +1 -1
- package/corpus/templates/plan/actions/update-visual-plan.ts +126 -10
- package/corpus/templates/plan/app/hooks/use-plans.ts +2 -0
- package/corpus/templates/plan/app/i18n/en-US.ts +3 -3
- package/corpus/templates/plan/app/pages/PlansPage.tsx +65 -62
- package/corpus/templates/plan/changelog/2026-07-16-local-plan-previews-now-load-annotations-containing-html-lik.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-16-plan-agents-now-prevent-stale-edits-from-overwriting-newer-p.md +6 -0
- package/corpus/templates/plan/server/plan-mdx.ts +75 -2
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +21 -4
- package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +122 -0
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +11 -0
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +12 -3
- package/corpus/templates/slides/AGENTS.md +6 -0
- package/corpus/templates/slides/actions/add-slide.ts +230 -14
- package/corpus/templates/slides/actions/clone-context-slide.ts +302 -0
- package/corpus/templates/slides/actions/create-deck.ts +130 -0
- package/corpus/templates/slides/actions/extract-pdf.ts +6 -2
- package/corpus/templates/slides/actions/import-file.ts +5 -4
- package/corpus/templates/slides/actions/patch-deck.ts +200 -10
- package/corpus/templates/slides/actions/update-slide.ts +208 -15
- package/corpus/templates/slides/app/components/layout/Layout.tsx +2 -0
- package/corpus/templates/slides/app/components/visual-editor/CanvasCommentPins.tsx +16 -1
- package/corpus/templates/slides/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/slides/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +6 -3
- package/corpus/templates/slides/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/slides/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/slides/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/slides/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/slides/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/slides/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/slides/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/slides/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/slides/app/lib/validate-native-slide-html.ts +176 -0
- package/corpus/templates/slides/app/routes/agent.tsx +7 -1
- package/corpus/templates/slides/app/routes/settings.tsx +3 -0
- package/corpus/templates/slides/changelog/2026-07-16-creative-context-library.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-16-google-slides-native-cloning.md +6 -0
- package/corpus/templates/slides/package.json +1 -0
- package/corpus/templates/slides/server/handlers/import/docx-parser.ts +4 -85
- package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +7 -421
- package/corpus/templates/slides/server/plugins/creative-context.ts +166 -0
- package/dist/agent/engine/credential-errors.d.ts +1 -1
- package/dist/agent/engine/credential-errors.d.ts.map +1 -1
- package/dist/agent/engine/credential-errors.js +2 -2
- package/dist/agent/engine/credential-errors.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +25 -0
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +12 -2
- package/dist/agent/run-store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +1 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.js +30 -11
- package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +4 -3
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AgentAskPopover.d.ts +11 -0
- package/dist/client/AgentAskPopover.d.ts.map +1 -0
- package/dist/client/AgentAskPopover.js +30 -0
- package/dist/client/AgentAskPopover.js.map +1 -0
- package/dist/client/AgentChatHome.d.ts +1 -1
- package/dist/client/AgentChatHome.d.ts.map +1 -1
- package/dist/client/AgentChatHome.js +2 -2
- package/dist/client/AgentChatHome.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +9 -19
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +119 -80
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +4 -4
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts +3 -9
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +49 -189
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +12 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-page/AgentContextTab.d.ts.map +1 -1
- package/dist/client/agent-page/AgentContextTab.js +26 -28
- package/dist/client/agent-page/AgentContextTab.js.map +1 -1
- package/dist/client/agent-page/AgentEmptyState.d.ts +13 -0
- package/dist/client/agent-page/AgentEmptyState.d.ts.map +1 -0
- package/dist/client/agent-page/AgentEmptyState.js +6 -0
- package/dist/client/agent-page/AgentEmptyState.js.map +1 -0
- package/dist/client/agent-page/AgentJobsTab.d.ts +1 -1
- package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.js +90 -58
- package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
- package/dist/client/agent-page/AgentTabFrame.d.ts +12 -0
- package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -0
- package/dist/client/agent-page/AgentTabFrame.js +7 -0
- package/dist/client/agent-page/AgentTabFrame.js.map +1 -0
- package/dist/client/agent-page/AgentTabsPage.d.ts +9 -1
- package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
- package/dist/client/agent-page/AgentTabsPage.js +135 -99
- package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
- package/dist/client/agent-page/types.d.ts +1 -1
- package/dist/client/agent-page/types.d.ts.map +1 -1
- package/dist/client/agent-page/types.js.map +1 -1
- package/dist/client/analytics.d.ts +10 -3
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +37 -2
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +10 -3
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +2 -2
- 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 +15 -3
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/dynamic-suggestions.js +3 -3
- package/dist/client/dynamic-suggestions.js.map +1 -1
- package/dist/client/index.d.ts +4 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +5 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +74 -5
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts +11 -2
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +105 -31
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/session-replay.d.ts +28 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +122 -8
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/AutomationsSection.d.ts +3 -1
- package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
- package/dist/client/settings/AutomationsSection.js +16 -6
- package/dist/client/settings/AutomationsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +3 -3
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts +2 -0
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/settings/agent-settings-search.js +2 -2
- package/dist/client/settings/agent-settings-search.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts +2 -0
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +41 -7
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +40 -7
- package/dist/connections/catalog.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +2 -2
- package/dist/db/index.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +85 -15
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/content-patch.d.ts +4 -0
- package/dist/extensions/content-patch.d.ts.map +1 -1
- package/dist/extensions/content-patch.js +18 -0
- package/dist/extensions/content-patch.js.map +1 -1
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +14 -0
- package/dist/extensions/routes.js.map +1 -1
- package/dist/extensions/store.d.ts +1 -0
- package/dist/extensions/store.d.ts.map +1 -1
- package/dist/extensions/store.js +4 -1
- package/dist/extensions/store.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/ingestion/docx.d.ts +16 -0
- package/dist/ingestion/docx.d.ts.map +1 -0
- package/dist/ingestion/docx.js +129 -0
- package/dist/ingestion/docx.js.map +1 -0
- package/dist/ingestion/figma-node-to-html.d.ts +304 -0
- package/dist/ingestion/figma-node-to-html.d.ts.map +1 -0
- package/dist/ingestion/figma-node-to-html.js +1292 -0
- package/dist/ingestion/figma-node-to-html.js.map +1 -0
- package/dist/ingestion/figma.d.ts +115 -0
- package/dist/ingestion/figma.d.ts.map +1 -0
- package/dist/ingestion/figma.js +399 -0
- package/dist/ingestion/figma.js.map +1 -0
- package/dist/ingestion/index.d.ts +11 -0
- package/dist/ingestion/index.d.ts.map +1 -0
- package/dist/ingestion/index.js +11 -0
- package/dist/ingestion/index.js.map +1 -0
- package/dist/ingestion/media.d.ts +36 -0
- package/dist/ingestion/media.d.ts.map +1 -0
- package/dist/ingestion/media.js +178 -0
- package/dist/ingestion/media.js.map +1 -0
- package/dist/ingestion/notion.d.ts +12 -0
- package/dist/ingestion/notion.d.ts.map +1 -0
- package/dist/ingestion/notion.js +104 -0
- package/dist/ingestion/notion.js.map +1 -0
- package/dist/ingestion/office.d.ts +45 -0
- package/dist/ingestion/office.d.ts.map +1 -0
- package/dist/ingestion/office.js +141 -0
- package/dist/ingestion/office.js.map +1 -0
- package/dist/ingestion/orchestration.d.ts +52 -0
- package/dist/ingestion/orchestration.d.ts.map +1 -0
- package/dist/ingestion/orchestration.js +89 -0
- package/dist/ingestion/orchestration.js.map +1 -0
- package/dist/ingestion/pptx.d.ts +28 -0
- package/dist/ingestion/pptx.d.ts.map +1 -0
- package/dist/ingestion/pptx.js +255 -0
- package/dist/ingestion/pptx.js.map +1 -0
- package/dist/ingestion/selection.d.ts +20 -0
- package/dist/ingestion/selection.d.ts.map +1 -0
- package/dist/ingestion/selection.js +52 -0
- package/dist/ingestion/selection.js.map +1 -0
- package/dist/ingestion/website.d.ts +27 -0
- package/dist/ingestion/website.d.ts.map +1 -0
- package/dist/ingestion/website.js +100 -0
- package/dist/ingestion/website.js.map +1 -0
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +32 -27
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/localization/default-messages.d.ts +22 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +31 -9
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/observability/hosted-model-experiment.d.ts +39 -0
- package/dist/observability/hosted-model-experiment.d.ts.map +1 -0
- package/dist/observability/hosted-model-experiment.js +90 -0
- package/dist/observability/hosted-model-experiment.js.map +1 -0
- package/dist/observability/routes.d.ts +5 -5
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +5 -3
- package/dist/observability/traces.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/index.d.ts +35 -4
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +339 -8
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +18 -1
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
- package/dist/search-utils/index.d.ts +12 -0
- package/dist/search-utils/index.d.ts.map +1 -0
- package/dist/search-utils/index.js +95 -0
- package/dist/search-utils/index.js.map +1 -0
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +57 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/action-discovery.d.ts +8 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +26 -9
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +2 -2
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat/prompt-resources.d.ts +19 -0
- package/dist/server/agent-chat/prompt-resources.d.ts.map +1 -1
- package/dist/server/agent-chat/prompt-resources.js +95 -0
- package/dist/server/agent-chat/prompt-resources.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +7 -0
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +5 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/index.d.ts +5 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +5 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +48 -0
- package/dist/server/workspace-provider-oauth.d.ts.map +1 -0
- package/dist/server/workspace-provider-oauth.js +415 -0
- package/dist/server/workspace-provider-oauth.js.map +1 -0
- package/dist/styles/agent-native.css +9 -0
- package/dist/templates/chat/app/i18n/en-US.ts +3 -3
- package/dist/templates/chat/app/lib/agent-page.tsx +10 -1
- package/dist/templates/default/app/i18n/en-US.ts +3 -3
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
- package/dist/templates/workspace-root/.env.example +12 -0
- 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/dist/workspace-connections/index.d.ts +1 -0
- package/dist/workspace-connections/index.d.ts.map +1 -1
- package/dist/workspace-connections/index.js +1 -0
- package/dist/workspace-connections/index.js.map +1 -1
- package/dist/workspace-connections/lifecycle.d.ts +16 -0
- package/dist/workspace-connections/lifecycle.d.ts.map +1 -0
- package/dist/workspace-connections/lifecycle.js +14 -0
- package/dist/workspace-connections/lifecycle.js.map +1 -0
- package/dist/workspace-connections/store.d.ts.map +1 -1
- package/dist/workspace-connections/store.js +16 -0
- package/dist/workspace-connections/store.js.map +1 -1
- package/package.json +10 -3
- package/src/templates/chat/app/i18n/en-US.ts +3 -3
- package/src/templates/chat/app/lib/agent-page.spec.tsx +10 -1
- package/src/templates/chat/app/lib/agent-page.tsx +10 -1
- package/src/templates/default/app/i18n/en-US.ts +3 -3
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
- package/src/templates/workspace-root/.env.example +12 -0
|
@@ -64,3 +64,9 @@ export {
|
|
|
64
64
|
type WorkspaceConnectionCredentialResolutionStatus,
|
|
65
65
|
type WorkspaceConnectionCredentialsResolution,
|
|
66
66
|
} from "./credentials.js";
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
registerWorkspaceConnectionLifecycleListener,
|
|
70
|
+
type WorkspaceConnectionLifecycleEvent,
|
|
71
|
+
type WorkspaceConnectionLifecycleListener,
|
|
72
|
+
} from "./lifecycle.js";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type WorkspaceConnectionLifecycleEvent =
|
|
2
|
+
| {
|
|
3
|
+
type: "connection-deleted";
|
|
4
|
+
connectionId: string;
|
|
5
|
+
ownerEmail: string;
|
|
6
|
+
orgId: string | null;
|
|
7
|
+
}
|
|
8
|
+
| {
|
|
9
|
+
type: "grant-revoked";
|
|
10
|
+
connectionId: string;
|
|
11
|
+
appId: string;
|
|
12
|
+
ownerEmail: string;
|
|
13
|
+
orgId: string | null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type WorkspaceConnectionLifecycleListener = (
|
|
17
|
+
event: WorkspaceConnectionLifecycleEvent,
|
|
18
|
+
) => void | Promise<void>;
|
|
19
|
+
|
|
20
|
+
const LISTENERS_KEY = Symbol.for(
|
|
21
|
+
"@agent-native/core.workspace-connection-lifecycle-listeners",
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
function listeners(): Set<WorkspaceConnectionLifecycleListener> {
|
|
25
|
+
const global = globalThis as typeof globalThis & {
|
|
26
|
+
[LISTENERS_KEY]?: Set<WorkspaceConnectionLifecycleListener>;
|
|
27
|
+
};
|
|
28
|
+
global[LISTENERS_KEY] ??= new Set();
|
|
29
|
+
return global[LISTENERS_KEY];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function registerWorkspaceConnectionLifecycleListener(
|
|
33
|
+
listener: WorkspaceConnectionLifecycleListener,
|
|
34
|
+
): () => void {
|
|
35
|
+
listeners().add(listener);
|
|
36
|
+
return () => listeners().delete(listener);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function notifyWorkspaceConnectionLifecycle(
|
|
40
|
+
event: WorkspaceConnectionLifecycleEvent,
|
|
41
|
+
): Promise<void> {
|
|
42
|
+
await Promise.all([...listeners()].map((listener) => listener(event)));
|
|
43
|
+
}
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
getRequestOrgId,
|
|
25
25
|
getRequestUserEmail,
|
|
26
26
|
} from "../server/request-context.js";
|
|
27
|
+
import { notifyWorkspaceConnectionLifecycle } from "./lifecycle.js";
|
|
27
28
|
|
|
28
29
|
export type WorkspaceConnectionStatus =
|
|
29
30
|
| "connected"
|
|
@@ -1903,6 +1904,15 @@ export async function revokeWorkspaceConnectionGrant(
|
|
|
1903
1904
|
sql: `DELETE FROM ${table} WHERE connection_id = ? AND app_id = ? AND ${where.sql}`,
|
|
1904
1905
|
args: [normalizedConnectionId, normalizedAppId, ...where.args],
|
|
1905
1906
|
});
|
|
1907
|
+
if (result.rowsAffected > 0) {
|
|
1908
|
+
await notifyWorkspaceConnectionLifecycle({
|
|
1909
|
+
type: "grant-revoked",
|
|
1910
|
+
connectionId: normalizedConnectionId,
|
|
1911
|
+
appId: normalizedAppId,
|
|
1912
|
+
ownerEmail: scope.ownerEmail,
|
|
1913
|
+
orgId: scope.orgId,
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
1906
1916
|
return result.rowsAffected > 0;
|
|
1907
1917
|
}
|
|
1908
1918
|
|
|
@@ -1922,6 +1932,12 @@ export async function deleteWorkspaceConnection(id: string): Promise<boolean> {
|
|
|
1922
1932
|
sql: `DELETE FROM ${grantsTable} WHERE connection_id = ? AND ${where.sql}`,
|
|
1923
1933
|
args: [id, ...where.args],
|
|
1924
1934
|
});
|
|
1935
|
+
await notifyWorkspaceConnectionLifecycle({
|
|
1936
|
+
type: "connection-deleted",
|
|
1937
|
+
connectionId: id,
|
|
1938
|
+
ownerEmail: scope.ownerEmail,
|
|
1939
|
+
orgId: scope.orgId,
|
|
1940
|
+
});
|
|
1925
1941
|
}
|
|
1926
1942
|
return result.rowsAffected > 0;
|
|
1927
1943
|
}
|
|
@@ -192,6 +192,20 @@ re-typing it as a `content` argument.
|
|
|
192
192
|
extension panel (`chartType: "extension"`, `config.extensionId`), then
|
|
193
193
|
`navigate` to it.
|
|
194
194
|
|
|
195
|
+
## Repairing An Existing Extension-Backed Dashboard
|
|
196
|
+
|
|
197
|
+
When the user asks to fix data loading in an existing or migrated
|
|
198
|
+
extension-backed dashboard, treat the current extension body as user-authored
|
|
199
|
+
design. Read the dashboard config and extension once, identify the smallest
|
|
200
|
+
data-loading seam, and call `update-extension` with focused `patches` or
|
|
201
|
+
`edits`. Preserve the existing layout, CSS, copy, and interactions. Do not
|
|
202
|
+
send a reconstructed full `content` body for a data-only repair;
|
|
203
|
+
`update-extension` blocks full-body replacement unless
|
|
204
|
+
`allowFullReplacement: true` is explicitly supplied. Use that flag only for a
|
|
205
|
+
user-requested broad visual rewrite or a complete replacement body supplied by
|
|
206
|
+
the user. If a focused edit fails, inspect the current body and change the
|
|
207
|
+
target rather than retrying the same arguments.
|
|
208
|
+
|
|
195
209
|
### Display truncation is cosmetic — do not chase the "missing" tail
|
|
196
210
|
|
|
197
211
|
A tool result ending in `...[truncated — full result was N chars; only first
|
|
@@ -315,6 +329,10 @@ calling other actions from the script are not available.
|
|
|
315
329
|
type DashboardMutationApi = {
|
|
316
330
|
dashboard: {
|
|
317
331
|
set(patch: DashboardPatch): void;
|
|
332
|
+
setFilterDefault(
|
|
333
|
+
filterId: string,
|
|
334
|
+
value: string | number | boolean | null,
|
|
335
|
+
): void;
|
|
318
336
|
panel(id: string): PanelSelection;
|
|
319
337
|
section(id: string): SectionSelection;
|
|
320
338
|
panels(ids: string[]): PanelSelection;
|
|
@@ -329,6 +347,7 @@ type DashboardPatch = {
|
|
|
329
347
|
columns?: number;
|
|
330
348
|
filters?: unknown[];
|
|
331
349
|
variables?: Record<string, string>;
|
|
350
|
+
parentId?: string;
|
|
332
351
|
};
|
|
333
352
|
|
|
334
353
|
type PanelTimeScope =
|
|
@@ -340,6 +359,7 @@ type PanelTimeScope =
|
|
|
340
359
|
type PanelConfig = Record<string, unknown> & {
|
|
341
360
|
// Use "dashboard" for AI-generated first-party panels by default.
|
|
342
361
|
timeScope?: PanelTimeScope;
|
|
362
|
+
// Fixed bar width in pixels for bar charts.
|
|
343
363
|
};
|
|
344
364
|
|
|
345
365
|
type PanelPatch = {
|
|
@@ -351,7 +371,8 @@ type PanelPatch = {
|
|
|
351
371
|
| "amplitude"
|
|
352
372
|
| "first-party"
|
|
353
373
|
| "demo"
|
|
354
|
-
| "prometheus"
|
|
374
|
+
| "prometheus"
|
|
375
|
+
| "program";
|
|
355
376
|
chartType?:
|
|
356
377
|
| "line"
|
|
357
378
|
| "area"
|
|
@@ -397,6 +418,14 @@ type PanelSelection = {
|
|
|
397
418
|
moveBefore(panelId: string): void;
|
|
398
419
|
moveAfter(panelId: string): void;
|
|
399
420
|
moveToIndex(index: number): void;
|
|
421
|
+
moveNextTo(panelId: string): void;
|
|
422
|
+
nextTo(panelId: string): void;
|
|
423
|
+
moveToRow(rowNumber: number): void;
|
|
424
|
+
moveToRowStart(rowNumber: number): void;
|
|
425
|
+
moveToRowEnd(rowNumber: number): void;
|
|
426
|
+
atRow(rowNumber: number): void;
|
|
427
|
+
atRowStart(rowNumber: number): void;
|
|
428
|
+
atRowEnd(rowNumber: number): void;
|
|
400
429
|
remove(): void;
|
|
401
430
|
set(patch: PanelPatch): void;
|
|
402
431
|
setTitle(title: string): void;
|
|
@@ -404,26 +433,40 @@ type PanelSelection = {
|
|
|
404
433
|
setWidth(width: number): void;
|
|
405
434
|
setConfig(patch: Record<string, unknown>): void;
|
|
406
435
|
setConfigPath(path: string, value: unknown): void;
|
|
407
|
-
duplicate(newPanelId: string, patch?: PanelPatch):
|
|
436
|
+
duplicate(newPanelId: string, patch?: PanelPatch): PanelPlacement;
|
|
408
437
|
};
|
|
409
438
|
|
|
410
439
|
type SectionSelection = PanelSelection & {
|
|
411
440
|
append(panelIds: string[]): void;
|
|
412
441
|
};
|
|
413
442
|
|
|
414
|
-
type
|
|
443
|
+
type PanelPlacement = {
|
|
415
444
|
atTop(): void;
|
|
416
445
|
atBottom(): void;
|
|
417
446
|
before(panelId: string): void;
|
|
418
447
|
after(panelId: string): void;
|
|
419
448
|
atIndex(index: number): void;
|
|
449
|
+
nextTo(panelId: string): void;
|
|
450
|
+
atRow(rowNumber: number): void;
|
|
451
|
+
atRowStart(rowNumber: number): void;
|
|
452
|
+
atRowEnd(rowNumber: number): void;
|
|
420
453
|
};
|
|
454
|
+
|
|
455
|
+
type InsertedPanel = PanelPlacement;
|
|
421
456
|
```
|
|
422
457
|
|
|
423
458
|
Examples:
|
|
424
459
|
|
|
425
460
|
```ts
|
|
426
461
|
dashboard.panels(["dau-over-time", "wau-over-time"]).moveToTop();
|
|
462
|
+
dashboard
|
|
463
|
+
.panel("recurring-users-by-template")
|
|
464
|
+
.duplicate("recurring-users-by-template-bar", {
|
|
465
|
+
title: "Recurring Signed-In Users by Template (Bar)",
|
|
466
|
+
chartType: "bar",
|
|
467
|
+
})
|
|
468
|
+
.nextTo("recurring-users-by-template");
|
|
469
|
+
dashboard.setFilterDefault("emailFilter", "exclude_builder");
|
|
427
470
|
dashboard.panel("top-referrers").setTitle("Top Referrers by Domain");
|
|
428
471
|
dashboard.panel("retention").set({
|
|
429
472
|
width: 2,
|
|
@@ -175,6 +175,15 @@ details live in `.agents/skills/`.
|
|
|
175
175
|
or bespoke workflow cannot be done faithfully with the built-in dashboard JSON
|
|
176
176
|
config/components or saved-analysis markdown/chart format, automatically build
|
|
177
177
|
it as an extension instead and tell the user why.
|
|
178
|
+
- For an existing extension-backed dashboard or migrated surface such as Risk
|
|
179
|
+
Meeting, separate data repair from visual redesign. Inspect the dashboard and
|
|
180
|
+
extension first, then use `update-extension` `patches`/`edits` that touch only
|
|
181
|
+
the data-loading seam. Preserve the existing layout, CSS, copy, and
|
|
182
|
+
interactions; never reconstruct the full HTML body for a data-only fix.
|
|
183
|
+
`update-extension` blocks full-body replacement unless
|
|
184
|
+
`allowFullReplacement: true` is explicit, and that flag is reserved for a
|
|
185
|
+
user-requested broad rewrite or a complete replacement body supplied by the
|
|
186
|
+
user. If a focused edit fails, do not retry unchanged arguments.
|
|
178
187
|
- Use framework sharing and access helpers for dashboards, analyses, and saved
|
|
179
188
|
resources.
|
|
180
189
|
- Dashboard email reports live in SQL via the
|
|
@@ -14,6 +14,7 @@ import { movePanelsById, type PanelOrderTarget } from "./dashboard-panel-order";
|
|
|
14
14
|
export const DASHBOARD_MUTATION_API_TYPES = `type DashboardScript = {
|
|
15
15
|
dashboard: {
|
|
16
16
|
set(patch: DashboardPatch): void;
|
|
17
|
+
setFilterDefault(filterId: string, value: string | number | boolean | null): void;
|
|
17
18
|
panel(id: string): PanelSelection;
|
|
18
19
|
section(id: string): SectionSelection;
|
|
19
20
|
panels(ids: string[]): PanelSelection;
|
|
@@ -41,6 +42,7 @@ type PanelTimeScope =
|
|
|
41
42
|
type PanelConfig = Record<string, unknown> & {
|
|
42
43
|
/** Use "dashboard" for AI-generated first-party panels by default. */
|
|
43
44
|
timeScope?: PanelTimeScope;
|
|
45
|
+
/** Fixed bar width in pixels for bar charts. */
|
|
44
46
|
};
|
|
45
47
|
|
|
46
48
|
type PanelPatch = {
|
|
@@ -96,14 +98,14 @@ type PanelSelection = {
|
|
|
96
98
|
setWidth(width: number): void;
|
|
97
99
|
setConfig(patch: Record<string, unknown>): void;
|
|
98
100
|
setConfigPath(path: string, value: unknown): void; // path under config, e.g. "yAxis.format" or "config.yAxis.format"
|
|
99
|
-
duplicate(newPanelId: string, patch?: PanelPatch):
|
|
101
|
+
duplicate(newPanelId: string, patch?: PanelPatch): PanelPlacement;
|
|
100
102
|
};
|
|
101
103
|
|
|
102
104
|
type SectionSelection = PanelSelection & {
|
|
103
105
|
append(panelIds: string[]): void;
|
|
104
106
|
};
|
|
105
107
|
|
|
106
|
-
type
|
|
108
|
+
type PanelPlacement = {
|
|
107
109
|
atTop(): void;
|
|
108
110
|
atBottom(): void;
|
|
109
111
|
before(panelId: string): void;
|
|
@@ -113,10 +115,14 @@ type InsertedPanel = {
|
|
|
113
115
|
atRow(rowNumber: number): void; // 1-based visible row number, end of row
|
|
114
116
|
atRowStart(rowNumber: number): void;
|
|
115
117
|
atRowEnd(rowNumber: number): void;
|
|
116
|
-
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type InsertedPanel = PanelPlacement;`;
|
|
117
121
|
|
|
118
122
|
export const DASHBOARD_MUTATION_EXAMPLES = [
|
|
119
123
|
'dashboard.panels(["dau-over-time","wau-over-time"]).moveToTop();',
|
|
124
|
+
'dashboard.panel("recurring-users-by-template").duplicate("recurring-users-by-template-bar", {"title":"Recurring Signed-In Users by Template (Bar)","chartType":"bar"}).nextTo("recurring-users-by-template");',
|
|
125
|
+
'dashboard.setFilterDefault("emailFilter","exclude_builder");',
|
|
120
126
|
'dashboard.panel("top-referrers").setTitle("Top Referrers by Domain");',
|
|
121
127
|
'dashboard.panel("retention").set({"width":2,"config":{"description":"Updated definition."}});',
|
|
122
128
|
'dashboard.panelsMatching({"titleIncludes":"Signed-In"}).moveToTop();',
|
|
@@ -183,6 +189,11 @@ export type DashboardMutationOperation =
|
|
|
183
189
|
| {
|
|
184
190
|
op: "setDashboard";
|
|
185
191
|
patch: Record<string, unknown>;
|
|
192
|
+
}
|
|
193
|
+
| {
|
|
194
|
+
op: "setFilterDefault";
|
|
195
|
+
filterId: string;
|
|
196
|
+
value: string | number | boolean | null;
|
|
186
197
|
};
|
|
187
198
|
|
|
188
199
|
export interface DashboardMutationResult {
|
|
@@ -217,6 +228,7 @@ type DashboardPlacementTarget = PanelOrderTarget | VisualPlacementTarget;
|
|
|
217
228
|
|
|
218
229
|
const DASHBOARD_SUBJECTS = [
|
|
219
230
|
"set",
|
|
231
|
+
"setFilterDefault",
|
|
220
232
|
"panel",
|
|
221
233
|
"section",
|
|
222
234
|
"panels",
|
|
@@ -277,6 +289,49 @@ function panelsFromConfig(config: Record<string, unknown>) {
|
|
|
277
289
|
return panels as Array<Record<string, unknown>>;
|
|
278
290
|
}
|
|
279
291
|
|
|
292
|
+
function requireDashboardFilter(
|
|
293
|
+
config: Record<string, unknown>,
|
|
294
|
+
filterId: string,
|
|
295
|
+
): Record<string, unknown> {
|
|
296
|
+
if (!Array.isArray(config.filters)) {
|
|
297
|
+
throw new Error("config.filters must be an array");
|
|
298
|
+
}
|
|
299
|
+
const filters = config.filters as Array<Record<string, unknown>>;
|
|
300
|
+
const filter = filters.find((item) => item?.id === filterId);
|
|
301
|
+
if (!filter) {
|
|
302
|
+
const ids = filters
|
|
303
|
+
.map((item) => (typeof item?.id === "string" ? item.id : ""))
|
|
304
|
+
.filter(Boolean);
|
|
305
|
+
throw new Error(
|
|
306
|
+
`filter "${filterId}" was not found. Available filter ids: ${compactList(ids)}.`,
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
return filter;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function setFilterDefault(
|
|
313
|
+
config: Record<string, unknown>,
|
|
314
|
+
filterId: string,
|
|
315
|
+
value: string | number | boolean | null,
|
|
316
|
+
): void {
|
|
317
|
+
const filter = requireDashboardFilter(config, filterId);
|
|
318
|
+
if (Array.isArray(filter.options) && filter.options.length > 0) {
|
|
319
|
+
const optionValues = filter.options
|
|
320
|
+
.map((option) =>
|
|
321
|
+
option && typeof option === "object" && !Array.isArray(option)
|
|
322
|
+
? (option as Record<string, unknown>).value
|
|
323
|
+
: undefined,
|
|
324
|
+
)
|
|
325
|
+
.filter((optionValue) => optionValue !== undefined);
|
|
326
|
+
if (!optionValues.some((optionValue) => Object.is(optionValue, value))) {
|
|
327
|
+
throw new Error(
|
|
328
|
+
`filter "${filterId}" default ${JSON.stringify(value)} is not one of its option values: ${optionValues.map((optionValue) => JSON.stringify(optionValue)).join(", ")}`,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
filter.default = value;
|
|
333
|
+
}
|
|
334
|
+
|
|
280
335
|
function panelId(panel: Record<string, unknown>): string {
|
|
281
336
|
return typeof panel.id === "string" ? panel.id : "";
|
|
282
337
|
}
|
|
@@ -895,6 +950,14 @@ export function applyDashboardMutationOperations(
|
|
|
895
950
|
);
|
|
896
951
|
break;
|
|
897
952
|
}
|
|
953
|
+
case "setFilterDefault": {
|
|
954
|
+
setFilterDefault(config, op.filterId, op.value);
|
|
955
|
+
dashboardFieldsChanged.add(`filters.${op.filterId}.default`);
|
|
956
|
+
commandLog.push(
|
|
957
|
+
`setFilterDefault(${op.filterId}: ${JSON.stringify(op.value)})`,
|
|
958
|
+
);
|
|
959
|
+
break;
|
|
960
|
+
}
|
|
898
961
|
default:
|
|
899
962
|
throw new Error(
|
|
900
963
|
`unsupported dashboard mutation op ${(op as any).op}`,
|
|
@@ -1304,6 +1367,33 @@ function operationsFromStatement(
|
|
|
1304
1367
|
];
|
|
1305
1368
|
}
|
|
1306
1369
|
|
|
1370
|
+
if (subject.name === "setFilterDefault") {
|
|
1371
|
+
if (commands.length > 0) {
|
|
1372
|
+
throw new Error("dashboard.setFilterDefault(...) cannot be chained");
|
|
1373
|
+
}
|
|
1374
|
+
if (subject.args.length !== 2) {
|
|
1375
|
+
throw new Error(
|
|
1376
|
+
"dashboard.setFilterDefault(...) requires filterId and value",
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
const value = subject.args[1];
|
|
1380
|
+
if (
|
|
1381
|
+
value !== null &&
|
|
1382
|
+
!["string", "number", "boolean"].includes(typeof value)
|
|
1383
|
+
) {
|
|
1384
|
+
throw new Error(
|
|
1385
|
+
"dashboard.setFilterDefault(...) value must be a string, number, boolean, or null",
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
return [
|
|
1389
|
+
{
|
|
1390
|
+
op: "setFilterDefault",
|
|
1391
|
+
filterId: assertString(subject.args[0], "filter id"),
|
|
1392
|
+
value: value as string | number | boolean | null,
|
|
1393
|
+
},
|
|
1394
|
+
];
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1307
1397
|
if (commands.length === 0) {
|
|
1308
1398
|
throw new Error(`mutation statement has no command: ${statement}`);
|
|
1309
1399
|
}
|
|
@@ -1370,9 +1460,33 @@ function operationsFromStatement(
|
|
|
1370
1460
|
|
|
1371
1461
|
requirePanelIds(config, panelIds);
|
|
1372
1462
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1463
|
+
const operations: DashboardMutationOperation[] = [];
|
|
1464
|
+
for (let index = 0; index < commands.length; index++) {
|
|
1465
|
+
const command = commands[index];
|
|
1466
|
+
if (command.name !== "duplicate") {
|
|
1467
|
+
operations.push(...operationFromPanelCommand(panelIds, command));
|
|
1468
|
+
continue;
|
|
1469
|
+
}
|
|
1470
|
+
if (panelIds.length !== 1) {
|
|
1471
|
+
throw new Error("duplicate requires exactly one selected panel");
|
|
1472
|
+
}
|
|
1473
|
+
const placement = commands[index + 1];
|
|
1474
|
+
if (placement && index + 1 !== commands.length - 1) {
|
|
1475
|
+
throw new Error("duplicate accepts at most one placement method");
|
|
1476
|
+
}
|
|
1477
|
+
operations.push({
|
|
1478
|
+
op: "duplicatePanel",
|
|
1479
|
+
panelId: panelIds[0],
|
|
1480
|
+
newPanelId: assertString(command.args[0], "newPanelId"),
|
|
1481
|
+
patch:
|
|
1482
|
+
command.args[1] === undefined
|
|
1483
|
+
? undefined
|
|
1484
|
+
: assertObject(command.args[1], "duplicate patch"),
|
|
1485
|
+
...(placement ? targetFromChainCall(placement) : {}),
|
|
1486
|
+
});
|
|
1487
|
+
if (placement) index++;
|
|
1488
|
+
}
|
|
1489
|
+
return operations;
|
|
1376
1490
|
}
|
|
1377
1491
|
|
|
1378
1492
|
export function parseDashboardMutationScript(
|
|
@@ -85,6 +85,11 @@ const mutationOperationSchema = z.discriminatedUnion("op", [
|
|
|
85
85
|
op: z.literal("setDashboard"),
|
|
86
86
|
patch: z.record(z.string(), z.unknown()),
|
|
87
87
|
}),
|
|
88
|
+
z.object({
|
|
89
|
+
op: z.literal("setFilterDefault"),
|
|
90
|
+
filterId: z.string().min(1),
|
|
91
|
+
value: z.union([z.string(), z.number(), z.boolean(), z.null()]),
|
|
92
|
+
}),
|
|
88
93
|
]);
|
|
89
94
|
|
|
90
95
|
function parseJsonArrayString(
|
|
@@ -112,19 +117,41 @@ function parseJsonArrayString(
|
|
|
112
117
|
const operationsInputSchema = z
|
|
113
118
|
.union([
|
|
114
119
|
z.array(mutationOperationSchema),
|
|
115
|
-
z.string().transform((value) =>
|
|
120
|
+
z.string().transform((value) => {
|
|
121
|
+
const trimmed = value.trim();
|
|
122
|
+
return trimmed ? parseJsonArrayString(trimmed, "operations") : undefined;
|
|
123
|
+
}),
|
|
116
124
|
])
|
|
117
125
|
.optional();
|
|
118
126
|
|
|
127
|
+
function nonEmptyCode(value: string | undefined): string | undefined {
|
|
128
|
+
return value?.trim() ? value : undefined;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function nonEmptyOperations(
|
|
132
|
+
value: DashboardMutationOperation[] | undefined,
|
|
133
|
+
): DashboardMutationOperation[] | undefined {
|
|
134
|
+
return value && value.length > 0 ? value : undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
119
137
|
const apiHelp =
|
|
120
138
|
"Constrained TypeScript-like dashboard mutation script. The server parses only calls on `dashboard`; it does not execute arbitrary JavaScript. " +
|
|
121
139
|
"No variables, imports, loops, functions, templates, network, filesystem, or DB access. Arguments must be JSON-compatible literals, so quote object keys. " +
|
|
122
|
-
"Subjects: dashboard.set, dashboard.panel, dashboard.panels, dashboard.panelsMatching, dashboard.section, dashboard.insertPanel. " +
|
|
123
|
-
|
|
140
|
+
"Subjects: dashboard.set, dashboard.setFilterDefault, dashboard.panel, dashboard.panels, dashboard.panelsMatching, dashboard.section, dashboard.insertPanel. " +
|
|
141
|
+
'For a simple default-filter change, use `dashboard.setFilterDefault("emailFilter","exclude_builder");`; it verifies the filter and option value without resending every filter or revalidating unchanged panel SQL. ' +
|
|
142
|
+
'Selection methods: moveToTop, moveToBottom, moveBefore, moveAfter, moveToIndex, moveNextTo, moveToRow, remove, set, setTitle, setSql, setWidth, setConfig, setConfigPath, duplicate. Duplicate supports one chained placement method, for example `dashboard.panel("source").duplicate("copy", {"chartType":"bar"}).nextTo("source");`. ' +
|
|
124
143
|
"Inserted panels support atTop, atBottom, before, after, atIndex, nextTo, atRow, atRowStart, and atRowEnd. Use nextTo(panelId) or atRow(rowNumber) for visible row placement. " +
|
|
125
144
|
"AI-generated first-party panels are dashboard-time-bound by default: set config.timeScope to dashboard and include a matching dashboard time filter in SQL. Allowed values are dashboard, fixed-window, cohort-history, and all-time; use all-time only when the user requests full available history and put all-time, lifetime, or historical in the title or description. A {{timeRange}} token requires the timeRange select filter; {{<id>Start}}/{{<id>End}} require a matching date-range filter. Server validation rejects unbound first-party SQL. " +
|
|
126
145
|
`Examples: ${DASHBOARD_MUTATION_EXAMPLES.slice(0, 5).join(" ")}`;
|
|
127
146
|
|
|
147
|
+
const agentInputSchema = z.object({
|
|
148
|
+
dashboardId: z
|
|
149
|
+
.string()
|
|
150
|
+
.min(1)
|
|
151
|
+
.describe("Dashboard id, e.g. 'agent-native-templates-first-party'."),
|
|
152
|
+
code: z.string().min(1).describe(apiHelp),
|
|
153
|
+
});
|
|
154
|
+
|
|
128
155
|
function resolveScope() {
|
|
129
156
|
const orgId = getRequestOrgId() || null;
|
|
130
157
|
const email = getRequestUserEmail();
|
|
@@ -162,17 +189,52 @@ async function syncToCollab(
|
|
|
162
189
|
}
|
|
163
190
|
}
|
|
164
191
|
|
|
165
|
-
function
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
)
|
|
192
|
+
function sqlValidationScope(
|
|
193
|
+
operations: DashboardMutationOperation[],
|
|
194
|
+
): ReadonlySet<string> | "all" | null {
|
|
195
|
+
const panelIds = new Set<string>();
|
|
196
|
+
for (const op of operations) {
|
|
197
|
+
if (op.op === "setDashboard") {
|
|
198
|
+
if (
|
|
199
|
+
Object.keys(op.patch).some((key) =>
|
|
200
|
+
["filters", "variables", "panels"].includes(key),
|
|
201
|
+
)
|
|
202
|
+
) {
|
|
203
|
+
return "all";
|
|
204
|
+
}
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (op.op === "insertPanel") {
|
|
208
|
+
if (typeof op.panel.id === "string") panelIds.add(op.panel.id);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (op.op === "duplicatePanel") {
|
|
212
|
+
panelIds.add(op.newPanelId);
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (op.op === "updatePanelPath") {
|
|
216
|
+
panelIds.add(op.panelId);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (
|
|
220
|
+
op.op === "updatePanel" &&
|
|
221
|
+
Object.keys(op.patch).some((key) =>
|
|
222
|
+
["sql", "source", "chartType", "config"].includes(key),
|
|
223
|
+
)
|
|
224
|
+
) {
|
|
225
|
+
panelIds.add(op.panelId);
|
|
226
|
+
}
|
|
171
227
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
228
|
+
return panelIds.size > 0 ? panelIds : null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async function validateMutationSql(
|
|
232
|
+
config: Record<string, unknown>,
|
|
233
|
+
operations: DashboardMutationOperation[],
|
|
234
|
+
): Promise<string | null> {
|
|
235
|
+
const scope = sqlValidationScope(operations);
|
|
236
|
+
if (scope === null) return null;
|
|
237
|
+
return validatePanelSql(config, scope === "all" ? undefined : scope);
|
|
176
238
|
}
|
|
177
239
|
|
|
178
240
|
function movedPanelIdsFrom(operations: DashboardMutationOperation[]): string[] {
|
|
@@ -214,7 +276,7 @@ export default defineAction({
|
|
|
214
276
|
code: z.string().optional().describe(apiHelp),
|
|
215
277
|
operations: operationsInputSchema.describe(
|
|
216
278
|
"Structured equivalent of the typed script. Native callers should pass an array of mutation ops; shell/legacy callers may pass a JSON string. " +
|
|
217
|
-
"Supported ops: movePanels, removePanels, updatePanel, updatePanelPath, insertPanel, duplicatePanel, setDashboard.",
|
|
279
|
+
"Supported ops: movePanels, removePanels, updatePanel, updatePanelPath, insertPanel, duplicatePanel, setDashboard, setFilterDefault.",
|
|
218
280
|
),
|
|
219
281
|
dryRun: z
|
|
220
282
|
.boolean()
|
|
@@ -233,6 +295,7 @@ export default defineAction({
|
|
|
233
295
|
.optional()
|
|
234
296
|
.describe("If true, include the allowed TypeScript API and examples."),
|
|
235
297
|
}),
|
|
298
|
+
agentInputSchema,
|
|
236
299
|
http: { method: "POST" },
|
|
237
300
|
mcpApp: {
|
|
238
301
|
compactCatalog: true,
|
|
@@ -245,18 +308,18 @@ export default defineAction({
|
|
|
245
308
|
}),
|
|
246
309
|
},
|
|
247
310
|
run: async (args) => {
|
|
311
|
+
const code = nonEmptyCode(args.code);
|
|
312
|
+
const requestedOperations = nonEmptyOperations(args.operations);
|
|
248
313
|
const wantsHelpOnly =
|
|
249
314
|
args.returnTypes === true &&
|
|
250
315
|
!args.dashboardId &&
|
|
251
316
|
!args.id &&
|
|
252
|
-
!
|
|
253
|
-
!
|
|
317
|
+
!code &&
|
|
318
|
+
!requestedOperations;
|
|
254
319
|
if (wantsHelpOnly) return helpResult();
|
|
255
320
|
|
|
256
321
|
const dashboardId = resolveDashboardId(args);
|
|
257
|
-
const suppliedModes = [
|
|
258
|
-
(value) => value !== undefined,
|
|
259
|
-
).length;
|
|
322
|
+
const suppliedModes = [code, requestedOperations].filter(Boolean).length;
|
|
260
323
|
if (suppliedModes === 0) {
|
|
261
324
|
throw new Error("provide `code` or `operations`.");
|
|
262
325
|
}
|
|
@@ -282,9 +345,9 @@ export default defineAction({
|
|
|
282
345
|
);
|
|
283
346
|
}
|
|
284
347
|
const nextRoot = cloneConfig(existing.config as Record<string, unknown>);
|
|
285
|
-
const nextOperations =
|
|
286
|
-
?
|
|
287
|
-
: parseDashboardMutationScript(nextRoot,
|
|
348
|
+
const nextOperations = requestedOperations
|
|
349
|
+
? requestedOperations
|
|
350
|
+
: parseDashboardMutationScript(nextRoot, code!);
|
|
288
351
|
const nextMutation = applyDashboardMutationOperations(
|
|
289
352
|
nextRoot,
|
|
290
353
|
nextOperations,
|
|
@@ -313,20 +376,19 @@ export default defineAction({
|
|
|
313
376
|
root = computed.nextRoot;
|
|
314
377
|
operations = computed.nextOperations;
|
|
315
378
|
mutation = computed.nextMutation;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if (sqlError) throw new Error(sqlError);
|
|
319
|
-
}
|
|
379
|
+
const sqlError = await validateMutationSql(root, operations);
|
|
380
|
+
if (sqlError) throw new Error(sqlError);
|
|
320
381
|
} else {
|
|
321
382
|
const saved = await upsertDashboardWithRetry(
|
|
322
383
|
dashboardId,
|
|
323
384
|
ctx,
|
|
324
385
|
async (existing) => {
|
|
325
386
|
const computed = computeMutation(existing);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
387
|
+
const sqlError = await validateMutationSql(
|
|
388
|
+
computed.nextRoot,
|
|
389
|
+
computed.nextOperations,
|
|
390
|
+
);
|
|
391
|
+
if (sqlError) throw new Error(sqlError);
|
|
330
392
|
root = computed.nextRoot;
|
|
331
393
|
operations = computed.nextOperations;
|
|
332
394
|
mutation = computed.nextMutation;
|
|
@@ -387,19 +387,19 @@ export function validateDashboardConfig(
|
|
|
387
387
|
return null;
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
-
/**
|
|
391
|
-
* Dry-run each BigQuery panel's SQL so bad column names or type
|
|
392
|
-
* mismatches fail here, with the full BigQuery error text, rather than
|
|
393
|
-
* silently saving a broken dashboard that crashes on render.
|
|
394
|
-
*/
|
|
390
|
+
/** Validate every query panel, or only the supplied ids for a targeted edit. */
|
|
395
391
|
export async function validatePanelSql(
|
|
396
392
|
config: Record<string, unknown>,
|
|
393
|
+
panelIds?: ReadonlySet<string>,
|
|
397
394
|
): Promise<string | null> {
|
|
398
395
|
const panels = config.panels;
|
|
399
396
|
if (!Array.isArray(panels)) return null;
|
|
400
397
|
const vars = buildDryRunVars(config);
|
|
401
398
|
for (let i = 0; i < panels.length; i++) {
|
|
402
399
|
const p = panels[i] as Record<string, unknown>;
|
|
400
|
+
if (panelIds && (typeof p.id !== "string" || !panelIds.has(p.id))) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
403
|
// Sections are layout-only and extensions render their own iframe — neither
|
|
404
404
|
// has SQL to dry-run. heatmap, callout, and other query panels still
|
|
405
405
|
// validate normally below.
|