@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.
Files changed (368) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +25 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/a2a/client.ts +162 -17
  5. package/corpus/core/src/a2a/correlation.ts +50 -0
  6. package/corpus/core/src/a2a/handlers.ts +200 -14
  7. package/corpus/core/src/a2a/index.ts +7 -1
  8. package/corpus/core/src/a2a/invoke.ts +77 -1
  9. package/corpus/core/src/a2a/server.ts +13 -1
  10. package/corpus/core/src/a2a/task-store.ts +146 -6
  11. package/corpus/core/src/a2a/types.ts +32 -0
  12. package/corpus/core/src/action.ts +5 -2
  13. package/corpus/core/src/agent/production-agent.ts +33 -4
  14. package/corpus/core/src/client/AssistantChat.tsx +648 -603
  15. package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -4
  16. package/corpus/core/src/client/agent-chat-adapter.ts +23 -37
  17. package/corpus/core/src/client/agent-sidebar-state.ts +4 -0
  18. package/corpus/core/src/client/analytics.ts +84 -0
  19. package/corpus/core/src/client/chat/message-components.tsx +94 -22
  20. package/corpus/core/src/client/chat/tool-call-display.tsx +170 -47
  21. package/corpus/core/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
  22. package/corpus/core/src/client/chat-thread-url.ts +11 -0
  23. package/corpus/core/src/client/error-capture.ts +12 -0
  24. package/corpus/core/src/client/extensions/ExtensionSlot.tsx +37 -1
  25. package/corpus/core/src/client/index.ts +2 -0
  26. package/corpus/core/src/client/route-chunk-recovery.ts +20 -8
  27. package/corpus/core/src/client/session-replay.ts +31 -0
  28. package/corpus/core/src/client/use-run-stuck-detection.ts +27 -1
  29. package/corpus/core/src/db/client.ts +55 -0
  30. package/corpus/core/src/extensions/actions.ts +2 -14
  31. package/corpus/core/src/extensions/store.ts +1 -1
  32. package/corpus/core/src/localization/default-messages.ts +3 -0
  33. package/corpus/core/src/mcp/build-server.ts +2 -2
  34. package/corpus/core/src/observability/traces.ts +172 -19
  35. package/corpus/core/src/progress/actions.ts +4 -2
  36. package/corpus/core/src/provider-api/index.ts +205 -105
  37. package/corpus/core/src/scripts/call-agent.ts +190 -19
  38. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +112 -25
  39. package/corpus/core/src/server/agent-chat-plugin.ts +136 -4
  40. package/corpus/core/src/styles/agent-conversation.css +7 -0
  41. package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +20 -0
  42. package/corpus/core/src/templates/default/app/i18n/de-DE.ts +20 -0
  43. package/corpus/core/src/templates/default/app/i18n/en-US.ts +20 -0
  44. package/corpus/core/src/templates/default/app/i18n/es-ES.ts +20 -0
  45. package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
  46. package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +19 -0
  47. package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +20 -0
  48. package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +19 -0
  49. package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +20 -0
  50. package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +19 -0
  51. package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
  52. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
  53. package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  54. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  55. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  56. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  57. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
  58. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +54 -23
  59. package/corpus/templates/analytics/.builder/skills/apollo/SKILL.md +19 -41
  60. package/corpus/templates/analytics/.builder/skills/commonroom/SKILL.md +20 -35
  61. package/corpus/templates/analytics/.builder/skills/github/SKILL.md +23 -67
  62. package/corpus/templates/analytics/.builder/skills/pylon/SKILL.md +25 -43
  63. package/corpus/templates/analytics/AGENTS.md +22 -13
  64. package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
  65. package/corpus/templates/analytics/actions/configure-gong-native-insights.ts +29 -0
  66. package/corpus/templates/analytics/actions/content-calendar-schema.ts +8 -4
  67. package/corpus/templates/analytics/actions/content-calendar.ts +12 -4
  68. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -1
  69. package/corpus/templates/analytics/actions/gong-calls.ts +113 -22
  70. package/corpus/templates/analytics/actions/gong-native-insights.ts +166 -0
  71. package/corpus/templates/analytics/actions/hubspot-deals.ts +190 -46
  72. package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
  73. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  74. package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
  75. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
  76. package/corpus/templates/analytics/app/components/ui/chart.tsx +1 -1
  77. package/corpus/templates/analytics/app/hooks/use-chart-tooltip-flip.ts +21 -6
  78. package/corpus/templates/analytics/app/i18n/zh-TW.ts +13 -0
  79. package/corpus/templates/analytics/app/i18n-data.ts +134 -0
  80. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +181 -30
  81. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
  82. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +4 -3
  83. package/corpus/templates/analytics/changelog/2026-07-17-analytics-now-includes-a-default-alert-for-spikes-in-stuck-agent-chats.md +6 -0
  84. package/corpus/templates/analytics/changelog/2026-07-17-dashboard-editors-can-add-shared-extensions-or-opt-into-per-.md +6 -0
  85. package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extensions-show-a-loading-skeleton.md +6 -0
  86. package/corpus/templates/analytics/changelog/2026-07-17-errors-now-group-repeat-failures-consistently-and-keep-priva.md +6 -0
  87. package/corpus/templates/analytics/changelog/2026-07-17-gong-transcript-reviews-now-batch-bounded-call-windows-for-f.md +6 -0
  88. package/corpus/templates/analytics/changelog/2026-07-17-hubspot-deal-filters-now-run-in-hubspot-before-paging-result.md +6 -0
  89. package/corpus/templates/analytics/changelog/2026-07-17-notion-content-calendars-now-discover-the-matching-database-.md +6 -0
  90. package/corpus/templates/analytics/changelog/2026-07-17-pylon-dashboard-reads-now-use-the-paginated-issue-search-api.md +6 -0
  91. package/corpus/templates/analytics/changelog/2026-07-17-slack-reads-no-longer-join-channels-and-report-pagination-coverage.md +6 -0
  92. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +23 -14
  93. package/corpus/templates/analytics/docs/schemas/tracked-events.md +5 -1
  94. package/corpus/templates/analytics/server/handlers/notion.ts +14 -3
  95. package/corpus/templates/analytics/server/handlers/slack.ts +182 -29
  96. package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +3 -3
  97. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
  98. package/corpus/templates/analytics/server/lib/analytics-alerts.ts +209 -87
  99. package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +6 -2
  100. package/corpus/templates/analytics/server/lib/error-capture.ts +75 -8
  101. package/corpus/templates/analytics/server/lib/gong-native-policy.ts +72 -0
  102. package/corpus/templates/analytics/server/lib/gong.ts +54 -66
  103. package/corpus/templates/analytics/server/lib/hubspot.ts +40 -3
  104. package/corpus/templates/analytics/server/lib/notion.ts +83 -8
  105. package/corpus/templates/analytics/server/lib/real-data-actions.ts +4 -0
  106. package/corpus/templates/analytics/server/lib/slack.ts +242 -90
  107. package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -3
  108. package/corpus/templates/analytics/server/routes/api/pylon/accounts.get.ts +42 -1
  109. package/corpus/templates/analytics/server/routes/api/pylon/issues.get.ts +71 -1
  110. package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +44 -4
  111. package/corpus/templates/clips/actions/finalize-recording.ts +541 -62
  112. package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +19 -1
  113. package/corpus/templates/clips/app/components/library/create-folder-dialog.tsx +123 -0
  114. package/corpus/templates/clips/app/components/library/library-grid.tsx +42 -4
  115. package/corpus/templates/clips/app/components/library/recording-card.tsx +30 -0
  116. package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +17 -2
  117. package/corpus/templates/clips/app/components/player/video-player.tsx +14 -2
  118. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +2 -2
  119. package/corpus/templates/clips/app/entry.client.tsx +6 -1
  120. package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -1
  121. package/corpus/templates/clips/app/i18n/de-DE.ts +12 -1
  122. package/corpus/templates/clips/app/i18n/en-US.ts +12 -1
  123. package/corpus/templates/clips/app/i18n/es-ES.ts +11 -1
  124. package/corpus/templates/clips/app/i18n/fr-FR.ts +11 -1
  125. package/corpus/templates/clips/app/i18n/hi-IN.ts +10 -1
  126. package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -1
  127. package/corpus/templates/clips/app/i18n/ko-KR.ts +11 -1
  128. package/corpus/templates/clips/app/i18n/pt-BR.ts +11 -1
  129. package/corpus/templates/clips/app/i18n/zh-CN.ts +11 -1
  130. package/corpus/templates/clips/app/i18n/zh-TW.ts +11 -1
  131. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +72 -1
  132. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -1
  133. package/corpus/templates/clips/app/routes/record.tsx +3 -3
  134. package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -3
  135. package/corpus/templates/clips/changelog/2026-07-17-choose-which-workspace-receives-new-clips-recordings-and-des.md +6 -0
  136. package/corpus/templates/clips/changelog/2026-07-17-clips-now-retries-storage-verification-in-the-background-ins.md +6 -0
  137. package/corpus/templates/clips/changelog/2026-07-17-create-folders-directly-from-the-move-menu.md +6 -0
  138. package/corpus/templates/clips/changelog/2026-07-17-failed-desktop-uploads-now-offer-a-direct-way-to-reopen-clip.md +6 -0
  139. package/corpus/templates/clips/changelog/2026-07-17-fixed-broken-thumbnail-icons-appearing-over-playable-clip-em.md +6 -0
  140. package/corpus/templates/clips/changelog/2026-07-17-playback-comments-stay-readable-at-faster-playback-speeds.md +6 -0
  141. package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +3 -0
  142. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +3 -3
  143. package/corpus/templates/clips/desktop/src/app.tsx +19 -7
  144. package/corpus/templates/clips/desktop/src/lib/recorder.ts +111 -13
  145. package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +16 -7
  146. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -4
  147. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +32 -15
  148. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +45 -18
  149. package/corpus/templates/clips/server/jobs/media-verification.ts +130 -0
  150. package/corpus/templates/clips/server/lib/builder-media-compression.ts +15 -0
  151. package/corpus/templates/clips/server/lib/media-verification-state.ts +38 -0
  152. package/corpus/templates/clips/server/lib/player-thumbnail-url.ts +31 -0
  153. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +10 -3
  154. package/corpus/templates/clips/server/plugins/auth.ts +5 -5
  155. package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
  156. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +12 -2
  157. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +6 -1
  158. package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +340 -0
  159. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +24 -7
  160. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +91 -7
  161. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +14 -0
  162. package/corpus/templates/clips/shared/finalize-recovery.ts +61 -2
  163. package/corpus/templates/clips/shared/share-meta.ts +1 -1
  164. package/corpus/templates/content/app/entry.client.tsx +6 -1
  165. package/corpus/templates/dispatch/AGENTS.md +5 -0
  166. package/corpus/templates/dispatch/changelog/2026-07-17-apps-page-links-to-other-available-apps.md +6 -0
  167. package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +6 -0
  168. package/corpus/templates/mail/app/entry.client.tsx +6 -1
  169. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +11 -7
  170. package/corpus/templates/slides/.env.example +0 -1
  171. package/corpus/templates/slides/AGENTS.md +4 -0
  172. package/corpus/templates/slides/DEVELOPING.md +2 -2
  173. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
  174. package/corpus/templates/slides/actions/logo-config.ts +6 -7
  175. package/corpus/templates/slides/actions/search-images.ts +11 -39
  176. package/corpus/templates/slides/actions/search-logos.ts +5 -52
  177. package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +1 -1
  178. package/corpus/templates/slides/app/components/editor/LogoSearchPanel.tsx +16 -26
  179. package/corpus/templates/slides/app/entry.client.tsx +6 -1
  180. package/corpus/templates/slides/server/lib/media-search-providers.ts +216 -0
  181. package/corpus/templates/slides/server/register-secrets.ts +30 -0
  182. package/dist/a2a/client.d.ts +47 -1
  183. package/dist/a2a/client.d.ts.map +1 -1
  184. package/dist/a2a/client.js +94 -12
  185. package/dist/a2a/client.js.map +1 -1
  186. package/dist/a2a/correlation.d.ts +10 -0
  187. package/dist/a2a/correlation.d.ts.map +1 -0
  188. package/dist/a2a/correlation.js +40 -0
  189. package/dist/a2a/correlation.js.map +1 -0
  190. package/dist/a2a/handlers.d.ts.map +1 -1
  191. package/dist/a2a/handlers.js +147 -15
  192. package/dist/a2a/handlers.js.map +1 -1
  193. package/dist/a2a/index.d.ts +4 -4
  194. package/dist/a2a/index.d.ts.map +1 -1
  195. package/dist/a2a/index.js +2 -2
  196. package/dist/a2a/index.js.map +1 -1
  197. package/dist/a2a/invoke.d.ts +29 -2
  198. package/dist/a2a/invoke.d.ts.map +1 -1
  199. package/dist/a2a/invoke.js +33 -1
  200. package/dist/a2a/invoke.js.map +1 -1
  201. package/dist/a2a/server.d.ts.map +1 -1
  202. package/dist/a2a/server.js +14 -1
  203. package/dist/a2a/server.js.map +1 -1
  204. package/dist/a2a/task-store.d.ts +12 -1
  205. package/dist/a2a/task-store.d.ts.map +1 -1
  206. package/dist/a2a/task-store.js +96 -6
  207. package/dist/a2a/task-store.js.map +1 -1
  208. package/dist/a2a/types.d.ts +27 -0
  209. package/dist/a2a/types.d.ts.map +1 -1
  210. package/dist/a2a/types.js.map +1 -1
  211. package/dist/action.d.ts +5 -2
  212. package/dist/action.d.ts.map +1 -1
  213. package/dist/action.js.map +1 -1
  214. package/dist/agent/production-agent.d.ts +14 -0
  215. package/dist/agent/production-agent.d.ts.map +1 -1
  216. package/dist/agent/production-agent.js +19 -3
  217. package/dist/agent/production-agent.js.map +1 -1
  218. package/dist/client/AssistantChat.d.ts +14 -1
  219. package/dist/client/AssistantChat.d.ts.map +1 -1
  220. package/dist/client/AssistantChat.js +158 -136
  221. package/dist/client/AssistantChat.js.map +1 -1
  222. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  223. package/dist/client/MultiTabAssistantChat.js +27 -4
  224. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  225. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  226. package/dist/client/agent-chat-adapter.js +21 -39
  227. package/dist/client/agent-chat-adapter.js.map +1 -1
  228. package/dist/client/agent-sidebar-state.d.ts +1 -0
  229. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  230. package/dist/client/agent-sidebar-state.js +4 -0
  231. package/dist/client/agent-sidebar-state.js.map +1 -1
  232. package/dist/client/analytics.d.ts +14 -0
  233. package/dist/client/analytics.d.ts.map +1 -1
  234. package/dist/client/analytics.js +67 -0
  235. package/dist/client/analytics.js.map +1 -1
  236. package/dist/client/chat/message-components.d.ts +8 -0
  237. package/dist/client/chat/message-components.d.ts.map +1 -1
  238. package/dist/client/chat/message-components.js +62 -19
  239. package/dist/client/chat/message-components.js.map +1 -1
  240. package/dist/client/chat/tool-call-display.d.ts +6 -0
  241. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  242. package/dist/client/chat/tool-call-display.js +83 -14
  243. package/dist/client/chat/tool-call-display.js.map +1 -1
  244. package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts +8 -0
  245. package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts.map +1 -0
  246. package/dist/client/chat/use-agent-chat-lifecycle-tracking.js +51 -0
  247. package/dist/client/chat/use-agent-chat-lifecycle-tracking.js.map +1 -0
  248. package/dist/client/chat-thread-url.d.ts +2 -0
  249. package/dist/client/chat-thread-url.d.ts.map +1 -0
  250. package/dist/client/chat-thread-url.js +12 -0
  251. package/dist/client/chat-thread-url.js.map +1 -0
  252. package/dist/client/error-capture.d.ts.map +1 -1
  253. package/dist/client/error-capture.js +7 -0
  254. package/dist/client/error-capture.js.map +1 -1
  255. package/dist/client/extensions/ExtensionSlot.d.ts +3 -1
  256. package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
  257. package/dist/client/extensions/ExtensionSlot.js +28 -3
  258. package/dist/client/extensions/ExtensionSlot.js.map +1 -1
  259. package/dist/client/index.d.ts +1 -1
  260. package/dist/client/index.d.ts.map +1 -1
  261. package/dist/client/index.js +1 -1
  262. package/dist/client/index.js.map +1 -1
  263. package/dist/client/route-chunk-recovery.d.ts.map +1 -1
  264. package/dist/client/route-chunk-recovery.js +14 -9
  265. package/dist/client/route-chunk-recovery.js.map +1 -1
  266. package/dist/client/session-replay.d.ts +15 -0
  267. package/dist/client/session-replay.d.ts.map +1 -1
  268. package/dist/client/session-replay.js +20 -0
  269. package/dist/client/session-replay.js.map +1 -1
  270. package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
  271. package/dist/client/use-run-stuck-detection.js +25 -1
  272. package/dist/client/use-run-stuck-detection.js.map +1 -1
  273. package/dist/db/client.d.ts +7 -0
  274. package/dist/db/client.d.ts.map +1 -1
  275. package/dist/db/client.js +33 -0
  276. package/dist/db/client.js.map +1 -1
  277. package/dist/extensions/actions.d.ts.map +1 -1
  278. package/dist/extensions/actions.js +2 -10
  279. package/dist/extensions/actions.js.map +1 -1
  280. package/dist/extensions/store.js +1 -1
  281. package/dist/extensions/store.js.map +1 -1
  282. package/dist/localization/default-messages.d.ts +3 -0
  283. package/dist/localization/default-messages.d.ts.map +1 -1
  284. package/dist/localization/default-messages.js +3 -0
  285. package/dist/localization/default-messages.js.map +1 -1
  286. package/dist/mcp/build-server.d.ts +2 -0
  287. package/dist/mcp/build-server.d.ts.map +1 -1
  288. package/dist/mcp/build-server.js +2 -2
  289. package/dist/mcp/build-server.js.map +1 -1
  290. package/dist/notifications/routes.d.ts +2 -2
  291. package/dist/observability/routes.d.ts +5 -5
  292. package/dist/observability/traces.d.ts +9 -0
  293. package/dist/observability/traces.d.ts.map +1 -1
  294. package/dist/observability/traces.js +137 -19
  295. package/dist/observability/traces.js.map +1 -1
  296. package/dist/progress/actions.d.ts.map +1 -1
  297. package/dist/progress/actions.js +3 -2
  298. package/dist/progress/actions.js.map +1 -1
  299. package/dist/progress/routes.d.ts +1 -1
  300. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  301. package/dist/provider-api/index.d.ts.map +1 -1
  302. package/dist/provider-api/index.js +91 -8
  303. package/dist/provider-api/index.js.map +1 -1
  304. package/dist/scripts/call-agent.d.ts.map +1 -1
  305. package/dist/scripts/call-agent.js +140 -17
  306. package/dist/scripts/call-agent.js.map +1 -1
  307. package/dist/secrets/routes.d.ts +9 -9
  308. package/dist/server/agent-chat/action-filters-a2a.d.ts +24 -2
  309. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  310. package/dist/server/agent-chat/action-filters-a2a.js +62 -7
  311. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  312. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  313. package/dist/server/agent-chat-plugin.js +118 -5
  314. package/dist/server/agent-chat-plugin.js.map +1 -1
  315. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  316. package/dist/server/transcribe-voice.d.ts +1 -1
  317. package/dist/styles/agent-conversation.css +7 -0
  318. package/dist/templates/default/app/i18n/ar-SA.ts +20 -0
  319. package/dist/templates/default/app/i18n/de-DE.ts +20 -0
  320. package/dist/templates/default/app/i18n/en-US.ts +20 -0
  321. package/dist/templates/default/app/i18n/es-ES.ts +20 -0
  322. package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
  323. package/dist/templates/default/app/i18n/hi-IN.ts +19 -0
  324. package/dist/templates/default/app/i18n/ja-JP.ts +20 -0
  325. package/dist/templates/default/app/i18n/ko-KR.ts +19 -0
  326. package/dist/templates/default/app/i18n/pt-BR.ts +20 -0
  327. package/dist/templates/default/app/i18n/zh-CN.ts +19 -0
  328. package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
  329. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
  330. package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  331. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  332. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  333. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  334. package/package.json +1 -1
  335. package/src/templates/default/app/i18n/ar-SA.ts +20 -0
  336. package/src/templates/default/app/i18n/de-DE.ts +20 -0
  337. package/src/templates/default/app/i18n/en-US.ts +20 -0
  338. package/src/templates/default/app/i18n/es-ES.ts +20 -0
  339. package/src/templates/default/app/i18n/fr-FR.ts +21 -0
  340. package/src/templates/default/app/i18n/hi-IN.ts +19 -0
  341. package/src/templates/default/app/i18n/ja-JP.ts +20 -0
  342. package/src/templates/default/app/i18n/ko-KR.ts +19 -0
  343. package/src/templates/default/app/i18n/pt-BR.ts +20 -0
  344. package/src/templates/default/app/i18n/zh-CN.ts +19 -0
  345. package/src/templates/default/app/i18n/zh-TW.ts +19 -0
  346. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
  347. package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  348. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  349. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  350. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  351. package/corpus/templates/analytics/server/handlers/github.ts +0 -200
  352. package/corpus/templates/analytics/server/handlers/pylon.ts +0 -43
  353. package/corpus/templates/analytics/server/lib/apollo.ts +0 -167
  354. package/corpus/templates/analytics/server/lib/commonroom.ts +0 -149
  355. package/corpus/templates/analytics/server/lib/github.ts +0 -660
  356. package/corpus/templates/analytics/server/lib/mixpanel.ts +0 -156
  357. package/corpus/templates/analytics/server/lib/posthog.ts +0 -194
  358. package/corpus/templates/analytics/server/lib/pylon.ts +0 -109
  359. package/corpus/templates/analytics/server/routes/api/github/graphql.post.ts +0 -1
  360. package/corpus/templates/analytics/server/routes/api/github/issue.get.ts +0 -1
  361. package/corpus/templates/analytics/server/routes/api/github/org-prs.get.ts +0 -1
  362. package/corpus/templates/analytics/server/routes/api/github/pr.get.ts +0 -1
  363. package/corpus/templates/analytics/server/routes/api/github/prs.get.ts +0 -1
  364. package/corpus/templates/analytics/server/routes/api/github/search.get.ts +0 -1
  365. package/corpus/templates/slides/actions/fetch-logos.ts +0 -90
  366. package/corpus/templates/slides/actions/image-search.ts +0 -64
  367. package/corpus/templates/slides/actions/import-github.ts +0 -182
  368. 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 defaultHttp5xxAlertId(ownerEmail: string, orgId: string | null) {
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 `${DEFAULT_HTTP_5XX_ALERT_ID_PREFIX}-${hash}`;
331
+ return `${prefix}-${hash}`;
314
332
  }
