@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
|
@@ -129,6 +129,45 @@ function nanoidFallback(): string {
|
|
|
129
129
|
);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Normalize affected-row metadata from every createGetDb backend: libSQL,
|
|
134
|
+
* PGlite, Neon, postgres.js, better-sqlite3, and D1. Mirrors
|
|
135
|
+
* templates/design/actions/update-design.ts's `affectedRowCount`.
|
|
136
|
+
*/
|
|
137
|
+
function affectedRowCount(result: unknown): number | undefined {
|
|
138
|
+
const candidate = result as
|
|
139
|
+
| {
|
|
140
|
+
rowsAffected?: unknown;
|
|
141
|
+
affectedRows?: unknown;
|
|
142
|
+
rowCount?: unknown;
|
|
143
|
+
count?: unknown;
|
|
144
|
+
changes?: unknown;
|
|
145
|
+
meta?: { changes?: unknown };
|
|
146
|
+
}
|
|
147
|
+
| undefined;
|
|
148
|
+
const value =
|
|
149
|
+
candidate?.rowsAffected ??
|
|
150
|
+
candidate?.affectedRows ??
|
|
151
|
+
candidate?.rowCount ??
|
|
152
|
+
candidate?.count ??
|
|
153
|
+
candidate?.changes ??
|
|
154
|
+
candidate?.meta?.changes;
|
|
155
|
+
return typeof value === "number" ? value : undefined;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Thrown when a fenced `upsertDashboard` write (an `expectedUpdatedAt` was
|
|
160
|
+
* supplied) loses its compare-and-swap because another writer changed the
|
|
161
|
+
* row first. Callers should re-read the dashboard and re-apply their mutation
|
|
162
|
+
* against the fresh config — see `upsertDashboardWithRetry`.
|
|
163
|
+
*/
|
|
164
|
+
export class DashboardConflictError extends Error {
|
|
165
|
+
constructor(id: string) {
|
|
166
|
+
super(`Dashboard "${id}" changed between read and write.`);
|
|
167
|
+
this.name = "DashboardConflictError";
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
132
171
|
function changeScope(
|
|
133
172
|
ownerEmail: string,
|
|
134
173
|
orgId: string | null,
|
|
@@ -466,15 +505,33 @@ async function snapshotDashboardRevision(
|
|
|
466
505
|
* Upsert a dashboard. On create, caller becomes owner and visibility defaults
|
|
467
506
|
* to `private`; users explicitly promote useful dashboards to org/public via
|
|
468
507
|
* sharing. On update, `assertAccess` requires `editor`.
|
|
508
|
+
*
|
|
509
|
+
* `expectedUpdatedAt` fences the update against concurrent writers: pass the
|
|
510
|
+
* `updatedAt` observed by an earlier `getDashboard` call and the UPDATE only
|
|
511
|
+
* applies `WHERE id = ? AND updated_at = ?`. If another writer already saved
|
|
512
|
+
* in between, the fenced UPDATE affects zero rows and this throws
|
|
513
|
+
* `DashboardConflictError` instead of silently clobbering their write. Omit
|
|
514
|
+
* it (the default) to keep the prior unconditional last-write-wins behavior,
|
|
515
|
+
* which existing callers (legacy migration, revision restore, and any
|
|
516
|
+
* one-shot write that isn't a read-modify-write) still rely on.
|
|
469
517
|
*/
|
|
470
518
|
export async function upsertDashboard(
|
|
471
519
|
id: string,
|
|
472
520
|
kind: DashboardKind,
|
|
473
521
|
body: Record<string, unknown>,
|
|
474
522
|
ctx: AccessCtx,
|
|
523
|
+
expectedUpdatedAt?: string,
|
|
475
524
|
): Promise<DashboardRecord> {
|
|
476
525
|
// If the row exists (or legacy-migrates), require editor.
|
|
477
526
|
const existing = await getDashboard(id, ctx);
|
|
527
|
+
if (!existing && expectedUpdatedAt !== undefined) {
|
|
528
|
+
// A fence was supplied against a specific prior version, but the row is
|
|
529
|
+
// gone (deleted, or a legacy key that failed to migrate) by the time we
|
|
530
|
+
// looked. Treat this as a conflict rather than silently creating a fresh
|
|
531
|
+
// row — the caller's mutation was computed against state that no longer
|
|
532
|
+
// exists.
|
|
533
|
+
throw new DashboardConflictError(id);
|
|
534
|
+
}
|
|
478
535
|
const db = getDb() as any;
|
|
479
536
|
const { title, config } = configFromSettings(body);
|
|
480
537
|
const configJson = JSON.stringify(config);
|
|
@@ -487,17 +544,43 @@ export async function upsertDashboard(
|
|
|
487
544
|
existing.kind !== kind ||
|
|
488
545
|
existing.title !== title ||
|
|
489
546
|
JSON.stringify(existing.config) !== configJson;
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
.
|
|
547
|
+
const setValues = {
|
|
548
|
+
kind,
|
|
549
|
+
title,
|
|
550
|
+
config: configJson,
|
|
551
|
+
updatedAt: nowIso(),
|
|
552
|
+
updatedBy: ctx.email,
|
|
553
|
+
};
|
|
554
|
+
if (expectedUpdatedAt !== undefined) {
|
|
555
|
+
// Fenced write. Snapshot the revision only after we know this exact
|
|
556
|
+
// write actually landed — otherwise a lost race would record a
|
|
557
|
+
// revision for a save that never happened.
|
|
558
|
+
const updateResult = await db
|
|
559
|
+
.update(schema.dashboards)
|
|
560
|
+
.set(setValues)
|
|
561
|
+
.where(
|
|
562
|
+
and(
|
|
563
|
+
eq(schema.dashboards.id, id),
|
|
564
|
+
eq(schema.dashboards.updatedAt, expectedUpdatedAt),
|
|
565
|
+
),
|
|
566
|
+
);
|
|
567
|
+
const affected = affectedRowCount(updateResult);
|
|
568
|
+
if (affected === undefined) {
|
|
569
|
+
throw new Error(
|
|
570
|
+
"The database driver did not report an affected-row count for the fenced dashboard update.",
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
if (affected === 0) {
|
|
574
|
+
throw new DashboardConflictError(id);
|
|
575
|
+
}
|
|
576
|
+
if (changed) await snapshotDashboardRevision(db, existing, ctx);
|
|
577
|
+
} else {
|
|
578
|
+
if (changed) await snapshotDashboardRevision(db, existing, ctx);
|
|
579
|
+
await db
|
|
580
|
+
.update(schema.dashboards)
|
|
581
|
+
.set(setValues)
|
|
582
|
+
.where(eq(schema.dashboards.id, id));
|
|
583
|
+
}
|
|
501
584
|
} else {
|
|
502
585
|
await db.insert(schema.dashboards).values({
|
|
503
586
|
id,
|
|
@@ -528,6 +611,66 @@ export async function upsertDashboard(
|
|
|
528
611
|
return dashboard;
|
|
529
612
|
}
|
|
530
613
|
|
|
614
|
+
/** Max attempts (first try + retries) for `upsertDashboardWithRetry`. */
|
|
615
|
+
export const DASHBOARD_SAVE_MAX_ATTEMPTS = 3;
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Read-modify-write helper for the four action call sites that fetch a
|
|
619
|
+
* dashboard, mutate its config in memory, then save it back. Fences every
|
|
620
|
+
* save with the `updatedAt` of the record `mutate` was given, so a
|
|
621
|
+
* concurrent writer (agent adds a panel while a human drags one, or two
|
|
622
|
+
* agent calls race) never gets silently clobbered.
|
|
623
|
+
*
|
|
624
|
+
* `mutate` is invoked with the freshest `DashboardRecord` on every attempt —
|
|
625
|
+
* re-fetched from `getDashboard` each time — and must recompute the
|
|
626
|
+
* `{ kind, body }` to save FROM THAT RECORD, not from a closure over an
|
|
627
|
+
* earlier read; only then does a retry actually merge both writers' changes
|
|
628
|
+
* instead of re-deriving the same stale result. `mutate` may throw a
|
|
629
|
+
* non-conflict error (e.g. validation) to abort immediately without
|
|
630
|
+
* retrying.
|
|
631
|
+
*
|
|
632
|
+
* On a lost race, this re-reads and re-invokes `mutate` up to `maxAttempts`
|
|
633
|
+
* times before failing loud with a clear error so callers never silently
|
|
634
|
+
* drop a write or loop forever.
|
|
635
|
+
*/
|
|
636
|
+
export async function upsertDashboardWithRetry(
|
|
637
|
+
id: string,
|
|
638
|
+
ctx: AccessCtx,
|
|
639
|
+
mutate: (
|
|
640
|
+
existing: DashboardRecord,
|
|
641
|
+
) =>
|
|
642
|
+
| { kind: DashboardKind; body: Record<string, unknown> }
|
|
643
|
+
| Promise<{ kind: DashboardKind; body: Record<string, unknown> }>,
|
|
644
|
+
maxAttempts: number = DASHBOARD_SAVE_MAX_ATTEMPTS,
|
|
645
|
+
): Promise<DashboardRecord> {
|
|
646
|
+
let lastConflict: unknown;
|
|
647
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
648
|
+
const existing = await getDashboard(id, ctx);
|
|
649
|
+
if (!existing) {
|
|
650
|
+
throw new Error(
|
|
651
|
+
`dashboard "${id}" not found (or you don't have access).`,
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
const { kind, body } = await mutate(existing);
|
|
655
|
+
try {
|
|
656
|
+
return await upsertDashboard(id, kind, body, ctx, existing.updatedAt);
|
|
657
|
+
} catch (err) {
|
|
658
|
+
if (err instanceof DashboardConflictError) {
|
|
659
|
+
lastConflict = err;
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
throw err;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
const finalError = new Error(
|
|
666
|
+
`Could not save dashboard "${id}" after ${maxAttempts} attempt(s); it kept changing concurrently. Re-read the dashboard and try again.`,
|
|
667
|
+
);
|
|
668
|
+
if (lastConflict !== undefined) {
|
|
669
|
+
(finalError as Error & { cause?: unknown }).cause = lastConflict;
|
|
670
|
+
}
|
|
671
|
+
throw finalError;
|
|
672
|
+
}
|
|
673
|
+
|
|
531
674
|
export async function listDashboardRevisions(
|
|
532
675
|
dashboardId: string,
|
|
533
676
|
ctx: AccessCtx,
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@libsql/client": "^0.15.8",
|
|
23
23
|
"@tabler/icons-react": "catalog:",
|
|
24
24
|
"drizzle-orm": "^0.45.2",
|
|
25
|
-
"h3": "
|
|
25
|
+
"h3": "catalog:",
|
|
26
26
|
"isbot": "^5",
|
|
27
27
|
"nanoid": "^5.1.9",
|
|
28
28
|
"p-limit": "^7.3.0",
|
|
@@ -66,7 +66,6 @@
|
|
|
66
66
|
"tailwind-merge": "^3.5.0",
|
|
67
67
|
"tailwindcss": "catalog:",
|
|
68
68
|
"tsx": "^4.20.3",
|
|
69
|
-
"typescript": "catalog:",
|
|
70
69
|
"typescript-7": "catalog:",
|
|
71
70
|
"vite": "catalog:",
|
|
72
71
|
"vitest": "catalog:"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@fontsource-variable/inter": "^5.2.8",
|
|
24
24
|
"@libsql/client": "^0.15.0",
|
|
25
25
|
"drizzle-orm": "^0.45.2",
|
|
26
|
-
"h3": "
|
|
26
|
+
"h3": "catalog:",
|
|
27
27
|
"isbot": "^5.1.40",
|
|
28
28
|
"react": "catalog:",
|
|
29
29
|
"react-dom": "catalog:",
|
|
@@ -57,7 +57,6 @@
|
|
|
57
57
|
"sonner": "^2.0.7",
|
|
58
58
|
"tailwind-merge": "^3.6.0",
|
|
59
59
|
"tailwindcss": "catalog:",
|
|
60
|
-
"typescript": "catalog:",
|
|
61
60
|
"typescript-7": "catalog:",
|
|
62
61
|
"vite": "catalog:",
|
|
63
62
|
"vitest": "catalog:"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"chrono-node": "2.9.1",
|
|
27
27
|
"dotenv": "^17.2.1",
|
|
28
28
|
"drizzle-orm": "^0.45.2",
|
|
29
|
-
"h3": "
|
|
29
|
+
"h3": "catalog:",
|
|
30
30
|
"isbot": "^5",
|
|
31
31
|
"nanoid": "^5.1.9",
|
|
32
32
|
"zod": "^4.3.6"
|
|
@@ -93,7 +93,6 @@
|
|
|
93
93
|
"tailwind-merge": "^3.5.0",
|
|
94
94
|
"tailwindcss": "catalog:",
|
|
95
95
|
"tsx": "^4.20.3",
|
|
96
|
-
"typescript": "catalog:",
|
|
97
96
|
"typescript-7": "catalog:",
|
|
98
97
|
"vaul": "^1.1.2",
|
|
99
98
|
"vite": "catalog:",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@fontsource-variable/inter": "^5.2.8",
|
|
20
20
|
"@libsql/client": "^0.15.8",
|
|
21
21
|
"@tabler/icons-react": "catalog:",
|
|
22
|
-
"h3": "
|
|
22
|
+
"h3": "catalog:",
|
|
23
23
|
"isbot": "^5",
|
|
24
24
|
"node-pty": "^1.1.0",
|
|
25
25
|
"zod": "^4.4.3"
|
|
@@ -81,7 +81,6 @@
|
|
|
81
81
|
"tailwind-merge": "^3.5.0",
|
|
82
82
|
"tailwindcss": "catalog:",
|
|
83
83
|
"tsx": "^4.20.3",
|
|
84
|
-
"typescript": "catalog:",
|
|
85
84
|
"typescript-7": "catalog:",
|
|
86
85
|
"vaul": "^1.1.2",
|
|
87
86
|
"vite": "catalog:",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"dev:hot": "tsx scripts/dev.ts",
|
|
9
9
|
"build": "vite build",
|
|
10
10
|
"typecheck": "tsc --noEmit",
|
|
11
|
+
"test": "vitest --run",
|
|
11
12
|
"package": "pnpm build && tsx scripts/package.ts"
|
|
12
13
|
},
|
|
13
14
|
"dependencies": {
|
|
@@ -16,8 +17,8 @@
|
|
|
16
17
|
"devDependencies": {
|
|
17
18
|
"@types/chrome": "^0.2.0",
|
|
18
19
|
"tsx": "catalog:",
|
|
19
|
-
"typescript": "catalog:",
|
|
20
20
|
"typescript-7": "catalog:",
|
|
21
|
-
"vite": "catalog:"
|
|
21
|
+
"vite": "catalog:",
|
|
22
|
+
"vitest": "catalog:"
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
"build:tauri": "CLIPS_DESKTOP_LOCAL_BUILD=1 pnpm run check:prereqs && CLIPS_DESKTOP_LOCAL_BUILD=1 tauri build --config '{\"bundle\":{\"createUpdaterArtifacts\":false},\"plugins\":{\"updater\":{\"active\":false}}}' && node ./scripts/sign-macos-local.ts",
|
|
13
13
|
"tauri": "tauri",
|
|
14
14
|
"vite:dev": "vite",
|
|
15
|
-
"vite:build": "vite build"
|
|
15
|
+
"vite:build": "vite build",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"test": "vitest --run"
|
|
16
18
|
},
|
|
17
19
|
"dependencies": {
|
|
18
20
|
"@radix-ui/react-popover": "^1.1.15",
|
|
19
21
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
20
22
|
"@sentry/browser": "10.62.0",
|
|
21
|
-
"@tabler/icons-react": "
|
|
23
|
+
"@tabler/icons-react": "catalog:",
|
|
22
24
|
"@tauri-apps/api": "^2.11.0",
|
|
23
25
|
"@tauri-apps/plugin-fs": "2.5.1",
|
|
24
26
|
"@tauri-apps/plugin-process": "^2.3.1",
|
|
@@ -32,8 +34,8 @@
|
|
|
32
34
|
"@types/react": "^19.2.14",
|
|
33
35
|
"@types/react-dom": "^19.2.3",
|
|
34
36
|
"@vitejs/plugin-react": "catalog:",
|
|
35
|
-
"typescript": "catalog:",
|
|
36
37
|
"typescript-7": "catalog:",
|
|
37
|
-
"vite": "catalog:"
|
|
38
|
+
"vite": "catalog:",
|
|
39
|
+
"vitest": "catalog:"
|
|
38
40
|
}
|
|
39
41
|
}
|
|
@@ -2147,12 +2147,18 @@ async function startNativeFullscreenRecording(
|
|
|
2147
2147
|
console.log(
|
|
2148
2148
|
`[clips-recorder] native begin durationMs=${Date.now() - beginStartedAt} clickToLiveMs=${Date.now() - clickStartedAt}`,
|
|
2149
2149
|
);
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2150
|
+
// Cast: `transcriptionCapture` is only ever reassigned inside the
|
|
2151
|
+
// `startNativeTranscriptionBeforeRecording` closure above, so TS's
|
|
2152
|
+
// control-flow analysis can't see past that call and narrows this
|
|
2153
|
+
// read to `null`. Restate the variable's own declared type.
|
|
2154
|
+
await (transcriptionCapture as TranscriptionCapture | null)
|
|
2155
|
+
?.resetTimeline()
|
|
2156
|
+
.catch((err) => {
|
|
2157
|
+
console.warn(
|
|
2158
|
+
"[clips-recorder] transcription timeline reset failed:",
|
|
2159
|
+
err,
|
|
2160
|
+
);
|
|
2161
|
+
});
|
|
2156
2162
|
// Capture is now live — after rebasing the transcript timeline, stamp the
|
|
2157
2163
|
// timer baseline so the toolbar clock lines up with the real start.
|
|
2158
2164
|
startedAt = Date.now();
|
|
@@ -2164,12 +2170,15 @@ async function startNativeFullscreenRecording(
|
|
|
2164
2170
|
localCameraExport?.start(2_000);
|
|
2165
2171
|
} catch (err) {
|
|
2166
2172
|
await localCameraExport?.cancel().catch(() => {});
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
+
// Same TS narrowing gap as above: reassert the declared type.
|
|
2174
|
+
await (transcriptionCapture as TranscriptionCapture | null)
|
|
2175
|
+
?.cancel()
|
|
2176
|
+
.catch((cancelErr) => {
|
|
2177
|
+
console.warn(
|
|
2178
|
+
"[clips-recorder] native transcription cancel after start failure failed:",
|
|
2179
|
+
cancelErr,
|
|
2180
|
+
);
|
|
2181
|
+
});
|
|
2173
2182
|
// Tear down any capture started by the warm phase — on a countdown cancel
|
|
2174
2183
|
// (or a `begin` failure) the SCStream is already running with the mic live,
|
|
2175
2184
|
// and without this it would keep capturing after the aborted start.
|
|
@@ -2629,7 +2638,11 @@ async function startNativeFullscreenRecording(
|
|
|
2629
2638
|
console.log(
|
|
2630
2639
|
"[clips-recorder] native: paused during startup, pausing transcription",
|
|
2631
2640
|
);
|
|
2632
|
-
|
|
2641
|
+
// The `if` above already proves non-null at runtime; TS just can't see
|
|
2642
|
+
// it (same closure-narrowing gap as above).
|
|
2643
|
+
void (transcriptionCapture as TranscriptionCapture)
|
|
2644
|
+
.pause()
|
|
2645
|
+
.catch(() => {});
|
|
2633
2646
|
}
|
|
2634
2647
|
}
|
|
2635
2648
|
|
|
@@ -298,7 +298,10 @@ function appendFinalTranscript(session: VoiceSession, text: string): void {
|
|
|
298
298
|
} else if (clean === committed || clean.startsWith(`${committed} `)) {
|
|
299
299
|
// Some recognizers send the whole dictation as their final result.
|
|
300
300
|
session.finalTranscriptParts = [clean];
|
|
301
|
-
} else if (
|
|
301
|
+
} else if (
|
|
302
|
+
session.finalTranscriptParts[session.finalTranscriptParts.length - 1] !==
|
|
303
|
+
clean
|
|
304
|
+
) {
|
|
302
305
|
session.finalTranscriptParts.push(clean);
|
|
303
306
|
}
|
|
304
307
|
session.interimTranscript = "";
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@tabler/icons-react": "catalog:",
|
|
31
31
|
"drizzle-orm": "^0.45.2",
|
|
32
32
|
"ffmpeg-static": "^5.3.0",
|
|
33
|
-
"h3": "
|
|
33
|
+
"h3": "catalog:",
|
|
34
34
|
"isbot": "^5",
|
|
35
35
|
"postgres": "^3.4.9",
|
|
36
36
|
"zod": "^4.3.6"
|
|
@@ -92,7 +92,6 @@
|
|
|
92
92
|
"tailwind-merge": "^3.5.0",
|
|
93
93
|
"tailwindcss": "catalog:",
|
|
94
94
|
"tsx": "^4.20.3",
|
|
95
|
-
"typescript": "catalog:",
|
|
96
95
|
"typescript-7": "catalog:",
|
|
97
96
|
"vaul": "^1.1.2",
|
|
98
97
|
"vite": "catalog:",
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
now,
|
|
7
7
|
ownableColumns,
|
|
8
8
|
createSharesTable,
|
|
9
|
+
uniqueIndex,
|
|
9
10
|
} from "@agent-native/core/db/schema";
|
|
10
11
|
|
|
11
12
|
// -----------------------------------------------------------------------------
|
|
@@ -332,23 +333,34 @@ export const recordingReactions = table("recording_reactions", {
|
|
|
332
333
|
// Analytics: viewers + granular events
|
|
333
334
|
// -----------------------------------------------------------------------------
|
|
334
335
|
|
|
335
|
-
export const recordingViewers = table(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
.notNull()
|
|
347
|
-
.default(
|
|
348
|
-
|
|
349
|
-
.
|
|
350
|
-
|
|
351
|
-
|
|
336
|
+
export const recordingViewers = table(
|
|
337
|
+
"recording_viewers",
|
|
338
|
+
{
|
|
339
|
+
id: text("id").primaryKey(),
|
|
340
|
+
recordingId: text("recording_id").notNull(),
|
|
341
|
+
// Stable canonical identity for new viewers. Nullable so existing rows can
|
|
342
|
+
// be migrated additively and claimed on their next event.
|
|
343
|
+
viewerKey: text("viewer_key"),
|
|
344
|
+
viewerEmail: text("viewer_email"), // null = anonymous
|
|
345
|
+
viewerName: text("viewer_name"),
|
|
346
|
+
firstViewedAt: text("first_viewed_at").notNull().default(now()),
|
|
347
|
+
lastViewedAt: text("last_viewed_at").notNull().default(now()),
|
|
348
|
+
totalWatchMs: integer("total_watch_ms").notNull().default(0),
|
|
349
|
+
completedPct: integer("completed_pct").notNull().default(0),
|
|
350
|
+
// True once they meet the 5s / 75% / end-scrub rule.
|
|
351
|
+
countedView: integer("counted_view", { mode: "boolean" })
|
|
352
|
+
.notNull()
|
|
353
|
+
.default(false),
|
|
354
|
+
ctaClicked: integer("cta_clicked", { mode: "boolean" })
|
|
355
|
+
.notNull()
|
|
356
|
+
.default(false),
|
|
357
|
+
},
|
|
358
|
+
(viewer) => ({
|
|
359
|
+
recordingViewerKeyUnique: uniqueIndex(
|
|
360
|
+
"recording_viewers_recording_viewer_key_unique_idx",
|
|
361
|
+
).on(viewer.recordingId, viewer.viewerKey),
|
|
362
|
+
}),
|
|
363
|
+
);
|
|
352
364
|
|
|
353
365
|
// Per-view records — one row per distinct counted view, so the owner can see
|
|
354
366
|
// *who viewed and when* (not just an aggregate count or a single
|
|
@@ -825,6 +825,14 @@ const migrations = runMigrations(
|
|
|
825
825
|
`CREATE UNIQUE INDEX IF NOT EXISTS recording_views_session_unique_idx ON recording_views (recording_id, viewer_key, view_session_id)`,
|
|
826
826
|
].join("; "),
|
|
827
827
|
},
|
|
828
|
+
{
|
|
829
|
+
version: 48,
|
|
830
|
+
name: "recording-viewers-canonical-viewer-key",
|
|
831
|
+
sql: [
|
|
832
|
+
`ALTER TABLE recording_viewers ADD COLUMN IF NOT EXISTS viewer_key TEXT`,
|
|
833
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS recording_viewers_recording_viewer_key_unique_idx ON recording_viewers (recording_id, viewer_key)`,
|
|
834
|
+
].join("; "),
|
|
835
|
+
},
|
|
828
836
|
],
|
|
829
837
|
{ table: "clips_migrations" },
|
|
830
838
|
);
|