@agent-native/core 0.98.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 (243) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +24 -0
  3. package/corpus/core/package.json +2 -2
  4. package/corpus/core/src/action-change-marker.ts +8 -1
  5. package/corpus/core/src/changelog/parse.ts +8 -3
  6. package/corpus/core/src/client/AgentPanel.tsx +2 -3
  7. package/corpus/core/src/client/AssistantChat.tsx +83 -39
  8. package/corpus/core/src/client/analytics.ts +29 -0
  9. package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +16 -2
  10. package/corpus/core/src/client/chat-model-groups.ts +28 -0
  11. package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +442 -85
  12. package/corpus/core/src/client/composer/TiptapComposer.tsx +46 -29
  13. package/corpus/core/src/client/composer/VoiceButton.tsx +2 -1
  14. package/corpus/core/src/client/composer/index.ts +5 -0
  15. package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +1206 -67
  16. package/corpus/core/src/client/index.ts +5 -0
  17. package/corpus/core/src/client/progress/RunsTray.tsx +13 -1
  18. package/corpus/core/src/client/settings/SecretsSection.tsx +387 -266
  19. package/corpus/core/src/client/settings/SettingsPanel.tsx +117 -38
  20. package/corpus/core/src/client/use-action.ts +12 -0
  21. package/corpus/core/src/client/use-agent-chat-home-handoff.ts +8 -1
  22. package/corpus/core/src/client/use-agent-engine-configured.ts +17 -3
  23. package/corpus/core/src/client/use-db-sync.ts +84 -34
  24. package/corpus/core/src/client/use-pausing-interval.ts +14 -4
  25. package/corpus/core/src/integrations/scope-store.ts +1 -1
  26. package/corpus/core/src/integrations/usage-budget-store.ts +1 -1
  27. package/corpus/core/src/localization/default-messages.ts +44 -1
  28. package/corpus/core/src/mcp-client/workspace-servers.ts +4 -4
  29. package/corpus/core/src/secrets/crypto.ts +28 -8
  30. package/corpus/core/src/server/action-change.ts +5 -1
  31. package/corpus/core/src/server/action-routes.ts +8 -0
  32. package/corpus/core/src/server/poll.ts +1 -0
  33. package/corpus/core/src/server/realtime-voice.ts +299 -13
  34. package/corpus/core/src/styles/agent-native.css +2 -2
  35. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
  36. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
  37. package/corpus/core/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
  39. package/corpus/core/src/vite/client.ts +9 -1
  40. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +2 -2
  41. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +10 -5
  42. package/corpus/templates/analytics/AGENTS.md +9 -13
  43. package/corpus/templates/analytics/actions/navigate.ts +59 -5
  44. package/corpus/templates/analytics/actions/view-screen.ts +3 -6
  45. package/corpus/templates/analytics/app/components/ProviderCorpusJobNotifier.tsx +20 -3
  46. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +2 -1
  47. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -1
  48. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +21 -6
  49. package/corpus/templates/analytics/app/global.css +19 -20
  50. package/corpus/templates/analytics/app/lib/provider-corpus-job-sync.ts +26 -0
  51. package/corpus/templates/analytics/app/pages/Settings.tsx +35 -341
  52. package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +38 -7
  53. package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +1 -1
  54. package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +3 -0
  55. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +333 -272
  56. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +72 -17
  57. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +297 -108
  58. package/corpus/templates/analytics/app/root.tsx +28 -8
  59. package/corpus/templates/analytics/changelog/2026-06-24-first-party-signup-and-pageview-panels-now-honor-dashboard-filters.md +2 -1
  60. package/corpus/templates/analytics/changelog/2026-06-25-referrer-dashboard-panels-show-external-domains.md +2 -1
  61. package/corpus/templates/analytics/changelog/2026-07-06-mobile-chat-header-is-more-compact-and-the-menu-button-opens-navigation.md +1 -0
  62. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-history-and-chat-context.md +1 -0
  63. package/corpus/templates/analytics/changelog/2026-07-08-settings-are-cleaner-searchable-and-alerts-have-their-own-tab.md +1 -0
  64. package/corpus/templates/analytics/changelog/2026-07-08-sidebar-sections-stay-collapsed-until-opened.md +1 -0
  65. package/corpus/templates/analytics/changelog/2026-07-11-analytics-no-longer-repeatedly-restarts-background-requests-.md +6 -0
  66. package/corpus/templates/analytics/changelog/2026-07-11-analytics-only-asks-for-replay-storage-when-you-enable-sessi.md +6 -0
  67. package/corpus/templates/analytics/changelog/2026-07-11-charts-now-show-their-loading-skeleton-while-refreshing.md +6 -0
  68. package/corpus/templates/analytics/changelog/2026-07-11-realtime-voice-now-shows-a-clear-connection-indicator-comple.md +6 -0
  69. package/corpus/templates/analytics/changelog/2026-07-11-replay-event-counts-stay-hidden-until-recordings-finish-load.md +6 -0
  70. package/corpus/templates/analytics/changelog/2026-07-11-replay-storage-key-mismatches-show-actionable-setup-guidance.md +6 -0
  71. package/corpus/templates/analytics/changelog/2026-07-11-replay-timelines-group-continuous-scrolling-and-dev-tools-co.md +6 -0
  72. package/corpus/templates/analytics/changelog/2026-07-11-session-filters-now-stay-compact-in-a-settings-menu-at-mediu.md +6 -0
  73. package/corpus/templates/analytics/changelog/2026-07-11-session-replay-console-errors-now-link-to-matching-issues-or.md +6 -0
  74. package/corpus/templates/analytics/changelog/2026-07-11-session-replays-load-large-recordings-faster-and-surface-fai.md +6 -0
  75. package/corpus/templates/analytics/changelog/2026-07-11-session-replays-preserve-recorded-styles-and-viewport-layout.md +6 -0
  76. package/corpus/templates/analytics/changelog/2026-07-11-session-replays-stay-centered-instead-of-clipping-wide-recor.md +6 -0
  77. package/corpus/templates/analytics/package.json +1 -1
  78. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +1 -303
  79. package/corpus/templates/analytics/server/handlers/session-replay.ts +57 -0
  80. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +1 -1
  81. package/corpus/templates/analytics/server/lib/demo-dashboards.ts +16 -3
  82. package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +12 -0
  83. package/corpus/templates/analytics/server/lib/session-replay.ts +208 -2
  84. package/corpus/templates/analytics/server/plugins/onboarding.ts +7 -79
  85. package/corpus/templates/analytics/server/routes/api/session-replay/recordings/[recordingId]/chunks.get.ts +1 -0
  86. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +2 -2
  87. package/corpus/templates/assets/app/global.css +4 -4
  88. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +0 -1
  89. package/corpus/templates/assets/app/routes/library.tsx +0 -1
  90. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +2 -2
  91. package/corpus/templates/brain/app/global.css +5 -5
  92. package/corpus/templates/brain/app/root.tsx +0 -3
  93. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +2 -2
  94. package/corpus/templates/calendar/app/root.tsx +1 -0
  95. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +2 -2
  96. package/corpus/templates/clips/app/hooks/use-auto-title.ts +74 -8
  97. package/corpus/templates/clips/app/hooks/use-library.ts +12 -25
  98. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +20 -22
  99. package/corpus/templates/clips/changelog/2026-07-11-generated-titles-no-longer-cause-continuous-background-refreshes.md +6 -0
  100. package/corpus/templates/clips/changelog/2026-07-11-s3-storage-setup-stays-collapsed-until-you-choose-it-as-the-.md +6 -0
  101. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +2 -2
  102. package/corpus/templates/content/app/hooks/use-comments.ts +0 -1
  103. package/corpus/templates/content/changelog/2026-07-11-comments-now-update-from-live-collaboration-events-without-c.md +6 -0
  104. package/corpus/templates/design/app/components/layout/Header.tsx +1 -1
  105. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +2 -2
  106. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -2
  107. package/corpus/templates/macros/app/root.tsx +0 -3
  108. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +2 -2
  109. package/corpus/templates/mail/app/hooks/use-compose-state.ts +1 -0
  110. package/corpus/templates/mail/app/root.tsx +1 -12
  111. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +2 -2
  112. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +5 -2
  113. package/corpus/templates/plan/app/hooks/use-plans.ts +6 -13
  114. package/corpus/templates/plan/app/pages/PlansPage.tsx +5 -27
  115. package/corpus/templates/plan/changelog/2026-07-11-plan-refreshes-only-when-content-changes.md +6 -0
  116. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +4 -1
  117. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +1 -1
  118. package/corpus/templates/slides/app/components/layout/Header.tsx +1 -1
  119. package/corpus/templates/slides/app/context/DeckContext.tsx +1 -0
  120. package/corpus/templates/slides/app/hooks/use-slide-comments.ts +7 -31
  121. package/corpus/templates/slides/changelog/2026-07-11-comments-now-update-from-live-collaboration-events-without-c.md +6 -0
  122. package/dist/action-change-marker.d.ts +1 -0
  123. package/dist/action-change-marker.d.ts.map +1 -1
  124. package/dist/action-change-marker.js +7 -1
  125. package/dist/action-change-marker.js.map +1 -1
  126. package/dist/changelog/parse.d.ts +4 -2
  127. package/dist/changelog/parse.d.ts.map +1 -1
  128. package/dist/changelog/parse.js +5 -3
  129. package/dist/changelog/parse.js.map +1 -1
  130. package/dist/client/AgentPanel.d.ts.map +1 -1
  131. package/dist/client/AgentPanel.js +2 -3
  132. package/dist/client/AgentPanel.js.map +1 -1
  133. package/dist/client/AssistantChat.d.ts +7 -0
  134. package/dist/client/AssistantChat.d.ts.map +1 -1
  135. package/dist/client/AssistantChat.js +62 -40
  136. package/dist/client/AssistantChat.js.map +1 -1
  137. package/dist/client/analytics.d.ts.map +1 -1
  138. package/dist/client/analytics.js +26 -0
  139. package/dist/client/analytics.js.map +1 -1
  140. package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
  141. package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
  142. package/dist/client/blocks/library/wireframe-kit.js +9 -2
  143. package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
  144. package/dist/client/chat-model-groups.d.ts.map +1 -1
  145. package/dist/client/chat-model-groups.js +24 -0
  146. package/dist/client/chat-model-groups.js.map +1 -1
  147. package/dist/client/composer/RealtimeVoiceMode.d.ts +40 -4
  148. package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -1
  149. package/dist/client/composer/RealtimeVoiceMode.js +172 -42
  150. package/dist/client/composer/RealtimeVoiceMode.js.map +1 -1
  151. package/dist/client/composer/TiptapComposer.d.ts +4 -0
  152. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  153. package/dist/client/composer/TiptapComposer.js +47 -29
  154. package/dist/client/composer/TiptapComposer.js.map +1 -1
  155. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  156. package/dist/client/composer/VoiceButton.js +2 -2
  157. package/dist/client/composer/VoiceButton.js.map +1 -1
  158. package/dist/client/composer/index.d.ts +2 -2
  159. package/dist/client/composer/index.d.ts.map +1 -1
  160. package/dist/client/composer/index.js +1 -1
  161. package/dist/client/composer/index.js.map +1 -1
  162. package/dist/client/composer/useRealtimeVoiceMode.d.ts +100 -3
  163. package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -1
  164. package/dist/client/composer/useRealtimeVoiceMode.js +952 -51
  165. package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -1
  166. package/dist/client/index.d.ts +1 -1
  167. package/dist/client/index.d.ts.map +1 -1
  168. package/dist/client/index.js +1 -1
  169. package/dist/client/index.js.map +1 -1
  170. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  171. package/dist/client/progress/RunsTray.js +10 -1
  172. package/dist/client/progress/RunsTray.js.map +1 -1
  173. package/dist/client/settings/SecretsSection.d.ts +2 -3
  174. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  175. package/dist/client/settings/SecretsSection.js +46 -22
  176. package/dist/client/settings/SecretsSection.js.map +1 -1
  177. package/dist/client/settings/SettingsPanel.d.ts +9 -0
  178. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  179. package/dist/client/settings/SettingsPanel.js +46 -12
  180. package/dist/client/settings/SettingsPanel.js.map +1 -1
  181. package/dist/client/use-action.d.ts +2 -0
  182. package/dist/client/use-action.d.ts.map +1 -1
  183. package/dist/client/use-action.js +10 -0
  184. package/dist/client/use-action.js.map +1 -1
  185. package/dist/client/use-agent-chat-home-handoff.d.ts +2 -0
  186. package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -1
  187. package/dist/client/use-agent-chat-home-handoff.js +7 -1
  188. package/dist/client/use-agent-chat-home-handoff.js.map +1 -1
  189. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  190. package/dist/client/use-agent-engine-configured.js +17 -3
  191. package/dist/client/use-agent-engine-configured.js.map +1 -1
  192. package/dist/client/use-db-sync.d.ts +8 -2
  193. package/dist/client/use-db-sync.d.ts.map +1 -1
  194. package/dist/client/use-db-sync.js +57 -32
  195. package/dist/client/use-db-sync.js.map +1 -1
  196. package/dist/client/use-pausing-interval.d.ts.map +1 -1
  197. package/dist/client/use-pausing-interval.js +16 -4
  198. package/dist/client/use-pausing-interval.js.map +1 -1
  199. package/dist/integrations/scope-store.js +1 -1
  200. package/dist/integrations/scope-store.js.map +1 -1
  201. package/dist/integrations/usage-budget-store.js +1 -1
  202. package/dist/integrations/usage-budget-store.js.map +1 -1
  203. package/dist/localization/default-messages.d.ts +41 -1
  204. package/dist/localization/default-messages.d.ts.map +1 -1
  205. package/dist/localization/default-messages.js +41 -1
  206. package/dist/localization/default-messages.js.map +1 -1
  207. package/dist/mcp-client/workspace-servers.js +4 -4
  208. package/dist/mcp-client/workspace-servers.js.map +1 -1
  209. package/dist/observability/routes.d.ts +5 -5
  210. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  211. package/dist/secrets/crypto.d.ts +7 -6
  212. package/dist/secrets/crypto.d.ts.map +1 -1
  213. package/dist/secrets/crypto.js +30 -11
  214. package/dist/secrets/crypto.js.map +1 -1
  215. package/dist/secrets/routes.d.ts +9 -9
  216. package/dist/server/action-change.d.ts +1 -0
  217. package/dist/server/action-change.d.ts.map +1 -1
  218. package/dist/server/action-change.js +4 -1
  219. package/dist/server/action-change.js.map +1 -1
  220. package/dist/server/action-routes.d.ts.map +1 -1
  221. package/dist/server/action-routes.js +5 -0
  222. package/dist/server/action-routes.js.map +1 -1
  223. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  224. package/dist/server/poll.d.ts.map +1 -1
  225. package/dist/server/poll.js +1 -0
  226. package/dist/server/poll.js.map +1 -1
  227. package/dist/server/realtime-voice.d.ts +7 -0
  228. package/dist/server/realtime-voice.d.ts.map +1 -1
  229. package/dist/server/realtime-voice.js +222 -12
  230. package/dist/server/realtime-voice.js.map +1 -1
  231. package/dist/styles/agent-native.css +2 -2
  232. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
  233. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
  234. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
  235. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
  236. package/dist/vite/client.d.ts.map +1 -1
  237. package/dist/vite/client.js +6 -1
  238. package/dist/vite/client.js.map +1 -1
  239. package/package.json +2 -2
  240. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
  241. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
  242. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
  243. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