315
333
 
316
- async function defaultHttp5xxAlertScopes(): Promise<AccessCtx[]> {
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) return [{ email: ownerEmail, orgId }];
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
- .limit(1000);
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 scopes;
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
- await db.delete(schema.analyticsAlertRules).where(ownerWhere(ctx, id));
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
- export async function ensureDefaultHttp5xxSpikeAlertRules(): Promise<{
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
- if (!defaultHttp5xxAlertEnabled()) return { checked: 0, created: 0 };
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
- const threshold = envInt(
551
- "ANALYTICS_DEFAULT_HTTP_5XX_ALERT_THRESHOLD",
552
- 5,
553
- 1,
554
- 1000,
555
- );
556
- const windowMinutes = envInt(
557
- "ANALYTICS_DEFAULT_HTTP_5XX_ALERT_WINDOW_MINUTES",
558
- 5,
559
- 1,
560
- 60,
561
- );
562
- const cooldownMinutes = envInt(
563
- "ANALYTICS_DEFAULT_HTTP_5XX_ALERT_COOLDOWN_MINUTES",
564
- 30,
565
- 0,
566
- 24 * 60,
567
- );
568
-
569
- const scopesById = new Map<string, AccessCtx>();
570
- for (const scope of scopes) {
571
- scopesById.set(defaultHttp5xxAlertId(scope.email, scope.orgId), scope);
572
- }
573
- const allIds = Array.from(scopesById.keys());
574
-
575
- const existingIds = new Set<string>();
576
- for (const idChunk of chunkArray(allIds, DEFAULT_ALERT_SEED_CHUNK_SIZE)) {
577
- const rows = await db
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
- const missingIds = allIds.filter((id) => !existingIds.has(id));
585
- if (!missingIds.length) return { checked: scopes.length, created: 0 };
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
- const now = nowIso();
588
- const rowsToInsert = missingIds.map((id) => {
589
- const scope = scopesById.get(id)!;
590
- return {
591
- id,
592
- name: "Hosted app HTTP 5xx spike",
593
- description:
594
- "Default Agent Native alert for a spike in server responses with 5xx status codes.",
595
- eventName: "http.response",
596
- filters: JSON.stringify([
597
- { field: "properties.status_class", value: "5xx" },
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
- let created = 0;
616
- for (const rowChunk of chunkArray(
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: scopes.length, created };
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 incident-focused. In particular, do not add
5
- * raw replay-event/blob actions or dashboard/data mutation actions here.
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
- ? `${type}|${normalizeFrameFile(frame.file)}|${frame.function ?? ""}`
419
- : `${type}|${normalizeMessageForFingerprint(message)}`;
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
- occurrenceConditions.push(
1198
- eq(schema.errorEvents.sessionRecordingId, sessionRecordingId),
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: row.lastSessionRecordingId ?? null,
1257
- lastSessionRecordingPath: recordingPath(row.lastSessionRecordingId ?? null),
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: issueRow.lastSessionRecordingId ?? null,
1530
+ lastSessionRecordingId:
1531
+ issueRow.lastSessionRecordingId &&
1532
+ byId.has(issueRow.lastSessionRecordingId)
1533
+ ? issueRow.lastSessionRecordingId
1534
+ : null,
1471
1535
  lastSessionRecordingPath: recordingPath(
1472
- issueRow.lastSessionRecordingId ?? null,
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
+ }