@agent-native/core 0.97.0 → 0.98.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 (1019) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +56 -0
  3. package/corpus/core/docs/content/authentication.mdx +3 -3
  4. package/corpus/core/docs/content/doctor.mdx +170 -0
  5. package/corpus/core/docs/content/external-agents.mdx +8 -7
  6. package/corpus/core/docs/content/locales/ar-SA/authentication.mdx +2 -2
  7. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +8 -7
  8. package/corpus/core/docs/content/locales/ar-SA/mcp-protocol.mdx +1 -1
  9. package/corpus/core/docs/content/locales/ar-SA/security.mdx +2 -0
  10. package/corpus/core/docs/content/locales/de-DE/authentication.mdx +1 -1
  11. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +8 -7
  12. package/corpus/core/docs/content/locales/de-DE/mcp-protocol.mdx +1 -1
  13. package/corpus/core/docs/content/locales/de-DE/security.mdx +2 -0
  14. package/corpus/core/docs/content/locales/es-ES/authentication.mdx +2 -2
  15. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +8 -7
  16. package/corpus/core/docs/content/locales/es-ES/mcp-protocol.mdx +1 -1
  17. package/corpus/core/docs/content/locales/es-ES/security.mdx +2 -0
  18. package/corpus/core/docs/content/locales/fr-FR/authentication.mdx +1 -1
  19. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +8 -7
  20. package/corpus/core/docs/content/locales/fr-FR/mcp-protocol.mdx +1 -1
  21. package/corpus/core/docs/content/locales/fr-FR/security.mdx +2 -0
  22. package/corpus/core/docs/content/locales/hi-IN/authentication.mdx +2 -2
  23. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +8 -7
  24. package/corpus/core/docs/content/locales/hi-IN/mcp-protocol.mdx +1 -1
  25. package/corpus/core/docs/content/locales/hi-IN/security.mdx +2 -0
  26. package/corpus/core/docs/content/locales/ja-JP/authentication.mdx +2 -2
  27. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +8 -7
  28. package/corpus/core/docs/content/locales/ja-JP/mcp-protocol.mdx +1 -1
  29. package/corpus/core/docs/content/locales/ja-JP/security.mdx +2 -0
  30. package/corpus/core/docs/content/locales/ko-KR/authentication.mdx +2 -2
  31. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +8 -7
  32. package/corpus/core/docs/content/locales/ko-KR/mcp-protocol.mdx +1 -1
  33. package/corpus/core/docs/content/locales/ko-KR/security.mdx +2 -0
  34. package/corpus/core/docs/content/locales/pt-BR/authentication.mdx +2 -2
  35. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +8 -7
  36. package/corpus/core/docs/content/locales/pt-BR/mcp-protocol.mdx +1 -1
  37. package/corpus/core/docs/content/locales/pt-BR/security.mdx +2 -0
  38. package/corpus/core/docs/content/locales/zh-CN/authentication.mdx +2 -2
  39. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +8 -7
  40. package/corpus/core/docs/content/locales/zh-CN/mcp-protocol.mdx +1 -1
  41. package/corpus/core/docs/content/locales/zh-CN/security.mdx +2 -0
  42. package/corpus/core/docs/content/locales/zh-TW/authentication.mdx +2 -2
  43. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +8 -7
  44. package/corpus/core/docs/content/locales/zh-TW/mcp-protocol.mdx +1 -1
  45. package/corpus/core/docs/content/locales/zh-TW/security.mdx +2 -0
  46. package/corpus/core/docs/content/mcp-protocol.mdx +1 -1
  47. package/corpus/core/docs/content/security.mdx +2 -0
  48. package/corpus/core/package.json +6 -2
  49. package/corpus/core/scripts/finalize-build.mjs +63 -3
  50. package/corpus/core/scripts/materialize-source-corpus.mjs +101 -15
  51. package/corpus/core/src/action-change-marker.ts +8 -1
  52. package/corpus/core/src/action.ts +42 -0
  53. package/corpus/core/src/agent/engine/builder-engine.ts +3 -0
  54. package/corpus/core/src/agent/engine/context-directives-transform.ts +69 -0
  55. package/corpus/core/src/agent/engine/continuation-dispatch-retry.ts +168 -0
  56. package/corpus/core/src/agent/engine/tool-call-journal-seed.ts +85 -0
  57. package/corpus/core/src/agent/production-agent.ts +129 -244
  58. package/corpus/core/src/changelog/parse.ts +8 -3
  59. package/corpus/core/src/cli/doctor.ts +9 -3
  60. package/corpus/core/src/cli/plan-local.ts +10 -2
  61. package/corpus/core/src/cli/skills-content/assets-skill.ts +83 -0
  62. package/corpus/core/src/cli/skills-content/canvas.ts +153 -0
  63. package/corpus/core/src/cli/skills-content/connection.ts +52 -0
  64. package/corpus/core/src/cli/skills-content/content-skill.ts +109 -0
  65. package/corpus/core/src/cli/skills-content/design-exploration-skill.ts +118 -0
  66. package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +228 -0
  67. package/corpus/core/src/cli/skills-content/document-quality.ts +196 -0
  68. package/corpus/core/src/cli/skills-content/exemplar.ts +69 -0
  69. package/corpus/core/src/cli/skills-content/help.ts +77 -0
  70. package/corpus/core/src/cli/skills-content/index.ts +22 -0
  71. package/corpus/core/src/cli/skills-content/local-files.ts +95 -0
  72. package/corpus/core/src/cli/skills-content/plan-setup-auth.ts +80 -0
  73. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +470 -0
  74. package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +547 -0
  75. package/corpus/core/src/cli/skills-content/visualize-repo-skill.ts +93 -0
  76. package/corpus/core/src/cli/skills-content/wireframe.ts +349 -0
  77. package/corpus/core/src/cli/skills.ts +27 -2733
  78. package/corpus/core/src/client/AgentPanel.tsx +8 -8
  79. package/corpus/core/src/client/AssistantChat.tsx +83 -39
  80. package/corpus/core/src/client/CommandMenu.tsx +16 -5
  81. package/corpus/core/src/client/FeedbackButton.tsx +2 -2
  82. package/corpus/core/src/client/analytics.ts +29 -0
  83. package/corpus/core/src/client/app-providers.tsx +18 -5
  84. package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +16 -2
  85. package/corpus/core/src/client/chat/tool-call-display.tsx +3 -3
  86. package/corpus/core/src/client/chat-model-groups.ts +28 -0
  87. package/corpus/core/src/client/composer/PastedTextChip.tsx +1 -1
  88. package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +523 -68
  89. package/corpus/core/src/client/composer/TiptapComposer.tsx +47 -30
  90. package/corpus/core/src/client/composer/VoiceButton.tsx +22 -5
  91. package/corpus/core/src/client/composer/index.ts +5 -0
  92. package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +1271 -35
  93. package/corpus/core/src/client/context-xray/ContextXRayPanel.tsx +5 -2
  94. package/corpus/core/src/client/extensions/ExtensionEditor.tsx +37 -4
  95. package/corpus/core/src/client/extensions/ExtensionQueryErrorState.tsx +47 -0
  96. package/corpus/core/src/client/extensions/ExtensionSlot.tsx +39 -10
  97. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +44 -6
  98. package/corpus/core/src/client/extensions/ExtensionsListPage.tsx +12 -3
  99. package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +49 -11
  100. package/corpus/core/src/client/index.ts +5 -13
  101. package/corpus/core/src/client/progress/RunsTray.tsx +23 -4
  102. package/corpus/core/src/client/settings/SecretsSection.tsx +387 -266
  103. package/corpus/core/src/client/settings/SettingsPanel.tsx +117 -38
  104. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +7 -0
  105. package/corpus/core/src/client/settings/useBuilderStatus.ts +6 -0
  106. package/corpus/core/src/client/tool-cells/EditCell.tsx +19 -16
  107. package/corpus/core/src/client/tool-cells/FilesChangedSummary.tsx +26 -23
  108. package/corpus/core/src/client/tool-cells/WriteCell.tsx +19 -16
  109. package/corpus/core/src/client/use-action.ts +12 -0
  110. package/corpus/core/src/client/use-agent-chat-home-handoff.ts +8 -1
  111. package/corpus/core/src/client/use-agent-engine-configured.ts +17 -3
  112. package/corpus/core/src/client/use-db-sync.ts +84 -34
  113. package/corpus/core/src/client/use-pausing-interval.ts +14 -4
  114. package/corpus/core/src/client/visual-style-controls.tsx +1 -1
  115. package/corpus/core/src/deploy/build.ts +36 -14
  116. package/corpus/core/src/integrations/google-docs-poller.ts +23 -2
  117. package/corpus/core/src/integrations/plugin.ts +10 -0
  118. package/corpus/core/src/integrations/scope-store.ts +1 -1
  119. package/corpus/core/src/integrations/usage-budget-store.ts +1 -1
  120. package/corpus/core/src/integrations/webhook-handler.ts +27 -2
  121. package/corpus/core/src/jobs/scheduler.ts +28 -2
  122. package/corpus/core/src/localization/default-messages.ts +51 -1
  123. package/corpus/core/src/mcp/oauth-token.ts +6 -1
  124. package/corpus/core/src/mcp-client/workspace-servers.ts +4 -4
  125. package/corpus/core/src/observability/routes.ts +36 -0
  126. package/corpus/core/src/observability/sentiment.ts +261 -0
  127. package/corpus/core/src/observability/store.ts +23 -0
  128. package/corpus/core/src/observability/traces.ts +49 -63
  129. package/corpus/core/src/observability/tracking-identity.ts +55 -0
  130. package/corpus/core/src/observability/types.ts +13 -0
  131. package/corpus/core/src/secrets/crypto.ts +28 -8
  132. package/corpus/core/src/secrets/storage.ts +67 -3
  133. package/corpus/core/src/server/action-change.ts +5 -1
  134. package/corpus/core/src/server/action-routes.ts +8 -0
  135. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +199 -0
  136. package/corpus/core/src/server/agent-chat/browser-team-tools.ts +510 -0
  137. package/corpus/core/src/server/agent-chat/context-tools.ts +595 -0
  138. package/corpus/core/src/server/agent-chat/framework-prompts.ts +470 -0
  139. package/corpus/core/src/server/agent-chat/lazy-fs.ts +11 -0
  140. package/corpus/core/src/server/agent-chat/mcp-glue.ts +91 -0
  141. package/corpus/core/src/server/agent-chat/plugin-options.ts +350 -0
  142. package/corpus/core/src/server/agent-chat/process-run-failure.ts +62 -0
  143. package/corpus/core/src/server/agent-chat/prompt-resources.ts +688 -0
  144. package/corpus/core/src/server/agent-chat/recurring-jobs-runtime.ts +80 -0
  145. package/corpus/core/src/server/agent-chat/request-surface.ts +71 -0
  146. package/corpus/core/src/server/agent-chat/run-code-tools.ts +67 -0
  147. package/corpus/core/src/server/agent-chat/script-entries.ts +779 -0
  148. package/corpus/core/src/server/agent-chat/shared-thread.ts +301 -0
  149. package/corpus/core/src/server/agent-chat/skill-frontmatter.ts +41 -0
  150. package/corpus/core/src/server/agent-chat-plugin.ts +364 -4182
  151. package/corpus/core/src/server/agent-teams.ts +26 -3
  152. package/corpus/core/src/server/auth.ts +55 -57
  153. package/corpus/core/src/server/credential-provider.ts +22 -25
  154. package/corpus/core/src/server/edge.ts +1 -0
  155. package/corpus/core/src/server/onboarding-html.ts +1 -16
  156. package/corpus/core/src/server/poll.ts +1 -0
  157. package/corpus/core/src/server/realtime-voice.ts +335 -14
  158. package/corpus/core/src/server/request-origin.ts +6 -2
  159. package/corpus/core/src/server/ssr-handler.ts +55 -2
  160. package/corpus/core/src/sharing/access.ts +155 -11
  161. package/corpus/core/src/sharing/registry.ts +7 -0
  162. package/corpus/core/src/styles/agent-native.css +17 -16
  163. package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +1 -1
  164. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
  165. package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +6 -0
  166. package/corpus/core/src/templates/default/app/i18n/de-DE.ts +6 -0
  167. package/corpus/core/src/templates/default/app/i18n/en-US.ts +6 -0
  168. package/corpus/core/src/templates/default/app/i18n/es-ES.ts +6 -0
  169. package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +6 -0
  170. package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +6 -0
  171. package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +6 -0
  172. package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +6 -0
  173. package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +6 -0
  174. package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +6 -0
  175. package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +6 -0
  176. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +27 -29
  177. package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +2 -1
  178. package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -1
  179. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +32 -0
  180. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
  181. package/corpus/core/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
  182. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
  183. package/corpus/core/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +25 -0
  184. package/corpus/core/src/templates/workspace-core/src/server/index.ts +4 -2
  185. package/corpus/core/src/testing.ts +26 -0
  186. package/corpus/core/src/triggers/dispatcher.ts +23 -2
  187. package/corpus/core/src/vite/client.ts +135 -3
  188. package/corpus/core/tsconfig.cli.json +1 -1
  189. package/corpus/core/tsconfig.json +5 -1
  190. package/corpus/templates/analytics/.agents/skills/bigquery/SKILL.md +2 -2
  191. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +1 -1
  192. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +2 -2
  193. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +10 -5
  194. package/corpus/templates/analytics/AGENTS.md +15 -6
  195. package/corpus/templates/analytics/actions/install-dashboard-template.ts +79 -43
  196. package/corpus/templates/analytics/actions/list-explorer-dashboards.ts +3 -3
  197. package/corpus/templates/analytics/actions/list-sql-dashboards.ts +8 -3
  198. package/corpus/templates/analytics/actions/navigate.ts +59 -5
  199. package/corpus/templates/analytics/actions/rename-analysis.ts +8 -2
  200. package/corpus/templates/analytics/actions/rename-dashboard.ts +8 -7
  201. package/corpus/templates/analytics/actions/view-screen.ts +7 -29
  202. package/corpus/templates/analytics/app/components/ProviderCorpusJobNotifier.tsx +20 -3
  203. package/corpus/templates/analytics/app/components/ResourceLoadError.tsx +42 -0
  204. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +2 -1
  205. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +85 -70
  206. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -1
  207. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +128 -95
  208. package/corpus/templates/analytics/app/components/layout/SidebarLoadError.tsx +24 -0
  209. package/corpus/templates/analytics/app/global.css +19 -20
  210. package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +15 -5
  211. package/corpus/templates/analytics/app/i18n/zh-TW.ts +4 -0
  212. package/corpus/templates/analytics/app/i18n-data.ts +40 -0
  213. package/corpus/templates/analytics/app/lib/provider-corpus-job-sync.ts +26 -0
  214. package/corpus/templates/analytics/app/pages/Settings.tsx +41 -343
  215. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/SqlPreview.tsx +36 -20
  216. package/corpus/templates/analytics/app/pages/adhoc/explorer/index.tsx +34 -20
  217. package/corpus/templates/analytics/app/pages/adhoc/explorer/use-explorer-config.ts +42 -41
  218. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +43 -36
  219. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewsMenu.tsx +11 -2
  220. package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +38 -7
  221. package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +1 -1
  222. package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +3 -0
  223. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +333 -272
  224. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +72 -17
  225. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +297 -108
  226. package/corpus/templates/analytics/app/root.tsx +40 -8
  227. package/corpus/templates/analytics/app/routes/_index.tsx +14 -2
  228. package/corpus/templates/analytics/changelog/2026-06-24-first-party-signup-and-pageview-panels-now-honor-dashboard-filters.md +2 -1
  229. package/corpus/templates/analytics/changelog/2026-06-25-referrer-dashboard-panels-show-external-domains.md +2 -1
  230. package/corpus/templates/analytics/changelog/2026-07-03-agent-llm-observability-dashboard.md +1 -1
  231. package/corpus/templates/analytics/changelog/2026-07-06-mobile-chat-header-is-more-compact-and-the-menu-button-opens-navigation.md +1 -0
  232. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-history-and-chat-context.md +1 -0
  233. package/corpus/templates/analytics/changelog/2026-07-08-settings-are-cleaner-searchable-and-alerts-have-their-own-tab.md +1 -0
  234. package/corpus/templates/analytics/changelog/2026-07-08-sidebar-sections-stay-collapsed-until-opened.md +1 -0
  235. package/corpus/templates/analytics/changelog/2026-07-11-agent-feedback-sentiment-dashboard.md +6 -0
  236. package/corpus/templates/analytics/changelog/2026-07-11-analytics-chats-now-start-faster-by-loading-metric-definitio.md +6 -0
  237. package/corpus/templates/analytics/changelog/2026-07-11-analytics-no-longer-repeatedly-restarts-background-requests-.md +6 -0
  238. package/corpus/templates/analytics/changelog/2026-07-11-analytics-only-asks-for-replay-storage-when-you-enable-sessi.md +6 -0
  239. package/corpus/templates/analytics/changelog/2026-07-11-charts-now-show-their-loading-skeleton-while-refreshing.md +6 -0
  240. package/corpus/templates/analytics/changelog/2026-07-11-command-and-sql-previews-now-respond-without-lag.md +6 -0
  241. package/corpus/templates/analytics/changelog/2026-07-11-command-search-now-reports-loading-failures-and-lets-you-ret.md +6 -0
  242. package/corpus/templates/analytics/changelog/2026-07-11-dashboard-navigation-now-loads-faster-and-reports-request-fa.md +6 -0
  243. package/corpus/templates/analytics/changelog/2026-07-11-inferred-message-sentiment-dashboard.md +6 -0
  244. package/corpus/templates/analytics/changelog/2026-07-11-microphone-settings-from-realtime-voice-mode-now-open-the-vo.md +6 -0
  245. package/corpus/templates/analytics/changelog/2026-07-11-more-dashboard-edit-paths-are-now-safe-against-simultaneous-.md +6 -0
  246. package/corpus/templates/analytics/changelog/2026-07-11-realtime-voice-now-shows-a-clear-connection-indicator-comple.md +6 -0
  247. package/corpus/templates/analytics/changelog/2026-07-11-renaming-a-dashboard-is-now-safe-against-simultaneous-agent-.md +6 -0
  248. package/corpus/templates/analytics/changelog/2026-07-11-renaming-an-analysis-is-now-safe-against-simultaneous-edits.md +6 -0
  249. package/corpus/templates/analytics/changelog/2026-07-11-replay-event-counts-stay-hidden-until-recordings-finish-load.md +6 -0
  250. package/corpus/templates/analytics/changelog/2026-07-11-replay-storage-key-mismatches-show-actionable-setup-guidance.md +6 -0
  251. package/corpus/templates/analytics/changelog/2026-07-11-replay-timelines-group-continuous-scrolling-and-dev-tools-co.md +6 -0
  252. package/corpus/templates/analytics/changelog/2026-07-11-session-filters-now-stay-compact-in-a-settings-menu-at-mediu.md +6 -0
  253. package/corpus/templates/analytics/changelog/2026-07-11-session-replay-console-errors-now-link-to-matching-issues-or.md +6 -0
  254. package/corpus/templates/analytics/changelog/2026-07-11-session-replays-load-large-recordings-faster-and-surface-fai.md +6 -0
  255. package/corpus/templates/analytics/changelog/2026-07-11-session-replays-preserve-recorded-styles-and-viewport-layout.md +6 -0
  256. package/corpus/templates/analytics/changelog/2026-07-11-session-replays-stay-centered-instead-of-clipping-wide-recor.md +6 -0
  257. package/corpus/templates/analytics/changelog/2026-07-11-workspace-mounted-analytics-now-opens-ask-reliably-and-route.md +6 -0
  258. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +37 -3
  259. package/corpus/templates/analytics/package.json +1 -1
  260. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +37 -1
  261. package/corpus/templates/analytics/server/handlers/session-replay.ts +57 -0
  262. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +1 -24
  263. package/corpus/templates/analytics/server/lib/dashboard-seeds.ts +0 -5
  264. package/corpus/templates/analytics/server/lib/dashboards-store.ts +289 -20
  265. package/corpus/templates/analytics/server/lib/data-dictionary-context.ts +106 -34
  266. package/corpus/templates/analytics/server/lib/demo-dashboards.ts +20 -4
  267. package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +12 -0
  268. package/corpus/templates/analytics/server/lib/session-replay.ts +208 -2
  269. package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -39
  270. package/corpus/templates/analytics/server/plugins/onboarding.ts +7 -79
  271. package/corpus/templates/analytics/server/routes/api/session-replay/recordings/[recordingId]/chunks.get.ts +1 -0
  272. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +1 -1
  273. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +2 -2
  274. package/corpus/templates/assets/app/components/create/RecentDraftsSection.tsx +30 -4
  275. package/corpus/templates/assets/app/global.css +4 -4
  276. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +0 -1
  277. package/corpus/templates/assets/app/routes/library.tsx +49 -6
  278. package/corpus/templates/assets/changelog/2026-07-11-library-load-failures-now-show-a-retry-action.md +6 -0
  279. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +1 -1
  280. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +2 -2
  281. package/corpus/templates/brain/app/global.css +5 -5
  282. package/corpus/templates/brain/app/root.tsx +0 -3
  283. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +1 -1
  284. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +2 -2
  285. package/corpus/templates/calendar/.env.example +5 -0
  286. package/corpus/templates/calendar/app/components/calendar/EventCard.tsx +2 -2
  287. package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
  288. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  289. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +37 -1
  290. package/corpus/templates/calendar/app/pages/BookingsList.tsx +20 -3
  291. package/corpus/templates/calendar/app/root.tsx +1 -0
  292. package/corpus/templates/calendar/changelog/2026-07-11-booking-load-failures-now-show-a-retry-action.md +6 -0
  293. package/corpus/templates/calendar/changelog/2026-07-11-event-cards-give-subtle-press-feedback-and-smoother-hover.md +6 -0
  294. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -1
  295. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +2 -2
  296. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +1 -1
  297. package/corpus/templates/clips/actions/decline-invite.ts +8 -0
  298. package/corpus/templates/clips/app/components/library/folder-tree.tsx +209 -187
  299. package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +2 -2
  300. package/corpus/templates/clips/app/components/player/reactions-tray.tsx +17 -5
  301. package/corpus/templates/clips/app/components/player/scrubber.tsx +5 -3
  302. package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +2 -2
  303. package/corpus/templates/clips/app/components/workspace/insights-hub.tsx +119 -95
  304. package/corpus/templates/clips/app/global.css +45 -0
  305. package/corpus/templates/clips/app/hooks/use-auto-title.ts +74 -8
  306. package/corpus/templates/clips/app/hooks/use-library.ts +12 -25
  307. package/corpus/templates/clips/app/root.tsx +4 -0
  308. package/corpus/templates/clips/app/routes/_app.notifications.tsx +23 -2
  309. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +20 -22
  310. package/corpus/templates/clips/app/routes/_app.trash.tsx +24 -2
  311. package/corpus/templates/clips/changelog/2026-07-11-controls-and-folders-now-move-more-smoothly.md +6 -0
  312. package/corpus/templates/clips/changelog/2026-07-11-declining-an-invitation-now-requires-being-its-recipient.md +6 -0
  313. package/corpus/templates/clips/changelog/2026-07-11-generated-titles-no-longer-cause-continuous-background-refreshes.md +6 -0
  314. package/corpus/templates/clips/changelog/2026-07-11-recording-overlays-are-lighter-weight-and-no-longer-cause-pa.md +6 -0
  315. package/corpus/templates/clips/changelog/2026-07-11-s3-storage-setup-stays-collapsed-until-you-choose-it-as-the-.md +6 -0
  316. package/corpus/templates/clips/changelog/2026-07-11-workspace-load-failures-now-show-a-retry-action.md +6 -0
  317. package/corpus/templates/clips/chrome-extension/src/overlay.css +34 -5
  318. package/corpus/templates/clips/chrome-extension/src/styles.css +2 -2
  319. package/corpus/templates/clips/desktop/src/styles.css +71 -26
  320. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +1 -1
  321. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +2 -2
  322. package/corpus/templates/content/actions/move-document.ts +34 -18
  323. package/corpus/templates/content/app/components/QueryErrorState.tsx +39 -0
  324. package/corpus/templates/content/app/components/editor/LinkHoverPreview.tsx +1 -1
  325. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +225 -1435
  326. package/corpus/templates/content/app/components/editor/database/GalleryView.tsx +368 -0
  327. package/corpus/templates/content/app/components/editor/database/ListView.tsx +353 -0
  328. package/corpus/templates/content/app/components/editor/database/TimelineView.tsx +580 -0
  329. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +11 -2
  330. package/corpus/templates/content/app/global.css +19 -19
  331. package/corpus/templates/content/app/hooks/use-comments.ts +0 -1
  332. package/corpus/templates/content/app/root.tsx +2 -2
  333. package/corpus/templates/content/app/routes/_app._index.tsx +11 -1
  334. package/corpus/templates/content/changelog/2026-07-11-comments-now-update-from-live-collaboration-events-without-c.md +6 -0
  335. package/corpus/templates/content/changelog/2026-07-11-document-load-failures-now-show-a-retry-action.md +6 -0
  336. package/corpus/templates/content/changelog/2026-07-11-editor-toggle-feedback-now-feels-more-responsive.md +6 -0
  337. package/corpus/templates/content/changelog/2026-07-11-moving-documents-at-the-same-time-no-longer-scrambles-their-.md +6 -0
  338. package/corpus/templates/content/changelog/2026-07-11-public-document-chats-now-start-faster-while-keeping-full-do.md +6 -0
  339. package/corpus/templates/content/changelog/2026-07-11-reopening-a-comment-now-uses-consistent-permissions-everywhe.md +6 -0
  340. package/corpus/templates/content/changelog/2026-07-11-sidebar-resizing-now-tracks-your-cursor-instantly-instead-of.md +6 -0
  341. package/corpus/templates/content/server/lib/public-documents.ts +47 -10
  342. package/corpus/templates/content/server/routes/api/comments/[id].patch.ts +24 -24
  343. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +1 -1
  344. package/corpus/templates/design/app/components/QueryErrorState.tsx +24 -0
  345. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +1 -1
  346. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +5 -2
  347. package/corpus/templates/design/app/components/design/EditPanel.tsx +326 -319
  348. package/corpus/templates/design/app/components/design/LayersPanel.tsx +198 -193
  349. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +11 -4
  350. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +1 -1
  351. package/corpus/templates/design/app/components/layout/Header.tsx +1 -1
  352. package/corpus/templates/design/app/components/layout/Layout.tsx +1 -1
  353. package/corpus/templates/design/app/pages/DesignSystems.tsx +7 -1
  354. package/corpus/templates/design/app/pages/Index.tsx +14 -2
  355. package/corpus/templates/design/app/pages/Present.tsx +16 -3
  356. package/corpus/templates/design/app/pages/Templates.tsx +10 -4
  357. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +484 -0
  358. package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +378 -0
  359. package/corpus/templates/design/app/pages/design-editor/design-data-geometry-utils.ts +138 -0
  360. package/corpus/templates/design/app/pages/design-editor/dom-utils.ts +15 -0
  361. package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +180 -0
  362. package/corpus/templates/design/app/pages/design-editor/html-layer-positioning.ts +226 -0
  363. package/corpus/templates/design/app/pages/design-editor/png-export-render.ts +348 -0
  364. package/corpus/templates/design/app/pages/design-editor/screen-command-utils.ts +160 -0
  365. package/corpus/templates/design/app/pages/design-editor/text-edit-utils.ts +238 -0
  366. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +23 -1
  367. package/corpus/templates/design/app/pages/design-editor/types.ts +25 -0
  368. package/corpus/templates/design/app/root.tsx +10 -1
  369. package/corpus/templates/design/changelog/2026-07-11-canvas-context-menus-now-open-without-motion-jitter.md +6 -0
  370. package/corpus/templates/design/changelog/2026-07-11-design-load-failures-now-show-a-retry-action.md +6 -0
  371. package/corpus/templates/design/changelog/2026-07-11-inspector-tooltips-appear-instantly-as-you-sweep-across-icon.md +6 -0
  372. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +1 -1
  373. package/corpus/templates/dispatch/app/i18n/zh-TW.ts +10 -0
  374. package/corpus/templates/dispatch/app/i18n-data.ts +123 -0
  375. package/corpus/templates/dispatch/app/routes/integrations.tsx +163 -144
  376. package/corpus/templates/dispatch/changelog/2026-07-11-dispatch-mcp-connections-now-start-with-safer-app-access-and.md +6 -0
  377. package/corpus/templates/dispatch/changelog/2026-07-11-overview-and-chat-now-share-a-cleaner-more-stable-flow.md +6 -0
  378. package/corpus/templates/dispatch/changelog/2026-07-11-query-errors-now-show-a-retry-option.md +6 -0
  379. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +1 -1
  380. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +2 -2
  381. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +3 -3
  382. package/corpus/templates/forms/app/root.tsx +34 -8
  383. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +1 -1
  384. package/corpus/templates/macros/app/components/DailyProgress.tsx +25 -5
  385. package/corpus/templates/macros/app/components/QueryErrorState.tsx +31 -0
  386. package/corpus/templates/macros/app/components/WeightTracker.tsx +5 -1
  387. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -2
  388. package/corpus/templates/macros/app/components/ui/button.tsx +1 -1
  389. package/corpus/templates/macros/app/components/ui/progress.tsx +1 -1
  390. package/corpus/templates/macros/app/components/ui/tabs.tsx +1 -1
  391. package/corpus/templates/macros/app/i18n/ar-SA.ts +2 -0
  392. package/corpus/templates/macros/app/i18n/de-DE.ts +2 -0
  393. package/corpus/templates/macros/app/i18n/en-US.ts +2 -0
  394. package/corpus/templates/macros/app/i18n/es-ES.ts +2 -0
  395. package/corpus/templates/macros/app/i18n/fr-FR.ts +2 -0
  396. package/corpus/templates/macros/app/i18n/hi-IN.ts +2 -0
  397. package/corpus/templates/macros/app/i18n/ja-JP.ts +2 -0
  398. package/corpus/templates/macros/app/i18n/ko-KR.ts +2 -0
  399. package/corpus/templates/macros/app/i18n/pt-BR.ts +2 -0
  400. package/corpus/templates/macros/app/i18n/zh-CN.ts +2 -0
  401. package/corpus/templates/macros/app/i18n/zh-TW.ts +2 -0
  402. package/corpus/templates/macros/app/root.tsx +0 -3
  403. package/corpus/templates/macros/app/routes/_index.tsx +22 -12
  404. package/corpus/templates/macros/app/routes/analytics.tsx +31 -10
  405. package/corpus/templates/macros/changelog/2026-07-11-daily-tracking-now-loads-and-updates-more-quickly.md +6 -0
  406. package/corpus/templates/macros/changelog/2026-07-11-data-load-failures-now-show-a-clear-error-with-a-retry-actio.md +6 -0
  407. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +1 -1
  408. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +2 -2
  409. package/corpus/templates/mail/.env.example +16 -11
  410. package/corpus/templates/mail/actions/list-emails.ts +39 -35
  411. package/corpus/templates/mail/app/components/email/ComposeModal.tsx +58 -6
  412. package/corpus/templates/mail/app/components/email/EmailListItem.tsx +35 -2
  413. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +113 -104
  414. package/corpus/templates/mail/app/hooks/use-compose-state.ts +1 -0
  415. package/corpus/templates/mail/app/root.tsx +9 -22
  416. package/corpus/templates/mail/changelog/2026-07-11-compose-and-navigation-motion-now-feel-faster-and-smoother.md +6 -0
  417. package/corpus/templates/mail/changelog/2026-07-11-swipe-to-archive-or-snooze-now-responds-to-quick-flicks-not-.md +6 -0
  418. package/corpus/templates/mail/changelog/2026-07-11-the-assistant-now-sees-the-same-inbox-you-do-snoozed-mail-st.md +6 -0
  419. package/corpus/templates/mail/server/handlers/emails.ts +25 -69
  420. package/corpus/templates/mail/server/lib/list-inbox-emails.ts +169 -0
  421. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +1 -1
  422. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +2 -2
  423. package/corpus/templates/plan/.env.example +4 -0
  424. package/corpus/templates/plan/actions/create-plan-design.ts +89 -81
  425. package/corpus/templates/plan/actions/create-prototype-plan.ts +72 -59
  426. package/corpus/templates/plan/actions/create-ui-plan.ts +70 -55
  427. package/corpus/templates/plan/actions/create-visual-plan.ts +65 -51
  428. package/corpus/templates/plan/actions/update-local-plan-folder.ts +43 -30
  429. package/corpus/templates/plan/actions/update-visual-plan.ts +81 -64
  430. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +17 -0
  431. package/corpus/templates/plan/app/components/ui/tabs.tsx +1 -1
  432. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +5 -2
  433. package/corpus/templates/plan/app/hooks/use-plans.ts +6 -13
  434. package/corpus/templates/plan/app/i18n/ar-SA.ts +10 -0
  435. package/corpus/templates/plan/app/i18n/de-DE.ts +10 -0
  436. package/corpus/templates/plan/app/i18n/en-US.ts +10 -0
  437. package/corpus/templates/plan/app/i18n/es-ES.ts +10 -0
  438. package/corpus/templates/plan/app/i18n/fr-FR.ts +10 -0
  439. package/corpus/templates/plan/app/i18n/hi-IN.ts +10 -0
  440. package/corpus/templates/plan/app/i18n/ja-JP.ts +10 -0
  441. package/corpus/templates/plan/app/i18n/ko-KR.ts +10 -0
  442. package/corpus/templates/plan/app/i18n/pt-BR.ts +10 -0
  443. package/corpus/templates/plan/app/i18n/zh-CN.ts +10 -0
  444. package/corpus/templates/plan/app/i18n/zh-TW.ts +10 -0
  445. package/corpus/templates/plan/app/lib/plan-local-bridge.ts +80 -1
  446. package/corpus/templates/plan/app/pages/PlansPage.tsx +157 -31
  447. package/corpus/templates/plan/app/root.tsx +11 -0
  448. package/corpus/templates/plan/changelog/2026-07-11-local-plans-now-explain-and-recover-from-browser-permission-.md +6 -0
  449. package/corpus/templates/plan/changelog/2026-07-11-plan-edits-now-save-atomically-and-can-no-longer-partially-a.md +6 -0
  450. package/corpus/templates/plan/changelog/2026-07-11-plan-lists-now-show-a-clear-error-with-a-retry-action-when-t.md +6 -0
  451. package/corpus/templates/plan/changelog/2026-07-11-plan-refreshes-only-when-content-changes.md +6 -0
  452. package/corpus/templates/plan/shared/plan-content.ts +546 -260
  453. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +1 -1
  454. package/corpus/templates/slides/actions/delete-slide-comment.ts +49 -0
  455. package/corpus/templates/slides/actions/update-slide-comment.ts +93 -0
  456. package/corpus/templates/slides/actions/view-screen.ts +14 -6
  457. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +37 -11
  458. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -1
  459. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +2 -2
  460. package/corpus/templates/slides/app/components/editor/GenerateSlidesDialog.tsx +2 -2
  461. package/corpus/templates/slides/app/components/layout/Header.tsx +1 -1
  462. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +4 -2
  463. package/corpus/templates/slides/app/components/visual-editor/CanvasCommentPins.tsx +4 -3
  464. package/corpus/templates/slides/app/context/DeckContext.tsx +10 -0
  465. package/corpus/templates/slides/app/hooks/use-slide-comments.ts +7 -31
  466. package/corpus/templates/slides/app/i18n/ar-SA.ts +6 -0
  467. package/corpus/templates/slides/app/i18n/de-DE.ts +6 -0
  468. package/corpus/templates/slides/app/i18n/en-US.ts +6 -0
  469. package/corpus/templates/slides/app/i18n/es-ES.ts +6 -0
  470. package/corpus/templates/slides/app/i18n/fr-FR.ts +6 -0
  471. package/corpus/templates/slides/app/i18n/hi-IN.ts +6 -0
  472. package/corpus/templates/slides/app/i18n/ja-JP.ts +6 -0
  473. package/corpus/templates/slides/app/i18n/ko-KR.ts +6 -0
  474. package/corpus/templates/slides/app/i18n/pt-BR.ts +6 -0
  475. package/corpus/templates/slides/app/i18n/zh-CN.ts +5 -0
  476. package/corpus/templates/slides/app/i18n/zh-TW.ts +5 -0
  477. package/corpus/templates/slides/app/pages/DesignSystems.tsx +23 -2
  478. package/corpus/templates/slides/app/pages/Index.tsx +29 -1
  479. package/corpus/templates/slides/changelog/2026-07-11-comment-load-failures-now-show-a-retry-action-instead-of-say.md +6 -0
  480. package/corpus/templates/slides/changelog/2026-07-11-comment-pins-now-clear-with-a-faster-smoother-confirmation.md +6 -0
  481. package/corpus/templates/slides/changelog/2026-07-11-comments-now-update-from-live-collaboration-events-without-c.md +6 -0
  482. package/corpus/templates/slides/changelog/2026-07-11-deck-and-design-system-load-failures-now-show-a-retry-action.md +6 -0
  483. package/corpus/templates/slides/changelog/2026-07-11-editor-toggles-and-toolbar-menus-now-animate-smoothly.md +6 -0
  484. package/corpus/templates/slides/changelog/2026-07-11-the-assistant-can-now-resolve-reopen-and-delete-slide-commen.md +6 -0
  485. package/corpus/templates/slides/changelog/2026-07-11-viewing-slides-no-longer-loads-every-deck-s-full-contents-in.md +6 -0
  486. package/corpus/templates/slides/server/routes/api/comments/[id].delete.ts +29 -48
  487. package/corpus/templates/slides/server/routes/api/comments/[id].patch.ts +29 -65
  488. package/dist/action-change-marker.d.ts +1 -0
  489. package/dist/action-change-marker.d.ts.map +1 -1
  490. package/dist/action-change-marker.js +7 -1
  491. package/dist/action-change-marker.js.map +1 -1
  492. package/dist/action.d.ts +23 -0
  493. package/dist/action.d.ts.map +1 -1
  494. package/dist/action.js +13 -0
  495. package/dist/action.js.map +1 -1
  496. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  497. package/dist/agent/engine/builder-engine.js +3 -0
  498. package/dist/agent/engine/builder-engine.js.map +1 -1
  499. package/dist/agent/engine/context-directives-transform.d.ts +25 -0
  500. package/dist/agent/engine/context-directives-transform.d.ts.map +1 -0
  501. package/dist/agent/engine/context-directives-transform.js +53 -0
  502. package/dist/agent/engine/context-directives-transform.js.map +1 -0
  503. package/dist/agent/engine/continuation-dispatch-retry.d.ts +40 -0
  504. package/dist/agent/engine/continuation-dispatch-retry.d.ts.map +1 -0
  505. package/dist/agent/engine/continuation-dispatch-retry.js +109 -0
  506. package/dist/agent/engine/continuation-dispatch-retry.js.map +1 -0
  507. package/dist/agent/engine/tool-call-journal-seed.d.ts +46 -0
  508. package/dist/agent/engine/tool-call-journal-seed.d.ts.map +1 -0
  509. package/dist/agent/engine/tool-call-journal-seed.js +60 -0
  510. package/dist/agent/engine/tool-call-journal-seed.js.map +1 -0
  511. package/dist/agent/production-agent.d.ts +7 -0
  512. package/dist/agent/production-agent.d.ts.map +1 -1
  513. package/dist/agent/production-agent.js +102 -222
  514. package/dist/agent/production-agent.js.map +1 -1
  515. package/dist/changelog/parse.d.ts +4 -2
  516. package/dist/changelog/parse.d.ts.map +1 -1
  517. package/dist/changelog/parse.js +5 -3
  518. package/dist/changelog/parse.js.map +1 -1
  519. package/dist/cli/doctor.d.ts.map +1 -1
  520. package/dist/cli/doctor.js +7 -3
  521. package/dist/cli/doctor.js.map +1 -1
  522. package/dist/cli/plan-local.d.ts.map +1 -1
  523. package/dist/cli/plan-local.js +8 -2
  524. package/dist/cli/plan-local.js.map +1 -1
  525. package/dist/cli/skills-content/assets-skill.d.ts +2 -0
  526. package/dist/cli/skills-content/assets-skill.d.ts.map +1 -0
  527. package/dist/cli/skills-content/assets-skill.js +84 -0
  528. package/dist/cli/skills-content/assets-skill.js.map +1 -0
  529. package/dist/cli/skills-content/canvas.d.ts +4 -0
  530. package/dist/cli/skills-content/canvas.d.ts.map +1 -0
  531. package/dist/cli/skills-content/canvas.js +152 -0
  532. package/dist/cli/skills-content/canvas.js.map +1 -0
  533. package/dist/cli/skills-content/connection.d.ts +2 -0
  534. package/dist/cli/skills-content/connection.d.ts.map +1 -0
  535. package/dist/cli/skills-content/connection.js +53 -0
  536. package/dist/cli/skills-content/connection.js.map +1 -0
  537. package/dist/cli/skills-content/content-skill.d.ts +2 -0
  538. package/dist/cli/skills-content/content-skill.d.ts.map +1 -0
  539. package/dist/cli/skills-content/content-skill.js +110 -0
  540. package/dist/cli/skills-content/content-skill.js.map +1 -0
  541. package/dist/cli/skills-content/design-exploration-skill.d.ts +2 -0
  542. package/dist/cli/skills-content/design-exploration-skill.d.ts.map +1 -0
  543. package/dist/cli/skills-content/design-exploration-skill.js +119 -0
  544. package/dist/cli/skills-content/design-exploration-skill.js.map +1 -0
  545. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +2 -0
  546. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -0
  547. package/dist/cli/skills-content/design-visual-edit-skill.js +229 -0
  548. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -0
  549. package/dist/cli/skills-content/document-quality.d.ts +4 -0
  550. package/dist/cli/skills-content/document-quality.d.ts.map +1 -0
  551. package/dist/cli/skills-content/document-quality.js +195 -0
  552. package/dist/cli/skills-content/document-quality.js.map +1 -0
  553. package/dist/cli/skills-content/exemplar.d.ts +4 -0
  554. package/dist/cli/skills-content/exemplar.d.ts.map +1 -0
  555. package/dist/cli/skills-content/exemplar.js +68 -0
  556. package/dist/cli/skills-content/exemplar.js.map +1 -0
  557. package/dist/cli/skills-content/help.d.ts +2 -0
  558. package/dist/cli/skills-content/help.d.ts.map +1 -0
  559. package/dist/cli/skills-content/help.js +78 -0
  560. package/dist/cli/skills-content/help.js.map +1 -0
  561. package/dist/cli/skills-content/index.d.ts +23 -0
  562. package/dist/cli/skills-content/index.d.ts.map +1 -0
  563. package/dist/cli/skills-content/index.js +23 -0
  564. package/dist/cli/skills-content/index.js.map +1 -0
  565. package/dist/cli/skills-content/local-files.d.ts +2 -0
  566. package/dist/cli/skills-content/local-files.d.ts.map +1 -0
  567. package/dist/cli/skills-content/local-files.js +96 -0
  568. package/dist/cli/skills-content/local-files.js.map +1 -0
  569. package/dist/cli/skills-content/plan-setup-auth.d.ts +9 -0
  570. package/dist/cli/skills-content/plan-setup-auth.d.ts.map +1 -0
  571. package/dist/cli/skills-content/plan-setup-auth.js +81 -0
  572. package/dist/cli/skills-content/plan-setup-auth.js.map +1 -0
  573. package/dist/cli/skills-content/visual-plan-skill.d.ts +2 -0
  574. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -0
  575. package/dist/cli/skills-content/visual-plan-skill.js +471 -0
  576. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -0
  577. package/dist/cli/skills-content/visual-recap-skill.d.ts +2 -0
  578. package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -0
  579. package/dist/cli/skills-content/visual-recap-skill.js +548 -0
  580. package/dist/cli/skills-content/visual-recap-skill.js.map +1 -0
  581. package/dist/cli/skills-content/visualize-repo-skill.d.ts +2 -0
  582. package/dist/cli/skills-content/visualize-repo-skill.d.ts.map +1 -0
  583. package/dist/cli/skills-content/visualize-repo-skill.js +94 -0
  584. package/dist/cli/skills-content/visualize-repo-skill.js.map +1 -0
  585. package/dist/cli/skills-content/wireframe.d.ts +4 -0
  586. package/dist/cli/skills-content/wireframe.d.ts.map +1 -0
  587. package/dist/cli/skills-content/wireframe.js +347 -0
  588. package/dist/cli/skills-content/wireframe.js.map +1 -0
  589. package/dist/cli/skills.d.ts +2 -10
  590. package/dist/cli/skills.d.ts.map +1 -1
  591. package/dist/cli/skills.js +2 -2710
  592. package/dist/cli/skills.js.map +1 -1
  593. package/dist/client/AgentPanel.d.ts.map +1 -1
  594. package/dist/client/AgentPanel.js +6 -5
  595. package/dist/client/AgentPanel.js.map +1 -1
  596. package/dist/client/AssistantChat.d.ts +7 -0
  597. package/dist/client/AssistantChat.d.ts.map +1 -1
  598. package/dist/client/AssistantChat.js +62 -40
  599. package/dist/client/AssistantChat.js.map +1 -1
  600. package/dist/client/CommandMenu.d.ts.map +1 -1
  601. package/dist/client/CommandMenu.js +15 -3
  602. package/dist/client/CommandMenu.js.map +1 -1
  603. package/dist/client/FeedbackButton.js +2 -2
  604. package/dist/client/FeedbackButton.js.map +1 -1
  605. package/dist/client/analytics.d.ts.map +1 -1
  606. package/dist/client/analytics.js +26 -0
  607. package/dist/client/analytics.js.map +1 -1
  608. package/dist/client/app-providers.d.ts +13 -5
  609. package/dist/client/app-providers.d.ts.map +1 -1
  610. package/dist/client/app-providers.js +9 -6
  611. package/dist/client/app-providers.js.map +1 -1
  612. package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
  613. package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
  614. package/dist/client/blocks/library/wireframe-kit.js +9 -2
  615. package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
  616. package/dist/client/chat/tool-call-display.d.ts +4 -0
  617. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  618. package/dist/client/chat/tool-call-display.js +3 -3
  619. package/dist/client/chat/tool-call-display.js.map +1 -1
  620. package/dist/client/chat-model-groups.d.ts.map +1 -1
  621. package/dist/client/chat-model-groups.js +24 -0
  622. package/dist/client/chat-model-groups.js.map +1 -1
  623. package/dist/client/composer/PastedTextChip.js +1 -1
  624. package/dist/client/composer/PastedTextChip.js.map +1 -1
  625. package/dist/client/composer/RealtimeVoiceMode.d.ts +40 -2
  626. package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -1
  627. package/dist/client/composer/RealtimeVoiceMode.js +186 -35
  628. package/dist/client/composer/RealtimeVoiceMode.js.map +1 -1
  629. package/dist/client/composer/TiptapComposer.d.ts +4 -0
  630. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  631. package/dist/client/composer/TiptapComposer.js +48 -30
  632. package/dist/client/composer/TiptapComposer.js.map +1 -1
  633. package/dist/client/composer/VoiceButton.d.ts +2 -0
  634. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  635. package/dist/client/composer/VoiceButton.js +9 -3
  636. package/dist/client/composer/VoiceButton.js.map +1 -1
  637. package/dist/client/composer/index.d.ts +2 -2
  638. package/dist/client/composer/index.d.ts.map +1 -1
  639. package/dist/client/composer/index.js +1 -1
  640. package/dist/client/composer/index.js.map +1 -1
  641. package/dist/client/composer/useRealtimeVoiceMode.d.ts +104 -2
  642. package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -1
  643. package/dist/client/composer/useRealtimeVoiceMode.js +1015 -35
  644. package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -1
  645. package/dist/client/context-xray/ContextXRayPanel.d.ts.map +1 -1
  646. package/dist/client/context-xray/ContextXRayPanel.js +4 -1
  647. package/dist/client/context-xray/ContextXRayPanel.js.map +1 -1
  648. package/dist/client/extensions/ExtensionEditor.d.ts.map +1 -1
  649. package/dist/client/extensions/ExtensionEditor.js +15 -5
  650. package/dist/client/extensions/ExtensionEditor.js.map +1 -1
  651. package/dist/client/extensions/ExtensionQueryErrorState.d.ts +8 -0
  652. package/dist/client/extensions/ExtensionQueryErrorState.d.ts.map +1 -0
  653. package/dist/client/extensions/ExtensionQueryErrorState.js +11 -0
  654. package/dist/client/extensions/ExtensionQueryErrorState.js.map +1 -0
  655. package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
  656. package/dist/client/extensions/ExtensionSlot.js +17 -7
  657. package/dist/client/extensions/ExtensionSlot.js.map +1 -1
  658. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  659. package/dist/client/extensions/ExtensionViewer.js +17 -7
  660. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  661. package/dist/client/extensions/ExtensionsListPage.d.ts.map +1 -1
  662. package/dist/client/extensions/ExtensionsListPage.js +5 -3
  663. package/dist/client/extensions/ExtensionsListPage.js.map +1 -1
  664. package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
  665. package/dist/client/extensions/ExtensionsSidebarSection.js +21 -8
  666. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  667. package/dist/client/index.d.ts +1 -3
  668. package/dist/client/index.d.ts.map +1 -1
  669. package/dist/client/index.js +1 -6
  670. package/dist/client/index.js.map +1 -1
  671. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  672. package/dist/client/progress/RunsTray.js +17 -4
  673. package/dist/client/progress/RunsTray.js.map +1 -1
  674. package/dist/client/settings/SecretsSection.d.ts +2 -3
  675. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  676. package/dist/client/settings/SecretsSection.js +46 -22
  677. package/dist/client/settings/SecretsSection.js.map +1 -1
  678. package/dist/client/settings/SettingsPanel.d.ts +9 -0
  679. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  680. package/dist/client/settings/SettingsPanel.js +46 -12
  681. package/dist/client/settings/SettingsPanel.js.map +1 -1
  682. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  683. package/dist/client/settings/SettingsTabsPage.js +4 -0
  684. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  685. package/dist/client/settings/useBuilderStatus.d.ts +2 -0
  686. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  687. package/dist/client/settings/useBuilderStatus.js +4 -0
  688. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  689. package/dist/client/tool-cells/EditCell.d.ts.map +1 -1
  690. package/dist/client/tool-cells/EditCell.js +2 -1
  691. package/dist/client/tool-cells/EditCell.js.map +1 -1
  692. package/dist/client/tool-cells/FilesChangedSummary.d.ts.map +1 -1
  693. package/dist/client/tool-cells/FilesChangedSummary.js +2 -1
  694. package/dist/client/tool-cells/FilesChangedSummary.js.map +1 -1
  695. package/dist/client/tool-cells/WriteCell.d.ts.map +1 -1
  696. package/dist/client/tool-cells/WriteCell.js +2 -1
  697. package/dist/client/tool-cells/WriteCell.js.map +1 -1
  698. package/dist/client/use-action.d.ts +2 -0
  699. package/dist/client/use-action.d.ts.map +1 -1
  700. package/dist/client/use-action.js +10 -0
  701. package/dist/client/use-action.js.map +1 -1
  702. package/dist/client/use-agent-chat-home-handoff.d.ts +2 -0
  703. package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -1
  704. package/dist/client/use-agent-chat-home-handoff.js +7 -1
  705. package/dist/client/use-agent-chat-home-handoff.js.map +1 -1
  706. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  707. package/dist/client/use-agent-engine-configured.js +17 -3
  708. package/dist/client/use-agent-engine-configured.js.map +1 -1
  709. package/dist/client/use-db-sync.d.ts +8 -2
  710. package/dist/client/use-db-sync.d.ts.map +1 -1
  711. package/dist/client/use-db-sync.js +57 -32
  712. package/dist/client/use-db-sync.js.map +1 -1
  713. package/dist/client/use-pausing-interval.d.ts.map +1 -1
  714. package/dist/client/use-pausing-interval.js +16 -4
  715. package/dist/client/use-pausing-interval.js.map +1 -1
  716. package/dist/client/visual-style-controls.js +1 -1
  717. package/dist/client/visual-style-controls.js.map +1 -1
  718. package/dist/collab/routes.d.ts +1 -1
  719. package/dist/deploy/build.d.ts.map +1 -1
  720. package/dist/deploy/build.js +36 -14
  721. package/dist/deploy/build.js.map +1 -1
  722. package/dist/integrations/google-docs-poller.d.ts +7 -0
  723. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  724. package/dist/integrations/google-docs-poller.js +13 -3
  725. package/dist/integrations/google-docs-poller.js.map +1 -1
  726. package/dist/integrations/plugin.d.ts.map +1 -1
  727. package/dist/integrations/plugin.js +10 -0
  728. package/dist/integrations/plugin.js.map +1 -1
  729. package/dist/integrations/scope-store.js +1 -1
  730. package/dist/integrations/scope-store.js.map +1 -1
  731. package/dist/integrations/usage-budget-store.js +1 -1
  732. package/dist/integrations/usage-budget-store.js.map +1 -1
  733. package/dist/integrations/webhook-handler.d.ts +11 -0
  734. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  735. package/dist/integrations/webhook-handler.js +16 -4
  736. package/dist/integrations/webhook-handler.js.map +1 -1
  737. package/dist/jobs/scheduler.d.ts +12 -0
  738. package/dist/jobs/scheduler.d.ts.map +1 -1
  739. package/dist/jobs/scheduler.js +13 -3
  740. package/dist/jobs/scheduler.js.map +1 -1
  741. package/dist/localization/default-messages.d.ts +47 -0
  742. package/dist/localization/default-messages.d.ts.map +1 -1
  743. package/dist/localization/default-messages.js +48 -1
  744. package/dist/localization/default-messages.js.map +1 -1
  745. package/dist/mcp/oauth-token.d.ts +1 -1
  746. package/dist/mcp/oauth-token.d.ts.map +1 -1
  747. package/dist/mcp/oauth-token.js +6 -1
  748. package/dist/mcp/oauth-token.js.map +1 -1
  749. package/dist/mcp-client/workspace-servers.js +4 -4
  750. package/dist/mcp-client/workspace-servers.js.map +1 -1
  751. package/dist/notifications/routes.d.ts +2 -2
  752. package/dist/observability/routes.d.ts +5 -5
  753. package/dist/observability/routes.d.ts.map +1 -1
  754. package/dist/observability/routes.js +32 -0
  755. package/dist/observability/routes.js.map +1 -1
  756. package/dist/observability/sentiment.d.ts +42 -0
  757. package/dist/observability/sentiment.d.ts.map +1 -0
  758. package/dist/observability/sentiment.js +196 -0
  759. package/dist/observability/sentiment.js.map +1 -0
  760. package/dist/observability/store.d.ts +5 -0
  761. package/dist/observability/store.d.ts.map +1 -1
  762. package/dist/observability/store.js +17 -0
  763. package/dist/observability/store.js.map +1 -1
  764. package/dist/observability/traces.d.ts +2 -0
  765. package/dist/observability/traces.d.ts.map +1 -1
  766. package/dist/observability/traces.js +42 -57
  767. package/dist/observability/traces.js.map +1 -1
  768. package/dist/observability/tracking-identity.d.ts +3 -0
  769. package/dist/observability/tracking-identity.d.ts.map +1 -0
  770. package/dist/observability/tracking-identity.js +51 -0
  771. package/dist/observability/tracking-identity.js.map +1 -0
  772. package/dist/observability/types.d.ts +10 -0
  773. package/dist/observability/types.d.ts.map +1 -1
  774. package/dist/observability/types.js +3 -0
  775. package/dist/observability/types.js.map +1 -1
  776. package/dist/progress/routes.d.ts +1 -1
  777. package/dist/resources/handlers.d.ts +1 -1
  778. package/dist/secrets/crypto.d.ts +7 -6
  779. package/dist/secrets/crypto.d.ts.map +1 -1
  780. package/dist/secrets/crypto.js +30 -11
  781. package/dist/secrets/crypto.js.map +1 -1
  782. package/dist/secrets/routes.d.ts +9 -9
  783. package/dist/secrets/storage.d.ts +6 -0
  784. package/dist/secrets/storage.d.ts.map +1 -1
  785. package/dist/secrets/storage.js +61 -3
  786. package/dist/secrets/storage.js.map +1 -1
  787. package/dist/server/action-change.d.ts +1 -0
  788. package/dist/server/action-change.d.ts.map +1 -1
  789. package/dist/server/action-change.js +4 -1
  790. package/dist/server/action-change.js.map +1 -1
  791. package/dist/server/action-routes.d.ts.map +1 -1
  792. package/dist/server/action-routes.js +5 -0
  793. package/dist/server/action-routes.js.map +1 -1
  794. package/dist/server/agent-chat/action-filters-a2a.d.ts +50 -0
  795. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -0
  796. package/dist/server/agent-chat/action-filters-a2a.js +127 -0
  797. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -0
  798. package/dist/server/agent-chat/browser-team-tools.d.ts +21 -0
  799. package/dist/server/agent-chat/browser-team-tools.d.ts.map +1 -0
  800. package/dist/server/agent-chat/browser-team-tools.js +417 -0
  801. package/dist/server/agent-chat/browser-team-tools.js.map +1 -0
  802. package/dist/server/agent-chat/context-tools.d.ts +33 -0
  803. package/dist/server/agent-chat/context-tools.d.ts.map +1 -0
  804. package/dist/server/agent-chat/context-tools.js +520 -0
  805. package/dist/server/agent-chat/context-tools.js.map +1 -0
  806. package/dist/server/agent-chat/framework-prompts.d.ts +65 -0
  807. package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -0
  808. package/dist/server/agent-chat/framework-prompts.js +403 -0
  809. package/dist/server/agent-chat/framework-prompts.js.map +1 -0
  810. package/dist/server/agent-chat/lazy-fs.d.ts +2 -0
  811. package/dist/server/agent-chat/lazy-fs.d.ts.map +1 -0
  812. package/dist/server/agent-chat/lazy-fs.js +11 -0
  813. package/dist/server/agent-chat/lazy-fs.js.map +1 -0
  814. package/dist/server/agent-chat/mcp-glue.d.ts +9 -0
  815. package/dist/server/agent-chat/mcp-glue.d.ts.map +1 -0
  816. package/dist/server/agent-chat/mcp-glue.js +63 -0
  817. package/dist/server/agent-chat/mcp-glue.js.map +1 -0
  818. package/dist/server/agent-chat/plugin-options.d.ts +322 -0
  819. package/dist/server/agent-chat/plugin-options.d.ts.map +1 -0
  820. package/dist/server/agent-chat/plugin-options.js +2 -0
  821. package/dist/server/agent-chat/plugin-options.js.map +1 -0
  822. package/dist/server/agent-chat/process-run-failure.d.ts +12 -0
  823. package/dist/server/agent-chat/process-run-failure.d.ts.map +1 -0
  824. package/dist/server/agent-chat/process-run-failure.js +24 -0
  825. package/dist/server/agent-chat/process-run-failure.js.map +1 -0
  826. package/dist/server/agent-chat/prompt-resources.d.ts +28 -0
  827. package/dist/server/agent-chat/prompt-resources.d.ts.map +1 -0
  828. package/dist/server/agent-chat/prompt-resources.js +514 -0
  829. package/dist/server/agent-chat/prompt-resources.js.map +1 -0
  830. package/dist/server/agent-chat/recurring-jobs-runtime.d.ts +5 -0
  831. package/dist/server/agent-chat/recurring-jobs-runtime.d.ts.map +1 -0
  832. package/dist/server/agent-chat/recurring-jobs-runtime.js +53 -0
  833. package/dist/server/agent-chat/recurring-jobs-runtime.js.map +1 -0
  834. package/dist/server/agent-chat/request-surface.d.ts +8 -0
  835. package/dist/server/agent-chat/request-surface.d.ts.map +1 -0
  836. package/dist/server/agent-chat/request-surface.js +56 -0
  837. package/dist/server/agent-chat/request-surface.js.map +1 -0
  838. package/dist/server/agent-chat/run-code-tools.d.ts +17 -0
  839. package/dist/server/agent-chat/run-code-tools.d.ts.map +1 -0
  840. package/dist/server/agent-chat/run-code-tools.js +55 -0
  841. package/dist/server/agent-chat/run-code-tools.js.map +1 -0
  842. package/dist/server/agent-chat/script-entries.d.ts +47 -0
  843. package/dist/server/agent-chat/script-entries.d.ts.map +1 -0
  844. package/dist/server/agent-chat/script-entries.js +633 -0
  845. package/dist/server/agent-chat/script-entries.js.map +1 -0
  846. package/dist/server/agent-chat/shared-thread.d.ts +33 -0
  847. package/dist/server/agent-chat/shared-thread.d.ts.map +1 -0
  848. package/dist/server/agent-chat/shared-thread.js +242 -0
  849. package/dist/server/agent-chat/shared-thread.js.map +1 -0
  850. package/dist/server/agent-chat/skill-frontmatter.d.ts +7 -0
  851. package/dist/server/agent-chat/skill-frontmatter.d.ts.map +1 -0
  852. package/dist/server/agent-chat/skill-frontmatter.js +26 -0
  853. package/dist/server/agent-chat/skill-frontmatter.js.map +1 -0
  854. package/dist/server/agent-chat-plugin.d.ts +45 -486
  855. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  856. package/dist/server/agent-chat-plugin.js +173 -3005
  857. package/dist/server/agent-chat-plugin.js.map +1 -1
  858. package/dist/server/agent-teams.d.ts +10 -0
  859. package/dist/server/agent-teams.d.ts.map +1 -1
  860. package/dist/server/agent-teams.js +13 -3
  861. package/dist/server/agent-teams.js.map +1 -1
  862. package/dist/server/auth.d.ts.map +1 -1
  863. package/dist/server/auth.js +50 -52
  864. package/dist/server/auth.js.map +1 -1
  865. package/dist/server/credential-provider.d.ts.map +1 -1
  866. package/dist/server/credential-provider.js +22 -21
  867. package/dist/server/credential-provider.js.map +1 -1
  868. package/dist/server/edge.d.ts +1 -0
  869. package/dist/server/edge.d.ts.map +1 -1
  870. package/dist/server/edge.js +1 -0
  871. package/dist/server/edge.js.map +1 -1
  872. package/dist/server/onboarding-html.d.ts.map +1 -1
  873. package/dist/server/onboarding-html.js +1 -16
  874. package/dist/server/onboarding-html.js.map +1 -1
  875. package/dist/server/poll.d.ts.map +1 -1
  876. package/dist/server/poll.js +1 -0
  877. package/dist/server/poll.js.map +1 -1
  878. package/dist/server/realtime-voice.d.ts +10 -0
  879. package/dist/server/realtime-voice.d.ts.map +1 -1
  880. package/dist/server/realtime-voice.js +249 -15
  881. package/dist/server/realtime-voice.js.map +1 -1
  882. package/dist/server/request-origin.d.ts.map +1 -1
  883. package/dist/server/request-origin.js +6 -3
  884. package/dist/server/request-origin.js.map +1 -1
  885. package/dist/server/ssr-handler.d.ts.map +1 -1
  886. package/dist/server/ssr-handler.js +47 -2
  887. package/dist/server/ssr-handler.js.map +1 -1
  888. package/dist/sharing/access.d.ts +63 -3
  889. package/dist/sharing/access.d.ts.map +1 -1
  890. package/dist/sharing/access.js +53 -15
  891. package/dist/sharing/access.js.map +1 -1
  892. package/dist/sharing/registry.d.ts +7 -0
  893. package/dist/sharing/registry.d.ts.map +1 -1
  894. package/dist/sharing/registry.js.map +1 -1
  895. package/dist/styles/agent-native.css +17 -16
  896. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +1 -1
  897. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
  898. package/dist/templates/default/app/i18n/ar-SA.ts +6 -0
  899. package/dist/templates/default/app/i18n/de-DE.ts +6 -0
  900. package/dist/templates/default/app/i18n/en-US.ts +6 -0
  901. package/dist/templates/default/app/i18n/es-ES.ts +6 -0
  902. package/dist/templates/default/app/i18n/fr-FR.ts +6 -0
  903. package/dist/templates/default/app/i18n/hi-IN.ts +6 -0
  904. package/dist/templates/default/app/i18n/ja-JP.ts +6 -0
  905. package/dist/templates/default/app/i18n/ko-KR.ts +6 -0
  906. package/dist/templates/default/app/i18n/pt-BR.ts +6 -0
  907. package/dist/templates/default/app/i18n/zh-CN.ts +6 -0
  908. package/dist/templates/default/app/i18n/zh-TW.ts +6 -0
  909. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +27 -29
  910. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +2 -1
  911. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -1
  912. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +32 -0
  913. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
  914. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
  915. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
  916. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +25 -0
  917. package/dist/templates/workspace-core/src/server/index.ts +4 -2
  918. package/dist/testing.d.ts +16 -0
  919. package/dist/testing.d.ts.map +1 -0
  920. package/dist/testing.js +16 -0
  921. package/dist/testing.js.map +1 -0
  922. package/dist/triggers/dispatcher.d.ts +7 -0
  923. package/dist/triggers/dispatcher.d.ts.map +1 -1
  924. package/dist/triggers/dispatcher.js +13 -3
  925. package/dist/triggers/dispatcher.js.map +1 -1
  926. package/dist/vite/client.d.ts +16 -1
  927. package/dist/vite/client.d.ts.map +1 -1
  928. package/dist/vite/client.js +111 -3
  929. package/dist/vite/client.js.map +1 -1
  930. package/docs/content/authentication.mdx +3 -3
  931. package/docs/content/doctor.mdx +170 -0
  932. package/docs/content/external-agents.mdx +8 -7
  933. package/docs/content/locales/ar-SA/authentication.mdx +2 -2
  934. package/docs/content/locales/ar-SA/external-agents.mdx +8 -7
  935. package/docs/content/locales/ar-SA/mcp-protocol.mdx +1 -1
  936. package/docs/content/locales/ar-SA/security.mdx +2 -0
  937. package/docs/content/locales/de-DE/authentication.mdx +1 -1
  938. package/docs/content/locales/de-DE/external-agents.mdx +8 -7
  939. package/docs/content/locales/de-DE/mcp-protocol.mdx +1 -1
  940. package/docs/content/locales/de-DE/security.mdx +2 -0
  941. package/docs/content/locales/es-ES/authentication.mdx +2 -2
  942. package/docs/content/locales/es-ES/external-agents.mdx +8 -7
  943. package/docs/content/locales/es-ES/mcp-protocol.mdx +1 -1
  944. package/docs/content/locales/es-ES/security.mdx +2 -0
  945. package/docs/content/locales/fr-FR/authentication.mdx +1 -1
  946. package/docs/content/locales/fr-FR/external-agents.mdx +8 -7
  947. package/docs/content/locales/fr-FR/mcp-protocol.mdx +1 -1
  948. package/docs/content/locales/fr-FR/security.mdx +2 -0
  949. package/docs/content/locales/hi-IN/authentication.mdx +2 -2
  950. package/docs/content/locales/hi-IN/external-agents.mdx +8 -7
  951. package/docs/content/locales/hi-IN/mcp-protocol.mdx +1 -1
  952. package/docs/content/locales/hi-IN/security.mdx +2 -0
  953. package/docs/content/locales/ja-JP/authentication.mdx +2 -2
  954. package/docs/content/locales/ja-JP/external-agents.mdx +8 -7
  955. package/docs/content/locales/ja-JP/mcp-protocol.mdx +1 -1
  956. package/docs/content/locales/ja-JP/security.mdx +2 -0
  957. package/docs/content/locales/ko-KR/authentication.mdx +2 -2
  958. package/docs/content/locales/ko-KR/external-agents.mdx +8 -7
  959. package/docs/content/locales/ko-KR/mcp-protocol.mdx +1 -1
  960. package/docs/content/locales/ko-KR/security.mdx +2 -0
  961. package/docs/content/locales/pt-BR/authentication.mdx +2 -2
  962. package/docs/content/locales/pt-BR/external-agents.mdx +8 -7
  963. package/docs/content/locales/pt-BR/mcp-protocol.mdx +1 -1
  964. package/docs/content/locales/pt-BR/security.mdx +2 -0
  965. package/docs/content/locales/zh-CN/authentication.mdx +2 -2
  966. package/docs/content/locales/zh-CN/external-agents.mdx +8 -7
  967. package/docs/content/locales/zh-CN/mcp-protocol.mdx +1 -1
  968. package/docs/content/locales/zh-CN/security.mdx +2 -0
  969. package/docs/content/locales/zh-TW/authentication.mdx +2 -2
  970. package/docs/content/locales/zh-TW/external-agents.mdx +8 -7
  971. package/docs/content/locales/zh-TW/mcp-protocol.mdx +1 -1
  972. package/docs/content/locales/zh-TW/security.mdx +2 -0
  973. package/docs/content/mcp-protocol.mdx +1 -1
  974. package/docs/content/security.mdx +2 -0
  975. package/package.json +7 -3
  976. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +1 -1
  977. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
  978. package/src/templates/default/app/i18n/ar-SA.ts +6 -0
  979. package/src/templates/default/app/i18n/de-DE.ts +6 -0
  980. package/src/templates/default/app/i18n/en-US.ts +6 -0
  981. package/src/templates/default/app/i18n/es-ES.ts +6 -0
  982. package/src/templates/default/app/i18n/fr-FR.ts +6 -0
  983. package/src/templates/default/app/i18n/hi-IN.ts +6 -0
  984. package/src/templates/default/app/i18n/ja-JP.ts +6 -0
  985. package/src/templates/default/app/i18n/ko-KR.ts +6 -0
  986. package/src/templates/default/app/i18n/pt-BR.ts +6 -0
  987. package/src/templates/default/app/i18n/zh-CN.ts +6 -0
  988. package/src/templates/default/app/i18n/zh-TW.ts +6 -0
  989. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +27 -29
  990. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +2 -1
  991. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -1
  992. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +32 -0
  993. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
  994. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
  995. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
  996. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +25 -0
  997. package/src/templates/workspace-core/src/server/index.ts +4 -2
  998. package/corpus/core/src/client/ProductionAgentPanel.tsx +0 -9
  999. package/corpus/core/src/client/auth-redirect-url.ts +0 -23
  1000. package/corpus/core/src/client/useProductionAgent.ts +0 -253
  1001. package/corpus/core/src/shared/auth-redirect-url.ts +0 -1
  1002. package/corpus/templates/analytics/app/pages/Index.tsx +0 -16
  1003. package/corpus/templates/analytics/seeds/dashboards/agent-observability-llm.json +0 -173
  1004. package/dist/client/ProductionAgentPanel.d.ts +0 -6
  1005. package/dist/client/ProductionAgentPanel.d.ts.map +0 -1
  1006. package/dist/client/ProductionAgentPanel.js +0 -6
  1007. package/dist/client/ProductionAgentPanel.js.map +0 -1
  1008. package/dist/client/auth-redirect-url.d.ts +0 -2
  1009. package/dist/client/auth-redirect-url.d.ts.map +0 -1
  1010. package/dist/client/auth-redirect-url.js +0 -19
  1011. package/dist/client/auth-redirect-url.js.map +0 -1
  1012. package/dist/client/useProductionAgent.d.ts +0 -24
  1013. package/dist/client/useProductionAgent.d.ts.map +0 -1
  1014. package/dist/client/useProductionAgent.js +0 -179
  1015. package/dist/client/useProductionAgent.js.map +0 -1
  1016. package/dist/shared/auth-redirect-url.d.ts +0 -2
  1017. package/dist/shared/auth-redirect-url.d.ts.map +0 -1
  1018. package/dist/shared/auth-redirect-url.js +0 -2
  1019. package/dist/shared/auth-redirect-url.js.map +0 -1
