@agent-native/core 0.121.2 → 0.122.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +139 -0
- package/corpus/core/docs/content/actions.mdx +2 -2
- package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
- package/corpus/core/docs/content/authentication.mdx +2 -0
- package/corpus/core/docs/content/deployment.mdx +36 -0
- package/corpus/core/docs/content/http-api.mdx +266 -0
- package/corpus/core/docs/content/syncing-template-changes.mdx +159 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/a2a/activity.ts +38 -27
- package/corpus/core/src/agent/engine/builder-engine.ts +35 -4
- package/corpus/core/src/agent/run-manager.ts +20 -1
- package/corpus/core/src/agent/run-store.ts +4 -1
- package/corpus/core/src/agent/types.ts +28 -8
- package/corpus/core/src/chat-threads/store.ts +45 -0
- package/corpus/core/src/checkpoints/index.ts +2 -0
- package/corpus/core/src/checkpoints/route-match.ts +13 -0
- package/corpus/core/src/cli/create.ts +105 -17
- package/corpus/core/src/cli/index.ts +20 -0
- package/corpus/core/src/cli/template-baseline.ts +410 -0
- package/corpus/core/src/cli/template-sync.ts +1004 -0
- package/corpus/core/src/cli/templates-meta.ts +1 -0
- package/corpus/core/src/client/AssistantChat.tsx +38 -12
- package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/corpus/core/src/client/chat/message-components.tsx +127 -66
- package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
- package/corpus/core/src/client/error-format.ts +18 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
- package/corpus/core/src/client/org/TeamPage.tsx +7 -6
- package/corpus/core/src/client/sse-event-processor.ts +3 -0
- package/corpus/core/src/data-widgets/index.ts +41 -0
- package/corpus/core/src/deploy/build.ts +11 -9
- package/corpus/core/src/integrations/webhook-handler.ts +63 -9
- package/corpus/core/src/org/auto-join-domain.ts +4 -3
- package/corpus/core/src/org/context.ts +108 -39
- package/corpus/core/src/org/index.ts +5 -0
- package/corpus/core/src/org/service-identity.ts +60 -0
- package/corpus/core/src/provider-api/index.ts +22 -1
- package/corpus/core/src/scripts/docs/search.ts +12 -1
- package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
- package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
- package/corpus/core/src/server/agents-bundle.ts +84 -5
- package/corpus/core/src/server/auth.ts +4 -3
- package/corpus/core/src/server/builder-browser.ts +47 -19
- package/corpus/core/src/server/core-routes-plugin.ts +2 -2
- package/corpus/core/src/server/credential-provider.ts +209 -68
- package/corpus/core/src/server/index.ts +3 -0
- package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
- package/corpus/core/src/server/prompts/framework-core.ts +9 -21
- package/corpus/core/src/server/prompts/index.ts +0 -1
- package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
- package/corpus/core/src/server/ssr-handler.ts +13 -2
- package/corpus/core/src/settings/user-settings.ts +13 -1
- package/corpus/core/src/shared/cache-control.ts +141 -0
- package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/chat/_gitignore +1 -0
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
- package/corpus/core/src/vite/client.ts +5 -0
- package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
- package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
- package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
- package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/analytics/AGENTS.md +91 -563
- package/corpus/templates/analytics/_gitignore +1 -0
- package/corpus/templates/analytics/actions/bigquery.ts +12 -4
- package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
- package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
- package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
- package/corpus/templates/analytics/server/lib/notion.ts +15 -4
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/_gitignore +1 -0
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/calendar/_gitignore +1 -0
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/chat/_gitignore +1 -0
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
- package/corpus/templates/clips/AGENTS.md +5 -4
- package/corpus/templates/clips/_gitignore +1 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
- package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
- package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
- package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
- package/corpus/templates/clips/actions/list-recordings.ts +69 -19
- package/corpus/templates/clips/actions/list-viewers.ts +5 -2
- package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
- package/corpus/templates/clips/actions/request-transcript.ts +28 -1
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
- package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
- package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
- package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
- package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
- package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +46 -15
- package/corpus/templates/clips/app/routes/record.tsx +77 -31
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
- package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-desktop-app-now-copies-a-new-clip-s-share-link-to-your-c.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
- package/corpus/templates/clips/desktop/package.json +2 -0
- package/corpus/templates/clips/desktop/src/app.tsx +89 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
- package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
- package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
- package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
- package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
- package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
- package/corpus/templates/clips/desktop/src/styles.css +127 -78
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
- package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
- package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
- package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
- package/corpus/templates/clips/server/db/schema.ts +25 -0
- package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
- package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
- package/corpus/templates/clips/server/lib/recordings.ts +51 -3
- package/corpus/templates/clips/server/plugins/db.ts +23 -0
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
- package/corpus/templates/clips/shared/recording-link.ts +43 -0
- package/corpus/templates/clips/shared/share-attribution.ts +4 -0
- package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
- package/corpus/templates/clips/shared/view-analytics.ts +26 -0
- package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/content/AGENTS.md +62 -583
- package/corpus/templates/content/_gitignore +1 -0
- package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
- package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
- package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
- package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
- package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
- package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
- package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
- package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
- package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
- package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
- package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
- package/corpus/templates/design/AGENTS.md +88 -503
- package/corpus/templates/design/_gitignore +1 -0
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/dispatch/_gitignore +1 -0
- package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/forms/_gitignore +1 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/macros/_gitignore +1 -0
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/mail/_gitignore +1 -0
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/plan/_gitignore +1 -0
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/server/plugins/db.ts +4 -0
- package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/tasks/AGENTS.md +1 -1
- package/corpus/templates/tasks/_gitignore +1 -0
- package/dist/a2a/activity.d.ts +4 -1
- package/dist/a2a/activity.d.ts.map +1 -1
- package/dist/a2a/activity.js +27 -16
- package/dist/a2a/activity.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +1 -0
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +31 -4
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +18 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +1 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +2 -1
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +12 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +21 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts +10 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +41 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/checkpoints/index.d.ts +1 -0
- package/dist/checkpoints/index.d.ts.map +1 -1
- package/dist/checkpoints/index.js +1 -0
- package/dist/checkpoints/index.js.map +1 -1
- package/dist/checkpoints/route-match.d.ts +8 -0
- package/dist/checkpoints/route-match.d.ts.map +1 -0
- package/dist/checkpoints/route-match.js +13 -0
- package/dist/checkpoints/route-match.js.map +1 -0
- package/dist/cli/create.d.ts +35 -4
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +69 -19
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/template-baseline.d.ts +54 -0
- package/dist/cli/template-baseline.d.ts.map +1 -0
- package/dist/cli/template-baseline.js +334 -0
- package/dist/cli/template-baseline.js.map +1 -0
- package/dist/cli/template-sync.d.ts +57 -0
- package/dist/cli/template-sync.d.ts.map +1 -0
- package/dist/cli/template-sync.js +787 -0
- package/dist/cli/template-sync.js.map +1 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +1 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -10
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +32 -2
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +20 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +81 -46
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +14 -6
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +13 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +8 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +3 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +1 -1
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +3 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/data-widgets/index.d.ts +3 -0
- package/dist/data-widgets/index.d.ts.map +1 -1
- package/dist/data-widgets/index.js +33 -0
- package/dist/data-widgets/index.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +11 -7
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/provider-api-definitions.d.ts +1 -0
- package/dist/eject/provider-api-definitions.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +46 -9
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/org/auto-join-domain.d.ts +3 -2
- package/dist/org/auto-join-domain.d.ts.map +1 -1
- package/dist/org/auto-join-domain.js +1 -1
- package/dist/org/auto-join-domain.js.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +84 -28
- package/dist/org/context.js.map +1 -1
- package/dist/org/index.d.ts +1 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/org/service-identity.d.ts +43 -0
- package/dist/org/service-identity.d.ts.map +1 -0
- package/dist/org/service-identity.js +34 -0
- package/dist/org/service-identity.js.map +1 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +13 -11
- package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
- package/dist/provider-api/index.d.ts +4 -0
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +17 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/docs/search.d.ts.map +1 -1
- package/dist/scripts/docs/search.js +12 -1
- package/dist/scripts/docs/search.js.map +1 -1
- package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
- package/dist/server/agent-chat/context-tools.js +3 -3
- package/dist/server/agent-chat/context-tools.js.map +1 -1
- package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
- package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +33 -62
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +16 -10
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agents-bundle.d.ts +18 -0
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +70 -4
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +4 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +43 -19
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.js +2 -2
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +38 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +142 -64
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +7 -13
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +10 -21
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/prompts/index.d.ts +1 -1
- package/dist/server/prompts/index.d.ts.map +1 -1
- package/dist/server/prompts/index.js +1 -1
- package/dist/server/prompts/index.js.map +1 -1
- package/dist/server/prompts/shared-rules.d.ts +16 -10
- package/dist/server/prompts/shared-rules.d.ts.map +1 -1
- package/dist/server/prompts/shared-rules.js +19 -10
- package/dist/server/prompts/shared-rules.js.map +1 -1
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +10 -3
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/settings/user-settings.d.ts.map +1 -1
- package/dist/settings/user-settings.js +13 -1
- package/dist/settings/user-settings.js.map +1 -1
- package/dist/shared/cache-control.d.ts +52 -0
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +107 -0
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/chat/_gitignore +1 -0
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
- package/dist/vite/agents-bundle-plugin.js +8 -7
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.mdx +2 -2
- package/docs/content/agent-surfaces.mdx +1 -1
- package/docs/content/authentication.mdx +2 -0
- package/docs/content/deployment.mdx +36 -0
- package/docs/content/http-api.mdx +266 -0
- package/docs/content/syncing-template-changes.mdx +159 -0
- package/package.json +4 -3
- package/src/a2a/activity.ts +38 -27
- package/src/agent/engine/builder-engine.ts +35 -4
- package/src/agent/run-manager.ts +20 -1
- package/src/agent/run-store.ts +4 -1
- package/src/agent/types.ts +28 -8
- package/src/chat-threads/store.ts +45 -0
- package/src/checkpoints/index.ts +2 -0
- package/src/checkpoints/route-match.ts +13 -0
- package/src/cli/create.ts +105 -17
- package/src/cli/index.ts +20 -0
- package/src/cli/template-baseline.ts +410 -0
- package/src/cli/template-sync.ts +1004 -0
- package/src/cli/templates-meta.ts +1 -0
- package/src/client/AssistantChat.tsx +38 -12
- package/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/src/client/chat/message-components.tsx +127 -66
- package/src/client/chat/tool-call-display.tsx +29 -5
- package/src/client/error-format.ts +18 -0
- package/src/client/org/OrgSwitcher.tsx +30 -8
- package/src/client/org/TeamPage.tsx +7 -6
- package/src/client/sse-event-processor.ts +3 -0
- package/src/data-widgets/index.ts +41 -0
- package/src/deploy/build.ts +11 -9
- package/src/integrations/webhook-handler.ts +63 -9
- package/src/org/auto-join-domain.ts +4 -3
- package/src/org/context.ts +108 -39
- package/src/org/index.ts +5 -0
- package/src/org/service-identity.ts +60 -0
- package/src/provider-api/index.ts +22 -1
- package/src/scripts/docs/search.ts +12 -1
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
- package/src/server/agent-chat/context-tools.ts +9 -4
- package/src/server/agent-chat/framework-prompts.ts +38 -66
- package/src/server/agent-chat-plugin.ts +17 -10
- package/src/server/agents-bundle.ts +84 -5
- package/src/server/auth.ts +4 -3
- package/src/server/builder-browser.ts +47 -19
- package/src/server/core-routes-plugin.ts +2 -2
- package/src/server/credential-provider.ts +209 -68
- package/src/server/index.ts +3 -0
- package/src/server/prompts/framework-core-compact.ts +6 -13
- package/src/server/prompts/framework-core.ts +9 -21
- package/src/server/prompts/index.ts +0 -1
- package/src/server/prompts/shared-rules.ts +19 -11
- package/src/server/ssr-handler.ts +13 -2
- package/src/settings/user-settings.ts +13 -1
- package/src/shared/cache-control.ts +141 -0
- package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/chat/_gitignore +1 -0
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/src/vite/agents-bundle-plugin.ts +7 -6
- package/src/vite/client.ts +5 -0
|
@@ -56,7 +56,29 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
56
56
|
- Runs `skills update scaffold --project`
|
|
57
57
|
- Runs `typecheck` when the project has that script
|
|
58
58
|
|
|
59
|
-
3. **
|
|
59
|
+
3. **Pull upstream template changes (optional, separate from the bump)**
|
|
60
|
+
|
|
61
|
+
`agent-native upgrade` moves package versions. It never touches files that
|
|
62
|
+
were copied out of a template at scaffold time, so template fixes and
|
|
63
|
+
improvements do not arrive with a bump.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
agent-native template status # recorded ref vs latest, drift counts
|
|
67
|
+
agent-native template diff # what upstream changed, read-only
|
|
68
|
+
agent-native template sync # 3-way merge it into the app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`sync` defaults to the ref matching the installed `@agent-native/core`, so
|
|
72
|
+
run it after `upgrade`. It merges per file against a pristine baseline
|
|
73
|
+
stored in `refs/agent-native/template-baseline/<app-path>`; files upstream
|
|
74
|
+
did not touch are left alone, and real collisions get conflict markers.
|
|
75
|
+
After resolving markers, run `agent-native template accept` — the baseline
|
|
76
|
+
deliberately does not advance past an unresolved merge.
|
|
77
|
+
|
|
78
|
+
Apps scaffolded before provenance existed have no baseline. Create one
|
|
79
|
+
with `agent-native template baseline` before the first sync.
|
|
80
|
+
|
|
81
|
+
4. **If upgrade or typecheck fails**
|
|
60
82
|
|
|
61
83
|
- Read the concrete error
|
|
62
84
|
- Fix **app** source, actions, config, or env — not framework packages
|
|
@@ -68,7 +90,7 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
68
90
|
copied component; do not use that path to reproduce framework runtime
|
|
69
91
|
behavior or hide version skew.
|
|
70
92
|
|
|
71
|
-
|
|
93
|
+
5. **Dry-run / partial runs**
|
|
72
94
|
|
|
73
95
|
```bash
|
|
74
96
|
agent-native upgrade --dry-run
|
|
@@ -56,7 +56,29 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
56
56
|
- Runs `skills update scaffold --project`
|
|
57
57
|
- Runs `typecheck` when the project has that script
|
|
58
58
|
|
|
59
|
-
3. **
|
|
59
|
+
3. **Pull upstream template changes (optional, separate from the bump)**
|
|
60
|
+
|
|
61
|
+
`agent-native upgrade` moves package versions. It never touches files that
|
|
62
|
+
were copied out of a template at scaffold time, so template fixes and
|
|
63
|
+
improvements do not arrive with a bump.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
agent-native template status # recorded ref vs latest, drift counts
|
|
67
|
+
agent-native template diff # what upstream changed, read-only
|
|
68
|
+
agent-native template sync # 3-way merge it into the app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`sync` defaults to the ref matching the installed `@agent-native/core`, so
|
|
72
|
+
run it after `upgrade`. It merges per file against a pristine baseline
|
|
73
|
+
stored in `refs/agent-native/template-baseline/<app-path>`; files upstream
|
|
74
|
+
did not touch are left alone, and real collisions get conflict markers.
|
|
75
|
+
After resolving markers, run `agent-native template accept` — the baseline
|
|
76
|
+
deliberately does not advance past an unresolved merge.
|
|
77
|
+
|
|
78
|
+
Apps scaffolded before provenance existed have no baseline. Create one
|
|
79
|
+
with `agent-native template baseline` before the first sync.
|
|
80
|
+
|
|
81
|
+
4. **If upgrade or typecheck fails**
|
|
60
82
|
|
|
61
83
|
- Read the concrete error
|
|
62
84
|
- Fix **app** source, actions, config, or env — not framework packages
|
|
@@ -68,7 +90,7 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
68
90
|
copied component; do not use that path to reproduce framework runtime
|
|
69
91
|
behavior or hide version skew.
|
|
70
92
|
|
|
71
|
-
|
|
93
|
+
5. **Dry-run / partial runs**
|
|
72
94
|
|
|
73
95
|
```bash
|
|
74
96
|
agent-native upgrade --dry-run
|
|
@@ -56,7 +56,29 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
56
56
|
- Runs `skills update scaffold --project`
|
|
57
57
|
- Runs `typecheck` when the project has that script
|
|
58
58
|
|
|
59
|
-
3. **
|
|
59
|
+
3. **Pull upstream template changes (optional, separate from the bump)**
|
|
60
|
+
|
|
61
|
+
`agent-native upgrade` moves package versions. It never touches files that
|
|
62
|
+
were copied out of a template at scaffold time, so template fixes and
|
|
63
|
+
improvements do not arrive with a bump.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
agent-native template status # recorded ref vs latest, drift counts
|
|
67
|
+
agent-native template diff # what upstream changed, read-only
|
|
68
|
+
agent-native template sync # 3-way merge it into the app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`sync` defaults to the ref matching the installed `@agent-native/core`, so
|
|
72
|
+
run it after `upgrade`. It merges per file against a pristine baseline
|
|
73
|
+
stored in `refs/agent-native/template-baseline/<app-path>`; files upstream
|
|
74
|
+
did not touch are left alone, and real collisions get conflict markers.
|
|
75
|
+
After resolving markers, run `agent-native template accept` — the baseline
|
|
76
|
+
deliberately does not advance past an unresolved merge.
|
|
77
|
+
|
|
78
|
+
Apps scaffolded before provenance existed have no baseline. Create one
|
|
79
|
+
with `agent-native template baseline` before the first sync.
|
|
80
|
+
|
|
81
|
+
4. **If upgrade or typecheck fails**
|
|
60
82
|
|
|
61
83
|
- Read the concrete error
|
|
62
84
|
- Fix **app** source, actions, config, or env — not framework packages
|
|
@@ -68,7 +90,7 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
68
90
|
copied component; do not use that path to reproduce framework runtime
|
|
69
91
|
behavior or hide version skew.
|
|
70
92
|
|
|
71
|
-
|
|
93
|
+
5. **Dry-run / partial runs**
|
|
72
94
|
|
|
73
95
|
```bash
|
|
74
96
|
agent-native upgrade --dry-run
|
|
@@ -46,6 +46,7 @@ Read this skill before:
|
|
|
46
46
|
- **`recordings.visibility`** — framework-managed column from `ownableColumns()`.
|
|
47
47
|
- **`recording_viewers`** + **`recording_events`** — view counting.
|
|
48
48
|
- **`recording_views`** — append-only per-view log (who viewed, when) backing the owner-facing "Viewed by" popover. See "View counting" below.
|
|
49
|
+
- **`recording_agent_views`** — outside agents reading a clip through its public agent APIs, counted separately from humans. See "Agent views" below.
|
|
49
50
|
|
|
50
51
|
## Dropping in the share UI
|
|
51
52
|
|
|
@@ -213,6 +214,11 @@ they can fetch only the visual context they need.
|
|
|
213
214
|
|
|
214
215
|
## View counting
|
|
215
216
|
|
|
217
|
+
Clips counts **human views** and **agent views** separately. The two live in
|
|
218
|
+
different tables and never mix — see "Agent views" below before touching either.
|
|
219
|
+
|
|
220
|
+
### Human views
|
|
221
|
+
|
|
216
222
|
A view counts when **any** of these is true:
|
|
217
223
|
|
|
218
224
|
- The viewer has watched **≥ 5 seconds** of total real playback time
|
|
@@ -237,6 +243,34 @@ if (
|
|
|
237
243
|
|
|
238
244
|
Events feeding this live in `recording_events`. The `/api/view-event` route receives `view-start`, `watch-progress` (every 5s), `seek`, `pause`, `resume`, `cta-click`, `reaction`. Aggregate into `recording_viewers` on write to keep `get-insights` fast.
|
|
239
245
|
|
|
246
|
+
### Agent views
|
|
247
|
+
|
|
248
|
+
An **agent view** is an outside agent reading a clip through its public agent
|
|
249
|
+
APIs — `/api/agent-context.json`, `/api/agent-transcript.json`,
|
|
250
|
+
`/api/agent-frame.jpg`. Those routes are agent-only surfaces (a human watching a
|
|
251
|
+
clip never hits them), so a request on one is the signal.
|
|
252
|
+
|
|
253
|
+
- **Table:** `recording_agent_views` — one row per `(recordingId, agentKey, viewSessionId)`.
|
|
254
|
+
`agentKey` is a sha256 of user-agent + request IP, so an agent is countable
|
|
255
|
+
across polls without ever storing its IP. `agentLabel` is the product name
|
|
256
|
+
parsed from the user-agent (Claude, ChatGPT, Perplexity, …), falling back to
|
|
257
|
+
`"Agent"` — never the raw user-agent string.
|
|
258
|
+
- **Where it's written:** `recordAgentView` in `server/lib/agent-views.ts`,
|
|
259
|
+
called from `loadPublicAgentAccess` — the one choke point all three agent
|
|
260
|
+
routes share. Owner requests are skipped (they're previews, not views), and the
|
|
261
|
+
write is best-effort so view accounting can never fail an agent's read.
|
|
262
|
+
- **Dedup:** one agent's burst of context + transcript + frame polls collapses
|
|
263
|
+
into a single view via a 30-minute window (`AGENT_VIEW_SESSION_MS`), with
|
|
264
|
+
`requestCount` recording how many polls that view covered.
|
|
265
|
+
- **Reads:** `countRecordingAgentViews` and `listRecordingAgentViewers`. Surfaced
|
|
266
|
+
as `agentViews` / `agentViewers` on `get-recording-insights` and
|
|
267
|
+
`agentViewCount` on `get-recording-player-data`, and rendered in the views pill
|
|
268
|
+
popover (`RecordingViewsBadge`) next to human views.
|
|
269
|
+
|
|
270
|
+
Keeping this in its own table is deliberate: no human-view query can pick agents
|
|
271
|
+
up by forgetting a filter. Do not add agent rows to `recording_viewers` or
|
|
272
|
+
`recording_views`.
|
|
273
|
+
|
|
240
274
|
### Per-viewer view records ("Viewed by")
|
|
241
275
|
|
|
242
276
|
On top of the aggregate `viewCount` shown in the library and the `views` stat in the insights panel, Clips records **individual view records** — who viewed a clip and when — so the owner can see a timeline, not just a number.
|
|
@@ -17,7 +17,11 @@ ladder.
|
|
|
17
17
|
- Store large file/blob payloads in configured file/blob storage, not SQL: no
|
|
18
18
|
base64, `data:` URLs, images, video/audio, PDFs, ZIPs, screenshots,
|
|
19
19
|
thumbnails, or replay chunks in app tables, `application_state`, `settings`,
|
|
20
|
-
or `resources`; persist URLs, ids, or handles instead.
|
|
20
|
+
or `resources`; persist URLs, ids, or handles instead. Hosted/shared
|
|
21
|
+
recording uploads require configured storage — do not preserve video bytes
|
|
22
|
+
in SQL as a production fallback. The only exception: local SQLite/dev flows
|
|
23
|
+
may keep scratch chunks while a user connects Builder.io or S3-compatible
|
|
24
|
+
storage.
|
|
21
25
|
- Never hardcode API keys, tokens, webhook URLs, signing secrets, private Builder/internal data, customer data, or credential-looking literals. Use secrets/OAuth/runtime configuration and obvious placeholders in examples.
|
|
22
26
|
- Use actions for recording metadata, transcripts, cleanup, summaries, chapters,
|
|
23
27
|
comments, spaces/folders, meetings, and sharing. Do not bypass access helpers.
|
|
@@ -106,9 +110,6 @@ ladder.
|
|
|
106
110
|
Anthropic/OpenAI power the agent chat; Gemini powers cleanup, titles, and
|
|
107
111
|
meeting notes; any optional third-party speech provider is limited to
|
|
108
112
|
desktop voice dictation and is not used for recording transcripts.
|
|
109
|
-
- Hosted/shared recording uploads require configured storage. Do not preserve
|
|
110
|
-
video bytes in SQL as a production fallback; only local SQLite/dev flows may
|
|
111
|
-
keep scratch chunks while a user connects Builder.io or S3-compatible storage.
|
|
112
113
|
- Use `view-screen` when the active recording, transcript segment, meeting, or
|
|
113
114
|
share context is unclear.
|
|
114
115
|
- Calendar-sourced meeting actions are shortcuts, but do not add raw
|
|
@@ -489,6 +489,11 @@ function buildPrompt({
|
|
|
489
489
|
"dueDate"?: string // ISO date if explicitly mentioned
|
|
490
490
|
}>
|
|
491
491
|
}
|
|
492
|
+
Rules for summaryMd:
|
|
493
|
+
- Write it the way the person who made this recording would describe it themselves — plain, direct, and about the subject matter.
|
|
494
|
+
- Never narrate the recording from the outside. Do not write "the speaker", "the presenter", "the narrator", "the author", "the team", "the video", "this recording", "this clip", "this meeting", "the discussion covered", or any equivalent framing.
|
|
495
|
+
- Lead with the topic, decisions, and specifics. Name a person only when who said or owns something actually matters.
|
|
496
|
+
- No praise, no meta commentary about the transcript, no "overall" wrap-up sentence.
|
|
492
497
|
Rules for action items:
|
|
493
498
|
- Attribute each action item to a specific attendee whenever the transcript makes the owner clear (e.g. "I'll send the deck", "Alice will follow up").
|
|
494
499
|
- The "assigneeEmail" MUST be one of the attendee emails listed in the <context> block above — do not invent emails or use display names.
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Owner-only — uses assertAccess at editor level (owners always satisfy).
|
|
5
5
|
*
|
|
6
|
-
* Returns: views
|
|
7
|
-
*
|
|
6
|
+
* Returns: views (total counted human view sessions, so a returning viewer
|
|
7
|
+
* counts again), agentViews (outside agents reading the clip's agent APIs),
|
|
8
|
+
* uniqueViewers (distinct people behind those views), completionRate,
|
|
9
|
+
* dropOff (100 buckets), ctaConversionRate.
|
|
8
10
|
*
|
|
9
11
|
* Usage:
|
|
10
12
|
* pnpm action get-recording-insights --recordingId=<id>
|
|
@@ -12,11 +14,19 @@
|
|
|
12
14
|
|
|
13
15
|
import { defineAction } from "@agent-native/core";
|
|
14
16
|
import { assertAccess } from "@agent-native/core/sharing";
|
|
15
|
-
import { eq } from "drizzle-orm";
|
|
17
|
+
import { count, eq } from "drizzle-orm";
|
|
16
18
|
import { z } from "zod";
|
|
17
19
|
|
|
18
20
|
import { getDb, schema } from "../server/db/index.js";
|
|
19
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
countRecordingAgentViews,
|
|
23
|
+
listRecordingAgentViewers,
|
|
24
|
+
} from "../server/lib/agent-views.js";
|
|
25
|
+
import {
|
|
26
|
+
clampCompletionPct,
|
|
27
|
+
displayViewerName,
|
|
28
|
+
isCountedViewerRow,
|
|
29
|
+
} from "../shared/view-analytics.js";
|
|
20
30
|
|
|
21
31
|
export default defineAction({
|
|
22
32
|
description:
|
|
@@ -39,11 +49,31 @@ export default defineAction({
|
|
|
39
49
|
.from(schema.recordingEvents)
|
|
40
50
|
.where(eq(schema.recordingEvents.recordingId, args.recordingId));
|
|
41
51
|
|
|
42
|
-
const
|
|
52
|
+
const [[viewLogRow], agentViews, agentViewers] = await Promise.all([
|
|
53
|
+
db
|
|
54
|
+
.select({ value: count() })
|
|
55
|
+
.from(schema.recordingViews)
|
|
56
|
+
.where(eq(schema.recordingViews.recordingId, args.recordingId)),
|
|
57
|
+
countRecordingAgentViews(args.recordingId),
|
|
58
|
+
listRecordingAgentViewers(args.recordingId),
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
// Same definition as `countedViewCondition`, applied to rows already in
|
|
62
|
+
// memory so this action keeps its single viewer-row read. One row per
|
|
63
|
+
// person, so this is the distinct-viewer count, not the view total.
|
|
64
|
+
const countedViewers = viewerRows.filter(isCountedViewerRow).length;
|
|
43
65
|
const uniqueViewers = new Set(
|
|
44
|
-
viewerRows
|
|
66
|
+
viewerRows
|
|
67
|
+
.filter(isCountedViewerRow)
|
|
68
|
+
.map((v) => v.viewerEmail ?? `anon:${v.id}`),
|
|
45
69
|
).size;
|
|
46
70
|
|
|
71
|
+
// Mirrors `countRecordingViews`: `recording_views` only exists from
|
|
72
|
+
// migration v46, so clips recorded before it have zero log rows. Floor the
|
|
73
|
+
// total at the counted-viewer count so those clips keep reporting a real
|
|
74
|
+
// number instead of 0, and so total can never read below uniqueViewers.
|
|
75
|
+
const views = Math.max(Number(viewLogRow?.value ?? 0), countedViewers);
|
|
76
|
+
|
|
47
77
|
const completionRate =
|
|
48
78
|
viewerRows.length === 0
|
|
49
79
|
? 0
|
|
@@ -75,8 +105,12 @@ export default defineAction({
|
|
|
75
105
|
}
|
|
76
106
|
|
|
77
107
|
const ctaClicks = events.filter((e) => e.kind === "cta-click").length;
|
|
108
|
+
// CTA conversion is per person, so the denominator is counted viewers — not
|
|
109
|
+
// `views`, which counts repeat sessions from the same viewer.
|
|
78
110
|
const ctaConversionRate =
|
|
79
|
-
|
|
111
|
+
countedViewers === 0
|
|
112
|
+
? 0
|
|
113
|
+
: Math.min(100, (ctaClicks / countedViewers) * 100);
|
|
80
114
|
|
|
81
115
|
// Top viewers by total watch ms
|
|
82
116
|
const topViewers = viewerRows
|
|
@@ -85,13 +119,15 @@ export default defineAction({
|
|
|
85
119
|
.slice(0, 20)
|
|
86
120
|
.map((v) => ({
|
|
87
121
|
viewerEmail: v.viewerEmail,
|
|
88
|
-
viewerName: v.viewerName,
|
|
122
|
+
viewerName: displayViewerName(v.viewerName),
|
|
89
123
|
totalWatchMs: v.totalWatchMs ?? 0,
|
|
90
124
|
completedPct: clampCompletionPct(v.completedPct),
|
|
91
125
|
}));
|
|
92
126
|
|
|
93
127
|
return {
|
|
94
128
|
views,
|
|
129
|
+
agentViews,
|
|
130
|
+
agentViewers,
|
|
95
131
|
uniqueViewers,
|
|
96
132
|
completionRate,
|
|
97
133
|
ctaConversionRate,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* - reactions
|
|
8
8
|
* - chapters (parsed from recording.chaptersJson)
|
|
9
9
|
* - CTAs
|
|
10
|
+
* - counted-view total
|
|
10
11
|
*
|
|
11
12
|
* This is the read endpoint the player/:id and share/:id routes use.
|
|
12
13
|
* Access is gated by assertAccess at viewer level — for public-visibility
|
|
@@ -20,23 +21,24 @@
|
|
|
20
21
|
import { defineAction, embedApp } from "@agent-native/core";
|
|
21
22
|
import { readAppState } from "@agent-native/core/application-state";
|
|
22
23
|
import { buildDeepLink } from "@agent-native/core/server";
|
|
23
|
-
import {
|
|
24
|
-
getRequestOrgId,
|
|
25
|
-
getRequestUserEmail,
|
|
26
|
-
} from "@agent-native/core/server/request-context";
|
|
27
24
|
import { resolveAccess, ForbiddenError } from "@agent-native/core/sharing";
|
|
28
|
-
import {
|
|
25
|
+
import { asc, eq } from "drizzle-orm";
|
|
29
26
|
import { z } from "zod";
|
|
30
27
|
|
|
31
28
|
import { getDb, schema } from "../server/db/index.js";
|
|
32
29
|
import { isAgentRecordingCaller } from "../server/lib/agent-recording-access.js";
|
|
30
|
+
import { countRecordingAgentViews } from "../server/lib/agent-views.js";
|
|
33
31
|
import { isMediaVerificationPending } from "../server/lib/media-verification-state.js";
|
|
34
32
|
import { resolvePlayerVideoUrl } from "../server/lib/player-video-url.js";
|
|
35
33
|
import {
|
|
36
34
|
canOpenDirectRecordingPage,
|
|
37
35
|
isRecordingExpired,
|
|
38
36
|
} from "../server/lib/recording-page-access.js";
|
|
39
|
-
import {
|
|
37
|
+
import { hasExplicitRecordingShare } from "../server/lib/recording-share-grant.js";
|
|
38
|
+
import {
|
|
39
|
+
countRecordingViews,
|
|
40
|
+
parseSpaceIds,
|
|
41
|
+
} from "../server/lib/recordings.js";
|
|
40
42
|
import { parseBrowserDiagnosticsRow } from "../shared/browser-diagnostics.js";
|
|
41
43
|
import {
|
|
42
44
|
CLIPS_BUILDER_CREDITS_STATE_KEY,
|
|
@@ -93,7 +95,7 @@ function recordingDeepLink(recordingId: string): string {
|
|
|
93
95
|
|
|
94
96
|
export default defineAction({
|
|
95
97
|
description:
|
|
96
|
-
"Fetch everything the player page needs for a recording: metadata, transcript, comments, reactions, chapters, CTAs, and the caller's effective role. Agent calls receive a bounded transcript payload; browser player calls receive the full transcript.",
|
|
98
|
+
"Fetch everything the player page needs for a recording: metadata, transcript, comments, reactions, chapters, CTAs, the counted-view total, and the caller's effective role. Agent calls receive a bounded transcript payload; browser player calls receive the full transcript.",
|
|
97
99
|
schema: z.object({
|
|
98
100
|
recordingId: z.string().describe("Recording ID"),
|
|
99
101
|
}),
|
|
@@ -121,55 +123,13 @@ export default defineAction({
|
|
|
121
123
|
throw new ForbiddenError("Recording has expired");
|
|
122
124
|
}
|
|
123
125
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
isAgentRecordingCaller(ctx?.caller)
|
|
130
|
-
)
|
|
131
|
-
hasExplicitShare = true;
|
|
132
|
-
}
|
|
133
|
-
if (
|
|
134
|
-
rec.visibility === "public" &&
|
|
135
|
-
access.role !== "owner" &&
|
|
136
|
-
!hasExplicitShare
|
|
137
|
-
) {
|
|
138
|
-
const userEmail = getRequestUserEmail()?.trim().toLowerCase();
|
|
139
|
-
const orgId = getRequestOrgId();
|
|
140
|
-
const principals = [];
|
|
141
|
-
if (userEmail) {
|
|
142
|
-
principals.push(
|
|
143
|
-
and(
|
|
144
|
-
eq(schema.recordingShares.principalType, "user"),
|
|
145
|
-
sql`lower(${schema.recordingShares.principalId}) = ${userEmail}`,
|
|
146
|
-
),
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
if (orgId) {
|
|
150
|
-
principals.push(
|
|
151
|
-
and(
|
|
152
|
-
eq(schema.recordingShares.principalType, "org"),
|
|
153
|
-
eq(schema.recordingShares.principalId, orgId),
|
|
154
|
-
),
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
if (principals.length > 0) {
|
|
158
|
-
const [share] = await db
|
|
159
|
-
.select({ id: schema.recordingShares.id })
|
|
160
|
-
.from(schema.recordingShares)
|
|
161
|
-
.where(
|
|
162
|
-
and(
|
|
163
|
-
eq(schema.recordingShares.resourceId, args.recordingId),
|
|
164
|
-
or(...principals),
|
|
165
|
-
),
|
|
166
|
-
)
|
|
167
|
-
.limit(1);
|
|
168
|
-
hasExplicitShare = Boolean(share);
|
|
169
|
-
} else {
|
|
170
|
-
hasExplicitShare = false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
126
|
+
const hasExplicitShare = await hasExplicitRecordingShare({
|
|
127
|
+
recordingId: args.recordingId,
|
|
128
|
+
role: access.role,
|
|
129
|
+
visibility: rec.visibility,
|
|
130
|
+
hasPassword: Boolean(rec.password),
|
|
131
|
+
isAgentCaller: isAgentRecordingCaller(ctx?.caller),
|
|
132
|
+
});
|
|
173
133
|
|
|
174
134
|
if (
|
|
175
135
|
!canOpenDirectRecordingPage({
|
|
@@ -193,20 +153,27 @@ export default defineAction({
|
|
|
193
153
|
access.role === "owner" ||
|
|
194
154
|
access.role === "admin" ||
|
|
195
155
|
access.role === "editor";
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
156
|
+
// This action is on a 1-3s poll from the player, so every read here shares
|
|
157
|
+
// one Promise.all instead of adding serial round-trips.
|
|
158
|
+
const [
|
|
159
|
+
cleanupStateRaw,
|
|
160
|
+
builderCreditsRaw,
|
|
161
|
+
verificationPending,
|
|
162
|
+
viewCount,
|
|
163
|
+
agentViewCount,
|
|
164
|
+
] = await Promise.all([
|
|
165
|
+
readAppState(`transcript-cleanup-${args.recordingId}`).catch(() => null),
|
|
166
|
+
canEditRecording
|
|
167
|
+
? readAppState(CLIPS_BUILDER_CREDITS_STATE_KEY).catch(() => null)
|
|
168
|
+
: Promise.resolve(null),
|
|
169
|
+
isMediaVerificationPending({
|
|
170
|
+
ownerEmail: rec.ownerEmail,
|
|
171
|
+
recordingId: args.recordingId,
|
|
172
|
+
recordingStatus: rec.status,
|
|
173
|
+
}),
|
|
174
|
+
countRecordingViews(args.recordingId).catch(() => 0),
|
|
175
|
+
countRecordingAgentViews(args.recordingId).catch(() => 0),
|
|
176
|
+
]);
|
|
210
177
|
const cleanupState =
|
|
211
178
|
cleanupStateRaw && typeof cleanupStateRaw === "object"
|
|
212
179
|
? (cleanupStateRaw as Record<string, unknown>)
|
|
@@ -338,6 +305,8 @@ export default defineAction({
|
|
|
338
305
|
|
|
339
306
|
return {
|
|
340
307
|
role: access.role,
|
|
308
|
+
viewCount,
|
|
309
|
+
agentViewCount,
|
|
341
310
|
recording: {
|
|
342
311
|
id: rec.id,
|
|
343
312
|
organizationId: rec.organizationId,
|
|
@@ -19,6 +19,7 @@ import { desc, eq } from "drizzle-orm";
|
|
|
19
19
|
import { z } from "zod";
|
|
20
20
|
|
|
21
21
|
import { getDb, schema } from "../server/db/index.js";
|
|
22
|
+
import { displayViewerName } from "../shared/view-analytics.js";
|
|
22
23
|
|
|
23
24
|
export default defineAction({
|
|
24
25
|
description:
|
|
@@ -49,10 +50,7 @@ export default defineAction({
|
|
|
49
50
|
views: rows.map((v) => ({
|
|
50
51
|
id: v.id,
|
|
51
52
|
viewerEmail: v.viewerEmail,
|
|
52
|
-
|
|
53
|
-
// viewer_name (same convention as recording_viewers). Return null so
|
|
54
|
-
// callers render "Someone" instead of the raw session key.
|
|
55
|
-
viewerName: v.viewerName?.startsWith("anon:") ? null : v.viewerName,
|
|
53
|
+
viewerName: displayViewerName(v.viewerName),
|
|
56
54
|
viewedAt: v.viewedAt,
|
|
57
55
|
})),
|
|
58
56
|
};
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from "../server/lib/agent-recording-access.js";
|
|
22
22
|
import { resolvePlayerVideoUrl } from "../server/lib/player-video-url.js";
|
|
23
23
|
import {
|
|
24
|
+
countedViewCondition,
|
|
24
25
|
getActiveOrganizationId,
|
|
25
26
|
ownerEmailMatches,
|
|
26
27
|
parseSpaceIds,
|
|
@@ -63,6 +64,31 @@ export function resolveListRecordingMedia(
|
|
|
63
64
|
};
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
type ViewCountRow = { recordingId: string; count: number | string | null };
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* `recording_views` only exists from migration v46, so pre-migration clips have
|
|
71
|
+
* no log rows and must fall back to their counted-viewer count instead of
|
|
72
|
+
* dropping to 0. Same floor as `countRecordingViews`, so a library card and the
|
|
73
|
+
* clip page always agree.
|
|
74
|
+
*/
|
|
75
|
+
export function mergeViewCounts(
|
|
76
|
+
countedViewerRows: ViewCountRow[],
|
|
77
|
+
viewLogRows: ViewCountRow[],
|
|
78
|
+
): Record<string, number> {
|
|
79
|
+
const merged: Record<string, number> = {};
|
|
80
|
+
for (const row of countedViewerRows) {
|
|
81
|
+
merged[row.recordingId] = Number(row.count ?? 0);
|
|
82
|
+
}
|
|
83
|
+
for (const row of viewLogRows) {
|
|
84
|
+
merged[row.recordingId] = Math.max(
|
|
85
|
+
merged[row.recordingId] ?? 0,
|
|
86
|
+
Number(row.count ?? 0),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return merged;
|
|
90
|
+
}
|
|
91
|
+
|
|
66
92
|
export default defineAction({
|
|
67
93
|
description:
|
|
68
94
|
"List recordings visible to the current user. Supports filtering by view (library/shared/space/archive/trash/all), folder, space, tag, free-text, and sort. Public/unlisted recordings are discoverable only when owned by or previously viewed by the current user; the shared view returns accessible recordings owned by someone else.",
|
|
@@ -229,11 +255,26 @@ export default defineAction({
|
|
|
229
255
|
}
|
|
230
256
|
|
|
231
257
|
// Sort
|
|
232
|
-
const
|
|
258
|
+
const countedViewerCount = sql<number>`(
|
|
233
259
|
SELECT COUNT(1)
|
|
234
260
|
FROM ${schema.recordingViewers}
|
|
235
261
|
WHERE ${schema.recordingViewers.recordingId} = ${schema.recordings.id}
|
|
236
|
-
AND ${
|
|
262
|
+
AND ${countedViewCondition()}
|
|
263
|
+
)`;
|
|
264
|
+
const viewLogCount = sql<number>`(
|
|
265
|
+
SELECT COUNT(1)
|
|
266
|
+
FROM ${schema.recordingViews}
|
|
267
|
+
WHERE ${schema.recordingViews.recordingId} = ${schema.recordings.id}
|
|
268
|
+
)`;
|
|
269
|
+
// Same floor as `countRecordingViews`: `recording_views` only exists from
|
|
270
|
+
// migration v46, so pre-migration clips have no log rows and must fall back
|
|
271
|
+
// to the counted-viewer count instead of sorting as zero. CASE rather than
|
|
272
|
+
// MAX()/GREATEST() — the two-argument spelling differs across dialects.
|
|
273
|
+
const viewCountOrder = sql<number>`(
|
|
274
|
+
CASE WHEN ${viewLogCount} > ${countedViewerCount}
|
|
275
|
+
THEN ${viewLogCount}
|
|
276
|
+
ELSE ${countedViewerCount}
|
|
277
|
+
END
|
|
237
278
|
)`;
|
|
238
279
|
const orderBy =
|
|
239
280
|
args.sort === "oldest"
|
|
@@ -321,25 +362,34 @@ export default defineAction({
|
|
|
321
362
|
}
|
|
322
363
|
}
|
|
323
364
|
|
|
324
|
-
// Count views per recording
|
|
365
|
+
// Count views per recording — two set-wide grouped reads, never one per
|
|
366
|
+
// recording.
|
|
325
367
|
let viewsByRec: Record<string, number> = {};
|
|
326
368
|
if (ids.length) {
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
369
|
+
const [countedViewerRows, viewLogRows] = await Promise.all([
|
|
370
|
+
db
|
|
371
|
+
.select({
|
|
372
|
+
recordingId: schema.recordingViewers.recordingId,
|
|
373
|
+
count: sql<number>`COUNT(1)`,
|
|
374
|
+
})
|
|
375
|
+
.from(schema.recordingViewers)
|
|
376
|
+
.where(
|
|
377
|
+
and(
|
|
378
|
+
inArray(schema.recordingViewers.recordingId, ids),
|
|
379
|
+
countedViewCondition(),
|
|
380
|
+
),
|
|
381
|
+
)
|
|
382
|
+
.groupBy(schema.recordingViewers.recordingId),
|
|
383
|
+
db
|
|
384
|
+
.select({
|
|
385
|
+
recordingId: schema.recordingViews.recordingId,
|
|
386
|
+
count: sql<number>`COUNT(1)`,
|
|
387
|
+
})
|
|
388
|
+
.from(schema.recordingViews)
|
|
389
|
+
.where(inArray(schema.recordingViews.recordingId, ids))
|
|
390
|
+
.groupBy(schema.recordingViews.recordingId),
|
|
391
|
+
]);
|
|
392
|
+
viewsByRec = mergeViewCounts(countedViewerRows, viewLogRows);
|
|
343
393
|
}
|
|
344
394
|
|
|
345
395
|
const recordings = rows.map((row) => {
|
|
@@ -11,7 +11,10 @@ import { eq } from "drizzle-orm";
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
|
|
13
13
|
import { getDb, schema } from "../server/db/index.js";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
clampCompletionPct,
|
|
16
|
+
displayViewerName,
|
|
17
|
+
} from "../shared/view-analytics.js";
|
|
15
18
|
|
|
16
19
|
export default defineAction({
|
|
17
20
|
description:
|
|
@@ -37,7 +40,7 @@ export default defineAction({
|
|
|
37
40
|
.map((v) => ({
|
|
38
41
|
id: v.id,
|
|
39
42
|
viewerEmail: v.viewerEmail,
|
|
40
|
-
viewerName: v.viewerName,
|
|
43
|
+
viewerName: displayViewerName(v.viewerName),
|
|
41
44
|
totalWatchMs: v.totalWatchMs ?? 0,
|
|
42
45
|
completedPct: clampCompletionPct(v.completedPct),
|
|
43
46
|
countedView: Boolean(v.countedView),
|