@agent-native/core 0.96.0 → 0.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +39 -0
- package/corpus/core/docs/content/audit-log.mdx +2 -1
- package/corpus/core/docs/content/automations.mdx +7 -7
- package/corpus/core/docs/content/creating-templates.mdx +1 -1
- package/corpus/core/docs/content/internationalization.mdx +2 -1
- package/corpus/core/docs/content/locales/ar-SA/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ar-SA/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ar-SA/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ar-SA/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/ar-SA/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/ar-SA/security.mdx +8 -0
- package/corpus/core/docs/content/locales/de-DE/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/de-DE/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/de-DE/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/de-DE/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/package-lifecycle.mdx +22 -0
- package/corpus/core/docs/content/locales/de-DE/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/de-DE/security.mdx +8 -0
- package/corpus/core/docs/content/locales/es-ES/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/es-ES/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/es-ES/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/es-ES/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/package-lifecycle.mdx +22 -0
- package/corpus/core/docs/content/locales/es-ES/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/es-ES/security.mdx +8 -0
- package/corpus/core/docs/content/locales/fr-FR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/fr-FR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/fr-FR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/fr-FR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/fr-FR/sandbox-adapters.mdx +19 -8
- package/corpus/core/docs/content/locales/fr-FR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/hi-IN/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/hi-IN/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/hi-IN/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/hi-IN/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/package-lifecycle.mdx +20 -0
- package/corpus/core/docs/content/locales/hi-IN/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/hi-IN/security.mdx +8 -0
- package/corpus/core/docs/content/locales/ja-JP/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ja-JP/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ja-JP/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ja-JP/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/ja-JP/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/ja-JP/security.mdx +8 -0
- package/corpus/core/docs/content/locales/ko-KR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ko-KR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ko-KR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ko-KR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/package-lifecycle.mdx +20 -0
- package/corpus/core/docs/content/locales/ko-KR/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/ko-KR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/pt-BR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/pt-BR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/pt-BR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/pt-BR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/pt-BR/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/pt-BR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-CN/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/zh-CN/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/zh-CN/getting-started.mdx +6 -4
- package/corpus/core/docs/content/locales/zh-CN/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/zh-CN/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/zh-CN/security.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-TW/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/zh-TW/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/zh-TW/getting-started.mdx +6 -4
- package/corpus/core/docs/content/locales/zh-TW/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/zh-TW/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/zh-TW/security.mdx +8 -0
- package/corpus/core/docs/content/package-lifecycle.mdx +51 -0
- package/corpus/core/docs/content/sandbox-adapters.mdx +16 -5
- package/corpus/core/package.json +9 -2
- package/corpus/core/src/a2a/auth-policy.ts +33 -0
- package/corpus/core/src/agent/durable-background.ts +15 -7
- package/corpus/core/src/agent/run-store.ts +13 -4
- package/corpus/core/src/audit/actions/export-audit-events.ts +162 -0
- package/corpus/core/src/audit/store.ts +8 -3
- package/corpus/core/src/audit/types.ts +3 -0
- package/corpus/core/src/cli/doctor.ts +396 -0
- package/corpus/core/src/cli/index.ts +56 -0
- package/corpus/core/src/cli/info.ts +3 -3
- package/corpus/core/src/cli/package-lifecycle.ts +821 -0
- package/corpus/core/src/client/agent-chat-adapter.ts +9 -9
- package/corpus/core/src/guards/db-tool-scoping.ts +129 -0
- package/corpus/core/src/guards/index.ts +23 -0
- package/corpus/core/src/guards/no-drizzle-push.ts +116 -0
- package/corpus/core/src/guards/no-env-credentials.ts +229 -0
- package/corpus/core/src/guards/no-env-mutation.ts +114 -0
- package/corpus/core/src/guards/no-localhost-fallback.ts +124 -0
- package/corpus/core/src/guards/no-unscoped-credentials.ts +227 -0
- package/corpus/core/src/guards/no-unscoped-queries.ts +834 -0
- package/corpus/core/src/guards/scan-utils.ts +105 -0
- package/corpus/core/src/guards/types.ts +30 -0
- package/corpus/core/src/org/accept-pending.ts +9 -1
- package/corpus/core/src/org/migrations.ts +41 -0
- package/corpus/core/src/package-lifecycle/index.ts +1 -0
- package/corpus/core/src/package-lifecycle/manifest.ts +120 -0
- package/corpus/core/src/provider-api/custom-registry.ts +56 -0
- package/corpus/core/src/provider-api/index.ts +2 -0
- package/corpus/core/src/secrets/storage.ts +47 -27
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +54 -12
- package/corpus/core/src/server/core-routes-plugin.ts +30 -14
- package/corpus/core/src/server/csrf.ts +24 -5
- package/corpus/core/src/server/framework-request-handler.ts +34 -0
- package/corpus/core/src/server/google-realtime-session.ts +1 -36
- package/corpus/core/src/server/poll.ts +24 -2
- package/corpus/core/src/server/realtime-voice.ts +9 -0
- package/corpus/core/src/server/request-origin.ts +63 -0
- package/corpus/core/src/server/transcribe-voice.ts +1 -50
- package/corpus/core/src/templates/default/package.json +2 -2
- package/corpus/core/src/templates/headless/package.json +0 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/package.json +0 -1
- package/corpus/core/src/templates/workspace-root/package.json +0 -1
- package/corpus/core/src/triggers/actions.ts +11 -3
- package/corpus/core/src/triggers/types.ts +7 -1
- package/corpus/templates/analytics/actions/compose-dashboard.ts +65 -37
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +73 -24
- package/corpus/templates/analytics/actions/reorder-dashboard-panels.ts +16 -13
- package/corpus/templates/analytics/actions/update-dashboard.ts +53 -42
- package/corpus/templates/analytics/changelog/2026-07-10-dashboard-edits-from-the-agent-and-the-ui-at-the-same-time-n.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-timed-out-bigquery-jobs-are-now-cancelled-so-they-stop-consu.md +6 -0
- package/corpus/templates/analytics/package.json +1 -2
- package/corpus/templates/analytics/server/lib/bigquery.ts +3 -2
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +154 -11
- package/corpus/templates/assets/package.json +1 -2
- package/corpus/templates/brain/package.json +1 -2
- package/corpus/templates/calendar/package.json +1 -2
- package/corpus/templates/chat/package.json +1 -2
- package/corpus/templates/clips/changelog/2026-07-10-atomic-view-tracking.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +3 -2
- package/corpus/templates/clips/desktop/package.json +6 -4
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +26 -13
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +4 -1
- package/corpus/templates/clips/package.json +1 -2
- package/corpus/templates/clips/server/db/schema.ts +29 -17
- package/corpus/templates/clips/server/plugins/db.ts +8 -0
- package/corpus/templates/clips/server/routes/api/view-event.post.ts +260 -105
- package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +16 -0
- package/corpus/templates/content/AGENTS.md +72 -62
- package/corpus/templates/content/actions/_content-database-source-adapters.ts +84 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +206 -96
- package/corpus/templates/content/actions/_notion-database-source-adapter.ts +216 -0
- package/corpus/templates/content/actions/_position-utils.ts +76 -0
- package/corpus/templates/content/actions/_property-utils.ts +31 -20
- package/corpus/templates/content/actions/add-database-item.ts +52 -39
- package/corpus/templates/content/actions/attach-content-database-source.ts +95 -11
- package/corpus/templates/content/actions/change-content-database-source-role.ts +24 -1
- package/corpus/templates/content/actions/configure-document-property.ts +36 -27
- package/corpus/templates/content/actions/create-content-database.ts +40 -30
- package/corpus/templates/content/actions/create-document.ts +39 -32
- package/corpus/templates/content/actions/duplicate-document-property.ts +37 -28
- package/corpus/templates/content/actions/list-notion-database-sources.ts +80 -0
- package/corpus/templates/content/actions/move-document.ts +64 -48
- package/corpus/templates/content/actions/refresh-content-database-source.ts +42 -3
- package/corpus/templates/content/actions/share-local-file-document.ts +36 -27
- package/corpus/templates/content/actions/suggest-source-join-key.ts +39 -16
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +89 -23
- package/corpus/templates/content/app/components/editor/database/settings.tsx +1 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +18 -1
- package/corpus/templates/content/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/content/app/i18n-data.ts +40 -0
- package/corpus/templates/content/changelog/2026-07-10-failed-row-creation-and-source-attach-now-show-an-error-inst.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-items-added-at-the-same-time-no-longer-end-up-with-identical.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-notion-databases-can-add-read-only-details-to-content-tables.md +6 -0
- package/corpus/templates/content/package.json +1 -2
- package/corpus/templates/content/parity/matrix.md +25 -25
- package/corpus/templates/content/parity/matrix.ts +1 -0
- package/corpus/templates/content/server/routes/api/documents/[id]/move.patch.ts +43 -26
- package/corpus/templates/content/shared/api.ts +16 -1
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +8 -4
- package/corpus/templates/design/AGENTS.md +12 -2
- package/corpus/templates/design/DEVELOPING.md +10 -6
- package/corpus/templates/design/actions/apply-visual-edit.ts +191 -6
- package/corpus/templates/design/actions/duplicate-design.ts +31 -25
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +5 -1
- package/corpus/templates/design/changelog/2026-07-10-duplicating-a-design-can-no-longer-produce-a-copy-with-missi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-local-visual-edits-can-now-save-safe-leaf-text-class-and.md +6 -0
- package/corpus/templates/design/package.json +1 -1
- package/corpus/templates/design/shared/local-jsx-visual-edit.ts +388 -0
- package/corpus/templates/dispatch/package.json +1 -2
- package/corpus/templates/forms/actions/patch-form-fields.ts +82 -44
- package/corpus/templates/forms/changelog/2026-07-10-simultaneous-edits-to-different-form-fields-no-longer-overwr.md +6 -0
- package/corpus/templates/forms/package.json +1 -2
- package/corpus/templates/macros/package.json +1 -2
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +3 -1
- package/corpus/templates/mail/changelog/2026-07-10-fixed-calendar-rsvp-buttons-in-emails-firing-duplicate-respo.md +6 -0
- package/corpus/templates/mail/package.json +1 -2
- package/corpus/templates/plan/actions/restore-plan-version.ts +126 -96
- package/corpus/templates/plan/changelog/2026-07-10-restoring-a-plan-version-can-no-longer-leave-a-plan-half-res.md +6 -0
- package/corpus/templates/plan/package.json +1 -2
- package/corpus/templates/plan/server/plans.ts +9 -2
- package/corpus/templates/slides/actions/list-decks.ts +28 -0
- package/corpus/templates/slides/app/components/deck/MermaidRenderer.tsx +41 -26
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +4 -8
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +2 -4
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +4 -8
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +5 -12
- package/corpus/templates/slides/app/components/editor/HistoryPanel.tsx +3 -6
- package/corpus/templates/slides/app/components/editor/ImageDropPromptPopover.tsx +3 -6
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +2 -5
- package/corpus/templates/slides/app/context/DeckContext.tsx +47 -4
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +11 -30
- package/corpus/templates/slides/app/pages/Index.tsx +2 -3
- package/corpus/templates/slides/app/root.tsx +0 -5
- package/corpus/templates/slides/changelog/2026-07-10-deck-lists-load-much-faster-and-no-longer-re-download-slide-.md +6 -0
- package/corpus/templates/slides/package.json +1 -2
- package/dist/a2a/auth-policy.d.ts +19 -0
- package/dist/a2a/auth-policy.d.ts.map +1 -1
- package/dist/a2a/auth-policy.js +32 -0
- package/dist/a2a/auth-policy.js.map +1 -1
- package/dist/agent/durable-background.d.ts +8 -5
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +15 -8
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +9 -4
- package/dist/agent/run-store.js.map +1 -1
- package/dist/audit/actions/export-audit-events.d.ts +27 -0
- package/dist/audit/actions/export-audit-events.d.ts.map +1 -0
- package/dist/audit/actions/export-audit-events.js +144 -0
- package/dist/audit/actions/export-audit-events.js.map +1 -0
- package/dist/audit/store.d.ts +1 -0
- package/dist/audit/store.d.ts.map +1 -1
- package/dist/audit/store.js +8 -3
- package/dist/audit/store.js.map +1 -1
- package/dist/audit/types.d.ts +3 -0
- package/dist/audit/types.d.ts.map +1 -1
- package/dist/audit/types.js.map +1 -1
- package/dist/cli/doctor.d.ts +83 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +277 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.js +50 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/info.js +3 -3
- package/dist/cli/info.js.map +1 -1
- package/dist/cli/package-lifecycle.d.ts +50 -0
- package/dist/cli/package-lifecycle.d.ts.map +1 -0
- package/dist/cli/package-lifecycle.js +560 -0
- package/dist/cli/package-lifecycle.js.map +1 -0
- package/dist/client/agent-chat-adapter.js +7 -3
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/guards/db-tool-scoping.d.ts +38 -0
- package/dist/guards/db-tool-scoping.d.ts.map +1 -0
- package/dist/guards/db-tool-scoping.js +114 -0
- package/dist/guards/db-tool-scoping.js.map +1 -0
- package/dist/guards/index.d.ts +23 -0
- package/dist/guards/index.d.ts.map +1 -0
- package/dist/guards/index.js +19 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/guards/no-drizzle-push.d.ts +14 -0
- package/dist/guards/no-drizzle-push.d.ts.map +1 -0
- package/dist/guards/no-drizzle-push.js +97 -0
- package/dist/guards/no-drizzle-push.js.map +1 -0
- package/dist/guards/no-env-credentials.d.ts +36 -0
- package/dist/guards/no-env-credentials.d.ts.map +1 -0
- package/dist/guards/no-env-credentials.js +204 -0
- package/dist/guards/no-env-credentials.js.map +1 -0
- package/dist/guards/no-env-mutation.d.ts +23 -0
- package/dist/guards/no-env-mutation.d.ts.map +1 -0
- package/dist/guards/no-env-mutation.js +90 -0
- package/dist/guards/no-env-mutation.js.map +1 -0
- package/dist/guards/no-localhost-fallback.d.ts +30 -0
- package/dist/guards/no-localhost-fallback.d.ts.map +1 -0
- package/dist/guards/no-localhost-fallback.js +105 -0
- package/dist/guards/no-localhost-fallback.js.map +1 -0
- package/dist/guards/no-unscoped-credentials.d.ts +28 -0
- package/dist/guards/no-unscoped-credentials.d.ts.map +1 -0
- package/dist/guards/no-unscoped-credentials.js +199 -0
- package/dist/guards/no-unscoped-credentials.js.map +1 -0
- package/dist/guards/no-unscoped-queries.d.ts +32 -0
- package/dist/guards/no-unscoped-queries.d.ts.map +1 -0
- package/dist/guards/no-unscoped-queries.js +720 -0
- package/dist/guards/no-unscoped-queries.js.map +1 -0
- package/dist/guards/scan-utils.d.ts +28 -0
- package/dist/guards/scan-utils.d.ts.map +1 -0
- package/dist/guards/scan-utils.js +92 -0
- package/dist/guards/scan-utils.js.map +1 -0
- package/dist/guards/types.d.ts +28 -0
- package/dist/guards/types.d.ts.map +1 -0
- package/dist/guards/types.js +11 -0
- package/dist/guards/types.js.map +1 -0
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +9 -1
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/migrations.d.ts +7 -2
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +41 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/package-lifecycle/index.d.ts +2 -0
- package/dist/package-lifecycle/index.d.ts.map +1 -0
- package/dist/package-lifecycle/index.js +2 -0
- package/dist/package-lifecycle/index.js.map +1 -0
- package/dist/package-lifecycle/manifest.d.ts +24 -0
- package/dist/package-lifecycle/manifest.d.ts.map +1 -0
- package/dist/package-lifecycle/manifest.js +81 -0
- package/dist/package-lifecycle/manifest.js.map +1 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/custom-registry.d.ts +32 -1
- package/dist/provider-api/custom-registry.d.ts.map +1 -1
- package/dist/provider-api/custom-registry.js +41 -1
- package/dist/provider-api/custom-registry.js.map +1 -1
- package/dist/provider-api/index.d.ts +1 -1
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +1 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +45 -27
- package/dist/secrets/storage.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +47 -13
- 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 +23 -12
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/csrf.js +18 -5
- package/dist/server/csrf.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +34 -0
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-realtime-session.d.ts.map +1 -1
- package/dist/server/google-realtime-session.js +2 -34
- package/dist/server/google-realtime-session.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +24 -2
- package/dist/server/poll.js.map +1 -1
- package/dist/server/realtime-voice.d.ts.map +1 -1
- package/dist/server/realtime-voice.js +9 -0
- package/dist/server/realtime-voice.js.map +1 -1
- package/dist/server/request-origin.d.ts +10 -0
- package/dist/server/request-origin.d.ts.map +1 -0
- package/dist/server/request-origin.js +60 -0
- package/dist/server/request-origin.js.map +1 -0
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +2 -48
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/templates/default/package.json +2 -2
- package/dist/templates/headless/package.json +0 -1
- package/dist/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/dist/templates/workspace-core/package.json +0 -1
- package/dist/templates/workspace-root/package.json +0 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +8 -3
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/types.d.ts +7 -1
- package/dist/triggers/types.d.ts.map +1 -1
- package/dist/triggers/types.js.map +1 -1
- package/docs/content/audit-log.mdx +2 -1
- package/docs/content/automations.mdx +7 -7
- package/docs/content/creating-templates.mdx +1 -1
- package/docs/content/internationalization.mdx +2 -1
- package/docs/content/locales/ar-SA/audit-log.mdx +2 -1
- package/docs/content/locales/ar-SA/automations.mdx +7 -7
- package/docs/content/locales/ar-SA/getting-started.mdx +7 -1
- package/docs/content/locales/ar-SA/internationalization.mdx +1 -1
- package/docs/content/locales/ar-SA/package-lifecycle.mdx +19 -0
- package/docs/content/locales/ar-SA/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/ar-SA/security.mdx +8 -0
- package/docs/content/locales/de-DE/audit-log.mdx +2 -1
- package/docs/content/locales/de-DE/automations.mdx +7 -7
- package/docs/content/locales/de-DE/getting-started.mdx +7 -1
- package/docs/content/locales/de-DE/internationalization.mdx +1 -1
- package/docs/content/locales/de-DE/package-lifecycle.mdx +22 -0
- package/docs/content/locales/de-DE/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/de-DE/security.mdx +8 -0
- package/docs/content/locales/es-ES/audit-log.mdx +2 -1
- package/docs/content/locales/es-ES/automations.mdx +7 -7
- package/docs/content/locales/es-ES/getting-started.mdx +7 -1
- package/docs/content/locales/es-ES/internationalization.mdx +1 -1
- package/docs/content/locales/es-ES/package-lifecycle.mdx +22 -0
- package/docs/content/locales/es-ES/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/es-ES/security.mdx +8 -0
- package/docs/content/locales/fr-FR/audit-log.mdx +2 -1
- package/docs/content/locales/fr-FR/automations.mdx +7 -7
- package/docs/content/locales/fr-FR/getting-started.mdx +7 -1
- package/docs/content/locales/fr-FR/internationalization.mdx +1 -1
- package/docs/content/locales/fr-FR/package-lifecycle.mdx +21 -0
- package/docs/content/locales/fr-FR/sandbox-adapters.mdx +19 -8
- package/docs/content/locales/fr-FR/security.mdx +8 -0
- package/docs/content/locales/hi-IN/audit-log.mdx +2 -1
- package/docs/content/locales/hi-IN/automations.mdx +7 -7
- package/docs/content/locales/hi-IN/getting-started.mdx +7 -1
- package/docs/content/locales/hi-IN/internationalization.mdx +1 -1
- package/docs/content/locales/hi-IN/package-lifecycle.mdx +20 -0
- package/docs/content/locales/hi-IN/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/hi-IN/security.mdx +8 -0
- package/docs/content/locales/ja-JP/audit-log.mdx +2 -1
- package/docs/content/locales/ja-JP/automations.mdx +7 -7
- package/docs/content/locales/ja-JP/getting-started.mdx +7 -1
- package/docs/content/locales/ja-JP/internationalization.mdx +1 -1
- package/docs/content/locales/ja-JP/package-lifecycle.mdx +21 -0
- package/docs/content/locales/ja-JP/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/ja-JP/security.mdx +8 -0
- package/docs/content/locales/ko-KR/audit-log.mdx +2 -1
- package/docs/content/locales/ko-KR/automations.mdx +7 -7
- package/docs/content/locales/ko-KR/getting-started.mdx +7 -1
- package/docs/content/locales/ko-KR/internationalization.mdx +1 -1
- package/docs/content/locales/ko-KR/package-lifecycle.mdx +20 -0
- package/docs/content/locales/ko-KR/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/ko-KR/security.mdx +8 -0
- package/docs/content/locales/pt-BR/audit-log.mdx +2 -1
- package/docs/content/locales/pt-BR/automations.mdx +7 -7
- package/docs/content/locales/pt-BR/getting-started.mdx +7 -1
- package/docs/content/locales/pt-BR/internationalization.mdx +1 -1
- package/docs/content/locales/pt-BR/package-lifecycle.mdx +21 -0
- package/docs/content/locales/pt-BR/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/pt-BR/security.mdx +8 -0
- package/docs/content/locales/zh-CN/audit-log.mdx +2 -1
- package/docs/content/locales/zh-CN/automations.mdx +7 -7
- package/docs/content/locales/zh-CN/getting-started.mdx +6 -4
- package/docs/content/locales/zh-CN/internationalization.mdx +1 -1
- package/docs/content/locales/zh-CN/package-lifecycle.mdx +19 -0
- package/docs/content/locales/zh-CN/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/zh-CN/security.mdx +8 -0
- package/docs/content/locales/zh-TW/audit-log.mdx +2 -1
- package/docs/content/locales/zh-TW/automations.mdx +7 -7
- package/docs/content/locales/zh-TW/getting-started.mdx +6 -4
- package/docs/content/locales/zh-TW/internationalization.mdx +1 -1
- package/docs/content/locales/zh-TW/package-lifecycle.mdx +19 -0
- package/docs/content/locales/zh-TW/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/zh-TW/security.mdx +8 -0
- package/docs/content/package-lifecycle.mdx +51 -0
- package/docs/content/sandbox-adapters.mdx +16 -5
- package/package.json +10 -3
- package/src/templates/default/package.json +2 -2
- package/src/templates/headless/package.json +0 -1
- package/src/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/src/templates/workspace-core/package.json +0 -1
- package/src/templates/workspace-root/package.json +0 -1
- package/corpus/templates/slides/app/components/ui/toast.tsx +0 -1
- package/corpus/templates/slides/app/components/ui/toaster.tsx +0 -1
- package/corpus/templates/slides/app/hooks/use-toast.ts +0 -1
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
} from "@agent-native/core/server";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getDashboard,
|
|
16
|
+
upsertDashboard,
|
|
17
|
+
upsertDashboardWithRetry,
|
|
18
|
+
} from "../server/lib/dashboards-store";
|
|
15
19
|
import { validateFirstPartyAnalyticsSql } from "../server/lib/first-party-analytics.js";
|
|
16
20
|
import {
|
|
17
21
|
buildFirstPartyDashboardFilters,
|
|
@@ -235,61 +239,85 @@ export default defineAction({
|
|
|
235
239
|
? (existing.config.name as string)
|
|
236
240
|
: args.dashboardId);
|
|
237
241
|
|
|
242
|
+
function withFilters(
|
|
243
|
+
config: Record<string, unknown>,
|
|
244
|
+
): Record<string, unknown> {
|
|
245
|
+
return composedPanels.some((panel) =>
|
|
246
|
+
usesFirstPartyDashboardFilters(panel.sql),
|
|
247
|
+
)
|
|
248
|
+
? withFirstPartyDashboardFilters(config)
|
|
249
|
+
: config;
|
|
250
|
+
}
|
|
251
|
+
|
|
238
252
|
let finalConfig: Record<string, unknown>;
|
|
239
253
|
let appendedCount = composedPanels.length;
|
|
240
254
|
let skippedExistingIds: string[] = [];
|
|
241
255
|
|
|
242
256
|
if (existing && !args.overwrite) {
|
|
243
257
|
// Append: preserve existing panels + order, add only new panel ids.
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
258
|
+
// Recomputed on every retry attempt from the freshest existing config —
|
|
259
|
+
// via upsertDashboardWithRetry — so a panel a concurrent writer just
|
|
260
|
+
// added is never silently dropped by this merge.
|
|
261
|
+
const saved = await upsertDashboardWithRetry(
|
|
262
|
+
args.dashboardId,
|
|
263
|
+
ctx,
|
|
264
|
+
(freshExisting) => {
|
|
265
|
+
const existingConfig = freshExisting.config as Record<
|
|
266
|
+
string,
|
|
267
|
+
unknown
|
|
268
|
+
>;
|
|
269
|
+
const existingPanels = Array.isArray(existingConfig.panels)
|
|
270
|
+
? (existingConfig.panels as Array<Record<string, unknown>>)
|
|
271
|
+
: [];
|
|
272
|
+
const existingIds = new Set(
|
|
273
|
+
existingPanels
|
|
274
|
+
.map((p) => (typeof p?.id === "string" ? p.id : null))
|
|
275
|
+
.filter((id): id is string => !!id),
|
|
276
|
+
);
|
|
277
|
+
const toAppend: ComposedPanel[] = [];
|
|
278
|
+
const skipped: string[] = [];
|
|
279
|
+
for (const panel of composedPanels) {
|
|
280
|
+
if (existingIds.has(panel.id)) {
|
|
281
|
+
skipped.push(panel.id);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
toAppend.push(panel);
|
|
285
|
+
existingIds.add(panel.id);
|
|
286
|
+
}
|
|
287
|
+
appendedCount = toAppend.length;
|
|
288
|
+
skippedExistingIds = skipped;
|
|
289
|
+
const merged = withFilters({
|
|
290
|
+
...existingConfig,
|
|
291
|
+
name:
|
|
292
|
+
typeof existingConfig.name === "string" &&
|
|
293
|
+
existingConfig.name.trim()
|
|
294
|
+
? existingConfig.name
|
|
295
|
+
: dashboardName,
|
|
296
|
+
panels: [...existingPanels, ...toAppend],
|
|
297
|
+
});
|
|
298
|
+
return { kind: "sql" as const, body: merged };
|
|
299
|
+
},
|
|
252
300
|
);
|
|
253
|
-
|
|
254
|
-
for (const panel of composedPanels) {
|
|
255
|
-
if (existingIds.has(panel.id)) {
|
|
256
|
-
skippedExistingIds.push(panel.id);
|
|
257
|
-
continue;
|
|
258
|
-
}
|
|
259
|
-
toAppend.push(panel);
|
|
260
|
-
existingIds.add(panel.id);
|
|
261
|
-
}
|
|
262
|
-
appendedCount = toAppend.length;
|
|
263
|
-
finalConfig = {
|
|
264
|
-
...existingConfig,
|
|
265
|
-
name:
|
|
266
|
-
typeof existingConfig.name === "string" && existingConfig.name.trim()
|
|
267
|
-
? existingConfig.name
|
|
268
|
-
: dashboardName,
|
|
269
|
-
panels: [...existingPanels, ...toAppend],
|
|
270
|
-
};
|
|
301
|
+
finalConfig = saved.config as Record<string, unknown>;
|
|
271
302
|
} else {
|
|
272
303
|
// Create or overwrite: a fresh config with exactly the composed panels.
|
|
273
|
-
|
|
304
|
+
// No prior state can be lost here — create has none, and
|
|
305
|
+
// `overwrite: true` is an explicit full-replace request rather than a
|
|
306
|
+
// read-modify-write, so it saves unconditionally like update-dashboard's
|
|
307
|
+
// full-config replace mode.
|
|
308
|
+
finalConfig = withFilters({
|
|
274
309
|
name: dashboardName,
|
|
275
310
|
description:
|
|
276
311
|
"First-party analytics dashboard composed from the metric catalog.",
|
|
277
312
|
panels: composedPanels,
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (
|
|
282
|
-
composedPanels.some((panel) => usesFirstPartyDashboardFilters(panel.sql))
|
|
283
|
-
) {
|
|
284
|
-
finalConfig = withFirstPartyDashboardFilters(finalConfig);
|
|
313
|
+
});
|
|
314
|
+
await upsertDashboard(args.dashboardId, "sql", finalConfig, ctx);
|
|
285
315
|
}
|
|
286
316
|
|
|
287
317
|
const panelCount = Array.isArray(finalConfig.panels)
|
|
288
318
|
? (finalConfig.panels as unknown[]).length
|
|
289
319
|
: 0;
|
|
290
320
|
|
|
291
|
-
// Single atomic save through the same store path update-dashboard uses.
|
|
292
|
-
await upsertDashboard(args.dashboardId, "sql", finalConfig, ctx);
|
|
293
321
|
await syncToCollab(args.dashboardId, finalConfig);
|
|
294
322
|
|
|
295
323
|
const parts: string[] = [];
|
|
@@ -11,13 +11,18 @@ import {
|
|
|
11
11
|
} from "@agent-native/core/server";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getDashboard,
|
|
16
|
+
upsertDashboardWithRetry,
|
|
17
|
+
type DashboardRecord,
|
|
18
|
+
} from "../server/lib/dashboards-store";
|
|
15
19
|
import {
|
|
16
20
|
applyDashboardMutationOperations,
|
|
17
21
|
DASHBOARD_MUTATION_API_TYPES,
|
|
18
22
|
DASHBOARD_MUTATION_EXAMPLES,
|
|
19
23
|
parseDashboardMutationScript,
|
|
20
24
|
type DashboardMutationOperation,
|
|
25
|
+
type DashboardMutationResult,
|
|
21
26
|
} from "./dashboard-mutation-api";
|
|
22
27
|
import { compactDashboardResult } from "./dashboard-panel-order";
|
|
23
28
|
import { validateDashboardConfig, validatePanelSql } from "./update-dashboard";
|
|
@@ -260,33 +265,77 @@ export default defineAction({
|
|
|
260
265
|
|
|
261
266
|
const scope = resolveScope();
|
|
262
267
|
const ctx = { email: scope.email, orgId: scope.orgId };
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
268
|
+
|
|
269
|
+
// Recomputes the mutation from whatever dashboard state is passed in.
|
|
270
|
+
// `operations` sourced from `args.operations` are already concrete panel
|
|
271
|
+
// ids, safe to replay verbatim; `args.code` is re-parsed against `existing`
|
|
272
|
+
// every time because selectors like `panelsMatching(...)` resolve against
|
|
273
|
+
// the config at parse time, so a retry must re-resolve them against the
|
|
274
|
+
// fresh state, not reuse ids resolved from a now-stale config.
|
|
275
|
+
function computeMutation(
|
|
276
|
+
existing: Pick<DashboardRecord, "kind" | "config">,
|
|
277
|
+
) {
|
|
278
|
+
if (existing.kind !== "sql") {
|
|
279
|
+
throw new Error(
|
|
280
|
+
`mutate-dashboard only supports SQL dashboards; "${dashboardId}" is ${existing.kind}.`,
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
const nextRoot = cloneConfig(existing.config as Record<string, unknown>);
|
|
284
|
+
const nextOperations = args.operations
|
|
285
|
+
? (args.operations as DashboardMutationOperation[])
|
|
286
|
+
: parseDashboardMutationScript(nextRoot, args.code!);
|
|
287
|
+
const nextMutation = applyDashboardMutationOperations(
|
|
288
|
+
nextRoot,
|
|
289
|
+
nextOperations,
|
|
272
290
|
);
|
|
291
|
+
const validation = validateDashboardConfig(nextRoot);
|
|
292
|
+
if (validation) throw new Error(validation);
|
|
293
|
+
return { nextRoot, nextOperations, nextMutation };
|
|
273
294
|
}
|
|
274
295
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
296
|
+
// Assigned inside `computeMutation`'s caller (directly for dry-run, inside
|
|
297
|
+
// the retry callback for a real save); always assigned at least once
|
|
298
|
+
// before use below, since `upsertDashboardWithRetry` only resolves after
|
|
299
|
+
// its callback has run.
|
|
300
|
+
let root: Record<string, unknown>;
|
|
301
|
+
let operations!: DashboardMutationOperation[];
|
|
302
|
+
let mutation!: DashboardMutationResult;
|
|
280
303
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
304
|
+
if (args.dryRun === true) {
|
|
305
|
+
const existing = await getDashboard(dashboardId, ctx);
|
|
306
|
+
if (!existing) {
|
|
307
|
+
throw new Error(
|
|
308
|
+
`dashboard "${dashboardId}" not found (or you don't have access).`,
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
const computed = computeMutation(existing);
|
|
312
|
+
root = computed.nextRoot;
|
|
313
|
+
operations = computed.nextOperations;
|
|
314
|
+
mutation = computed.nextMutation;
|
|
315
|
+
if (operations.some(mutationCanChangePanelSql)) {
|
|
316
|
+
const sqlError = await validatePanelSql(root);
|
|
317
|
+
if (sqlError) throw new Error(sqlError);
|
|
318
|
+
}
|
|
319
|
+
} else {
|
|
320
|
+
const saved = await upsertDashboardWithRetry(
|
|
321
|
+
dashboardId,
|
|
322
|
+
ctx,
|
|
323
|
+
async (existing) => {
|
|
324
|
+
const computed = computeMutation(existing);
|
|
325
|
+
if (computed.nextOperations.some(mutationCanChangePanelSql)) {
|
|
326
|
+
const sqlError = await validatePanelSql(computed.nextRoot);
|
|
327
|
+
if (sqlError) throw new Error(sqlError);
|
|
328
|
+
}
|
|
329
|
+
root = computed.nextRoot;
|
|
330
|
+
operations = computed.nextOperations;
|
|
331
|
+
mutation = computed.nextMutation;
|
|
332
|
+
return { kind: "sql" as const, body: computed.nextRoot };
|
|
333
|
+
},
|
|
334
|
+
);
|
|
335
|
+
// Use the persisted config as the source of truth for the response —
|
|
336
|
+
// structurally identical to the winning attempt's `root`, but reflects
|
|
337
|
+
// exactly what was saved.
|
|
338
|
+
root = saved.config as Record<string, unknown>;
|
|
290
339
|
await syncToCollab(dashboardId, root);
|
|
291
340
|
}
|
|
292
341
|
|
|
@@ -11,10 +11,11 @@ import {
|
|
|
11
11
|
} from "@agent-native/core/server";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { upsertDashboardWithRetry } from "../server/lib/dashboards-store";
|
|
15
15
|
import {
|
|
16
16
|
compactDashboardResult,
|
|
17
17
|
movePanelsById,
|
|
18
|
+
type PanelOrderResult,
|
|
18
19
|
type PanelOrderTarget,
|
|
19
20
|
} from "./dashboard-panel-order";
|
|
20
21
|
|
|
@@ -155,20 +156,22 @@ export default defineAction({
|
|
|
155
156
|
const dashboardId = resolveDashboardId(args);
|
|
156
157
|
const scope = resolveScope();
|
|
157
158
|
const ctx = { email: scope.email, orgId: scope.orgId };
|
|
158
|
-
const existing = await getDashboard(dashboardId, ctx);
|
|
159
|
-
if (!existing) {
|
|
160
|
-
throw new Error(
|
|
161
|
-
`dashboard "${dashboardId}" not found (or you don't have access).`,
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
159
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
160
|
+
// Recomputed on every attempt from whichever dashboard state
|
|
161
|
+
// `upsertDashboardWithRetry` hands us, so a retry after a concurrent
|
|
162
|
+
// writer's save re-applies this move against their fresh panel order
|
|
163
|
+
// instead of silently discarding it.
|
|
164
|
+
let orderResult!: PanelOrderResult;
|
|
165
|
+
const saved = await upsertDashboardWithRetry(
|
|
166
|
+
dashboardId,
|
|
167
|
+
ctx,
|
|
168
|
+
(existing) => {
|
|
169
|
+
const root = existing.config as Record<string, unknown>;
|
|
170
|
+
orderResult = movePanelsById(root, args.panelIds, resolveTarget(args));
|
|
171
|
+
return { kind: existing.kind, body: root };
|
|
172
|
+
},
|
|
170
173
|
);
|
|
171
|
-
|
|
174
|
+
const root = saved.config as Record<string, unknown>;
|
|
172
175
|
await syncToCollab(dashboardId, root);
|
|
173
176
|
|
|
174
177
|
const compact = compactDashboardResult(root, orderResult.movedPanelIds);
|
|
@@ -13,12 +13,16 @@ import { z } from "zod";
|
|
|
13
13
|
|
|
14
14
|
import { interpolate } from "../app/pages/adhoc/sql-dashboard/interpolate";
|
|
15
15
|
import { dryRunQuery } from "../server/lib/bigquery";
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
upsertDashboard,
|
|
18
|
+
upsertDashboardWithRetry,
|
|
19
|
+
} from "../server/lib/dashboards-store";
|
|
17
20
|
import { parseDemoDescriptor } from "../server/lib/demo-source";
|
|
18
21
|
import { validateFirstPartyAnalyticsSql } from "../server/lib/first-party-analytics.js";
|
|
19
22
|
import {
|
|
20
23
|
applyPanelOrder,
|
|
21
24
|
compactDashboardResult,
|
|
25
|
+
type PanelOrderResult,
|
|
22
26
|
} from "./dashboard-panel-order";
|
|
23
27
|
|
|
24
28
|
/**
|
|
@@ -627,29 +631,27 @@ export default defineAction({
|
|
|
627
631
|
);
|
|
628
632
|
}
|
|
629
633
|
|
|
630
|
-
const existing = await getDashboard(dashboardId, ctx);
|
|
631
|
-
if (!existing) {
|
|
632
|
-
throw new Error(
|
|
633
|
-
`dashboard "${dashboardId}" not found (or you don't have access).`,
|
|
634
|
-
);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
const root = existing.config as any;
|
|
638
|
-
|
|
639
634
|
if (args.panelOrder) {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
635
|
+
// Recomputed on every retry attempt from the freshest dashboard config,
|
|
636
|
+
// so a concurrent writer's edit is never silently overwritten by this
|
|
637
|
+
// move.
|
|
638
|
+
let orderDetails!: PanelOrderResult;
|
|
639
|
+
const saved = await upsertDashboardWithRetry(
|
|
644
640
|
dashboardId,
|
|
645
|
-
existing.kind,
|
|
646
|
-
root as Record<string, unknown>,
|
|
647
641
|
ctx,
|
|
642
|
+
(existing) => {
|
|
643
|
+
const root = existing.config as Record<string, unknown>;
|
|
644
|
+
orderDetails = applyPanelOrder(root, args.panelOrder!);
|
|
645
|
+
const validation = validateDashboardConfig(root);
|
|
646
|
+
if (validation) throw new Error(validation);
|
|
647
|
+
return { kind: existing.kind, body: root };
|
|
648
|
+
},
|
|
648
649
|
);
|
|
649
|
-
|
|
650
|
+
const root = saved.config as Record<string, unknown>;
|
|
651
|
+
await syncToCollab(dashboardId, root);
|
|
650
652
|
return dashboardResult(
|
|
651
653
|
dashboardId,
|
|
652
|
-
root
|
|
654
|
+
root,
|
|
653
655
|
1,
|
|
654
656
|
`Moved ${orderDetails.movedPanelIds.length} panel id(s) to the front of dashboard "${dashboardId}"; it now has ${orderDetails.panelCount} panel(s).`,
|
|
655
657
|
orderDetails.movedPanelIds,
|
|
@@ -657,36 +659,45 @@ export default defineAction({
|
|
|
657
659
|
);
|
|
658
660
|
}
|
|
659
661
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
throw new Error(`applying op ${JSON.stringify(op)}: ${err.message}`);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
const validation = validateDashboardConfig(root);
|
|
670
|
-
if (validation) throw new Error(validation);
|
|
671
|
-
if (args.ops!.some((op) => opCanChangePanelSql(op as JsonOp))) {
|
|
672
|
-
const sqlError = await validatePanelSql(root);
|
|
673
|
-
if (sqlError) throw new Error(sqlError);
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
await upsertDashboard(
|
|
662
|
+
// Recomputed on every retry attempt from the freshest dashboard config —
|
|
663
|
+
// JSON-pointer ops are replayed against fresh state, not the stale config
|
|
664
|
+
// that produced the first (lost) attempt.
|
|
665
|
+
let appliedDetails: string[] = [];
|
|
666
|
+
const saved = await upsertDashboardWithRetry(
|
|
677
667
|
dashboardId,
|
|
678
|
-
existing.kind,
|
|
679
|
-
root as Record<string, unknown>,
|
|
680
668
|
ctx,
|
|
669
|
+
async (existing) => {
|
|
670
|
+
const root = existing.config as Record<string, unknown>;
|
|
671
|
+
const details: string[] = [];
|
|
672
|
+
for (const op of args.ops!) {
|
|
673
|
+
try {
|
|
674
|
+
details.push(applyJsonOp(root, op as JsonOp));
|
|
675
|
+
} catch (err: any) {
|
|
676
|
+
throw new Error(
|
|
677
|
+
`applying op ${JSON.stringify(op)}: ${err.message}`,
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
const validation = validateDashboardConfig(root);
|
|
683
|
+
if (validation) throw new Error(validation);
|
|
684
|
+
if (args.ops!.some((op) => opCanChangePanelSql(op as JsonOp))) {
|
|
685
|
+
const sqlError = await validatePanelSql(root);
|
|
686
|
+
if (sqlError) throw new Error(sqlError);
|
|
687
|
+
}
|
|
688
|
+
appliedDetails = details;
|
|
689
|
+
return { kind: existing.kind, body: root };
|
|
690
|
+
},
|
|
681
691
|
);
|
|
682
|
-
|
|
692
|
+
const root = saved.config as Record<string, unknown>;
|
|
693
|
+
await syncToCollab(dashboardId, root);
|
|
683
694
|
|
|
684
|
-
const panelCount = countPanels(root
|
|
695
|
+
const panelCount = countPanels(root);
|
|
685
696
|
return dashboardResult(
|
|
686
697
|
dashboardId,
|
|
687
|
-
root
|
|
688
|
-
|
|
689
|
-
`Applied ${
|
|
698
|
+
root,
|
|
699
|
+
appliedDetails.length,
|
|
700
|
+
`Applied ${appliedDetails.length} op(s); dashboard "${dashboardId}" now has ${panelCount} panel(s).`,
|
|
690
701
|
[],
|
|
691
702
|
args.returnConfig === true,
|
|
692
703
|
);
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@sparticuz/chromium-min": "^149.0.0",
|
|
26
26
|
"@tabler/icons-react": "catalog:",
|
|
27
27
|
"drizzle-orm": "^0.45.2",
|
|
28
|
-
"h3": "
|
|
28
|
+
"h3": "catalog:",
|
|
29
29
|
"isbot": "^5",
|
|
30
30
|
"playwright-core": "^1.61.1",
|
|
31
31
|
"postgres": "^3.4.9",
|
|
@@ -100,7 +100,6 @@
|
|
|
100
100
|
"tailwindcss": "catalog:",
|
|
101
101
|
"three": "^0.176.0",
|
|
102
102
|
"tsx": "^4.20.3",
|
|
103
|
-
"typescript": "catalog:",
|
|
104
103
|
"typescript-7": "catalog:",
|
|
105
104
|
"vaul": "^1.1.2",
|
|
106
105
|
"vite": "catalog:",
|
|
@@ -320,8 +320,8 @@ async function cancelQueryJob(
|
|
|
320
320
|
},
|
|
321
321
|
);
|
|
322
322
|
} catch {
|
|
323
|
-
//
|
|
324
|
-
//
|
|
323
|
+
// Cancellation is best-effort and must not hide the original abort or
|
|
324
|
+
// timeout reason if BigQuery or the network is unavailable.
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
327
|
|
|
@@ -502,6 +502,7 @@ export async function runQuery(
|
|
|
502
502
|
}
|
|
503
503
|
|
|
504
504
|
if (!data.jobComplete) {
|
|
505
|
+
await cancelQueryJob(projectId, jobId, token);
|
|
505
506
|
throw new Error("BigQuery query timed out after 60 seconds");
|
|
506
507
|
}
|
|
507
508
|
}
|