@agent-native/core 0.108.0 → 0.109.1
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 +25 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +162 -17
- package/corpus/core/src/a2a/correlation.ts +50 -0
- package/corpus/core/src/a2a/handlers.ts +200 -14
- package/corpus/core/src/a2a/index.ts +7 -1
- package/corpus/core/src/a2a/invoke.ts +77 -1
- package/corpus/core/src/a2a/server.ts +13 -1
- package/corpus/core/src/a2a/task-store.ts +146 -6
- package/corpus/core/src/a2a/types.ts +32 -0
- package/corpus/core/src/action.ts +5 -2
- package/corpus/core/src/agent/production-agent.ts +33 -4
- package/corpus/core/src/client/AssistantChat.tsx +648 -603
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -4
- package/corpus/core/src/client/agent-chat-adapter.ts +23 -37
- package/corpus/core/src/client/agent-sidebar-state.ts +4 -0
- package/corpus/core/src/client/analytics.ts +84 -0
- package/corpus/core/src/client/chat/message-components.tsx +94 -22
- package/corpus/core/src/client/chat/tool-call-display.tsx +170 -47
- package/corpus/core/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
- package/corpus/core/src/client/chat-thread-url.ts +11 -0
- package/corpus/core/src/client/error-capture.ts +12 -0
- package/corpus/core/src/client/extensions/ExtensionSlot.tsx +37 -1
- package/corpus/core/src/client/index.ts +2 -0
- package/corpus/core/src/client/route-chunk-recovery.ts +20 -8
- package/corpus/core/src/client/session-replay.ts +31 -0
- package/corpus/core/src/client/use-run-stuck-detection.ts +27 -1
- package/corpus/core/src/db/client.ts +55 -0
- package/corpus/core/src/extensions/actions.ts +2 -14
- package/corpus/core/src/extensions/store.ts +1 -1
- package/corpus/core/src/localization/default-messages.ts +3 -0
- package/corpus/core/src/mcp/build-server.ts +2 -2
- package/corpus/core/src/observability/traces.ts +172 -19
- package/corpus/core/src/progress/actions.ts +4 -2
- package/corpus/core/src/provider-api/index.ts +205 -105
- package/corpus/core/src/scripts/call-agent.ts +190 -19
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +112 -25
- package/corpus/core/src/server/agent-chat-plugin.ts +136 -4
- package/corpus/core/src/styles/agent-conversation.css +7 -0
- package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +54 -23
- package/corpus/templates/analytics/.builder/skills/apollo/SKILL.md +19 -41
- package/corpus/templates/analytics/.builder/skills/commonroom/SKILL.md +20 -35
- package/corpus/templates/analytics/.builder/skills/github/SKILL.md +23 -67
- package/corpus/templates/analytics/.builder/skills/pylon/SKILL.md +25 -43
- package/corpus/templates/analytics/AGENTS.md +22 -13
- package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
- package/corpus/templates/analytics/actions/configure-gong-native-insights.ts +29 -0
- package/corpus/templates/analytics/actions/content-calendar-schema.ts +8 -4
- package/corpus/templates/analytics/actions/content-calendar.ts +12 -4
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -1
- package/corpus/templates/analytics/actions/gong-calls.ts +113 -22
- package/corpus/templates/analytics/actions/gong-native-insights.ts +166 -0
- package/corpus/templates/analytics/actions/hubspot-deals.ts +190 -46
- package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
- package/corpus/templates/analytics/app/components/ui/chart.tsx +1 -1
- package/corpus/templates/analytics/app/hooks/use-chart-tooltip-flip.ts +21 -6
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +13 -0
- package/corpus/templates/analytics/app/i18n-data.ts +134 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +181 -30
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +4 -3
- package/corpus/templates/analytics/changelog/2026-07-17-analytics-now-includes-a-default-alert-for-spikes-in-stuck-agent-chats.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-editors-can-add-shared-extensions-or-opt-into-per-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extensions-show-a-loading-skeleton.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-errors-now-group-repeat-failures-consistently-and-keep-priva.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-gong-transcript-reviews-now-batch-bounded-call-windows-for-f.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-hubspot-deal-filters-now-run-in-hubspot-before-paging-result.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-notion-content-calendars-now-discover-the-matching-database-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-pylon-dashboard-reads-now-use-the-paginated-issue-search-api.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-slack-reads-no-longer-join-channels-and-report-pagination-coverage.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +23 -14
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +5 -1
- package/corpus/templates/analytics/server/handlers/notion.ts +14 -3
- package/corpus/templates/analytics/server/handlers/slack.ts +182 -29
- package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +3 -3
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
- package/corpus/templates/analytics/server/lib/analytics-alerts.ts +209 -87
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +6 -2
- package/corpus/templates/analytics/server/lib/error-capture.ts +75 -8
- package/corpus/templates/analytics/server/lib/gong-native-policy.ts +72 -0
- package/corpus/templates/analytics/server/lib/gong.ts +54 -66
- package/corpus/templates/analytics/server/lib/hubspot.ts +40 -3
- package/corpus/templates/analytics/server/lib/notion.ts +83 -8
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +4 -0
- package/corpus/templates/analytics/server/lib/slack.ts +242 -90
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -3
- package/corpus/templates/analytics/server/routes/api/pylon/accounts.get.ts +42 -1
- package/corpus/templates/analytics/server/routes/api/pylon/issues.get.ts +71 -1
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +44 -4
- package/corpus/templates/clips/actions/finalize-recording.ts +541 -62
- package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +19 -1
- package/corpus/templates/clips/app/components/library/create-folder-dialog.tsx +123 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +42 -4
- package/corpus/templates/clips/app/components/library/recording-card.tsx +30 -0
- package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +17 -2
- package/corpus/templates/clips/app/components/player/video-player.tsx +14 -2
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +2 -2
- package/corpus/templates/clips/app/entry.client.tsx +6 -1
- package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -1
- package/corpus/templates/clips/app/i18n/de-DE.ts +12 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +12 -1
- package/corpus/templates/clips/app/i18n/es-ES.ts +11 -1
- package/corpus/templates/clips/app/i18n/fr-FR.ts +11 -1
- package/corpus/templates/clips/app/i18n/hi-IN.ts +10 -1
- package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +11 -1
- package/corpus/templates/clips/app/i18n/pt-BR.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-CN.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-TW.ts +11 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +72 -1
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -1
- package/corpus/templates/clips/app/routes/record.tsx +3 -3
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -3
- package/corpus/templates/clips/changelog/2026-07-17-choose-which-workspace-receives-new-clips-recordings-and-des.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-clips-now-retries-storage-verification-in-the-background-ins.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-create-folders-directly-from-the-move-menu.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-failed-desktop-uploads-now-offer-a-direct-way-to-reopen-clip.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-fixed-broken-thumbnail-icons-appearing-over-playable-clip-em.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-playback-comments-stay-readable-at-faster-playback-speeds.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +3 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +3 -3
- package/corpus/templates/clips/desktop/src/app.tsx +19 -7
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +111 -13
- package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +16 -7
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -4
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +32 -15
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +45 -18
- package/corpus/templates/clips/server/jobs/media-verification.ts +130 -0
- package/corpus/templates/clips/server/lib/builder-media-compression.ts +15 -0
- package/corpus/templates/clips/server/lib/media-verification-state.ts +38 -0
- package/corpus/templates/clips/server/lib/player-thumbnail-url.ts +31 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +10 -3
- package/corpus/templates/clips/server/plugins/auth.ts +5 -5
- package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +12 -2
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +6 -1
- package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +340 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +24 -7
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +91 -7
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +14 -0
- package/corpus/templates/clips/shared/finalize-recovery.ts +61 -2
- package/corpus/templates/clips/shared/share-meta.ts +1 -1
- package/corpus/templates/content/app/entry.client.tsx +6 -1
- package/corpus/templates/dispatch/AGENTS.md +5 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-apps-page-links-to-other-available-apps.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +6 -0
- package/corpus/templates/mail/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +11 -7
- package/corpus/templates/slides/.env.example +0 -1
- package/corpus/templates/slides/AGENTS.md +4 -0
- package/corpus/templates/slides/DEVELOPING.md +2 -2
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
- package/corpus/templates/slides/actions/logo-config.ts +6 -7
- package/corpus/templates/slides/actions/search-images.ts +11 -39
- package/corpus/templates/slides/actions/search-logos.ts +5 -52
- package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/LogoSearchPanel.tsx +16 -26
- package/corpus/templates/slides/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/server/lib/media-search-providers.ts +216 -0
- package/corpus/templates/slides/server/register-secrets.ts +30 -0
- package/dist/a2a/client.d.ts +47 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +94 -12
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/correlation.d.ts +10 -0
- package/dist/a2a/correlation.d.ts.map +1 -0
- package/dist/a2a/correlation.js +40 -0
- package/dist/a2a/correlation.js.map +1 -0
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +147 -15
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/index.d.ts +4 -4
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +2 -2
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/invoke.d.ts +29 -2
- package/dist/a2a/invoke.d.ts.map +1 -1
- package/dist/a2a/invoke.js +33 -1
- package/dist/a2a/invoke.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +14 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.d.ts +12 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +96 -6
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/a2a/types.d.ts +27 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +5 -2
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +14 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +19 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +158 -136
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +27 -4
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -39
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +1 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -1
- package/dist/client/agent-sidebar-state.js +4 -0
- package/dist/client/agent-sidebar-state.js.map +1 -1
- package/dist/client/analytics.d.ts +14 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +67 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +8 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +62 -19
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +6 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +83 -14
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts +8 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts.map +1 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js +51 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js.map +1 -0
- package/dist/client/chat-thread-url.d.ts +2 -0
- package/dist/client/chat-thread-url.d.ts.map +1 -0
- package/dist/client/chat-thread-url.js +12 -0
- package/dist/client/chat-thread-url.js.map +1 -0
- package/dist/client/error-capture.d.ts.map +1 -1
- package/dist/client/error-capture.js +7 -0
- package/dist/client/error-capture.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.d.ts +3 -1
- package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +28 -3
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +14 -9
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/client/session-replay.d.ts +15 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +20 -0
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
- package/dist/client/use-run-stuck-detection.js +25 -1
- package/dist/client/use-run-stuck-detection.js.map +1 -1
- package/dist/db/client.d.ts +7 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +33 -0
- package/dist/db/client.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +2 -10
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/store.js +1 -1
- package/dist/extensions/store.js.map +1 -1
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +3 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/build-server.d.ts +2 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +2 -2
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/observability/traces.d.ts +9 -0
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +137 -19
- package/dist/observability/traces.js.map +1 -1
- package/dist/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +3 -2
- package/dist/progress/actions.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +91 -8
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +140 -17
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/action-filters-a2a.d.ts +24 -2
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +62 -7
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +118 -5
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-conversation.css +7 -0
- package/dist/templates/default/app/i18n/ar-SA.ts +20 -0
- package/dist/templates/default/app/i18n/de-DE.ts +20 -0
- package/dist/templates/default/app/i18n/en-US.ts +20 -0
- package/dist/templates/default/app/i18n/es-ES.ts +20 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +19 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +20 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +19 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +20 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +19 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- package/package.json +1 -1
- package/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/src/templates/default/app/i18n/en-US.ts +20 -0
- package/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- package/corpus/templates/analytics/server/handlers/github.ts +0 -200
- package/corpus/templates/analytics/server/handlers/pylon.ts +0 -43
- package/corpus/templates/analytics/server/lib/apollo.ts +0 -167
- package/corpus/templates/analytics/server/lib/commonroom.ts +0 -149
- package/corpus/templates/analytics/server/lib/github.ts +0 -660
- package/corpus/templates/analytics/server/lib/mixpanel.ts +0 -156
- package/corpus/templates/analytics/server/lib/posthog.ts +0 -194
- package/corpus/templates/analytics/server/lib/pylon.ts +0 -109
- package/corpus/templates/analytics/server/routes/api/github/graphql.post.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/issue.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/org-prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/pr.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/search.get.ts +0 -1
- package/corpus/templates/slides/actions/fetch-logos.ts +0 -90
- package/corpus/templates/slides/actions/image-search.ts +0 -64
- package/corpus/templates/slides/actions/import-github.ts +0 -182
- package/corpus/templates/slides/actions/logo-lookup.ts +0 -113
|
@@ -135,6 +135,12 @@ function nowIso(): string {
|
|
|
135
135
|
|
|
136
136
|
const ALERT_RULE_RUNNING_STALE_MS = 15 * 60 * 1000;
|
|
137
137
|
const DEFAULT_HTTP_5XX_ALERT_ID_PREFIX = "default-http-5xx-spike";
|
|
138
|
+
const DEFAULT_AGENT_CHAT_STUCK_ALERT_ID_PREFIX =
|
|
139
|
+
"default-agent-chat-stuck-spike";
|
|
140
|
+
const DEFAULT_AGENT_CHAT_STUCK_ALERT_THRESHOLD = 3;
|
|
141
|
+
const DEFAULT_AGENT_CHAT_STUCK_ALERT_WINDOW_MINUTES = 10;
|
|
142
|
+
const DEFAULT_AGENT_CHAT_STUCK_ALERT_COOLDOWN_MINUTES = 60;
|
|
143
|
+
const DEFAULT_ALERT_SCOPE_PAGE_SIZE = 500;
|
|
138
144
|
const ALERT_RULE_DEFAULTS_KEY = "analytics-alert-rule-defaults";
|
|
139
145
|
|
|
140
146
|
function safeJsonParse<T>(raw: unknown, fallback: T): T {
|
|
@@ -296,6 +302,14 @@ function defaultHttp5xxAlertEnabled(): boolean {
|
|
|
296
302
|
return currentDeployHostname() === "analytics.agent-native.com";
|
|
297
303
|
}
|
|
298
304
|
|
|
305
|
+
function defaultAgentChatStuckAlertEnabled(): boolean {
|
|
306
|
+
const configured = boolEnv(
|
|
307
|
+
"ANALYTICS_DEFAULT_AGENT_CHAT_STUCK_ALERT_ENABLED",
|
|
308
|
+
);
|
|
309
|
+
if (configured !== null) return configured;
|
|
310
|
+
return currentDeployHostname() === "analytics.agent-native.com";
|
|
311
|
+
}
|
|
312
|
+
|
|
299
313
|
function envInt(name: string, fallback: number, min: number, max: number) {
|
|
300
314
|
const raw = process.env[name]?.trim();
|
|
301
315
|
if (!raw) return fallback;
|
|
@@ -305,18 +319,30 @@ function envInt(name: string, fallback: number, min: number, max: number) {
|
|
|
305
319
|
: fallback;
|
|
306
320
|
}
|
|
307
321
|
|
|
308
|
-
function
|
|
322
|
+
function defaultAlertId(
|
|
323
|
+
prefix: string,
|
|
324
|
+
ownerEmail: string,
|
|
325
|
+
orgId: string | null,
|
|
326
|
+
) {
|
|
309
327
|
const hash = createHash("sha256")
|
|
310
328
|
.update(`${ownerEmail.toLowerCase()}|${orgId ?? ""}`)
|
|
311
329
|
.digest("hex")
|
|
312
330
|
.slice(0, 10);
|
|
313
|
-
return `${
|
|
331
|
+
return `${prefix}-${hash}`;
|
|
314
332
|
}
|
|
315
333
|
|
|
316
|
-
async function
|
|
334
|
+
async function defaultAnalyticsAlertScopePage(offset: number): Promise<{
|
|
335
|
+
scopes: AccessCtx[];
|
|
336
|
+
hasMore: boolean;
|
|
337
|
+
}> {
|
|
317
338
|
const ownerEmail = process.env.ANALYTICS_DEFAULT_ALERT_OWNER_EMAIL?.trim();
|
|
318
339
|
const orgId = process.env.ANALYTICS_DEFAULT_ALERT_ORG_ID?.trim() || null;
|
|
319
|
-
if (ownerEmail)
|
|
340
|
+
if (ownerEmail) {
|
|
341
|
+
return {
|
|
342
|
+
scopes: offset === 0 ? [{ email: ownerEmail, orgId }] : [],
|
|
343
|
+
hasMore: false,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
320
346
|
|
|
321
347
|
const db = getDb() as any;
|
|
322
348
|
const rows = await db
|
|
@@ -326,7 +352,16 @@ async function defaultHttp5xxAlertScopes(): Promise<AccessCtx[]> {
|
|
|
326
352
|
})
|
|
327
353
|
.from(schema.analyticsPublicKeys)
|
|
328
354
|
.where(isNull(schema.analyticsPublicKeys.revokedAt))
|
|
329
|
-
.
|
|
355
|
+
.groupBy(
|
|
356
|
+
schema.analyticsPublicKeys.ownerEmail,
|
|
357
|
+
schema.analyticsPublicKeys.orgId,
|
|
358
|
+
)
|
|
359
|
+
.orderBy(
|
|
360
|
+
asc(schema.analyticsPublicKeys.ownerEmail),
|
|
361
|
+
asc(schema.analyticsPublicKeys.orgId),
|
|
362
|
+
)
|
|
363
|
+
.limit(DEFAULT_ALERT_SCOPE_PAGE_SIZE)
|
|
364
|
+
.offset(offset);
|
|
330
365
|
|
|
331
366
|
const seen = new Set<string>();
|
|
332
367
|
const scopes: AccessCtx[] = [];
|
|
@@ -342,7 +377,10 @@ async function defaultHttp5xxAlertScopes(): Promise<AccessCtx[]> {
|
|
|
342
377
|
seen.add(key);
|
|
343
378
|
scopes.push({ email, orgId: scopeOrgId });
|
|
344
379
|
}
|
|
345
|
-
return
|
|
380
|
+
return {
|
|
381
|
+
scopes,
|
|
382
|
+
hasMore: rows.length === DEFAULT_ALERT_SCOPE_PAGE_SIZE,
|
|
383
|
+
};
|
|
346
384
|
}
|
|
347
385
|
|
|
348
386
|
function rowToRule(row: any): AnalyticsAlertRule {
|
|
@@ -517,10 +555,20 @@ export async function deleteAnalyticsAlertRule(
|
|
|
517
555
|
});
|
|
518
556
|
}
|
|
519
557
|
const db = getDb() as any;
|
|
520
|
-
|
|
558
|
+
const seededDefault =
|
|
559
|
+
id.startsWith(`${DEFAULT_HTTP_5XX_ALERT_ID_PREFIX}-`) ||
|
|
560
|
+
id.startsWith(`${DEFAULT_AGENT_CHAT_STUCK_ALERT_ID_PREFIX}-`);
|
|
561
|
+
if (seededDefault) {
|
|
562
|
+
await db
|
|
563
|
+
.update(schema.analyticsAlertRules)
|
|
564
|
+
.set({ enabled: false, updatedAt: nowIso() })
|
|
565
|
+
.where(ownerWhere(ctx, id));
|
|
566
|
+
} else {
|
|
567
|
+
await db.delete(schema.analyticsAlertRules).where(ownerWhere(ctx, id));
|
|
568
|
+
}
|
|
521
569
|
recordChange({
|
|
522
570
|
source: "analytics-alert-rules",
|
|
523
|
-
type: "delete",
|
|
571
|
+
type: seededDefault ? "change" : "delete",
|
|
524
572
|
key: existing.id,
|
|
525
573
|
owner: existing.ownerEmail,
|
|
526
574
|
orgId: existing.orgId ?? undefined,
|
|
@@ -529,6 +577,20 @@ export async function deleteAnalyticsAlertRule(
|
|
|
529
577
|
|
|
530
578
|
const DEFAULT_ALERT_SEED_CHUNK_SIZE = 500;
|
|
531
579
|
|
|
580
|
+
interface DefaultAnalyticsAlertDefinition {
|
|
581
|
+
idPrefix: string;
|
|
582
|
+
name: string;
|
|
583
|
+
description: string;
|
|
584
|
+
eventName: string;
|
|
585
|
+
filters: AnalyticsAlertFilter[];
|
|
586
|
+
threshold: number;
|
|
587
|
+
thresholdMode?: AnalyticsAlertThresholdMode;
|
|
588
|
+
distinctBy?: string | null;
|
|
589
|
+
windowMinutes: number;
|
|
590
|
+
cooldownMinutes: number;
|
|
591
|
+
severity: AnalyticsAlertSeverity;
|
|
592
|
+
}
|
|
593
|
+
|
|
532
594
|
function chunkArray<T>(items: T[], size: number): T[][] {
|
|
533
595
|
const chunks: T[][] = [];
|
|
534
596
|
for (let i = 0; i < items.length; i += size) {
|
|
@@ -537,95 +599,155 @@ function chunkArray<T>(items: T[], size: number): T[][] {
|
|
|
537
599
|
return chunks;
|
|
538
600
|
}
|
|
539
601
|
|
|
540
|
-
|
|
602
|
+
function defaultAnalyticsAlertDefinitions(): DefaultAnalyticsAlertDefinition[] {
|
|
603
|
+
const definitions: DefaultAnalyticsAlertDefinition[] = [];
|
|
604
|
+
|
|
605
|
+
if (defaultHttp5xxAlertEnabled()) {
|
|
606
|
+
definitions.push({
|
|
607
|
+
idPrefix: DEFAULT_HTTP_5XX_ALERT_ID_PREFIX,
|
|
608
|
+
name: "Hosted app HTTP 5xx spike",
|
|
609
|
+
description:
|
|
610
|
+
"Default Agent Native alert for a spike in server responses with 5xx status codes.",
|
|
611
|
+
eventName: "http.response",
|
|
612
|
+
filters: [{ field: "properties.status_class", value: "5xx" }],
|
|
613
|
+
threshold: envInt(
|
|
614
|
+
"ANALYTICS_DEFAULT_HTTP_5XX_ALERT_THRESHOLD",
|
|
615
|
+
5,
|
|
616
|
+
1,
|
|
617
|
+
1000,
|
|
618
|
+
),
|
|
619
|
+
windowMinutes: envInt(
|
|
620
|
+
"ANALYTICS_DEFAULT_HTTP_5XX_ALERT_WINDOW_MINUTES",
|
|
621
|
+
5,
|
|
622
|
+
1,
|
|
623
|
+
60,
|
|
624
|
+
),
|
|
625
|
+
cooldownMinutes: envInt(
|
|
626
|
+
"ANALYTICS_DEFAULT_HTTP_5XX_ALERT_COOLDOWN_MINUTES",
|
|
627
|
+
30,
|
|
628
|
+
0,
|
|
629
|
+
24 * 60,
|
|
630
|
+
),
|
|
631
|
+
severity: "critical",
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
if (defaultAgentChatStuckAlertEnabled()) {
|
|
636
|
+
definitions.push({
|
|
637
|
+
idPrefix: DEFAULT_AGENT_CHAT_STUCK_ALERT_ID_PREFIX,
|
|
638
|
+
name: "Hosted agent chat stuck spike",
|
|
639
|
+
description:
|
|
640
|
+
"Default Agent Native alert for a spike in agent chats detected as stuck.",
|
|
641
|
+
eventName: "agent_chat_stuck_detected",
|
|
642
|
+
filters: [],
|
|
643
|
+
threshold: envInt(
|
|
644
|
+
"ANALYTICS_DEFAULT_AGENT_CHAT_STUCK_ALERT_THRESHOLD",
|
|
645
|
+
DEFAULT_AGENT_CHAT_STUCK_ALERT_THRESHOLD,
|
|
646
|
+
1,
|
|
647
|
+
1000,
|
|
648
|
+
),
|
|
649
|
+
thresholdMode: "distinct_count",
|
|
650
|
+
distinctBy: "properties.runId",
|
|
651
|
+
windowMinutes: envInt(
|
|
652
|
+
"ANALYTICS_DEFAULT_AGENT_CHAT_STUCK_ALERT_WINDOW_MINUTES",
|
|
653
|
+
DEFAULT_AGENT_CHAT_STUCK_ALERT_WINDOW_MINUTES,
|
|
654
|
+
1,
|
|
655
|
+
60,
|
|
656
|
+
),
|
|
657
|
+
cooldownMinutes: envInt(
|
|
658
|
+
"ANALYTICS_DEFAULT_AGENT_CHAT_STUCK_ALERT_COOLDOWN_MINUTES",
|
|
659
|
+
DEFAULT_AGENT_CHAT_STUCK_ALERT_COOLDOWN_MINUTES,
|
|
660
|
+
0,
|
|
661
|
+
24 * 60,
|
|
662
|
+
),
|
|
663
|
+
severity: "critical",
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return definitions;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
export async function ensureDefaultAnalyticsAlertRules(): Promise<{
|
|
541
671
|
checked: number;
|
|
542
672
|
created: number;
|
|
543
673
|
}> {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
const scopes = await defaultHttp5xxAlertScopes();
|
|
547
|
-
if (!scopes.length) return { checked: 0, created: 0 };
|
|
674
|
+
const definitions = defaultAnalyticsAlertDefinitions();
|
|
675
|
+
if (!definitions.length) return { checked: 0, created: 0 };
|
|
548
676
|
|
|
549
677
|
const db = getDb() as any;
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
.select({ id: schema.analyticsAlertRules.id })
|
|
579
|
-
.from(schema.analyticsAlertRules)
|
|
580
|
-
.where(inArray(schema.analyticsAlertRules.id, idChunk));
|
|
581
|
-
for (const row of rows) existingIds.add(row.id);
|
|
582
|
-
}
|
|
678
|
+
let checked = 0;
|
|
679
|
+
let created = 0;
|
|
680
|
+
let offset = 0;
|
|
681
|
+
while (true) {
|
|
682
|
+
const page = await defaultAnalyticsAlertScopePage(offset);
|
|
683
|
+
const candidatesById = new Map<
|
|
684
|
+
string,
|
|
685
|
+
{ definition: DefaultAnalyticsAlertDefinition; scope: AccessCtx }
|
|
686
|
+
>();
|
|
687
|
+
for (const scope of page.scopes) {
|
|
688
|
+
for (const definition of definitions) {
|
|
689
|
+
candidatesById.set(
|
|
690
|
+
defaultAlertId(definition.idPrefix, scope.email, scope.orgId),
|
|
691
|
+
{ definition, scope },
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
const allIds = Array.from(candidatesById.keys());
|
|
696
|
+
checked += allIds.length;
|
|
697
|
+
|
|
698
|
+
const existingIds = new Set<string>();
|
|
699
|
+
for (const idChunk of chunkArray(allIds, DEFAULT_ALERT_SEED_CHUNK_SIZE)) {
|
|
700
|
+
const rows = await db
|
|
701
|
+
.select({ id: schema.analyticsAlertRules.id })
|
|
702
|
+
.from(schema.analyticsAlertRules)
|
|
703
|
+
.where(inArray(schema.analyticsAlertRules.id, idChunk));
|
|
704
|
+
for (const row of rows) existingIds.add(row.id);
|
|
705
|
+
}
|
|
583
706
|
|
|
584
|
-
|
|
585
|
-
|
|
707
|
+
const now = nowIso();
|
|
708
|
+
const rowsToInsert = allIds
|
|
709
|
+
.filter((id) => !existingIds.has(id))
|
|
710
|
+
.map((id) => {
|
|
711
|
+
const { definition, scope } = candidatesById.get(id)!;
|
|
712
|
+
return {
|
|
713
|
+
id,
|
|
714
|
+
name: definition.name,
|
|
715
|
+
description: definition.description,
|
|
716
|
+
eventName: definition.eventName,
|
|
717
|
+
filters: JSON.stringify(definition.filters),
|
|
718
|
+
thresholdMode: definition.thresholdMode ?? ("event_count" as const),
|
|
719
|
+
distinctBy: definition.distinctBy ?? null,
|
|
720
|
+
threshold: definition.threshold,
|
|
721
|
+
windowMinutes: definition.windowMinutes,
|
|
722
|
+
cooldownMinutes: definition.cooldownMinutes,
|
|
723
|
+
severity: definition.severity,
|
|
724
|
+
channels: JSON.stringify(["inbox"]),
|
|
725
|
+
emailRecipients: JSON.stringify([]),
|
|
726
|
+
enabled: true,
|
|
727
|
+
createdAt: now,
|
|
728
|
+
updatedAt: now,
|
|
729
|
+
ownerEmail: scope.email,
|
|
730
|
+
orgId: scope.orgId,
|
|
731
|
+
};
|
|
732
|
+
});
|
|
586
733
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
]),
|
|
599
|
-
thresholdMode: "event_count" as const,
|
|
600
|
-
distinctBy: null,
|
|
601
|
-
threshold,
|
|
602
|
-
windowMinutes,
|
|
603
|
-
cooldownMinutes,
|
|
604
|
-
severity: "critical" as const,
|
|
605
|
-
channels: JSON.stringify(["inbox"]),
|
|
606
|
-
emailRecipients: JSON.stringify([]),
|
|
607
|
-
enabled: true,
|
|
608
|
-
createdAt: now,
|
|
609
|
-
updatedAt: now,
|
|
610
|
-
ownerEmail: scope.email,
|
|
611
|
-
orgId: scope.orgId,
|
|
612
|
-
};
|
|
613
|
-
});
|
|
734
|
+
for (const rowChunk of chunkArray(
|
|
735
|
+
rowsToInsert,
|
|
736
|
+
DEFAULT_ALERT_SEED_CHUNK_SIZE,
|
|
737
|
+
)) {
|
|
738
|
+
const inserted = await db
|
|
739
|
+
.insert(schema.analyticsAlertRules)
|
|
740
|
+
.values(rowChunk)
|
|
741
|
+
.onConflictDoNothing()
|
|
742
|
+
.returning({ id: schema.analyticsAlertRules.id });
|
|
743
|
+
created += inserted.length;
|
|
744
|
+
}
|
|
614
745
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
rowsToInsert,
|
|
618
|
-
DEFAULT_ALERT_SEED_CHUNK_SIZE,
|
|
619
|
-
)) {
|
|
620
|
-
const inserted = await db
|
|
621
|
-
.insert(schema.analyticsAlertRules)
|
|
622
|
-
.values(rowChunk)
|
|
623
|
-
.onConflictDoNothing()
|
|
624
|
-
.returning({ id: schema.analyticsAlertRules.id });
|
|
625
|
-
created += inserted.length;
|
|
746
|
+
if (!page.hasMore) break;
|
|
747
|
+
offset += DEFAULT_ALERT_SCOPE_PAGE_SIZE;
|
|
626
748
|
}
|
|
627
749
|
|
|
628
|
-
return { checked
|
|
750
|
+
return { checked, created };
|
|
629
751
|
}
|
|
630
752
|
|
|
631
753
|
export async function listEnabledAnalyticsAlertRules(options: {
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The deliberately small authenticated MCP surface for Analytics.
|
|
3
3
|
*
|
|
4
|
-
* Keep this list read-only and
|
|
5
|
-
*
|
|
4
|
+
* Keep this list read-only and bounded. It includes incident evidence plus
|
|
5
|
+
* the narrow Gong deep-dive/synthesis/evidence operations used by sibling
|
|
6
|
+
* apps. Do not add raw replay blobs or dashboard/data mutation actions here.
|
|
6
7
|
*/
|
|
7
8
|
export const ANALYTICS_CONNECTOR_CATALOG = [
|
|
9
|
+
"account-deep-dive",
|
|
10
|
+
"gong-calls",
|
|
11
|
+
"gong-native-insights",
|
|
8
12
|
"list-session-recordings",
|
|
9
13
|
"get-session-replay-summary",
|
|
10
14
|
"get-session-replay-timeline",
|
|
@@ -373,6 +373,11 @@ export function normalizeFrameFile(file: string | null): string {
|
|
|
373
373
|
// Strip bundler content hashes in the basename: main.4f3a2b1c.js -> main.js
|
|
374
374
|
out = out.replace(/([._-])[0-9a-fA-F]{8,}(?=\.[a-z0-9]+$)/i, "");
|
|
375
375
|
out = out.replace(/([._-])[0-9a-fA-F]{8,}$/i, "");
|
|
376
|
+
// Vite also emits eight-character base64url hashes, e.g. entry-CVi_y2nS.js.
|
|
377
|
+
out = out.replace(
|
|
378
|
+
/([._-])(?=[A-Za-z0-9_-]{8}\.[a-z0-9]+$)(?=[A-Za-z0-9_-]*[A-Z0-9_])[A-Za-z0-9_-]{8}(?=\.[a-z0-9]+$)/,
|
|
379
|
+
"",
|
|
380
|
+
);
|
|
376
381
|
return out;
|
|
377
382
|
}
|
|
378
383
|
|
|
@@ -412,11 +417,15 @@ export function fingerprint(
|
|
|
412
417
|
frames: ParsedStackFrame[],
|
|
413
418
|
message: string,
|
|
414
419
|
): string {
|
|
420
|
+
// The client uses this synthetic type for bare Error rejections. Keep it
|
|
421
|
+
// in the same group as window errors while retaining the original event
|
|
422
|
+
// type in the stored occurrence.
|
|
423
|
+
const groupingType = type === "UnhandledRejection" ? "Error" : type;
|
|
415
424
|
const frame = topFrame(frames);
|
|
416
425
|
const key =
|
|
417
426
|
frame && (frame.file || frame.function)
|
|
418
|
-
? `${
|
|
419
|
-
: `${
|
|
427
|
+
? `${groupingType}|${normalizeFrameFile(frame.file)}|${frame.function ?? ""}`
|
|
428
|
+
: `${groupingType}|${normalizeMessageForFingerprint(message)}`;
|
|
420
429
|
return hashHex(key);
|
|
421
430
|
}
|
|
422
431
|
|
|
@@ -1123,6 +1132,28 @@ function recordingPath(recordingId: string | null): string | null {
|
|
|
1123
1132
|
return recordingId ? `/sessions/${recordingId}` : null;
|
|
1124
1133
|
}
|
|
1125
1134
|
|
|
1135
|
+
async function accessibleClientRecordingId(
|
|
1136
|
+
scope: ErrorReadScope,
|
|
1137
|
+
recordingId: string,
|
|
1138
|
+
): Promise<string | null> {
|
|
1139
|
+
const db = getDb() as any;
|
|
1140
|
+
const [row] = await db
|
|
1141
|
+
.select({ clientRecordingId: schema.sessionRecordings.clientRecordingId })
|
|
1142
|
+
.from(schema.sessionRecordings)
|
|
1143
|
+
.where(
|
|
1144
|
+
and(
|
|
1145
|
+
eq(schema.sessionRecordings.id, recordingId),
|
|
1146
|
+
accessFilter(
|
|
1147
|
+
schema.sessionRecordings,
|
|
1148
|
+
schema.sessionRecordingShares,
|
|
1149
|
+
accessCtx(scope),
|
|
1150
|
+
),
|
|
1151
|
+
),
|
|
1152
|
+
)
|
|
1153
|
+
.limit(1);
|
|
1154
|
+
return row?.clientRecordingId ?? null;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1126
1157
|
async function sparklinesForIssues(
|
|
1127
1158
|
issueIds: string[],
|
|
1128
1159
|
): Promise<Map<string, number[]>> {
|
|
@@ -1194,9 +1225,19 @@ export async function listErrorIssues(
|
|
|
1194
1225
|
),
|
|
1195
1226
|
];
|
|
1196
1227
|
if (sessionRecordingId) {
|
|
1197
|
-
|
|
1198
|
-
|
|
1228
|
+
const clientRecordingId = await accessibleClientRecordingId(
|
|
1229
|
+
scope,
|
|
1230
|
+
sessionRecordingId,
|
|
1199
1231
|
);
|
|
1232
|
+
const recordingConditions: any[] = [
|
|
1233
|
+
eq(schema.errorEvents.sessionRecordingId, sessionRecordingId),
|
|
1234
|
+
];
|
|
1235
|
+
if (clientRecordingId) {
|
|
1236
|
+
recordingConditions.push(
|
|
1237
|
+
eq(schema.errorEvents.clientRecordingId, clientRecordingId),
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
occurrenceConditions.push(or(...recordingConditions));
|
|
1200
1241
|
}
|
|
1201
1242
|
if (userId) {
|
|
1202
1243
|
occurrenceConditions.push(
|
|
@@ -1241,6 +1282,13 @@ export async function listErrorIssues(
|
|
|
1241
1282
|
.limit(limit);
|
|
1242
1283
|
|
|
1243
1284
|
const sparklines = await sparklinesForIssues(rows.map((row: any) => row.id));
|
|
1285
|
+
const { byId: accessibleLastRecordings } = await resolveAccessibleRecordings(
|
|
1286
|
+
scope,
|
|
1287
|
+
rows
|
|
1288
|
+
.map((row: any) => row.lastSessionRecordingId)
|
|
1289
|
+
.filter((value: unknown): value is string => Boolean(value)),
|
|
1290
|
+
[],
|
|
1291
|
+
);
|
|
1244
1292
|
const issues = rows.map((row: any) => ({
|
|
1245
1293
|
id: row.id,
|
|
1246
1294
|
fingerprint: row.fingerprint,
|
|
@@ -1253,8 +1301,17 @@ export async function listErrorIssues(
|
|
|
1253
1301
|
lastSeenAt: row.lastSeenAt,
|
|
1254
1302
|
eventCount: Number(row.eventCount ?? 0),
|
|
1255
1303
|
usersAffected: Number(row.usersAffected ?? 0),
|
|
1256
|
-
lastSessionRecordingId:
|
|
1257
|
-
|
|
1304
|
+
lastSessionRecordingId:
|
|
1305
|
+
row.lastSessionRecordingId &&
|
|
1306
|
+
accessibleLastRecordings.has(row.lastSessionRecordingId)
|
|
1307
|
+
? row.lastSessionRecordingId
|
|
1308
|
+
: null,
|
|
1309
|
+
lastSessionRecordingPath: recordingPath(
|
|
1310
|
+
row.lastSessionRecordingId &&
|
|
1311
|
+
accessibleLastRecordings.has(row.lastSessionRecordingId)
|
|
1312
|
+
? row.lastSessionRecordingId
|
|
1313
|
+
: null,
|
|
1314
|
+
),
|
|
1258
1315
|
assignee: row.assignee ?? null,
|
|
1259
1316
|
app: row.app ?? null,
|
|
1260
1317
|
template: row.template ?? null,
|
|
@@ -1390,6 +1447,9 @@ export async function getErrorIssue(
|
|
|
1390
1447
|
.filter((value: unknown): value is string => Boolean(value)),
|
|
1391
1448
|
),
|
|
1392
1449
|
) as string[];
|
|
1450
|
+
if (issueRow.lastSessionRecordingId) {
|
|
1451
|
+
srIds.push(issueRow.lastSessionRecordingId);
|
|
1452
|
+
}
|
|
1393
1453
|
const clientIds = Array.from(
|
|
1394
1454
|
new Set(
|
|
1395
1455
|
eventRows
|
|
@@ -1467,9 +1527,16 @@ export async function getErrorIssue(
|
|
|
1467
1527
|
lastSeenAt: issueRow.lastSeenAt,
|
|
1468
1528
|
eventCount: Number(issueRow.eventCount ?? 0),
|
|
1469
1529
|
usersAffected: Number(issueRow.usersAffected ?? 0),
|
|
1470
|
-
lastSessionRecordingId:
|
|
1530
|
+
lastSessionRecordingId:
|
|
1531
|
+
issueRow.lastSessionRecordingId &&
|
|
1532
|
+
byId.has(issueRow.lastSessionRecordingId)
|
|
1533
|
+
? issueRow.lastSessionRecordingId
|
|
1534
|
+
: null,
|
|
1471
1535
|
lastSessionRecordingPath: recordingPath(
|
|
1472
|
-
issueRow.lastSessionRecordingId
|
|
1536
|
+
issueRow.lastSessionRecordingId &&
|
|
1537
|
+
byId.has(issueRow.lastSessionRecordingId)
|
|
1538
|
+
? issueRow.lastSessionRecordingId
|
|
1539
|
+
: null,
|
|
1473
1540
|
),
|
|
1474
1541
|
assignee: issueRow.assignee ?? null,
|
|
1475
1542
|
app: issueRow.app ?? null,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getRequestOrgId,
|
|
3
|
+
getRequestUserEmail,
|
|
4
|
+
} from "@agent-native/core/server";
|
|
5
|
+
import {
|
|
6
|
+
getOrgSetting,
|
|
7
|
+
getUserSetting,
|
|
8
|
+
putOrgSetting,
|
|
9
|
+
putUserSetting,
|
|
10
|
+
} from "@agent-native/core/settings";
|
|
11
|
+
|
|
12
|
+
export const GONG_NATIVE_INSIGHTS_SETTING_KEY = "gong-native-insights-policy";
|
|
13
|
+
|
|
14
|
+
export interface GongNativeInsightsPolicy {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
configured: boolean;
|
|
17
|
+
scope: "workspace" | "user" | "none";
|
|
18
|
+
updatedAt: string | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function parsePolicy(
|
|
22
|
+
value: Record<string, unknown> | null,
|
|
23
|
+
scope: GongNativeInsightsPolicy["scope"],
|
|
24
|
+
): GongNativeInsightsPolicy {
|
|
25
|
+
return {
|
|
26
|
+
enabled: value?.enabled === true,
|
|
27
|
+
configured: value != null,
|
|
28
|
+
scope,
|
|
29
|
+
updatedAt: typeof value?.updatedAt === "string" ? value.updatedAt : null,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function readGongNativeInsightsPolicy(): Promise<GongNativeInsightsPolicy> {
|
|
34
|
+
const orgId = getRequestOrgId() || null;
|
|
35
|
+
if (orgId) {
|
|
36
|
+
return parsePolicy(
|
|
37
|
+
await getOrgSetting(orgId, GONG_NATIVE_INSIGHTS_SETTING_KEY),
|
|
38
|
+
"workspace",
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const email = getRequestUserEmail();
|
|
43
|
+
if (email) {
|
|
44
|
+
return parsePolicy(
|
|
45
|
+
await getUserSetting(email, GONG_NATIVE_INSIGHTS_SETTING_KEY),
|
|
46
|
+
"user",
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return parsePolicy(null, "none");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function writeGongNativeInsightsPolicy(
|
|
54
|
+
enabled: boolean,
|
|
55
|
+
): Promise<GongNativeInsightsPolicy> {
|
|
56
|
+
const orgId = getRequestOrgId() || null;
|
|
57
|
+
const email = getRequestUserEmail();
|
|
58
|
+
const value = {
|
|
59
|
+
enabled,
|
|
60
|
+
updatedAt: new Date().toISOString(),
|
|
61
|
+
updatedBy: email ?? "authenticated-agent",
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (orgId) {
|
|
65
|
+
await putOrgSetting(orgId, GONG_NATIVE_INSIGHTS_SETTING_KEY, value);
|
|
66
|
+
return parsePolicy(value, "workspace");
|
|
67
|
+
}
|
|
68
|
+
if (!email) throw new Error("no authenticated user");
|
|
69
|
+
|
|
70
|
+
await putUserSetting(email, GONG_NATIVE_INSIGHTS_SETTING_KEY, value);
|
|
71
|
+
return parsePolicy(value, "user");
|
|
72
|
+
}
|