@@ -125,7 +125,7 @@ function serviceOwnerForScope(key, access, orgId) {
125
125
  }
126
126
  function authorizationSql(alias = "") {
127
127
  const prefix = alias ? `${alias}.` : "";
128
- return `((${prefix}org_id = ? AND ? IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))`;
128
+ return `((${prefix}org_id = ? AND CAST(? AS TEXT) IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))`;
129
129
  }
130
130
  function authorizationArgs(access) {
131
131
  return [access.orgId, access.orgId, access.ownerEmail];
@@ -1 +1 @@
1
- {"version":3,"file":"scope-store.js","sourceRoot":"","sources":["../../src/integrations/scope-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport { getDbExec, intType, isPostgres } from \"../db/client.js\";\nimport {\n ensureColumnExists,\n ensureIndexExists,\n ensureTableExists,\n} from \"../db/ddl-guard.js\";\n\nlet initPromise: Promise<void> | undefined;\n\nexport type IntegrationConversationType =\n | \"channel\"\n | \"direct_message\"\n | \"group_direct_message\";\n\nexport type IntegrationConversationTrust =\n | \"trusted\"\n | \"guest\"\n | \"external_shared\"\n | \"unknown\";\n\nexport interface IntegrationScopeAccess {\n ownerEmail: string;\n orgId?: string | null;\n}\n\nexport interface IntegrationScopeKey {\n platform: string;\n tenantId: string;\n conversationId: string;\n}\n\nexport interface IntegrationScopePolicy {\n requireMention: boolean;\n allowDirectMessages: boolean;\n allowGuests: boolean;\n allowExternalShared: boolean;\n allowUnknownTrust: boolean;\n}\n\nexport const DEFAULT_INTEGRATION_SCOPE_POLICY: Readonly<IntegrationScopePolicy> =\n Object.freeze({\n requireMention: true,\n allowDirectMessages: false,\n allowGuests: false,\n allowExternalShared: false,\n allowUnknownTrust: false,\n });\n\nexport interface IntegrationScope extends IntegrationScopeKey {\n id: string;\n conversationType: IntegrationConversationType;\n trust: IntegrationConversationTrust;\n ownerEmail: string;\n orgId: string | null;\n installationId: string | null;\n serviceOwnerEmail: string;\n defaultModel: string | null;\n policy: IntegrationScopePolicy;\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface SaveIntegrationScopeInput extends IntegrationScopeKey {\n conversationType: IntegrationConversationType;\n trust?: IntegrationConversationTrust;\n /**\n * Omit to use the caller's active org, or pass null for a personal scope.\n * Passing an org other than the caller's active org is always rejected.\n */\n orgId?: string | null;\n installationId?: string | null;\n defaultModel?: string | null;\n policy?: Partial<IntegrationScopePolicy>;\n}\n\nconst CONVERSATION_TYPES = new Set<IntegrationConversationType>([\n \"channel\",\n \"direct_message\",\n \"group_direct_message\",\n]);\nconst TRUST_VALUES = new Set<IntegrationConversationTrust>([\n \"trusted\",\n \"guest\",\n \"external_shared\",\n \"unknown\",\n]);\n\nasync function ensureTable(): Promise<void> {\n if (!initPromise) {\n initPromise = (async () => {\n const db = getDbExec();\n const createSql = `CREATE TABLE IF NOT EXISTS integration_conversation_scopes (\n id TEXT PRIMARY KEY,\n platform TEXT NOT NULL,\n tenant_id TEXT NOT NULL,\n conversation_id TEXT NOT NULL,\n conversation_type TEXT NOT NULL,\n trust_level TEXT NOT NULL DEFAULT 'unknown',\n owner_email TEXT NOT NULL,\n org_id TEXT,\n installation_id TEXT,\n service_owner_email TEXT NOT NULL,\n default_model TEXT,\n require_mention ${intType()} NOT NULL DEFAULT 1,\n allow_direct_messages ${intType()} NOT NULL DEFAULT 0,\n allow_guests ${intType()} NOT NULL DEFAULT 0,\n allow_external_shared ${intType()} NOT NULL DEFAULT 0,\n allow_unknown_trust ${intType()} NOT NULL DEFAULT 0,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )`;\n const uniqueIndexSql =\n \"CREATE UNIQUE INDEX IF NOT EXISTS idx_integration_scope_external_key ON integration_conversation_scopes(platform, tenant_id, conversation_id)\";\n const ownerIndexSql =\n \"CREATE INDEX IF NOT EXISTS idx_integration_scope_owner ON integration_conversation_scopes(owner_email, platform, tenant_id)\";\n const orgIndexSql =\n \"CREATE INDEX IF NOT EXISTS idx_integration_scope_org ON integration_conversation_scopes(org_id, platform, tenant_id)\";\n\n if (isPostgres()) {\n await ensureTableExists(\"integration_conversation_scopes\", createSql);\n await ensureColumnExists(\n \"integration_conversation_scopes\",\n \"default_model\",\n \"ALTER TABLE integration_conversation_scopes ADD COLUMN IF NOT EXISTS default_model TEXT\",\n );\n await ensureIndexExists(\n \"idx_integration_scope_external_key\",\n uniqueIndexSql,\n );\n await ensureIndexExists(\"idx_integration_scope_owner\", ownerIndexSql);\n await ensureIndexExists(\"idx_integration_scope_org\", orgIndexSql);\n return;\n }\n\n await db.execute(createSql);\n try {\n await db.execute(\n \"ALTER TABLE integration_conversation_scopes ADD COLUMN default_model TEXT\",\n );\n } catch (error) {\n if (!/duplicate/i.test(String((error as Error)?.message ?? error))) {\n throw error;\n }\n }\n await db.execute(uniqueIndexSql);\n await db.execute(ownerIndexSql);\n await db.execute(orgIndexSql);\n })().catch((error) => {\n initPromise = undefined;\n throw error;\n });\n }\n return initPromise;\n}\n\nfunction requiredString(value: unknown, name: string, maxLength = 255): string {\n const normalized = String(value ?? \"\").trim();\n if (!normalized) throw new Error(`${name} is required`);\n if (normalized.length > maxLength) {\n throw new Error(`${name} must be at most ${maxLength} characters`);\n }\n return normalized;\n}\n\nfunction normalizeEmail(value: unknown, name: string): string {\n const email = requiredString(value, name, 320).toLowerCase();\n if (!email.includes(\"@\")) throw new Error(`${name} must be an email address`);\n return email;\n}\n\nfunction normalizeAccess(\n access: IntegrationScopeAccess,\n): Required<IntegrationScopeAccess> {\n return {\n ownerEmail: normalizeEmail(access.ownerEmail, \"ownerEmail\"),\n orgId: access.orgId ? requiredString(access.orgId, \"orgId\") : null,\n };\n}\n\nfunction normalizeKey(key: IntegrationScopeKey): IntegrationScopeKey {\n return {\n platform: requiredString(key.platform, \"platform\", 80).toLowerCase(),\n tenantId: requiredString(key.tenantId, \"tenantId\"),\n conversationId: requiredString(key.conversationId, \"conversationId\"),\n };\n}\n\n/** A stable, non-secret subject key suitable for a scope budget. */\nexport function integrationScopeSubjectKey(key: IntegrationScopeKey): string {\n const normalized = normalizeKey(key);\n return JSON.stringify([\n normalized.platform,\n normalized.tenantId,\n normalized.conversationId,\n ]);\n}\n\nfunction scopeId(key: IntegrationScopeKey): string {\n return `scope:${integrationScopeSubjectKey(key)}`;\n}\n\nfunction serviceOwnerForScope(\n key: IntegrationScopeKey,\n access: Required<IntegrationScopeAccess>,\n orgId: string | null,\n): string {\n if (!orgId) return access.ownerEmail;\n const subject = createHash(\"sha256\")\n .update(`${orgId}:${integrationScopeSubjectKey(key)}`)\n .digest(\"hex\")\n .slice(0, 24);\n return `integration+${subject}@service.agent-native.local`;\n}\n\nfunction authorizationSql(alias = \"\"): string {\n const prefix = alias ? `${alias}.` : \"\";\n return `((${prefix}org_id = ? AND ? IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))`;\n}\n\nfunction authorizationArgs(\n access: Required<IntegrationScopeAccess>,\n): unknown[] {\n return [access.orgId, access.orgId, access.ownerEmail];\n}\n\nfunction policyFromRow(row: Record<string, unknown>): IntegrationScopePolicy {\n return {\n requireMention: Number(row.require_mention) === 1,\n allowDirectMessages: Number(row.allow_direct_messages) === 1,\n allowGuests: Number(row.allow_guests) === 1,\n allowExternalShared: Number(row.allow_external_shared) === 1,\n allowUnknownTrust: Number(row.allow_unknown_trust) === 1,\n };\n}\n\nfunction rowToScope(row: Record<string, unknown>): IntegrationScope {\n return {\n id: String(row.id),\n platform: String(row.platform),\n tenantId: String(row.tenant_id),\n conversationId: String(row.conversation_id),\n conversationType: row.conversation_type as IntegrationConversationType,\n trust: row.trust_level as IntegrationConversationTrust,\n ownerEmail: String(row.owner_email),\n orgId: row.org_id == null ? null : String(row.org_id),\n installationId:\n row.installation_id == null ? null : String(row.installation_id),\n serviceOwnerEmail: String(row.service_owner_email),\n defaultModel: row.default_model == null ? null : String(row.default_model),\n policy: policyFromRow(row),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n };\n}\n\nconst SELECT_COLUMNS = `id, platform, tenant_id, conversation_id,\n conversation_type, trust_level, owner_email, org_id, installation_id,\n service_owner_email, require_mention, allow_direct_messages, allow_guests,\n allow_external_shared, allow_unknown_trust, default_model, created_at, updated_at`;\n\nfunction isUniqueViolation(error: unknown): boolean {\n const value = error as { code?: string; message?: string } | null;\n if (value?.code === \"23505\") return true;\n return /unique|duplicate/i.test(String(value?.message ?? error ?? \"\"));\n}\n\nfunction normalizePolicy(\n policy: Partial<IntegrationScopePolicy> | undefined,\n): IntegrationScopePolicy {\n return {\n ...DEFAULT_INTEGRATION_SCOPE_POLICY,\n ...policy,\n };\n}\n\nfunction resolveOrgId(\n requested: string | null | undefined,\n access: Required<IntegrationScopeAccess>,\n): string | null {\n if (requested === null) return null;\n if (requested === undefined) return access.orgId;\n const normalized = requiredString(requested, \"orgId\");\n if (!access.orgId || normalized !== access.orgId) {\n throw new Error(\n \"Not authorized to manage an integration scope for that org\",\n );\n }\n return normalized;\n}\n\nexport async function getIntegrationScope(\n keyInput: IntegrationScopeKey,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationScope | null> {\n await ensureTable();\n const key = normalizeKey(keyInput);\n const access = normalizeAccess(accessInput);\n const { rows } = await getDbExec().execute({\n sql: `SELECT ${SELECT_COLUMNS}\n FROM integration_conversation_scopes\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}\n LIMIT 1`,\n args: [\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n return rows.length > 0\n ? rowToScope(rows[0] as Record<string, unknown>)\n : null;\n}\n\nexport async function listIntegrationScopes(\n accessInput: IntegrationScopeAccess,\n filter: { platform?: string; tenantId?: string } = {},\n): Promise<IntegrationScope[]> {\n await ensureTable();\n const access = normalizeAccess(accessInput);\n const clauses = [authorizationSql()];\n const args: unknown[] = [...authorizationArgs(access)];\n if (filter.platform) {\n clauses.push(\"platform = ?\");\n args.push(requiredString(filter.platform, \"platform\", 80).toLowerCase());\n }\n if (filter.tenantId) {\n clauses.push(\"tenant_id = ?\");\n args.push(requiredString(filter.tenantId, \"tenantId\"));\n }\n const { rows } = await getDbExec().execute({\n sql: `SELECT ${SELECT_COLUMNS}\n FROM integration_conversation_scopes\n WHERE ${clauses.join(\" AND \")}\n ORDER BY platform, tenant_id, conversation_id`,\n args,\n });\n return rows.map((row) => rowToScope(row as Record<string, unknown>));\n}\n\nexport async function saveIntegrationScope(\n input: SaveIntegrationScopeInput,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationScope> {\n await ensureTable();\n const key = normalizeKey(input);\n const access = normalizeAccess(accessInput);\n const orgId = resolveOrgId(input.orgId, access);\n if (!CONVERSATION_TYPES.has(input.conversationType)) {\n throw new Error(\"Unsupported integration conversation type\");\n }\n const trust = input.trust ?? \"unknown\";\n if (!TRUST_VALUES.has(trust)) {\n throw new Error(\"Unsupported integration conversation trust level\");\n }\n const serviceOwnerEmail = serviceOwnerForScope(key, access, orgId);\n const installationId = input.installationId\n ? requiredString(input.installationId, \"installationId\")\n : null;\n const defaultModel = input.defaultModel?.trim().slice(0, 200) || null;\n const policy = normalizePolicy(input.policy);\n const now = Date.now();\n const db = getDbExec();\n\n const updated = await db.execute({\n sql: `UPDATE integration_conversation_scopes SET\n conversation_type = ?, trust_level = ?, installation_id = ?,\n service_owner_email = ?, require_mention = ?, allow_direct_messages = ?,\n allow_guests = ?, allow_external_shared = ?, allow_unknown_trust = ?,\n default_model = ?, updated_at = ?\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}`,\n args: [\n input.conversationType,\n trust,\n installationId,\n serviceOwnerEmail,\n policy.requireMention ? 1 : 0,\n policy.allowDirectMessages ? 1 : 0,\n policy.allowGuests ? 1 : 0,\n policy.allowExternalShared ? 1 : 0,\n policy.allowUnknownTrust ? 1 : 0,\n defaultModel,\n now,\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n\n if (updated.rowsAffected === 0) {\n try {\n await db.execute({\n sql: `INSERT INTO integration_conversation_scopes (\n id, platform, tenant_id, conversation_id, conversation_type,\n trust_level, owner_email, org_id, installation_id,\n service_owner_email, require_mention, allow_direct_messages,\n allow_guests, allow_external_shared, allow_unknown_trust,\n default_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n scopeId(key),\n key.platform,\n key.tenantId,\n key.conversationId,\n input.conversationType,\n trust,\n access.ownerEmail,\n orgId,\n installationId,\n serviceOwnerEmail,\n policy.requireMention ? 1 : 0,\n policy.allowDirectMessages ? 1 : 0,\n policy.allowGuests ? 1 : 0,\n policy.allowExternalShared ? 1 : 0,\n policy.allowUnknownTrust ? 1 : 0,\n defaultModel,\n now,\n now,\n ],\n });\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new Error(\"Integration scope is not available to this caller\");\n }\n throw error;\n }\n }\n\n const saved = await getIntegrationScope(key, access);\n if (!saved) throw new Error(\"Integration scope write could not be verified\");\n return saved;\n}\n\nexport async function deleteIntegrationScope(\n keyInput: IntegrationScopeKey,\n accessInput: IntegrationScopeAccess,\n): Promise<boolean> {\n await ensureTable();\n const key = normalizeKey(keyInput);\n const access = normalizeAccess(accessInput);\n const result = await getDbExec().execute({\n sql: `DELETE FROM integration_conversation_scopes\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}`,\n args: [\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n return result.rowsAffected > 0;\n}\n\nexport type IntegrationScopePolicyDenial =\n | \"mention_required\"\n | \"direct_messages_disabled\"\n | \"guests_disabled\"\n | \"external_shared_disabled\"\n | \"unverified_conversation_disabled\";\n\nexport function evaluateIntegrationScopePolicy(\n scope: Pick<IntegrationScope, \"conversationType\" | \"trust\" | \"policy\">,\n context: { mentioned: boolean },\n):\n | { allowed: true }\n | { allowed: false; reason: IntegrationScopePolicyDenial } {\n if (scope.policy.requireMention && !context.mentioned) {\n return { allowed: false, reason: \"mention_required\" };\n }\n if (\n (scope.conversationType === \"direct_message\" ||\n scope.conversationType === \"group_direct_message\") &&\n !scope.policy.allowDirectMessages\n ) {\n return { allowed: false, reason: \"direct_messages_disabled\" };\n }\n if (scope.trust === \"guest\" && !scope.policy.allowGuests) {\n return { allowed: false, reason: \"guests_disabled\" };\n }\n if (scope.trust === \"external_shared\" && !scope.policy.allowExternalShared) {\n return { allowed: false, reason: \"external_shared_disabled\" };\n }\n if (scope.trust === \"unknown\" && !scope.policy.allowUnknownTrust) {\n return { allowed: false, reason: \"unverified_conversation_disabled\" };\n }\n return { allowed: true };\n}\n\n/** Test-only reset for suites that swap the injected database. */\nexport function _resetIntegrationScopeStoreForTests(): void {\n initPromise = undefined;\n}\n"]}
1
+ {"version":3,"file":"scope-store.js","sourceRoot":"","sources":["../../src/integrations/scope-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport { getDbExec, intType, isPostgres } from \"../db/client.js\";\nimport {\n ensureColumnExists,\n ensureIndexExists,\n ensureTableExists,\n} from \"../db/ddl-guard.js\";\n\nlet initPromise: Promise<void> | undefined;\n\nexport type IntegrationConversationType =\n | \"channel\"\n | \"direct_message\"\n | \"group_direct_message\";\n\nexport type IntegrationConversationTrust =\n | \"trusted\"\n | \"guest\"\n | \"external_shared\"\n | \"unknown\";\n\nexport interface IntegrationScopeAccess {\n ownerEmail: string;\n orgId?: string | null;\n}\n\nexport interface IntegrationScopeKey {\n platform: string;\n tenantId: string;\n conversationId: string;\n}\n\nexport interface IntegrationScopePolicy {\n requireMention: boolean;\n allowDirectMessages: boolean;\n allowGuests: boolean;\n allowExternalShared: boolean;\n allowUnknownTrust: boolean;\n}\n\nexport const DEFAULT_INTEGRATION_SCOPE_POLICY: Readonly<IntegrationScopePolicy> =\n Object.freeze({\n requireMention: true,\n allowDirectMessages: false,\n allowGuests: false,\n allowExternalShared: false,\n allowUnknownTrust: false,\n });\n\nexport interface IntegrationScope extends IntegrationScopeKey {\n id: string;\n conversationType: IntegrationConversationType;\n trust: IntegrationConversationTrust;\n ownerEmail: string;\n orgId: string | null;\n installationId: string | null;\n serviceOwnerEmail: string;\n defaultModel: string | null;\n policy: IntegrationScopePolicy;\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface SaveIntegrationScopeInput extends IntegrationScopeKey {\n conversationType: IntegrationConversationType;\n trust?: IntegrationConversationTrust;\n /**\n * Omit to use the caller's active org, or pass null for a personal scope.\n * Passing an org other than the caller's active org is always rejected.\n */\n orgId?: string | null;\n installationId?: string | null;\n defaultModel?: string | null;\n policy?: Partial<IntegrationScopePolicy>;\n}\n\nconst CONVERSATION_TYPES = new Set<IntegrationConversationType>([\n \"channel\",\n \"direct_message\",\n \"group_direct_message\",\n]);\nconst TRUST_VALUES = new Set<IntegrationConversationTrust>([\n \"trusted\",\n \"guest\",\n \"external_shared\",\n \"unknown\",\n]);\n\nasync function ensureTable(): Promise<void> {\n if (!initPromise) {\n initPromise = (async () => {\n const db = getDbExec();\n const createSql = `CREATE TABLE IF NOT EXISTS integration_conversation_scopes (\n id TEXT PRIMARY KEY,\n platform TEXT NOT NULL,\n tenant_id TEXT NOT NULL,\n conversation_id TEXT NOT NULL,\n conversation_type TEXT NOT NULL,\n trust_level TEXT NOT NULL DEFAULT 'unknown',\n owner_email TEXT NOT NULL,\n org_id TEXT,\n installation_id TEXT,\n service_owner_email TEXT NOT NULL,\n default_model TEXT,\n require_mention ${intType()} NOT NULL DEFAULT 1,\n allow_direct_messages ${intType()} NOT NULL DEFAULT 0,\n allow_guests ${intType()} NOT NULL DEFAULT 0,\n allow_external_shared ${intType()} NOT NULL DEFAULT 0,\n allow_unknown_trust ${intType()} NOT NULL DEFAULT 0,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )`;\n const uniqueIndexSql =\n \"CREATE UNIQUE INDEX IF NOT EXISTS idx_integration_scope_external_key ON integration_conversation_scopes(platform, tenant_id, conversation_id)\";\n const ownerIndexSql =\n \"CREATE INDEX IF NOT EXISTS idx_integration_scope_owner ON integration_conversation_scopes(owner_email, platform, tenant_id)\";\n const orgIndexSql =\n \"CREATE INDEX IF NOT EXISTS idx_integration_scope_org ON integration_conversation_scopes(org_id, platform, tenant_id)\";\n\n if (isPostgres()) {\n await ensureTableExists(\"integration_conversation_scopes\", createSql);\n await ensureColumnExists(\n \"integration_conversation_scopes\",\n \"default_model\",\n \"ALTER TABLE integration_conversation_scopes ADD COLUMN IF NOT EXISTS default_model TEXT\",\n );\n await ensureIndexExists(\n \"idx_integration_scope_external_key\",\n uniqueIndexSql,\n );\n await ensureIndexExists(\"idx_integration_scope_owner\", ownerIndexSql);\n await ensureIndexExists(\"idx_integration_scope_org\", orgIndexSql);\n return;\n }\n\n await db.execute(createSql);\n try {\n await db.execute(\n \"ALTER TABLE integration_conversation_scopes ADD COLUMN default_model TEXT\",\n );\n } catch (error) {\n if (!/duplicate/i.test(String((error as Error)?.message ?? error))) {\n throw error;\n }\n }\n await db.execute(uniqueIndexSql);\n await db.execute(ownerIndexSql);\n await db.execute(orgIndexSql);\n })().catch((error) => {\n initPromise = undefined;\n throw error;\n });\n }\n return initPromise;\n}\n\nfunction requiredString(value: unknown, name: string, maxLength = 255): string {\n const normalized = String(value ?? \"\").trim();\n if (!normalized) throw new Error(`${name} is required`);\n if (normalized.length > maxLength) {\n throw new Error(`${name} must be at most ${maxLength} characters`);\n }\n return normalized;\n}\n\nfunction normalizeEmail(value: unknown, name: string): string {\n const email = requiredString(value, name, 320).toLowerCase();\n if (!email.includes(\"@\")) throw new Error(`${name} must be an email address`);\n return email;\n}\n\nfunction normalizeAccess(\n access: IntegrationScopeAccess,\n): Required<IntegrationScopeAccess> {\n return {\n ownerEmail: normalizeEmail(access.ownerEmail, \"ownerEmail\"),\n orgId: access.orgId ? requiredString(access.orgId, \"orgId\") : null,\n };\n}\n\nfunction normalizeKey(key: IntegrationScopeKey): IntegrationScopeKey {\n return {\n platform: requiredString(key.platform, \"platform\", 80).toLowerCase(),\n tenantId: requiredString(key.tenantId, \"tenantId\"),\n conversationId: requiredString(key.conversationId, \"conversationId\"),\n };\n}\n\n/** A stable, non-secret subject key suitable for a scope budget. */\nexport function integrationScopeSubjectKey(key: IntegrationScopeKey): string {\n const normalized = normalizeKey(key);\n return JSON.stringify([\n normalized.platform,\n normalized.tenantId,\n normalized.conversationId,\n ]);\n}\n\nfunction scopeId(key: IntegrationScopeKey): string {\n return `scope:${integrationScopeSubjectKey(key)}`;\n}\n\nfunction serviceOwnerForScope(\n key: IntegrationScopeKey,\n access: Required<IntegrationScopeAccess>,\n orgId: string | null,\n): string {\n if (!orgId) return access.ownerEmail;\n const subject = createHash(\"sha256\")\n .update(`${orgId}:${integrationScopeSubjectKey(key)}`)\n .digest(\"hex\")\n .slice(0, 24);\n return `integration+${subject}@service.agent-native.local`;\n}\n\nfunction authorizationSql(alias = \"\"): string {\n const prefix = alias ? `${alias}.` : \"\";\n return `((${prefix}org_id = ? AND CAST(? AS TEXT) IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))`;\n}\n\nfunction authorizationArgs(\n access: Required<IntegrationScopeAccess>,\n): unknown[] {\n return [access.orgId, access.orgId, access.ownerEmail];\n}\n\nfunction policyFromRow(row: Record<string, unknown>): IntegrationScopePolicy {\n return {\n requireMention: Number(row.require_mention) === 1,\n allowDirectMessages: Number(row.allow_direct_messages) === 1,\n allowGuests: Number(row.allow_guests) === 1,\n allowExternalShared: Number(row.allow_external_shared) === 1,\n allowUnknownTrust: Number(row.allow_unknown_trust) === 1,\n };\n}\n\nfunction rowToScope(row: Record<string, unknown>): IntegrationScope {\n return {\n id: String(row.id),\n platform: String(row.platform),\n tenantId: String(row.tenant_id),\n conversationId: String(row.conversation_id),\n conversationType: row.conversation_type as IntegrationConversationType,\n trust: row.trust_level as IntegrationConversationTrust,\n ownerEmail: String(row.owner_email),\n orgId: row.org_id == null ? null : String(row.org_id),\n installationId:\n row.installation_id == null ? null : String(row.installation_id),\n serviceOwnerEmail: String(row.service_owner_email),\n defaultModel: row.default_model == null ? null : String(row.default_model),\n policy: policyFromRow(row),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n };\n}\n\nconst SELECT_COLUMNS = `id, platform, tenant_id, conversation_id,\n conversation_type, trust_level, owner_email, org_id, installation_id,\n service_owner_email, require_mention, allow_direct_messages, allow_guests,\n allow_external_shared, allow_unknown_trust, default_model, created_at, updated_at`;\n\nfunction isUniqueViolation(error: unknown): boolean {\n const value = error as { code?: string; message?: string } | null;\n if (value?.code === \"23505\") return true;\n return /unique|duplicate/i.test(String(value?.message ?? error ?? \"\"));\n}\n\nfunction normalizePolicy(\n policy: Partial<IntegrationScopePolicy> | undefined,\n): IntegrationScopePolicy {\n return {\n ...DEFAULT_INTEGRATION_SCOPE_POLICY,\n ...policy,\n };\n}\n\nfunction resolveOrgId(\n requested: string | null | undefined,\n access: Required<IntegrationScopeAccess>,\n): string | null {\n if (requested === null) return null;\n if (requested === undefined) return access.orgId;\n const normalized = requiredString(requested, \"orgId\");\n if (!access.orgId || normalized !== access.orgId) {\n throw new Error(\n \"Not authorized to manage an integration scope for that org\",\n );\n }\n return normalized;\n}\n\nexport async function getIntegrationScope(\n keyInput: IntegrationScopeKey,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationScope | null> {\n await ensureTable();\n const key = normalizeKey(keyInput);\n const access = normalizeAccess(accessInput);\n const { rows } = await getDbExec().execute({\n sql: `SELECT ${SELECT_COLUMNS}\n FROM integration_conversation_scopes\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}\n LIMIT 1`,\n args: [\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n return rows.length > 0\n ? rowToScope(rows[0] as Record<string, unknown>)\n : null;\n}\n\nexport async function listIntegrationScopes(\n accessInput: IntegrationScopeAccess,\n filter: { platform?: string; tenantId?: string } = {},\n): Promise<IntegrationScope[]> {\n await ensureTable();\n const access = normalizeAccess(accessInput);\n const clauses = [authorizationSql()];\n const args: unknown[] = [...authorizationArgs(access)];\n if (filter.platform) {\n clauses.push(\"platform = ?\");\n args.push(requiredString(filter.platform, \"platform\", 80).toLowerCase());\n }\n if (filter.tenantId) {\n clauses.push(\"tenant_id = ?\");\n args.push(requiredString(filter.tenantId, \"tenantId\"));\n }\n const { rows } = await getDbExec().execute({\n sql: `SELECT ${SELECT_COLUMNS}\n FROM integration_conversation_scopes\n WHERE ${clauses.join(\" AND \")}\n ORDER BY platform, tenant_id, conversation_id`,\n args,\n });\n return rows.map((row) => rowToScope(row as Record<string, unknown>));\n}\n\nexport async function saveIntegrationScope(\n input: SaveIntegrationScopeInput,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationScope> {\n await ensureTable();\n const key = normalizeKey(input);\n const access = normalizeAccess(accessInput);\n const orgId = resolveOrgId(input.orgId, access);\n if (!CONVERSATION_TYPES.has(input.conversationType)) {\n throw new Error(\"Unsupported integration conversation type\");\n }\n const trust = input.trust ?? \"unknown\";\n if (!TRUST_VALUES.has(trust)) {\n throw new Error(\"Unsupported integration conversation trust level\");\n }\n const serviceOwnerEmail = serviceOwnerForScope(key, access, orgId);\n const installationId = input.installationId\n ? requiredString(input.installationId, \"installationId\")\n : null;\n const defaultModel = input.defaultModel?.trim().slice(0, 200) || null;\n const policy = normalizePolicy(input.policy);\n const now = Date.now();\n const db = getDbExec();\n\n const updated = await db.execute({\n sql: `UPDATE integration_conversation_scopes SET\n conversation_type = ?, trust_level = ?, installation_id = ?,\n service_owner_email = ?, require_mention = ?, allow_direct_messages = ?,\n allow_guests = ?, allow_external_shared = ?, allow_unknown_trust = ?,\n default_model = ?, updated_at = ?\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}`,\n args: [\n input.conversationType,\n trust,\n installationId,\n serviceOwnerEmail,\n policy.requireMention ? 1 : 0,\n policy.allowDirectMessages ? 1 : 0,\n policy.allowGuests ? 1 : 0,\n policy.allowExternalShared ? 1 : 0,\n policy.allowUnknownTrust ? 1 : 0,\n defaultModel,\n now,\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n\n if (updated.rowsAffected === 0) {\n try {\n await db.execute({\n sql: `INSERT INTO integration_conversation_scopes (\n id, platform, tenant_id, conversation_id, conversation_type,\n trust_level, owner_email, org_id, installation_id,\n service_owner_email, require_mention, allow_direct_messages,\n allow_guests, allow_external_shared, allow_unknown_trust,\n default_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n scopeId(key),\n key.platform,\n key.tenantId,\n key.conversationId,\n input.conversationType,\n trust,\n access.ownerEmail,\n orgId,\n installationId,\n serviceOwnerEmail,\n policy.requireMention ? 1 : 0,\n policy.allowDirectMessages ? 1 : 0,\n policy.allowGuests ? 1 : 0,\n policy.allowExternalShared ? 1 : 0,\n policy.allowUnknownTrust ? 1 : 0,\n defaultModel,\n now,\n now,\n ],\n });\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new Error(\"Integration scope is not available to this caller\");\n }\n throw error;\n }\n }\n\n const saved = await getIntegrationScope(key, access);\n if (!saved) throw new Error(\"Integration scope write could not be verified\");\n return saved;\n}\n\nexport async function deleteIntegrationScope(\n keyInput: IntegrationScopeKey,\n accessInput: IntegrationScopeAccess,\n): Promise<boolean> {\n await ensureTable();\n const key = normalizeKey(keyInput);\n const access = normalizeAccess(accessInput);\n const result = await getDbExec().execute({\n sql: `DELETE FROM integration_conversation_scopes\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}`,\n args: [\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n return result.rowsAffected > 0;\n}\n\nexport type IntegrationScopePolicyDenial =\n | \"mention_required\"\n | \"direct_messages_disabled\"\n | \"guests_disabled\"\n | \"external_shared_disabled\"\n | \"unverified_conversation_disabled\";\n\nexport function evaluateIntegrationScopePolicy(\n scope: Pick<IntegrationScope, \"conversationType\" | \"trust\" | \"policy\">,\n context: { mentioned: boolean },\n):\n | { allowed: true }\n | { allowed: false; reason: IntegrationScopePolicyDenial } {\n if (scope.policy.requireMention && !context.mentioned) {\n return { allowed: false, reason: \"mention_required\" };\n }\n if (\n (scope.conversationType === \"direct_message\" ||\n scope.conversationType === \"group_direct_message\") &&\n !scope.policy.allowDirectMessages\n ) {\n return { allowed: false, reason: \"direct_messages_disabled\" };\n }\n if (scope.trust === \"guest\" && !scope.policy.allowGuests) {\n return { allowed: false, reason: \"guests_disabled\" };\n }\n if (scope.trust === \"external_shared\" && !scope.policy.allowExternalShared) {\n return { allowed: false, reason: \"external_shared_disabled\" };\n }\n if (scope.trust === \"unknown\" && !scope.policy.allowUnknownTrust) {\n return { allowed: false, reason: \"unverified_conversation_disabled\" };\n }\n return { allowed: true };\n}\n\n/** Test-only reset for suites that swap the injected database. */\nexport function _resetIntegrationScopeStoreForTests(): void {\n initPromise = undefined;\n}\n"]}
@@ -136,7 +136,7 @@ function requirePeriod(value) {
136
136
  }
137
137
  function authorizationSql(alias = "") {
138
138
  const prefix = alias ? `${alias}.` : "";
139
- return `((${prefix}subject_type = 'user' AND ${prefix}owner_email = ?) OR (${prefix}subject_type <> 'user' AND ((${prefix}org_id = ? AND ? IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))))`;
139
+ return `((${prefix}subject_type = 'user' AND ${prefix}owner_email = ?) OR (${prefix}subject_type <> 'user' AND ((${prefix}org_id = ? AND CAST(? AS TEXT) IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))))`;
140
140
  }
141
141
  function authorizationArgs(access) {
142
142
  return [access.ownerEmail, access.orgId, access.orgId, access.ownerEmail];
@@ -1 +1 @@
1
- {"version":3,"file":"usage-budget-store.js","sourceRoot":"","sources":["../../src/integrations/usage-budget-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDbExec, intType, isPostgres, type DbExec } from \"../db/client.js\";\nimport { ensureIndexExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport {\n getIntegrationScope,\n integrationScopeSubjectKey,\n type IntegrationScopeAccess,\n type IntegrationScopeKey,\n} from \"./scope-store.js\";\n\nlet initPromise: Promise<void> | undefined;\nlet transactionTail: Promise<void> = Promise.resolve();\n\n/** All budget values are integer millionths of one billing currency unit. */\nexport const INTEGRATION_BUDGET_COST_UNIT = \"currency_micros\" as const;\n\nexport type IntegrationBudgetPeriod = \"day\" | \"month\";\nexport type IntegrationBudgetSubject =\n | { type: \"org\"; orgId: string }\n | { type: \"user\"; userEmail: string }\n | { type: \"scope\"; scope: IntegrationScopeKey };\n\nexport interface IntegrationUsageBudget {\n id: string;\n subjectType: IntegrationBudgetSubject[\"type\"];\n subjectId: string;\n period: IntegrationBudgetPeriod;\n /** Integer millionths of one billing currency unit. */\n limitMicros: number;\n /** Threshold in basis points: 8,000 means 80%. */\n thresholdBps: number;\n ownerEmail: string;\n orgId: string | null;\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface IntegrationBudgetSnapshot {\n budget: IntegrationUsageBudget;\n windowStart: number;\n windowEnd: number;\n usedMicros: number;\n reservedMicros: number;\n remainingMicros: number;\n costUnit: typeof INTEGRATION_BUDGET_COST_UNIT;\n}\n\nexport type IntegrationReservationStatus =\n | \"pending\"\n | \"reserved\"\n | \"denied\"\n | \"settled\"\n | \"released\";\n\nexport interface IntegrationBudgetReservationResult {\n allowed: boolean;\n reservationId: string;\n status: IntegrationReservationStatus;\n estimatedCostMicros: number;\n settledCostMicros: number | null;\n thresholdEventEmitted: boolean;\n snapshot: IntegrationBudgetSnapshot;\n}\n\nexport interface IntegrationBudgetThresholdEvent {\n id: string;\n budgetId: string;\n windowStart: number;\n thresholdBps: number;\n observedMicros: number;\n createdAt: number;\n}\n\ninterface ResolvedSubject {\n type: IntegrationBudgetSubject[\"type\"];\n id: string;\n partitionKey: string;\n orgId: string | null;\n}\n\ninterface ReservationRow {\n id: string;\n reservationKey: string;\n budgetId: string;\n windowStart: number;\n estimatedCostMicros: number;\n settledCostMicros: number | null;\n status: IntegrationReservationStatus;\n}\n\nasync function ensureTables(): Promise<void> {\n if (!initPromise) {\n initPromise = (async () => {\n const db = getDbExec();\n const budgetsSql = `CREATE TABLE IF NOT EXISTS integration_usage_budgets (\n id TEXT PRIMARY KEY,\n partition_key TEXT NOT NULL,\n subject_type TEXT NOT NULL,\n subject_id TEXT NOT NULL,\n period TEXT NOT NULL,\n limit_micros ${intType()} NOT NULL,\n threshold_bps ${intType()} NOT NULL DEFAULT 8000,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )`;\n const windowsSql = `CREATE TABLE IF NOT EXISTS integration_usage_budget_windows (\n budget_id TEXT NOT NULL,\n window_start ${intType()} NOT NULL,\n used_micros ${intType()} NOT NULL DEFAULT 0,\n reserved_micros ${intType()} NOT NULL DEFAULT 0,\n updated_at ${intType()} NOT NULL,\n PRIMARY KEY (budget_id, window_start)\n )`;\n const reservationsSql = `CREATE TABLE IF NOT EXISTS integration_usage_reservations (\n id TEXT PRIMARY KEY,\n reservation_key TEXT NOT NULL,\n budget_id TEXT NOT NULL,\n window_start ${intType()} NOT NULL,\n estimated_cost_micros ${intType()} NOT NULL,\n settled_cost_micros ${intType()},\n status TEXT NOT NULL,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )`;\n const eventsSql = `CREATE TABLE IF NOT EXISTS integration_usage_budget_events (\n id TEXT PRIMARY KEY,\n budget_id TEXT NOT NULL,\n window_start ${intType()} NOT NULL,\n threshold_bps ${intType()} NOT NULL,\n observed_micros ${intType()} NOT NULL,\n created_at ${intType()} NOT NULL\n )`;\n const indexes = [\n {\n name: \"idx_integration_budget_subject\",\n sql: \"CREATE UNIQUE INDEX IF NOT EXISTS idx_integration_budget_subject ON integration_usage_budgets(partition_key, subject_type, subject_id, period)\",\n },\n {\n name: \"idx_integration_budget_owner\",\n sql: \"CREATE INDEX IF NOT EXISTS idx_integration_budget_owner ON integration_usage_budgets(owner_email, subject_type)\",\n },\n {\n name: \"idx_integration_budget_org\",\n sql: \"CREATE INDEX IF NOT EXISTS idx_integration_budget_org ON integration_usage_budgets(org_id, subject_type)\",\n },\n {\n name: \"idx_integration_reservation_budget\",\n sql: \"CREATE INDEX IF NOT EXISTS idx_integration_reservation_budget ON integration_usage_reservations(budget_id, window_start, status)\",\n },\n {\n name: \"idx_integration_budget_event_window\",\n sql: \"CREATE UNIQUE INDEX IF NOT EXISTS idx_integration_budget_event_window ON integration_usage_budget_events(budget_id, window_start, threshold_bps)\",\n },\n ];\n\n if (isPostgres()) {\n await ensureTableExists(\"integration_usage_budgets\", budgetsSql);\n await ensureTableExists(\"integration_usage_budget_windows\", windowsSql);\n await ensureTableExists(\n \"integration_usage_reservations\",\n reservationsSql,\n );\n await ensureTableExists(\"integration_usage_budget_events\", eventsSql);\n for (const index of indexes) {\n await ensureIndexExists(index.name, index.sql);\n }\n return;\n }\n\n await db.execute(budgetsSql);\n await db.execute(windowsSql);\n await db.execute(reservationsSql);\n await db.execute(eventsSql);\n for (const index of indexes) await db.execute(index.sql);\n })().catch((error) => {\n initPromise = undefined;\n throw error;\n });\n }\n return initPromise;\n}\n\nfunction requiredString(value: unknown, name: string, maxLength = 512): string {\n const normalized = String(value ?? \"\").trim();\n if (!normalized) throw new Error(`${name} is required`);\n if (normalized.length > maxLength) {\n throw new Error(`${name} must be at most ${maxLength} characters`);\n }\n return normalized;\n}\n\nfunction normalizeEmail(value: unknown, name: string): string {\n const normalized = requiredString(value, name, 320).toLowerCase();\n if (!normalized.includes(\"@\")) {\n throw new Error(`${name} must be an email address`);\n }\n return normalized;\n}\n\nfunction normalizeAccess(\n access: IntegrationScopeAccess,\n): Required<IntegrationScopeAccess> {\n return {\n ownerEmail: normalizeEmail(access.ownerEmail, \"ownerEmail\"),\n orgId: access.orgId ? requiredString(access.orgId, \"orgId\") : null,\n };\n}\n\nfunction requireMicros(value: number, name: string, allowZero = false): number {\n if (!Number.isSafeInteger(value) || value < (allowZero ? 0 : 1)) {\n throw new Error(`${name} must be a safe integer in currency micros`);\n }\n return value;\n}\n\nfunction requireThresholdBps(value: number): number {\n if (!Number.isInteger(value) || value < 1 || value > 10_000) {\n throw new Error(\"thresholdBps must be an integer from 1 to 10000\");\n }\n return value;\n}\n\nfunction requirePeriod(\n value: IntegrationBudgetPeriod,\n): IntegrationBudgetPeriod {\n if (value !== \"day\" && value !== \"month\") {\n throw new Error(\"period must be day or month\");\n }\n return value;\n}\n\nfunction authorizationSql(alias = \"\"): string {\n const prefix = alias ? `${alias}.` : \"\";\n return `((${prefix}subject_type = 'user' AND ${prefix}owner_email = ?) OR (${prefix}subject_type <> 'user' AND ((${prefix}org_id = ? AND ? IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))))`;\n}\n\nfunction authorizationArgs(\n access: Required<IntegrationScopeAccess>,\n): unknown[] {\n return [access.ownerEmail, access.orgId, access.orgId, access.ownerEmail];\n}\n\nasync function resolveSubject(\n subject: IntegrationBudgetSubject,\n access: Required<IntegrationScopeAccess>,\n): Promise<ResolvedSubject> {\n if (subject.type === \"org\") {\n const orgId = requiredString(subject.orgId, \"subject.orgId\");\n if (!access.orgId || access.orgId !== orgId) {\n throw new Error(\"Not authorized to manage a budget for that org\");\n }\n return { type: \"org\", id: orgId, partitionKey: `org:${orgId}`, orgId };\n }\n\n if (subject.type === \"user\") {\n const userEmail = normalizeEmail(subject.userEmail, \"subject.userEmail\");\n if (userEmail !== access.ownerEmail) {\n throw new Error(\"Not authorized to manage another user's budget\");\n }\n return {\n type: \"user\",\n id: userEmail,\n partitionKey: access.orgId\n ? `org:${access.orgId}`\n : `owner:${access.ownerEmail}`,\n orgId: access.orgId,\n };\n }\n\n const scope = await getIntegrationScope(subject.scope, access);\n if (!scope)\n throw new Error(\"Integration scope is not available to this caller\");\n return {\n type: \"scope\",\n id: integrationScopeSubjectKey(subject.scope),\n partitionKey: scope.orgId\n ? `org:${scope.orgId}`\n : `owner:${scope.ownerEmail}`,\n orgId: scope.orgId,\n };\n}\n\nfunction stableId(prefix: string, parts: unknown[]): string {\n return `${prefix}:${JSON.stringify(parts)}`;\n}\n\nfunction rowToBudget(row: Record<string, unknown>): IntegrationUsageBudget {\n return {\n id: String(row.id),\n subjectType: row.subject_type as IntegrationBudgetSubject[\"type\"],\n subjectId: String(row.subject_id),\n period: row.period as IntegrationBudgetPeriod,\n limitMicros: Number(row.limit_micros),\n thresholdBps: Number(row.threshold_bps),\n ownerEmail: String(row.owner_email),\n orgId: row.org_id == null ? null : String(row.org_id),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n };\n}\n\nfunction rowToReservation(row: Record<string, unknown>): ReservationRow {\n return {\n id: String(row.id),\n reservationKey: String(row.reservation_key),\n budgetId: String(row.budget_id),\n windowStart: Number(row.window_start),\n estimatedCostMicros: Number(row.estimated_cost_micros),\n settledCostMicros:\n row.settled_cost_micros == null ? null : Number(row.settled_cost_micros),\n status: row.status as IntegrationReservationStatus,\n };\n}\n\nfunction windowForPeriod(\n period: IntegrationBudgetPeriod,\n timestamp: number,\n): { start: number; end: number } {\n const date = new Date(timestamp);\n if (!Number.isFinite(date.getTime()))\n throw new Error(\"Invalid budget timestamp\");\n const start =\n period === \"day\"\n ? Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())\n : Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1);\n const end =\n period === \"day\"\n ? start + 24 * 60 * 60 * 1000\n : Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 1);\n return { start, end };\n}\n\nasync function withSerializedTransaction<T>(\n fn: (tx: DbExec) => Promise<T>,\n): Promise<T> {\n const previous = transactionTail;\n let release!: () => void;\n transactionTail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous.catch(() => {});\n const db = getDbExec();\n try {\n if (db.transaction) return await db.transaction(fn);\n await db.execute(isPostgres() ? \"BEGIN\" : \"BEGIN IMMEDIATE\");\n try {\n const result = await fn(db);\n await db.execute(\"COMMIT\");\n return result;\n } catch (error) {\n await db.execute(\"ROLLBACK\").catch(() => {});\n throw error;\n }\n } finally {\n release();\n }\n}\n\nasync function findBudget(\n db: DbExec,\n budgetId: string,\n access: Required<IntegrationScopeAccess>,\n): Promise<IntegrationUsageBudget | null> {\n const { rows } = await db.execute({\n sql: `SELECT id, subject_type, subject_id, period, limit_micros,\n threshold_bps, owner_email, org_id, created_at, updated_at\n FROM integration_usage_budgets\n WHERE id = ? AND ${authorizationSql()} LIMIT 1`,\n args: [budgetId, ...authorizationArgs(access)],\n });\n return rows.length > 0\n ? rowToBudget(rows[0] as Record<string, unknown>)\n : null;\n}\n\nasync function ensureWindow(\n db: DbExec,\n budgetId: string,\n windowStart: number,\n now: number,\n): Promise<void> {\n // SQLite and Postgres both support this exact conflict target. It is used\n // only as the atomic create-if-absent primitive for the counter row.\n await db.execute({\n sql: `INSERT INTO integration_usage_budget_windows\n (budget_id, window_start, used_micros, reserved_micros, updated_at)\n VALUES (?, ?, 0, 0, ?)\n ON CONFLICT (budget_id, window_start) DO NOTHING`,\n args: [budgetId, windowStart, now],\n });\n}\n\nasync function snapshotForBudget(\n db: DbExec,\n budget: IntegrationUsageBudget,\n timestamp: number,\n): Promise<IntegrationBudgetSnapshot> {\n const window = windowForPeriod(budget.period, timestamp);\n const { rows } = await db.execute({\n sql: `SELECT used_micros, reserved_micros\n FROM integration_usage_budget_windows\n WHERE budget_id = ? AND window_start = ? LIMIT 1`,\n args: [budget.id, window.start],\n });\n const usedMicros = rows.length > 0 ? Number(rows[0].used_micros) : 0;\n const reservedMicros = rows.length > 0 ? Number(rows[0].reserved_micros) : 0;\n return {\n budget,\n windowStart: window.start,\n windowEnd: window.end,\n usedMicros,\n reservedMicros,\n remainingMicros: Math.max(\n 0,\n budget.limitMicros - usedMicros - reservedMicros,\n ),\n costUnit: INTEGRATION_BUDGET_COST_UNIT,\n };\n}\n\nasync function emitThresholdEvent(\n db: DbExec,\n budget: IntegrationUsageBudget,\n snapshot: IntegrationBudgetSnapshot,\n now: number,\n): Promise<boolean> {\n const observedMicros = snapshot.usedMicros + snapshot.reservedMicros;\n if (observedMicros * 10_000 < budget.limitMicros * budget.thresholdBps) {\n return false;\n }\n const eventId = stableId(\"integration-budget-threshold\", [\n budget.id,\n snapshot.windowStart,\n budget.thresholdBps,\n ]);\n const result = await db.execute({\n sql: `INSERT INTO integration_usage_budget_events\n (id, budget_id, window_start, threshold_bps, observed_micros, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO NOTHING`,\n args: [\n eventId,\n budget.id,\n snapshot.windowStart,\n budget.thresholdBps,\n observedMicros,\n now,\n ],\n });\n return result.rowsAffected > 0;\n}\n\nexport async function saveIntegrationUsageBudget(\n input: {\n subject: IntegrationBudgetSubject;\n period: IntegrationBudgetPeriod;\n limitMicros: number;\n thresholdBps?: number;\n },\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationUsageBudget> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const subject = await resolveSubject(input.subject, access);\n const period = requirePeriod(input.period);\n const limitMicros = requireMicros(input.limitMicros, \"limitMicros\");\n const thresholdBps = requireThresholdBps(input.thresholdBps ?? 8_000);\n const id = stableId(\"integration-budget\", [\n subject.partitionKey,\n subject.type,\n subject.id,\n period,\n ]);\n const now = Date.now();\n\n await withSerializedTransaction(async (tx) => {\n // The stable id is derived entirely from the authorized partition. The\n // conflict update therefore cannot cross an owner/org boundary.\n await tx.execute({\n sql: `INSERT INTO integration_usage_budgets (\n id, partition_key, subject_type, subject_id, period, limit_micros,\n threshold_bps, owner_email, org_id, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n limit_micros = excluded.limit_micros,\n threshold_bps = excluded.threshold_bps,\n updated_at = excluded.updated_at`,\n args: [\n id,\n subject.partitionKey,\n subject.type,\n subject.id,\n period,\n limitMicros,\n thresholdBps,\n access.ownerEmail,\n subject.orgId,\n now,\n now,\n ],\n });\n });\n\n const saved = await getIntegrationUsageBudget(id, access);\n if (!saved) throw new Error(\"Integration budget write could not be verified\");\n return saved;\n}\n\nexport async function getIntegrationUsageBudget(\n budgetIdInput: string,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationUsageBudget | null> {\n await ensureTables();\n const budgetId = requiredString(budgetIdInput, \"budgetId\", 2_048);\n return findBudget(getDbExec(), budgetId, normalizeAccess(accessInput));\n}\n\n/** List budgets visible in the caller's personal/active-org partition. */\nexport async function listIntegrationUsageBudgets(\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationUsageBudget[]> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const { rows } = await getDbExec().execute({\n sql: `SELECT id, partition_key, subject_type, subject_id, period,\n limit_micros, threshold_bps, owner_email, org_id, created_at, updated_at\n FROM integration_usage_budgets\n WHERE ${authorizationSql()}\n ORDER BY updated_at DESC`,\n args: authorizationArgs(access),\n });\n return rows.map((row) => rowToBudget(row as Record<string, unknown>));\n}\n\nexport async function getIntegrationBudgetSnapshot(\n budgetIdInput: string,\n accessInput: IntegrationScopeAccess,\n timestamp = Date.now(),\n): Promise<IntegrationBudgetSnapshot | null> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budget = await findBudget(\n getDbExec(),\n requiredString(budgetIdInput, \"budgetId\", 2_048),\n access,\n );\n return budget ? snapshotForBudget(getDbExec(), budget, timestamp) : null;\n}\n\nexport async function reserveIntegrationUsageBudget(\n input: {\n budgetId: string;\n reservationId: string;\n estimatedCostMicros: number;\n timestamp?: number;\n },\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationBudgetReservationResult> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budgetId = requiredString(input.budgetId, \"budgetId\", 2_048);\n const reservationId = requiredString(\n input.reservationId,\n \"reservationId\",\n 512,\n );\n const estimatedCostMicros = requireMicros(\n input.estimatedCostMicros,\n \"estimatedCostMicros\",\n );\n const timestamp = input.timestamp ?? Date.now();\n\n return withSerializedTransaction(async (tx) => {\n const budget = await findBudget(tx, budgetId, access);\n if (!budget)\n throw new Error(\"Integration budget is not available to this caller\");\n const window = windowForPeriod(budget.period, timestamp);\n const now = Date.now();\n const storageId = stableId(\"integration-reservation\", [\n budget.id,\n reservationId,\n ]);\n\n const inserted = await tx.execute({\n sql: `INSERT INTO integration_usage_reservations (\n id, reservation_key, budget_id, window_start,\n estimated_cost_micros, settled_cost_micros, status,\n created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, NULL, 'pending', ?, ?)\n ON CONFLICT (id) DO NOTHING`,\n args: [\n storageId,\n reservationId,\n budget.id,\n window.start,\n estimatedCostMicros,\n now,\n now,\n ],\n });\n\n if (inserted.rowsAffected === 0) {\n const existing = await getReservation(tx, storageId, budget.id);\n if (!existing) {\n throw new Error(\"Reservation id is not available to this caller\");\n }\n if (existing.estimatedCostMicros !== estimatedCostMicros) {\n throw new Error(\n \"Reservation id was already used with a different estimate\",\n );\n }\n if (existing.windowStart !== window.start) {\n throw new Error(\n \"Reservation id was already used in a different budget window\",\n );\n }\n const snapshot = await snapshotForBudget(\n tx,\n budget,\n existing.windowStart,\n );\n return {\n allowed:\n existing.status === \"reserved\" || existing.status === \"settled\",\n reservationId,\n status: existing.status,\n estimatedCostMicros,\n settledCostMicros: existing.settledCostMicros,\n thresholdEventEmitted: false,\n snapshot,\n };\n }\n\n await ensureWindow(tx, budget.id, window.start, now);\n const reserved = await tx.execute({\n sql: `UPDATE integration_usage_budget_windows\n SET reserved_micros = reserved_micros + ?, updated_at = ?\n WHERE budget_id = ? AND window_start = ?\n AND used_micros + reserved_micros + ? <= ?`,\n args: [\n estimatedCostMicros,\n now,\n budget.id,\n window.start,\n estimatedCostMicros,\n budget.limitMicros,\n ],\n });\n const allowed = reserved.rowsAffected > 0;\n const status: IntegrationReservationStatus = allowed\n ? \"reserved\"\n : \"denied\";\n await tx.execute({\n sql: `UPDATE integration_usage_reservations\n SET status = ?, updated_at = ? WHERE id = ? AND status = 'pending'`,\n args: [status, now, storageId],\n });\n const snapshot = await snapshotForBudget(tx, budget, timestamp);\n const thresholdEventEmitted = allowed\n ? await emitThresholdEvent(tx, budget, snapshot, now)\n : false;\n return {\n allowed,\n reservationId,\n status,\n estimatedCostMicros,\n settledCostMicros: null,\n thresholdEventEmitted,\n snapshot,\n };\n });\n}\n\nasync function getReservation(\n db: DbExec,\n storageId: string,\n budgetId: string,\n): Promise<ReservationRow | null> {\n const { rows } = await db.execute({\n sql: `SELECT id, reservation_key, budget_id, window_start,\n estimated_cost_micros, settled_cost_micros, status\n FROM integration_usage_reservations\n WHERE id = ? AND budget_id = ? LIMIT 1`,\n args: [storageId, budgetId],\n });\n return rows.length > 0\n ? rowToReservation(rows[0] as Record<string, unknown>)\n : null;\n}\n\nexport async function settleIntegrationUsageBudget(\n input: {\n budgetId: string;\n reservationId: string;\n actualCostMicros: number;\n },\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationBudgetReservationResult> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budgetId = requiredString(input.budgetId, \"budgetId\", 2_048);\n const reservationId = requiredString(\n input.reservationId,\n \"reservationId\",\n 512,\n );\n const actualCostMicros = requireMicros(\n input.actualCostMicros,\n \"actualCostMicros\",\n true,\n );\n\n return withSerializedTransaction(async (tx) => {\n const budget = await findBudget(tx, budgetId, access);\n if (!budget)\n throw new Error(\"Integration budget is not available to this caller\");\n const storageId = stableId(\"integration-reservation\", [\n budget.id,\n reservationId,\n ]);\n const reservation = await getReservation(tx, storageId, budget.id);\n if (!reservation) {\n throw new Error(\"Integration budget reservation was not found\");\n }\n if (reservation.status === \"denied\" || reservation.status === \"released\") {\n throw new Error(`Cannot settle a ${reservation.status} reservation`);\n }\n if (reservation.status === \"pending\") {\n throw new Error(\"Cannot settle a pending reservation\");\n }\n if (\n reservation.status === \"settled\" &&\n reservation.settledCostMicros !== actualCostMicros\n ) {\n throw new Error(\"Reservation was already settled with a different cost\");\n }\n\n let thresholdEventEmitted = false;\n if (reservation.status === \"reserved\") {\n const now = Date.now();\n const updated = await tx.execute({\n sql: `UPDATE integration_usage_budget_windows SET\n reserved_micros = reserved_micros - ?,\n used_micros = used_micros + ?,\n updated_at = ?\n WHERE budget_id = ? AND window_start = ?\n AND reserved_micros >= ?`,\n args: [\n reservation.estimatedCostMicros,\n actualCostMicros,\n now,\n budget.id,\n reservation.windowStart,\n reservation.estimatedCostMicros,\n ],\n });\n if (updated.rowsAffected === 0) {\n throw new Error(\n \"Integration budget reservation counter is inconsistent\",\n );\n }\n await tx.execute({\n sql: `UPDATE integration_usage_reservations SET\n status = 'settled', settled_cost_micros = ?, updated_at = ?\n WHERE id = ? AND status = 'reserved'`,\n args: [actualCostMicros, now, reservation.id],\n });\n const thresholdSnapshot = await snapshotForBudget(\n tx,\n budget,\n reservation.windowStart,\n );\n thresholdEventEmitted = await emitThresholdEvent(\n tx,\n budget,\n thresholdSnapshot,\n now,\n );\n }\n\n const snapshot = await snapshotForBudget(\n tx,\n budget,\n reservation.windowStart,\n );\n return {\n allowed: true,\n reservationId,\n status: \"settled\",\n estimatedCostMicros: reservation.estimatedCostMicros,\n settledCostMicros: actualCostMicros,\n thresholdEventEmitted,\n snapshot,\n };\n });\n}\n\nexport async function releaseIntegrationUsageBudget(\n input: { budgetId: string; reservationId: string },\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationBudgetReservationResult> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budgetId = requiredString(input.budgetId, \"budgetId\", 2_048);\n const reservationId = requiredString(\n input.reservationId,\n \"reservationId\",\n 512,\n );\n\n return withSerializedTransaction(async (tx) => {\n const budget = await findBudget(tx, budgetId, access);\n if (!budget)\n throw new Error(\"Integration budget is not available to this caller\");\n const storageId = stableId(\"integration-reservation\", [\n budget.id,\n reservationId,\n ]);\n const reservation = await getReservation(tx, storageId, budget.id);\n if (!reservation) {\n throw new Error(\"Integration budget reservation was not found\");\n }\n if (reservation.status === \"settled\") {\n throw new Error(\"Cannot release a settled reservation\");\n }\n if (reservation.status === \"pending\") {\n throw new Error(\"Cannot release a pending reservation\");\n }\n\n if (reservation.status === \"reserved\") {\n const now = Date.now();\n const updated = await tx.execute({\n sql: `UPDATE integration_usage_budget_windows SET\n reserved_micros = reserved_micros - ?, updated_at = ?\n WHERE budget_id = ? AND window_start = ?\n AND reserved_micros >= ?`,\n args: [\n reservation.estimatedCostMicros,\n now,\n budget.id,\n reservation.windowStart,\n reservation.estimatedCostMicros,\n ],\n });\n if (updated.rowsAffected === 0) {\n throw new Error(\n \"Integration budget reservation counter is inconsistent\",\n );\n }\n await tx.execute({\n sql: `UPDATE integration_usage_reservations\n SET status = 'released', updated_at = ?\n WHERE id = ? AND status = 'reserved'`,\n args: [now, reservation.id],\n });\n }\n\n const snapshot = await snapshotForBudget(\n tx,\n budget,\n reservation.windowStart,\n );\n return {\n allowed: false,\n reservationId,\n status: reservation.status === \"denied\" ? \"denied\" : \"released\",\n estimatedCostMicros: reservation.estimatedCostMicros,\n settledCostMicros: reservation.settledCostMicros,\n thresholdEventEmitted: false,\n snapshot,\n };\n });\n}\n\nexport async function listIntegrationBudgetThresholdEvents(\n budgetIdInput: string,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationBudgetThresholdEvent[]> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budgetId = requiredString(budgetIdInput, \"budgetId\", 2_048);\n const budget = await findBudget(getDbExec(), budgetId, access);\n if (!budget) return [];\n const { rows } = await getDbExec().execute({\n sql: `SELECT id, budget_id, window_start, threshold_bps,\n observed_micros, created_at\n FROM integration_usage_budget_events\n WHERE budget_id = ? ORDER BY window_start DESC, created_at DESC`,\n args: [budget.id],\n });\n return rows.map((row) => ({\n id: String(row.id),\n budgetId: String(row.budget_id),\n windowStart: Number(row.window_start),\n thresholdBps: Number(row.threshold_bps),\n observedMicros: Number(row.observed_micros),\n createdAt: Number(row.created_at),\n }));\n}\n\n/** Test-only reset for suites that swap the injected database. */\nexport function _resetIntegrationUsageBudgetStoreForTests(): void {\n initPromise = undefined;\n transactionTail = Promise.resolve();\n}\n"]}
1
+ {"version":3,"file":"usage-budget-store.js","sourceRoot":"","sources":["../../src/integrations/usage-budget-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDbExec, intType, isPostgres, type DbExec } from \"../db/client.js\";\nimport { ensureIndexExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport {\n getIntegrationScope,\n integrationScopeSubjectKey,\n type IntegrationScopeAccess,\n type IntegrationScopeKey,\n} from \"./scope-store.js\";\n\nlet initPromise: Promise<void> | undefined;\nlet transactionTail: Promise<void> = Promise.resolve();\n\n/** All budget values are integer millionths of one billing currency unit. */\nexport const INTEGRATION_BUDGET_COST_UNIT = \"currency_micros\" as const;\n\nexport type IntegrationBudgetPeriod = \"day\" | \"month\";\nexport type IntegrationBudgetSubject =\n | { type: \"org\"; orgId: string }\n | { type: \"user\"; userEmail: string }\n | { type: \"scope\"; scope: IntegrationScopeKey };\n\nexport interface IntegrationUsageBudget {\n id: string;\n subjectType: IntegrationBudgetSubject[\"type\"];\n subjectId: string;\n period: IntegrationBudgetPeriod;\n /** Integer millionths of one billing currency unit. */\n limitMicros: number;\n /** Threshold in basis points: 8,000 means 80%. */\n thresholdBps: number;\n ownerEmail: string;\n orgId: string | null;\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface IntegrationBudgetSnapshot {\n budget: IntegrationUsageBudget;\n windowStart: number;\n windowEnd: number;\n usedMicros: number;\n reservedMicros: number;\n remainingMicros: number;\n costUnit: typeof INTEGRATION_BUDGET_COST_UNIT;\n}\n\nexport type IntegrationReservationStatus =\n | \"pending\"\n | \"reserved\"\n | \"denied\"\n | \"settled\"\n | \"released\";\n\nexport interface IntegrationBudgetReservationResult {\n allowed: boolean;\n reservationId: string;\n status: IntegrationReservationStatus;\n estimatedCostMicros: number;\n settledCostMicros: number | null;\n thresholdEventEmitted: boolean;\n snapshot: IntegrationBudgetSnapshot;\n}\n\nexport interface IntegrationBudgetThresholdEvent {\n id: string;\n budgetId: string;\n windowStart: number;\n thresholdBps: number;\n observedMicros: number;\n createdAt: number;\n}\n\ninterface ResolvedSubject {\n type: IntegrationBudgetSubject[\"type\"];\n id: string;\n partitionKey: string;\n orgId: string | null;\n}\n\ninterface ReservationRow {\n id: string;\n reservationKey: string;\n budgetId: string;\n windowStart: number;\n estimatedCostMicros: number;\n settledCostMicros: number | null;\n status: IntegrationReservationStatus;\n}\n\nasync function ensureTables(): Promise<void> {\n if (!initPromise) {\n initPromise = (async () => {\n const db = getDbExec();\n const budgetsSql = `CREATE TABLE IF NOT EXISTS integration_usage_budgets (\n id TEXT PRIMARY KEY,\n partition_key TEXT NOT NULL,\n subject_type TEXT NOT NULL,\n subject_id TEXT NOT NULL,\n period TEXT NOT NULL,\n limit_micros ${intType()} NOT NULL,\n threshold_bps ${intType()} NOT NULL DEFAULT 8000,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )`;\n const windowsSql = `CREATE TABLE IF NOT EXISTS integration_usage_budget_windows (\n budget_id TEXT NOT NULL,\n window_start ${intType()} NOT NULL,\n used_micros ${intType()} NOT NULL DEFAULT 0,\n reserved_micros ${intType()} NOT NULL DEFAULT 0,\n updated_at ${intType()} NOT NULL,\n PRIMARY KEY (budget_id, window_start)\n )`;\n const reservationsSql = `CREATE TABLE IF NOT EXISTS integration_usage_reservations (\n id TEXT PRIMARY KEY,\n reservation_key TEXT NOT NULL,\n budget_id TEXT NOT NULL,\n window_start ${intType()} NOT NULL,\n estimated_cost_micros ${intType()} NOT NULL,\n settled_cost_micros ${intType()},\n status TEXT NOT NULL,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )`;\n const eventsSql = `CREATE TABLE IF NOT EXISTS integration_usage_budget_events (\n id TEXT PRIMARY KEY,\n budget_id TEXT NOT NULL,\n window_start ${intType()} NOT NULL,\n threshold_bps ${intType()} NOT NULL,\n observed_micros ${intType()} NOT NULL,\n created_at ${intType()} NOT NULL\n )`;\n const indexes = [\n {\n name: \"idx_integration_budget_subject\",\n sql: \"CREATE UNIQUE INDEX IF NOT EXISTS idx_integration_budget_subject ON integration_usage_budgets(partition_key, subject_type, subject_id, period)\",\n },\n {\n name: \"idx_integration_budget_owner\",\n sql: \"CREATE INDEX IF NOT EXISTS idx_integration_budget_owner ON integration_usage_budgets(owner_email, subject_type)\",\n },\n {\n name: \"idx_integration_budget_org\",\n sql: \"CREATE INDEX IF NOT EXISTS idx_integration_budget_org ON integration_usage_budgets(org_id, subject_type)\",\n },\n {\n name: \"idx_integration_reservation_budget\",\n sql: \"CREATE INDEX IF NOT EXISTS idx_integration_reservation_budget ON integration_usage_reservations(budget_id, window_start, status)\",\n },\n {\n name: \"idx_integration_budget_event_window\",\n sql: \"CREATE UNIQUE INDEX IF NOT EXISTS idx_integration_budget_event_window ON integration_usage_budget_events(budget_id, window_start, threshold_bps)\",\n },\n ];\n\n if (isPostgres()) {\n await ensureTableExists(\"integration_usage_budgets\", budgetsSql);\n await ensureTableExists(\"integration_usage_budget_windows\", windowsSql);\n await ensureTableExists(\n \"integration_usage_reservations\",\n reservationsSql,\n );\n await ensureTableExists(\"integration_usage_budget_events\", eventsSql);\n for (const index of indexes) {\n await ensureIndexExists(index.name, index.sql);\n }\n return;\n }\n\n await db.execute(budgetsSql);\n await db.execute(windowsSql);\n await db.execute(reservationsSql);\n await db.execute(eventsSql);\n for (const index of indexes) await db.execute(index.sql);\n })().catch((error) => {\n initPromise = undefined;\n throw error;\n });\n }\n return initPromise;\n}\n\nfunction requiredString(value: unknown, name: string, maxLength = 512): string {\n const normalized = String(value ?? \"\").trim();\n if (!normalized) throw new Error(`${name} is required`);\n if (normalized.length > maxLength) {\n throw new Error(`${name} must be at most ${maxLength} characters`);\n }\n return normalized;\n}\n\nfunction normalizeEmail(value: unknown, name: string): string {\n const normalized = requiredString(value, name, 320).toLowerCase();\n if (!normalized.includes(\"@\")) {\n throw new Error(`${name} must be an email address`);\n }\n return normalized;\n}\n\nfunction normalizeAccess(\n access: IntegrationScopeAccess,\n): Required<IntegrationScopeAccess> {\n return {\n ownerEmail: normalizeEmail(access.ownerEmail, \"ownerEmail\"),\n orgId: access.orgId ? requiredString(access.orgId, \"orgId\") : null,\n };\n}\n\nfunction requireMicros(value: number, name: string, allowZero = false): number {\n if (!Number.isSafeInteger(value) || value < (allowZero ? 0 : 1)) {\n throw new Error(`${name} must be a safe integer in currency micros`);\n }\n return value;\n}\n\nfunction requireThresholdBps(value: number): number {\n if (!Number.isInteger(value) || value < 1 || value > 10_000) {\n throw new Error(\"thresholdBps must be an integer from 1 to 10000\");\n }\n return value;\n}\n\nfunction requirePeriod(\n value: IntegrationBudgetPeriod,\n): IntegrationBudgetPeriod {\n if (value !== \"day\" && value !== \"month\") {\n throw new Error(\"period must be day or month\");\n }\n return value;\n}\n\nfunction authorizationSql(alias = \"\"): string {\n const prefix = alias ? `${alias}.` : \"\";\n return `((${prefix}subject_type = 'user' AND ${prefix}owner_email = ?) OR (${prefix}subject_type <> 'user' AND ((${prefix}org_id = ? AND CAST(? AS TEXT) IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))))`;\n}\n\nfunction authorizationArgs(\n access: Required<IntegrationScopeAccess>,\n): unknown[] {\n return [access.ownerEmail, access.orgId, access.orgId, access.ownerEmail];\n}\n\nasync function resolveSubject(\n subject: IntegrationBudgetSubject,\n access: Required<IntegrationScopeAccess>,\n): Promise<ResolvedSubject> {\n if (subject.type === \"org\") {\n const orgId = requiredString(subject.orgId, \"subject.orgId\");\n if (!access.orgId || access.orgId !== orgId) {\n throw new Error(\"Not authorized to manage a budget for that org\");\n }\n return { type: \"org\", id: orgId, partitionKey: `org:${orgId}`, orgId };\n }\n\n if (subject.type === \"user\") {\n const userEmail = normalizeEmail(subject.userEmail, \"subject.userEmail\");\n if (userEmail !== access.ownerEmail) {\n throw new Error(\"Not authorized to manage another user's budget\");\n }\n return {\n type: \"user\",\n id: userEmail,\n partitionKey: access.orgId\n ? `org:${access.orgId}`\n : `owner:${access.ownerEmail}`,\n orgId: access.orgId,\n };\n }\n\n const scope = await getIntegrationScope(subject.scope, access);\n if (!scope)\n throw new Error(\"Integration scope is not available to this caller\");\n return {\n type: \"scope\",\n id: integrationScopeSubjectKey(subject.scope),\n partitionKey: scope.orgId\n ? `org:${scope.orgId}`\n : `owner:${scope.ownerEmail}`,\n orgId: scope.orgId,\n };\n}\n\nfunction stableId(prefix: string, parts: unknown[]): string {\n return `${prefix}:${JSON.stringify(parts)}`;\n}\n\nfunction rowToBudget(row: Record<string, unknown>): IntegrationUsageBudget {\n return {\n id: String(row.id),\n subjectType: row.subject_type as IntegrationBudgetSubject[\"type\"],\n subjectId: String(row.subject_id),\n period: row.period as IntegrationBudgetPeriod,\n limitMicros: Number(row.limit_micros),\n thresholdBps: Number(row.threshold_bps),\n ownerEmail: String(row.owner_email),\n orgId: row.org_id == null ? null : String(row.org_id),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n };\n}\n\nfunction rowToReservation(row: Record<string, unknown>): ReservationRow {\n return {\n id: String(row.id),\n reservationKey: String(row.reservation_key),\n budgetId: String(row.budget_id),\n windowStart: Number(row.window_start),\n estimatedCostMicros: Number(row.estimated_cost_micros),\n settledCostMicros:\n row.settled_cost_micros == null ? null : Number(row.settled_cost_micros),\n status: row.status as IntegrationReservationStatus,\n };\n}\n\nfunction windowForPeriod(\n period: IntegrationBudgetPeriod,\n timestamp: number,\n): { start: number; end: number } {\n const date = new Date(timestamp);\n if (!Number.isFinite(date.getTime()))\n throw new Error(\"Invalid budget timestamp\");\n const start =\n period === \"day\"\n ? Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())\n : Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1);\n const end =\n period === \"day\"\n ? start + 24 * 60 * 60 * 1000\n : Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 1);\n return { start, end };\n}\n\nasync function withSerializedTransaction<T>(\n fn: (tx: DbExec) => Promise<T>,\n): Promise<T> {\n const previous = transactionTail;\n let release!: () => void;\n transactionTail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous.catch(() => {});\n const db = getDbExec();\n try {\n if (db.transaction) return await db.transaction(fn);\n await db.execute(isPostgres() ? \"BEGIN\" : \"BEGIN IMMEDIATE\");\n try {\n const result = await fn(db);\n await db.execute(\"COMMIT\");\n return result;\n } catch (error) {\n await db.execute(\"ROLLBACK\").catch(() => {});\n throw error;\n }\n } finally {\n release();\n }\n}\n\nasync function findBudget(\n db: DbExec,\n budgetId: string,\n access: Required<IntegrationScopeAccess>,\n): Promise<IntegrationUsageBudget | null> {\n const { rows } = await db.execute({\n sql: `SELECT id, subject_type, subject_id, period, limit_micros,\n threshold_bps, owner_email, org_id, created_at, updated_at\n FROM integration_usage_budgets\n WHERE id = ? AND ${authorizationSql()} LIMIT 1`,\n args: [budgetId, ...authorizationArgs(access)],\n });\n return rows.length > 0\n ? rowToBudget(rows[0] as Record<string, unknown>)\n : null;\n}\n\nasync function ensureWindow(\n db: DbExec,\n budgetId: string,\n windowStart: number,\n now: number,\n): Promise<void> {\n // SQLite and Postgres both support this exact conflict target. It is used\n // only as the atomic create-if-absent primitive for the counter row.\n await db.execute({\n sql: `INSERT INTO integration_usage_budget_windows\n (budget_id, window_start, used_micros, reserved_micros, updated_at)\n VALUES (?, ?, 0, 0, ?)\n ON CONFLICT (budget_id, window_start) DO NOTHING`,\n args: [budgetId, windowStart, now],\n });\n}\n\nasync function snapshotForBudget(\n db: DbExec,\n budget: IntegrationUsageBudget,\n timestamp: number,\n): Promise<IntegrationBudgetSnapshot> {\n const window = windowForPeriod(budget.period, timestamp);\n const { rows } = await db.execute({\n sql: `SELECT used_micros, reserved_micros\n FROM integration_usage_budget_windows\n WHERE budget_id = ? AND window_start = ? LIMIT 1`,\n args: [budget.id, window.start],\n });\n const usedMicros = rows.length > 0 ? Number(rows[0].used_micros) : 0;\n const reservedMicros = rows.length > 0 ? Number(rows[0].reserved_micros) : 0;\n return {\n budget,\n windowStart: window.start,\n windowEnd: window.end,\n usedMicros,\n reservedMicros,\n remainingMicros: Math.max(\n 0,\n budget.limitMicros - usedMicros - reservedMicros,\n ),\n costUnit: INTEGRATION_BUDGET_COST_UNIT,\n };\n}\n\nasync function emitThresholdEvent(\n db: DbExec,\n budget: IntegrationUsageBudget,\n snapshot: IntegrationBudgetSnapshot,\n now: number,\n): Promise<boolean> {\n const observedMicros = snapshot.usedMicros + snapshot.reservedMicros;\n if (observedMicros * 10_000 < budget.limitMicros * budget.thresholdBps) {\n return false;\n }\n const eventId = stableId(\"integration-budget-threshold\", [\n budget.id,\n snapshot.windowStart,\n budget.thresholdBps,\n ]);\n const result = await db.execute({\n sql: `INSERT INTO integration_usage_budget_events\n (id, budget_id, window_start, threshold_bps, observed_micros, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO NOTHING`,\n args: [\n eventId,\n budget.id,\n snapshot.windowStart,\n budget.thresholdBps,\n observedMicros,\n now,\n ],\n });\n return result.rowsAffected > 0;\n}\n\nexport async function saveIntegrationUsageBudget(\n input: {\n subject: IntegrationBudgetSubject;\n period: IntegrationBudgetPeriod;\n limitMicros: number;\n thresholdBps?: number;\n },\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationUsageBudget> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const subject = await resolveSubject(input.subject, access);\n const period = requirePeriod(input.period);\n const limitMicros = requireMicros(input.limitMicros, \"limitMicros\");\n const thresholdBps = requireThresholdBps(input.thresholdBps ?? 8_000);\n const id = stableId(\"integration-budget\", [\n subject.partitionKey,\n subject.type,\n subject.id,\n period,\n ]);\n const now = Date.now();\n\n await withSerializedTransaction(async (tx) => {\n // The stable id is derived entirely from the authorized partition. The\n // conflict update therefore cannot cross an owner/org boundary.\n await tx.execute({\n sql: `INSERT INTO integration_usage_budgets (\n id, partition_key, subject_type, subject_id, period, limit_micros,\n threshold_bps, owner_email, org_id, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n limit_micros = excluded.limit_micros,\n threshold_bps = excluded.threshold_bps,\n updated_at = excluded.updated_at`,\n args: [\n id,\n subject.partitionKey,\n subject.type,\n subject.id,\n period,\n limitMicros,\n thresholdBps,\n access.ownerEmail,\n subject.orgId,\n now,\n now,\n ],\n });\n });\n\n const saved = await getIntegrationUsageBudget(id, access);\n if (!saved) throw new Error(\"Integration budget write could not be verified\");\n return saved;\n}\n\nexport async function getIntegrationUsageBudget(\n budgetIdInput: string,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationUsageBudget | null> {\n await ensureTables();\n const budgetId = requiredString(budgetIdInput, \"budgetId\", 2_048);\n return findBudget(getDbExec(), budgetId, normalizeAccess(accessInput));\n}\n\n/** List budgets visible in the caller's personal/active-org partition. */\nexport async function listIntegrationUsageBudgets(\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationUsageBudget[]> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const { rows } = await getDbExec().execute({\n sql: `SELECT id, partition_key, subject_type, subject_id, period,\n limit_micros, threshold_bps, owner_email, org_id, created_at, updated_at\n FROM integration_usage_budgets\n WHERE ${authorizationSql()}\n ORDER BY updated_at DESC`,\n args: authorizationArgs(access),\n });\n return rows.map((row) => rowToBudget(row as Record<string, unknown>));\n}\n\nexport async function getIntegrationBudgetSnapshot(\n budgetIdInput: string,\n accessInput: IntegrationScopeAccess,\n timestamp = Date.now(),\n): Promise<IntegrationBudgetSnapshot | null> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budget = await findBudget(\n getDbExec(),\n requiredString(budgetIdInput, \"budgetId\", 2_048),\n access,\n );\n return budget ? snapshotForBudget(getDbExec(), budget, timestamp) : null;\n}\n\nexport async function reserveIntegrationUsageBudget(\n input: {\n budgetId: string;\n reservationId: string;\n estimatedCostMicros: number;\n timestamp?: number;\n },\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationBudgetReservationResult> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budgetId = requiredString(input.budgetId, \"budgetId\", 2_048);\n const reservationId = requiredString(\n input.reservationId,\n \"reservationId\",\n 512,\n );\n const estimatedCostMicros = requireMicros(\n input.estimatedCostMicros,\n \"estimatedCostMicros\",\n );\n const timestamp = input.timestamp ?? Date.now();\n\n return withSerializedTransaction(async (tx) => {\n const budget = await findBudget(tx, budgetId, access);\n if (!budget)\n throw new Error(\"Integration budget is not available to this caller\");\n const window = windowForPeriod(budget.period, timestamp);\n const now = Date.now();\n const storageId = stableId(\"integration-reservation\", [\n budget.id,\n reservationId,\n ]);\n\n const inserted = await tx.execute({\n sql: `INSERT INTO integration_usage_reservations (\n id, reservation_key, budget_id, window_start,\n estimated_cost_micros, settled_cost_micros, status,\n created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, NULL, 'pending', ?, ?)\n ON CONFLICT (id) DO NOTHING`,\n args: [\n storageId,\n reservationId,\n budget.id,\n window.start,\n estimatedCostMicros,\n now,\n now,\n ],\n });\n\n if (inserted.rowsAffected === 0) {\n const existing = await getReservation(tx, storageId, budget.id);\n if (!existing) {\n throw new Error(\"Reservation id is not available to this caller\");\n }\n if (existing.estimatedCostMicros !== estimatedCostMicros) {\n throw new Error(\n \"Reservation id was already used with a different estimate\",\n );\n }\n if (existing.windowStart !== window.start) {\n throw new Error(\n \"Reservation id was already used in a different budget window\",\n );\n }\n const snapshot = await snapshotForBudget(\n tx,\n budget,\n existing.windowStart,\n );\n return {\n allowed:\n existing.status === \"reserved\" || existing.status === \"settled\",\n reservationId,\n status: existing.status,\n estimatedCostMicros,\n settledCostMicros: existing.settledCostMicros,\n thresholdEventEmitted: false,\n snapshot,\n };\n }\n\n await ensureWindow(tx, budget.id, window.start, now);\n const reserved = await tx.execute({\n sql: `UPDATE integration_usage_budget_windows\n SET reserved_micros = reserved_micros + ?, updated_at = ?\n WHERE budget_id = ? AND window_start = ?\n AND used_micros + reserved_micros + ? <= ?`,\n args: [\n estimatedCostMicros,\n now,\n budget.id,\n window.start,\n estimatedCostMicros,\n budget.limitMicros,\n ],\n });\n const allowed = reserved.rowsAffected > 0;\n const status: IntegrationReservationStatus = allowed\n ? \"reserved\"\n : \"denied\";\n await tx.execute({\n sql: `UPDATE integration_usage_reservations\n SET status = ?, updated_at = ? WHERE id = ? AND status = 'pending'`,\n args: [status, now, storageId],\n });\n const snapshot = await snapshotForBudget(tx, budget, timestamp);\n const thresholdEventEmitted = allowed\n ? await emitThresholdEvent(tx, budget, snapshot, now)\n : false;\n return {\n allowed,\n reservationId,\n status,\n estimatedCostMicros,\n settledCostMicros: null,\n thresholdEventEmitted,\n snapshot,\n };\n });\n}\n\nasync function getReservation(\n db: DbExec,\n storageId: string,\n budgetId: string,\n): Promise<ReservationRow | null> {\n const { rows } = await db.execute({\n sql: `SELECT id, reservation_key, budget_id, window_start,\n estimated_cost_micros, settled_cost_micros, status\n FROM integration_usage_reservations\n WHERE id = ? AND budget_id = ? LIMIT 1`,\n args: [storageId, budgetId],\n });\n return rows.length > 0\n ? rowToReservation(rows[0] as Record<string, unknown>)\n : null;\n}\n\nexport async function settleIntegrationUsageBudget(\n input: {\n budgetId: string;\n reservationId: string;\n actualCostMicros: number;\n },\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationBudgetReservationResult> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budgetId = requiredString(input.budgetId, \"budgetId\", 2_048);\n const reservationId = requiredString(\n input.reservationId,\n \"reservationId\",\n 512,\n );\n const actualCostMicros = requireMicros(\n input.actualCostMicros,\n \"actualCostMicros\",\n true,\n );\n\n return withSerializedTransaction(async (tx) => {\n const budget = await findBudget(tx, budgetId, access);\n if (!budget)\n throw new Error(\"Integration budget is not available to this caller\");\n const storageId = stableId(\"integration-reservation\", [\n budget.id,\n reservationId,\n ]);\n const reservation = await getReservation(tx, storageId, budget.id);\n if (!reservation) {\n throw new Error(\"Integration budget reservation was not found\");\n }\n if (reservation.status === \"denied\" || reservation.status === \"released\") {\n throw new Error(`Cannot settle a ${reservation.status} reservation`);\n }\n if (reservation.status === \"pending\") {\n throw new Error(\"Cannot settle a pending reservation\");\n }\n if (\n reservation.status === \"settled\" &&\n reservation.settledCostMicros !== actualCostMicros\n ) {\n throw new Error(\"Reservation was already settled with a different cost\");\n }\n\n let thresholdEventEmitted = false;\n if (reservation.status === \"reserved\") {\n const now = Date.now();\n const updated = await tx.execute({\n sql: `UPDATE integration_usage_budget_windows SET\n reserved_micros = reserved_micros - ?,\n used_micros = used_micros + ?,\n updated_at = ?\n WHERE budget_id = ? AND window_start = ?\n AND reserved_micros >= ?`,\n args: [\n reservation.estimatedCostMicros,\n actualCostMicros,\n now,\n budget.id,\n reservation.windowStart,\n reservation.estimatedCostMicros,\n ],\n });\n if (updated.rowsAffected === 0) {\n throw new Error(\n \"Integration budget reservation counter is inconsistent\",\n );\n }\n await tx.execute({\n sql: `UPDATE integration_usage_reservations SET\n status = 'settled', settled_cost_micros = ?, updated_at = ?\n WHERE id = ? AND status = 'reserved'`,\n args: [actualCostMicros, now, reservation.id],\n });\n const thresholdSnapshot = await snapshotForBudget(\n tx,\n budget,\n reservation.windowStart,\n );\n thresholdEventEmitted = await emitThresholdEvent(\n tx,\n budget,\n thresholdSnapshot,\n now,\n );\n }\n\n const snapshot = await snapshotForBudget(\n tx,\n budget,\n reservation.windowStart,\n );\n return {\n allowed: true,\n reservationId,\n status: \"settled\",\n estimatedCostMicros: reservation.estimatedCostMicros,\n settledCostMicros: actualCostMicros,\n thresholdEventEmitted,\n snapshot,\n };\n });\n}\n\nexport async function releaseIntegrationUsageBudget(\n input: { budgetId: string; reservationId: string },\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationBudgetReservationResult> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budgetId = requiredString(input.budgetId, \"budgetId\", 2_048);\n const reservationId = requiredString(\n input.reservationId,\n \"reservationId\",\n 512,\n );\n\n return withSerializedTransaction(async (tx) => {\n const budget = await findBudget(tx, budgetId, access);\n if (!budget)\n throw new Error(\"Integration budget is not available to this caller\");\n const storageId = stableId(\"integration-reservation\", [\n budget.id,\n reservationId,\n ]);\n const reservation = await getReservation(tx, storageId, budget.id);\n if (!reservation) {\n throw new Error(\"Integration budget reservation was not found\");\n }\n if (reservation.status === \"settled\") {\n throw new Error(\"Cannot release a settled reservation\");\n }\n if (reservation.status === \"pending\") {\n throw new Error(\"Cannot release a pending reservation\");\n }\n\n if (reservation.status === \"reserved\") {\n const now = Date.now();\n const updated = await tx.execute({\n sql: `UPDATE integration_usage_budget_windows SET\n reserved_micros = reserved_micros - ?, updated_at = ?\n WHERE budget_id = ? AND window_start = ?\n AND reserved_micros >= ?`,\n args: [\n reservation.estimatedCostMicros,\n now,\n budget.id,\n reservation.windowStart,\n reservation.estimatedCostMicros,\n ],\n });\n if (updated.rowsAffected === 0) {\n throw new Error(\n \"Integration budget reservation counter is inconsistent\",\n );\n }\n await tx.execute({\n sql: `UPDATE integration_usage_reservations\n SET status = 'released', updated_at = ?\n WHERE id = ? AND status = 'reserved'`,\n args: [now, reservation.id],\n });\n }\n\n const snapshot = await snapshotForBudget(\n tx,\n budget,\n reservation.windowStart,\n );\n return {\n allowed: false,\n reservationId,\n status: reservation.status === \"denied\" ? \"denied\" : \"released\",\n estimatedCostMicros: reservation.estimatedCostMicros,\n settledCostMicros: reservation.settledCostMicros,\n thresholdEventEmitted: false,\n snapshot,\n };\n });\n}\n\nexport async function listIntegrationBudgetThresholdEvents(\n budgetIdInput: string,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationBudgetThresholdEvent[]> {\n await ensureTables();\n const access = normalizeAccess(accessInput);\n const budgetId = requiredString(budgetIdInput, \"budgetId\", 2_048);\n const budget = await findBudget(getDbExec(), budgetId, access);\n if (!budget) return [];\n const { rows } = await getDbExec().execute({\n sql: `SELECT id, budget_id, window_start, threshold_bps,\n observed_micros, created_at\n FROM integration_usage_budget_events\n WHERE budget_id = ? ORDER BY window_start DESC, created_at DESC`,\n args: [budget.id],\n });\n return rows.map((row) => ({\n id: String(row.id),\n budgetId: String(row.budget_id),\n windowStart: Number(row.window_start),\n thresholdBps: Number(row.threshold_bps),\n observedMicros: Number(row.observed_micros),\n createdAt: Number(row.created_at),\n }));\n}\n\n/** Test-only reset for suites that swap the injected database. */\nexport function _resetIntegrationUsageBudgetStoreForTests(): void {\n initPromise = undefined;\n transactionTail = Promise.resolve();\n}\n"]}
@@ -9,6 +9,17 @@ export interface WebhookHandlerOptions {
9
9
  systemPrompt: string;
10
10
  /** Action entries for the agent */
11
11
  actions: Record<string, ActionEntry>;
12
+ /**
13
+ * Tool names to expose on the FIRST engine request. When provided, every
14
+ * other name in `actions` (framework additions such as
15
+ * `list-integration-memory` / `call-agent` merged in by
16
+ * `createIntegrationsPlugin`) is deferred behind the attached `tool-search`
17
+ * entry instead of being serialized on every inbound message — the run
18
+ * loop's mid-run tool expansion (`expandActiveTools` in `runAgentLoop`)
19
+ * still lets the model discover and call them after a search. Omit to keep
20
+ * the full `actions` set visible up front (current behavior).
21
+ */
22
+ initialToolNames?: string[];
12
23
  /** Model to use. Defaults to the resolved engine's default model. */
13
24
  model?: string;
14
25
  /** Anthropic API key */
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-handler.d.ts","sourceRoot":"","sources":["../../src/integrations/webhook-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAmBlC,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAC;AA6BtC,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8CnE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,eAAe,CAAC;IACzB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,CAAC,EACH,WAAW,GACX,MAAM,GACN;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IACtD,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,yEAAyE;IACzE,aAAa,CAAC,EAAE,CACd,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,eAAe,KACrB,OAAO,CACR;QACE,OAAO,EAAE,IAAI,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GACD;QAAE,OAAO,EAAE,KAAK,CAAA;KAAE,CACrB,CAAC;CACH;AAsCD,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,qBAAqB,CAAC,QAAQ,CAAC,EAC7C,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAyB7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CA0E5C;AA6ID;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAgCrD;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAgBf"}
1
+ {"version":3,"file":"webhook-handler.d.ts","sourceRoot":"","sources":["../../src/integrations/webhook-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAmBlC,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAC;AA8BtC,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8CnE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,eAAe,CAAC;IACzB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,CAAC,EACH,WAAW,GACX,MAAM,GACN;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IACtD,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,yEAAyE;IACzE,aAAa,CAAC,EAAE,CACd,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,eAAe,KACrB,OAAO,CACR;QACE,OAAO,EAAE,IAAI,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GACD;QAAE,OAAO,EAAE,KAAK,CAAA;KAAE,CACrB,CAAC;CACH;AAsCD,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,qBAAqB,CAAC,QAAQ,CAAC,EAC7C,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAyB7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CA0E5C;AA6ID;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAgCrD;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAgBf"}
@@ -4,10 +4,11 @@ import { formatLlmCredentialErrorMessage, isLlmCredentialError, } from "../agent
4
4
  import { getConfiguredEngineNameForRequest, getStoredModelForEngine, normalizeModelForEngine, resolveEngine, } from "../agent/engine/index.js";
5
5
  import { resolveMainChatMaxOutputTokens } from "../agent/engine/output-tokens.js";
6
6
  import { PROVIDER_TO_ENV } from "../agent/engine/provider-env-vars.js";
7
- import { runAgentLoop, actionsToEngineTools, getOwnerActiveApiKey, getOwnerApiKey, engineToProvider, } from "../agent/production-agent.js";
7
+ import { runAgentLoop, actionsToEngineTools, filterInitialEngineTools, getOwnerActiveApiKey, getOwnerApiKey, engineToProvider, } from "../agent/production-agent.js";
8
8
  import { startRun } from "../agent/run-manager.js";
9
9
  import { buildCurrentTimeUserContext, buildRuntimeContextPrompt, } from "../agent/runtime-context.js";
10
10
  import { buildAssistantMessage, extractThreadMeta, } from "../agent/thread-data-builder.js";
11
+ import { attachToolSearch } from "../agent/tool-search.js";
11
12
  import { createThread, getThread } from "../chat-threads/store.js";
12
13
  import { updateThreadData } from "../chat-threads/store.js";
13
14
  import { isLocalDatabase } from "../db/client.js";
@@ -392,7 +393,7 @@ async function recordInboundIntegrationAudit(task, incoming) {
392
393
  * Shared between the new processor endpoint and any direct callers.
393
394
  */
394
395
  async function processIncomingMessage(incoming, options, opts = {}) {
395
- const { adapter, systemPrompt, actions, model, apiKey, ownerEmail, engine: engineOption, } = options;
396
+ const { adapter, systemPrompt, actions, initialToolNames, model, apiKey, ownerEmail, engine: engineOption, } = options;
396
397
  let effectiveSystemPrompt = systemPrompt + buildRuntimeContextPrompt();
397
398
  // Resolve or create internal thread
398
399
  let mapping = await getThreadMapping(incoming.platform, incoming.externalThreadId);
@@ -542,10 +543,20 @@ async function processIncomingMessage(incoming, options, opts = {}) {
542
543
  // A2A delegation. Without this, getRequestOrgId() returns undefined and
543
544
  // call-agent can't look up the org's a2a_secret or org_domain.
544
545
  let orgId;
546
+ let runnableActions;
545
547
  let tools;
548
+ let availableTools;
546
549
  try {
547
550
  orgId = opts.orgId ?? (await resolveOrgIdForEmail(ownerEmail));
548
- tools = actionsToEngineTools(actions);
551
+ // Attach tool-search on a shallow copy so framework additions merged in
552
+ // by `createIntegrationsPlugin` (integration memory, `call-agent`) can be
553
+ // deferred behind it without mutating the plugin's long-lived registry.
554
+ // `runAgentLoop`'s `expandActiveTools` re-expands from `availableTools`
555
+ // after a tool-search call, so anything filtered out of the initial
556
+ // `tools` list stays reachable.
557
+ runnableActions = attachToolSearch({ ...actions });
558
+ availableTools = actionsToEngineTools(runnableActions);
559
+ tools = filterInitialEngineTools(availableTools, initialToolNames);
549
560
  }
550
561
  catch (error) {
551
562
  await releaseApplicableIntegrationBudgets(budgetReservations.reservations);
@@ -613,8 +624,9 @@ async function processIncomingMessage(incoming, options, opts = {}) {
613
624
  model: resolvedModel,
614
625
  systemPrompt: effectiveSystemPrompt,
615
626
  tools,
627
+ availableTools,
616
628
  messages,
617
- actions,
629
+ actions: runnableActions,
618
630
  send: async (event) => {
619
631
  if (progress) {
620
632
  await Promise.resolve(progress.onEvent(event)).catch(() => { });