@@ -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"]}
@@ -185,6 +185,7 @@ declare const messages: {
185
185
  cliRequiresDevMode: string;
186
186
  cliRequiresDevModeDescription: string;
187
187
  toggleAgent: string;
188
+ checkingAiConnection: string;
188
189
  voiceMode: {
189
190
  entryButtonLabel: string;
190
191
  promptTitle: string;
@@ -199,7 +200,45 @@ declare const messages: {
199
200
  showChat: string;
200
201
  hideChat: string;
201
202
  end: string;
202
- microphoneSettings: string;
203
+ voiceSettings: string;
204
+ settings: {
205
+ microphone: string;
206
+ defaultMicrophone: string;
207
+ microphoneSwitchFailed: string;
208
+ language: string;
209
+ autoLanguage: string;
210
+ languages: {
211
+ en: string;
212
+ es: string;
213
+ fr: string;
214
+ de: string;
215
+ it: string;
216
+ pt: string;
217
+ ja: string;
218
+ ko: string;
219
+ zh: string;
220
+ };
221
+ intelligence: string;
222
+ intelligenceLevels: {
223
+ instant: string;
224
+ balanced: string;
225
+ deep: string;
226
+ };
227
+ voiceStyle: string;
228
+ voiceChangePending: string;
229
+ voiceDescriptions: {
230
+ marin: string;
231
+ cedar: string;
232
+ coral: string;
233
+ sage: string;
234
+ verse: string;
235
+ alloy: string;
236
+ ash: string;
237
+ ballad: string;
238
+ echo: string;
239
+ shimmer: string;
240
+ };
241
+ };
203
242
  status: {
204
243
  connecting: string;
205
244
  listening: string;
@@ -213,6 +252,7 @@ declare const messages: {
213
252
  responseFailed: string;
214
253
  sessionFailed: string;
215
254
  channelDisconnected: string;
255
+ connectionTimedOut: string;
216
256
  connectionFailed: string;
217
257
  offerFailed: string;
218
258
  };
@@ -1 +1 @@
1
- {"version":3,"file":"default-messages.d.ts","sourceRoot":"","sources":["../../src/localization/default-messages.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"default-messages.d.ts","sourceRoot":"","sources":["../../src/localization/default-messages.ts"],"names":[],"mappings":"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"}
@@ -190,6 +190,7 @@ const messages = {
190
190
  cliRequiresDevMode: "CLI requires dev mode",
191
191
  cliRequiresDevModeDescription: "Run this app locally with pnpm dev or use Builder.io to access the CLI terminal.",
192
192
  toggleAgent: "Toggle agent",
193
+ checkingAiConnection: "Checking AI connection...",
193
194
  voiceMode: {
194
195
  entryButtonLabel: "Use microphone",
195
196
  promptTitle: "Talk to your app",
@@ -204,7 +205,45 @@ const messages = {
204
205
  showChat: "Show chat",
205
206
  hideChat: "Hide chat",
206
207
  end: "End voice mode",
207
- microphoneSettings: "Microphone settings",
208
+ voiceSettings: "Voice settings",
209
+ settings: {
210
+ microphone: "Microphone",
211
+ defaultMicrophone: "System default",
212
+ microphoneSwitchFailed: "Could not switch microphones. Your current microphone is still active.",
213
+ language: "Language",
214
+ autoLanguage: "Auto",
215
+ languages: {
216
+ en: "English",
217
+ es: "Spanish",
218
+ fr: "French",
219
+ de: "German",
220
+ it: "Italian",
221
+ pt: "Portuguese",
222
+ ja: "Japanese",
223
+ ko: "Korean",
224
+ zh: "Chinese",
225
+ },
226
+ intelligence: "Intelligence",
227
+ intelligenceLevels: {
228
+ instant: "Instant",
229
+ balanced: "Balanced",
230
+ deep: "Deep",
231
+ },
232
+ voiceStyle: "Voice style",
233
+ voiceChangePending: "Your new voice will apply next time you start voice mode.",
234
+ voiceDescriptions: {
235
+ marin: "Warm and natural",
236
+ cedar: "Clear and grounded",
237
+ coral: "Friendly and bright",
238
+ sage: "Calm and thoughtful",
239
+ verse: "Expressive and versatile",
240
+ alloy: "Balanced and neutral",
241
+ ash: "Smooth and confident",
242
+ ballad: "Warm and expressive",
243
+ echo: "Clear and direct",
244
+ shimmer: "Light and upbeat",
245
+ },
246
+ },
208
247
  status: {
209
248
  connecting: "Connecting",
210
249
  listening: "Listening",
@@ -218,6 +257,7 @@ const messages = {
218
257
  responseFailed: "OpenAI could not complete the voice response.",
219
258
  sessionFailed: "The realtime voice session encountered an error.",
220
259
  channelDisconnected: "The realtime voice control channel disconnected.",
260
+ connectionTimedOut: "The realtime voice connection timed out. Try again after the app finishes loading.",
221
261
  connectionFailed: "The realtime voice connection failed.",
222
262
  offerFailed: "The browser did not create an audio offer.",
223
263
  },