spine-framework 0.3.124 → 0.3.126

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 (319) hide show
  1. package/.framework/cli/commands/agents.ts +35 -37
  2. package/.framework/cli/commands/auth.ts +35 -34
  3. package/.framework/cli/commands/create-app.ts +104 -40
  4. package/.framework/cli/commands/dev.ts +104 -69
  5. package/.framework/cli/commands/doctor.ts +179 -69
  6. package/.framework/cli/commands/generate.ts +83 -143
  7. package/.framework/cli/commands/init.ts +72 -34
  8. package/.framework/cli/commands/install-app.ts +260 -125
  9. package/.framework/cli/commands/items.ts +33 -44
  10. package/.framework/cli/commands/migrate.ts +122 -40
  11. package/.framework/cli/commands/migrations.ts +33 -40
  12. package/.framework/cli/commands/pipelines.ts +31 -39
  13. package/.framework/cli/commands/status.ts +47 -23
  14. package/.framework/cli/commands/system.ts +47 -37
  15. package/.framework/cli/commands/test.ts +112 -68
  16. package/.framework/cli/commands/validate-app.ts +215 -121
  17. package/.framework/cli/context.ts +112 -130
  18. package/.framework/cli/env-loader.ts +47 -18
  19. package/.framework/cli/index.ts +81 -42
  20. package/.framework/docs/runtime-types.md +1024 -0
  21. package/.framework/functions/_shared/agent-runner.ts +1296 -961
  22. package/.framework/functions/_shared/app-manifest.ts +82 -68
  23. package/.framework/functions/_shared/audit.ts +135 -83
  24. package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
  25. package/.framework/functions/_shared/db.ts +80 -126
  26. package/.framework/functions/_shared/hash-api-key.ts +63 -0
  27. package/.framework/functions/_shared/index.ts +224 -335
  28. package/.framework/functions/_shared/kb.ts +319 -0
  29. package/.framework/functions/_shared/llm.ts +92 -0
  30. package/.framework/functions/_shared/logging.ts +288 -0
  31. package/.framework/functions/_shared/middleware.ts +329 -365
  32. package/.framework/functions/_shared/outcomes.ts +36 -0
  33. package/.framework/functions/_shared/permissions.ts +359 -643
  34. package/.framework/functions/_shared/pipeline-runner.ts +243 -316
  35. package/.framework/functions/_shared/principal.ts +376 -468
  36. package/.framework/functions/_shared/resolve-credentials.ts +102 -0
  37. package/.framework/functions/_shared/resolve-ids.ts +188 -16
  38. package/.framework/functions/_shared/retry-deliveries.ts +104 -0
  39. package/.framework/functions/_shared/schema-utils.ts +611 -373
  40. package/.framework/functions/_shared/testing.ts +207 -137
  41. package/.framework/functions/_shared/tracing.ts +276 -0
  42. package/.framework/functions/_shared/trigger-engine.ts +159 -211
  43. package/.framework/functions/_shared/webhook-registration.ts +95 -81
  44. package/.framework/functions/_shared/webhook-registry.ts +153 -75
  45. package/.framework/functions/account-nodes.ts +31 -53
  46. package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
  47. package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
  48. package/.framework/functions/adapters/openai-outbound.ts +40 -0
  49. package/.framework/functions/admin-data.ts +685 -537
  50. package/.framework/functions/admin-funnel.ts +31 -20
  51. package/.framework/functions/admin-install-funnel.ts +47 -28
  52. package/.framework/functions/admin-signals.ts +47 -29
  53. package/.framework/functions/ai-agents.ts +122 -147
  54. package/.framework/functions/ai-interactions.ts +180 -90
  55. package/.framework/functions/api-keys.ts +250 -192
  56. package/.framework/functions/apps.ts +203 -197
  57. package/.framework/functions/auth.ts +98 -91
  58. package/.framework/functions/cil-agent-ingest.ts +773 -0
  59. package/.framework/functions/cil-agent.ts +592 -0
  60. package/.framework/functions/cil-callmap.ts +1227 -0
  61. package/.framework/functions/cil-config.ts +583 -0
  62. package/.framework/functions/cil-context.ts +445 -0
  63. package/.framework/functions/cil-doc.ts +1752 -0
  64. package/.framework/functions/cil-embeddings.ts +1202 -0
  65. package/.framework/functions/cil-graph.ts +585 -0
  66. package/.framework/functions/cil-ingest.ts +2416 -0
  67. package/.framework/functions/cil-pipeline.ts +318 -0
  68. package/.framework/functions/cil-project.ts +499 -0
  69. package/.framework/functions/cil-validate.ts +469 -0
  70. package/.framework/functions/debug-auth.ts +73 -53
  71. package/.framework/functions/deliveries.ts +117 -0
  72. package/.framework/functions/embeddings.ts +528 -516
  73. package/.framework/functions/eval-harness.ts +158 -106
  74. package/.framework/functions/integration-outbound.ts +311 -0
  75. package/.framework/functions/integration-routes.ts +240 -466
  76. package/.framework/functions/integrations.ts +132 -140
  77. package/.framework/functions/invites.ts +401 -201
  78. package/.framework/functions/item-progress.ts +113 -53
  79. package/.framework/functions/kb.ts +28 -0
  80. package/.framework/functions/logs.ts +239 -222
  81. package/.framework/functions/observability.ts +308 -259
  82. package/.framework/functions/pipeline-executions.ts +179 -235
  83. package/.framework/functions/pipelines.ts +163 -205
  84. package/.framework/functions/prompt-configs.ts +109 -156
  85. package/.framework/functions/roles.ts +97 -147
  86. package/.framework/functions/system-cron.ts +132 -218
  87. package/.framework/functions/system.ts +112 -52
  88. package/.framework/functions/tests.ts +32 -28
  89. package/.framework/functions/timers.ts +162 -210
  90. package/.framework/functions/triggers.ts +282 -346
  91. package/.framework/functions/types.ts +283 -400
  92. package/.framework/migrations/001_core_schema.sql +630 -0
  93. package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
  94. package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
  95. package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
  96. package/.framework/migrations/005_core_observability.sql +598 -0
  97. package/.framework/migrations/006_security_hardening_rls.sql +97 -0
  98. package/.framework/migrations/007_kb_article_list.sql +237 -0
  99. package/.framework/migrations/008_items_target.sql +8 -0
  100. package/.framework/migrations/009_roles_slug_unique.sql +11 -0
  101. package/.framework/public/spine.config.json +91 -0
  102. package/.framework/scripts/app-install-cli.ts +112 -98
  103. package/.framework/src/App.tsx +67 -20
  104. package/.framework/src/apps/admin/index.tsx +97 -27
  105. package/.framework/src/components/AppWrapper.tsx +50 -11
  106. package/.framework/src/components/CustomAppLoader.tsx +131 -22
  107. package/.framework/src/components/admin/AdminListPage.tsx +75 -8
  108. package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
  109. package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
  110. package/.framework/src/components/admin/PageInstructions.tsx +49 -0
  111. package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
  112. package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
  113. package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
  114. package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
  115. package/.framework/src/components/app-sidebar.tsx +50 -3
  116. package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
  117. package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
  118. package/.framework/src/components/kb/KBArticleList.tsx +557 -0
  119. package/.framework/src/components/layout/AppShell.tsx +54 -16
  120. package/.framework/src/components/layout/Header.tsx +50 -38
  121. package/.framework/src/components/layout/Layout.tsx +48 -32
  122. package/.framework/src/components/layout/Sidebar.tsx +167 -16
  123. package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
  124. package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
  125. package/.framework/src/components/runtime/DataFilters.tsx +78 -1
  126. package/.framework/src/components/runtime/DataHeader.tsx +32 -29
  127. package/.framework/src/components/runtime/DataListPage.tsx +161 -2
  128. package/.framework/src/components/runtime/DataStats.tsx +48 -1
  129. package/.framework/src/components/runtime/DataTable.tsx +153 -1
  130. package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
  131. package/.framework/src/components/runtime/index.ts +16 -9
  132. package/.framework/src/components/search-form.tsx +33 -1
  133. package/.framework/src/components/shared/AgentView.tsx +48 -51
  134. package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
  135. package/.framework/src/components/shared/InviteManager.tsx +113 -52
  136. package/.framework/src/components/shared/MemberList.tsx +182 -0
  137. package/.framework/src/components/shared/SchemaFields.tsx +96 -78
  138. package/.framework/src/components/ui/DataTable.tsx +86 -56
  139. package/.framework/src/components/ui/Form.tsx +188 -109
  140. package/.framework/src/components/ui/ItemCard.tsx +86 -58
  141. package/.framework/src/components/ui/ItemListView.tsx +88 -61
  142. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
  143. package/.framework/src/components/ui/Modal.tsx +81 -4
  144. package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
  145. package/.framework/src/components/ui/accordion.tsx +97 -5
  146. package/.framework/src/components/ui/alert-dialog.tsx +225 -13
  147. package/.framework/src/components/ui/alert.tsx +113 -6
  148. package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
  149. package/.framework/src/components/ui/avatar.tsx +129 -7
  150. package/.framework/src/components/ui/badge.tsx +65 -3
  151. package/.framework/src/components/ui/breadcrumb.tsx +145 -8
  152. package/.framework/src/components/ui/button-group.tsx +81 -4
  153. package/.framework/src/components/ui/button.tsx +49 -2
  154. package/.framework/src/components/ui/calendar.tsx +65 -3
  155. package/.framework/src/components/ui/card.tsx +145 -8
  156. package/.framework/src/components/ui/carousel.tsx +129 -7
  157. package/.framework/src/components/ui/chart.tsx +161 -10
  158. package/.framework/src/components/ui/checkbox.tsx +49 -2
  159. package/.framework/src/components/ui/collapsible.tsx +81 -5
  160. package/.framework/src/components/ui/combobox.tsx +305 -20
  161. package/.framework/src/components/ui/command.tsx +177 -11
  162. package/.framework/src/components/ui/context-menu.tsx +273 -17
  163. package/.framework/src/components/ui/dialog.tsx +209 -27
  164. package/.framework/src/components/ui/direction.tsx +64 -4
  165. package/.framework/src/components/ui/drawer.tsx +193 -12
  166. package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
  167. package/.framework/src/components/ui/empty.tsx +145 -9
  168. package/.framework/src/components/ui/field.tsx +209 -14
  169. package/.framework/src/components/ui/hover-card.tsx +81 -4
  170. package/.framework/src/components/ui/input-group.tsx +162 -10
  171. package/.framework/src/components/ui/input-otp.tsx +98 -5
  172. package/.framework/src/components/ui/input.tsx +49 -2
  173. package/.framework/src/components/ui/item.tsx +225 -13
  174. package/.framework/src/components/ui/kbd.tsx +65 -3
  175. package/.framework/src/components/ui/label.tsx +49 -2
  176. package/.framework/src/components/ui/menubar.tsx +289 -17
  177. package/.framework/src/components/ui/native-select.tsx +97 -5
  178. package/.framework/src/components/ui/navigation-menu.tsx +177 -10
  179. package/.framework/src/components/ui/pagination.tsx +161 -9
  180. package/.framework/src/components/ui/popover.tsx +145 -8
  181. package/.framework/src/components/ui/progress.tsx +49 -2
  182. package/.framework/src/components/ui/radio-group.tsx +65 -3
  183. package/.framework/src/components/ui/resizable.tsx +82 -4
  184. package/.framework/src/components/ui/scroll-area.tsx +65 -3
  185. package/.framework/src/components/ui/select.tsx +193 -11
  186. package/.framework/src/components/ui/separator.tsx +49 -2
  187. package/.framework/src/components/ui/sheet.tsx +193 -11
  188. package/.framework/src/components/ui/sidebar.tsx +481 -38
  189. package/.framework/src/components/ui/skeleton.tsx +49 -2
  190. package/.framework/src/components/ui/slider.tsx +49 -2
  191. package/.framework/src/components/ui/sonner.tsx +49 -2
  192. package/.framework/src/components/ui/spinner.tsx +49 -2
  193. package/.framework/src/components/ui/switch.tsx +49 -2
  194. package/.framework/src/components/ui/table-primitives.tsx +160 -33
  195. package/.framework/src/components/ui/table.tsx +161 -9
  196. package/.framework/src/components/ui/tabs.tsx +113 -6
  197. package/.framework/src/components/ui/textarea.tsx +49 -2
  198. package/.framework/src/components/ui/toggle-group.tsx +81 -4
  199. package/.framework/src/components/ui/toggle.tsx +65 -3
  200. package/.framework/src/components/ui/tooltip.tsx +97 -5
  201. package/.framework/src/contexts/AppContext.tsx +129 -45
  202. package/.framework/src/contexts/AuthContext.tsx +187 -144
  203. package/.framework/src/hooks/use-mobile.ts +48 -2
  204. package/.framework/src/hooks/useApi.ts +208 -159
  205. package/.framework/src/hooks/useAppPath.ts +32 -23
  206. package/.framework/src/hooks/useApps.ts +51 -20
  207. package/.framework/src/hooks/useEntityList.ts +32 -78
  208. package/.framework/src/hooks/useEntityRecord.ts +35 -96
  209. package/.framework/src/hooks/useForm.ts +32 -92
  210. package/.framework/src/hooks/useListSchema.ts +49 -78
  211. package/.framework/src/hooks/useSchemaRecord.ts +114 -105
  212. package/.framework/src/lib/api.ts +195 -116
  213. package/.framework/src/lib/supabase.ts +98 -64
  214. package/.framework/src/lib/utils.ts +287 -151
  215. package/.framework/src/main.tsx +49 -3
  216. package/.framework/src/pages/DashboardPage.tsx +52 -29
  217. package/.framework/src/pages/NotFoundPage.tsx +32 -10
  218. package/.framework/src/pages/SetupPage.tsx +32 -12
  219. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
  220. package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
  221. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
  222. package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
  223. package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
  224. package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
  225. package/.framework/src/pages/admin/AppsPage.tsx +49 -2
  226. package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
  227. package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
  228. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
  229. package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
  230. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
  231. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
  232. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
  233. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
  234. package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
  235. package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
  236. package/.framework/src/pages/admin/LogsPage.tsx +422 -75
  237. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
  238. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
  239. package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
  240. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
  241. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
  242. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
  243. package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
  244. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
  245. package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
  246. package/.framework/src/pages/admin/RolesPage.tsx +171 -18
  247. package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
  248. package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
  249. package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
  250. package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
  251. package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
  252. package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
  253. package/.framework/src/pages/admin/TimersPage.tsx +48 -20
  254. package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
  255. package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
  256. package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
  257. package/.framework/src/pages/admin/TypesPage.tsx +48 -20
  258. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
  259. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
  260. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
  261. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
  262. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
  263. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
  264. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
  265. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
  266. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
  267. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  268. package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
  269. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
  270. package/.framework/src/pages/auth/LoginPage.tsx +50 -23
  271. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
  272. package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
  273. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
  274. package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
  275. package/.framework/src/types/auth.ts +128 -71
  276. package/.framework/src/types/types.ts +373 -157
  277. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
  278. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
  279. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
  280. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
  281. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
  282. package/docs/README.md +9 -130
  283. package/netlify.toml +5 -2
  284. package/package.json +13 -25
  285. package/scripts/kb-ingest-docs.ts +203 -0
  286. package/spine.config.json +65 -4
  287. package/.framework/migrations/001_schema.sql +0 -425
  288. package/.framework/migrations/002_rls_and_functions.sql +0 -763
  289. package/.framework/migrations/004_enhancements.sql +0 -43
  290. package/.framework/migrations/005_auth_user_trigger.sql +0 -105
  291. package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
  292. package/.framework/migrations/016_invites.sql +0 -27
  293. package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
  294. package/.framework/migrations/018_apps_required_roles.sql +0 -17
  295. package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
  296. package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
  297. package/.framework/migrations/021_app_domains.sql +0 -112
  298. package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
  299. package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
  300. package/.framework/migrations/024_messages_account_id.sql +0 -9
  301. package/.framework/migrations/025_retype_threads_messages.sql +0 -240
  302. package/.framework/migrations/026_fix_rls_policies.sql +0 -47
  303. package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
  304. package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
  305. package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
  306. package/.framework/migrations/030_messages_updated_by.sql +0 -6
  307. package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
  308. package/docs/APPS.md +0 -232
  309. package/docs/ARCHITECTURE.md +0 -246
  310. package/docs/INSTALL.md +0 -155
  311. package/docs/design-schema-spec.md +0 -1837
  312. package/docs/dev-guides/01-create-an-app.md +0 -183
  313. package/docs/dev-guides/02-create-a-function.md +0 -178
  314. package/docs/dev-guides/03-create-a-component.md +0 -178
  315. package/docs/dev-guides/04-webhook-handlers.md +0 -129
  316. package/docs/dev-guides/05-testing.md +0 -168
  317. package/docs/dev-guides/README.md +0 -40
  318. package/docs/npm-packages-plan.md +0 -288
  319. package/docs/spine-core--api-reference.md +0 -822
@@ -1,80 +1,68 @@
1
- /**
2
- * @module webhook-registration
3
- * @audience custom-developer
4
- * @layer shared-util
5
- * @stability stable
6
- *
7
- * Helper utilities for custom webhook handlers to self-register.
8
- * Use this in your custom Netlify functions to register as webhook handlers.
9
- *
10
- * **Usage in a custom function:**
11
- * ```ts
12
- * import { createHandler } from '../_shared/middleware'
13
- * import { registerWebhookHandler } from '../_shared/webhook-registration'
14
- * import { adminDb } from '../_shared/db'
15
- *
16
- * export const handler = createHandler(async (event, ctx) => {
17
- * // Your webhook logic here
18
- * })
19
- *
20
- * // Self-register on first load (idempotent)
21
- * registerWebhookHandler({
22
- * name: 'my-custom-handler',
23
- * functionName: 'custom_my-webhook',
24
- * description: 'Handles my custom integration events',
25
- * events: ['user.created', 'item.updated'],
26
- * db: adminDb
27
- * }).catch(console.error)
28
- * ```
29
- *
30
- * @seeAlso webhook-registry.ts (core lookup service)
31
- * @seeAlso 014_webhook_registry.sql (database table)
32
- */
33
1
 
34
- import { adminDb } from './db'
35
2
 
3
+
4
+
5
+ // CIL[BEGIN chunk_id="webhookregistration_imports_1784020784" type="module_header" identity="imports" parent="none"]
6
+ // CIL[DOC-MACRO purpose="Import database dependency for webhook registration"]
7
+ // CIL[DOC-RESPONSIBILITY responsibility="Import adminDb for database operations"]
8
+ // CIL[DOC-CONTEXT module="webhook-registration" layer="shared" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"\\\"]"]
9
+ // CIL[DOC-CONTRACT inputs="none" outputs="adminDb" errors="none" side_effects="none"]
10
+ // CIL[DOC-MICRO logic_summary="Import database connection for webhook handler management" notable_decisions="[]"]
11
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
12
+ // CIL[DOC-STABILITY stability="stable"]
13
+ // CIL[DOC-AUDIENCE audience="developer"]
14
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, \."]
15
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
16
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
17
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
18
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
19
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
20
+ import { adminDb } from './db'
21
+ // CIL[END chunk_id="webhookregistration_imports_1784020784"]
22
+ // CIL[BEGIN chunk_id="webhookregistration_interface_1784020784" type="interface" identity="WebhookHandlerRegistration" parent="none"]
23
+ // CIL[DOC-MACRO purpose="Define webhook handler registration interface"]
24
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide structure for webhook handler configuration"]
25
+ // CIL[DOC-CONTEXT module="webhook-registration" layer="shared" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"\\\"]"]
26
+ // CIL[DOC-CONTRACT inputs="none" outputs="WebhookHandlerRegistration interface" errors="none" side_effects="none"]
27
+ // CIL[DOC-MICRO logic_summary="Interface with handler metadata, events, and optional database" notable_decisions="[]"]
28
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
29
+ // CIL[DOC-STABILITY stability="stable"]
30
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, \."]
31
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
32
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
33
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
34
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
35
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
36
36
  export interface WebhookHandlerRegistration {
37
- /** Unique handler identifier (e.g., 'cortex-handler') */
38
37
  name: string
39
-
40
- /** Netlify function name (e.g., 'custom_cortex-handler') */
41
38
  functionName: string
42
-
43
- /** Human-readable description */
44
39
  description?: string
45
-
46
- /** Events this handler subscribes to */
47
40
  events?: string[]
48
-
49
- /** Account ID (null for system handlers) */
41
+ appId?: string | null
50
42
  accountId?: string | null
51
-
52
- /** Database client (defaults to adminDb) */
43
+ isSystem?: boolean
53
44
  db?: typeof adminDb
54
45
  }
55
-
56
- /**
57
- * Registers a webhook handler in the database registry.
58
- * Idempotent - safe to call multiple times.
59
- *
60
- * @param config - Handler registration configuration
61
- * @returns Promise that resolves when registration completes
62
- *
63
- * @example
64
- * ```ts
65
- * await registerWebhookHandler({
66
- * name: 'slack-webhook',
67
- * functionName: 'custom_slack-integration',
68
- * description: 'Posts notifications to Slack',
69
- * events: ['item.created', 'item.updated']
70
- * })
71
- * ```
72
- */
46
+ // CIL[END chunk_id="webhookregistration_interface_1784020784"]
47
+ // CIL[BEGIN chunk_id="webhookregistration_registerwebhookhandler_1784020784" type="function" identity="registerWebhookHandler" parent="none"]
48
+ // CIL[DOC-MACRO purpose="Register webhook handler in database"]
49
+ // CIL[DOC-RESPONSIBILITY responsibility="Create or update webhook handler record"]
50
+ // CIL[DOC-CONTEXT module="webhook-registration" layer="shared" related_files="[\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"\\\"]"]
51
+ // CIL[DOC-CONTRACT inputs="none" outputs="void" errors="database errors" side_effects="database update"]
52
+ // CIL[DOC-MICRO logic_summary="Upserts handler record with metadata and activation status" notable_decisions="[]"]
53
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
54
+ // CIL[DOC-STABILITY stability="stable"]
55
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/functions/custom_cil-embeddings.ts, \."]
56
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
57
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
58
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
59
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
60
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
73
61
  export async function registerWebhookHandler(
74
62
  config: WebhookHandlerRegistration
75
63
  ): Promise<void> {
76
64
  const db = config.db || adminDb
77
-
65
+
78
66
  try {
79
67
  const { error } = await db
80
68
  .from('webhook_handlers')
@@ -83,12 +71,15 @@ export async function registerWebhookHandler(
83
71
  function_name: config.functionName,
84
72
  description: config.description || `${config.name} webhook handler`,
85
73
  events: config.events || [],
74
+ app_id: config.appId || null,
86
75
  account_id: config.accountId || null,
76
+ is_system: config.isSystem || false,
87
77
  is_active: true,
88
78
  is_deleted: false,
89
- updated_at: new Date().toISOString()
79
+ updated_at: new Date().toISOString(),
80
+ created_at: new Date().toISOString()
90
81
  }, {
91
- onConflict: 'name'
82
+ onConflict: 'app_id,account_id,name'
92
83
  })
93
84
 
94
85
  if (error) {
@@ -102,19 +93,29 @@ export async function registerWebhookHandler(
102
93
  throw err
103
94
  }
104
95
  }
105
-
106
- /**
107
- * Deregisters a webhook handler (soft delete).
108
- *
109
- * @param name - Handler identifier to deregister
110
- * @param db - Optional database client
111
- */
96
+ // CIL[END chunk_id="webhookregistration_registerwebhookhandler_1784020784"]
97
+ // CIL[BEGIN chunk_id="webhookregistration_deregisterwebhookhandler_1784020784" type="function" identity="deregisterWebhookHandler" parent="none"]
98
+ // CIL[DOC-MACRO purpose="Deregister webhook handler from database"]
99
+ // CIL[DOC-RESPONSIBILITY responsibility="Soft delete webhook handler record"]
100
+ // CIL[DOC-CONTEXT module="webhook-registration" layer="shared" related_files="[\"\\\"]"]
101
+ // CIL[DOC-CONTRACT inputs="none" outputs="void" errors="database errors" side_effects="database update"]
102
+ // CIL[DOC-MICRO logic_summary="Updates handler to inactive and deleted status" notable_decisions="[]"]
103
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
104
+ // CIL[DOC-STABILITY stability="stable"]
105
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: \."]
106
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
107
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
108
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
109
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
110
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
112
111
  export async function deregisterWebhookHandler(
113
112
  name: string,
113
+ appId: string | null = null,
114
+ accountId: string | null = null,
114
115
  db: typeof adminDb = adminDb
115
116
  ): Promise<void> {
116
117
  try {
117
- const { error } = await db
118
+ let query = db
118
119
  .from('webhook_handlers')
119
120
  .update({
120
121
  is_active: false,
@@ -123,6 +124,11 @@ export async function deregisterWebhookHandler(
123
124
  })
124
125
  .eq('name', name)
125
126
 
127
+ if (appId !== undefined) query = query.eq('app_id', appId)
128
+ if (accountId !== undefined) query = query.eq('account_id', accountId)
129
+
130
+ const { error } = await query
131
+
126
132
  if (error) {
127
133
  console.error(`[webhook-registration] Failed to deregister ${name}:`, error)
128
134
  throw error
@@ -134,14 +140,21 @@ export async function deregisterWebhookHandler(
134
140
  throw err
135
141
  }
136
142
  }
137
-
138
- /**
139
- * Checks if a handler is registered.
140
- *
141
- * @param name - Handler identifier to check
142
- * @param db - Optional database client
143
- * @returns True if handler exists and is active
144
- */
143
+ // CIL[END chunk_id="webhookregistration_deregisterwebhookhandler_1784020784"]
144
+ // CIL[BEGIN chunk_id="webhookregistration_ishandlerregistered_1784020784" type="function" identity="isHandlerRegistered" parent="none"]
145
+ // CIL[DOC-MACRO purpose="Check if webhook handler is registered and active"]
146
+ // CIL[DOC-RESPONSIBILITY responsibility="Verify handler registration status"]
147
+ // CIL[DOC-CONTEXT module="webhook-registration" layer="shared" related_files="[\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\"]"]
148
+ // CIL[DOC-CONTRACT inputs="none" outputs="boolean" errors="database errors" side_effects="none"]
149
+ // CIL[DOC-MICRO logic_summary="Queries webhook_handlers table for active, non-deleted handler" notable_decisions="[]"]
150
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
151
+ // CIL[DOC-STABILITY stability="stable"]
152
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: .framework/migrations/015_simplify_apps_table.sql, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx."]
153
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
154
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
155
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
156
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
157
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
145
158
  export async function isHandlerRegistered(
146
159
  name: string,
147
160
  db: typeof adminDb = adminDb
@@ -166,3 +179,4 @@ export async function isHandlerRegistered(
166
179
  return false
167
180
  }
168
181
  }
182
+ // CIL[END chunk_id="webhookregistration_ishandlerregistered_1784020784"]
@@ -1,85 +1,129 @@
1
- /**
2
- * @module webhook-registry
3
- * @audience core-contributor
4
- * @layer shared-service
5
- * @stability stable
6
- *
7
- * Dynamic webhook handler registry for runtime handler resolution.
8
- * Replaces static imports with database-driven handler lookups.
9
- *
10
- * **Pattern:**
11
- * 1. Custom handlers self-register via `integrations` table or `webhook_handlers` table
12
- * 2. Core looks up handler by name at runtime
13
- * 3. Dynamic import loads the handler function
14
- *
15
- * **Benefits:**
16
- * - Core has zero hardcoded dependencies on custom handlers
17
- * - Handlers can be added/removed without core code changes
18
- * - Multi-tenancy: different tenants can have different handlers
19
- *
20
- * @seeAlso integration-routes.ts (uses this registry)
21
- * @seeAlso custom_webhook-handlers.ts (legacy static registry - being phased out)
22
- */
23
1
 
2
+
3
+
4
+
5
+
6
+ // CIL[BEGIN chunk_id="webhookregistry_imports_1784020784" type="module_header" identity="imports" parent="none"]
7
+ // CIL[DOC-MACRO purpose="Import database dependency and initialize handler cache"]
8
+ // CIL[DOC-RESPONSIBILITY responsibility="Import adminDb and create handler caching system"]
9
+ // CIL[DOC-CONTEXT module="webhook-registry" layer="shared" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
10
+ // CIL[DOC-CONTRACT inputs="none" outputs="adminDb, handlerCache" errors="none" side_effects="none"]
11
+ // CIL[DOC-MICRO logic_summary="Import database and initialize Map for handler metadata caching" notable_decisions="[]"]
12
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
13
+ // CIL[DOC-STABILITY stability="stable"]
14
+ // CIL[DOC-AUDIENCE audience="developer"]
15
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/src/components/ui/dialog.tsx, \."]
16
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
17
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
18
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
19
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
20
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
24
21
  import { adminDb } from './db'
25
22
 
26
- // In-memory cache for handler metadata (not the handlers themselves)
27
- const handlerCache = new Map<string, { functionName: string; loaded: boolean }>()
28
-
29
- /**
30
- * Looks up a webhook handler in the database registry.
31
- * Returns the function name to dynamically import.
32
- *
33
- * @param handlerName - The handler identifier (e.g., "cortex-handler")
34
- * @returns Handler metadata or null if not found
35
- */
36
- export async function lookupHandler(handlerName: string): Promise<{ functionName: string } | null> {
37
- // Check cache first
38
- const cached = handlerCache.get(handlerName)
23
+ interface HandlerCacheEntry {
24
+ functionName: string
25
+ loaded: boolean
26
+ }
27
+
28
+ const handlerCache = new Map<string, HandlerCacheEntry>()
29
+ // CIL[END chunk_id="webhookregistry_imports_1784020784"]
30
+ // CIL[BEGIN chunk_id="webhookregistry_lookuphandler_1784020784" type="function" identity="lookupHandler" parent="none"]
31
+ // CIL[DOC-MACRO purpose="Lookup webhook handler metadata with caching"]
32
+ // CIL[DOC-RESPONSIBILITY responsibility="Find handler function name in database with cache optimization"]
33
+ // CIL[DOC-CONTEXT module="webhook-registry" layer="shared" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
34
+ // CIL[DOC-CONTRACT inputs="none" outputs="function name or null" errors="database errors" side_effects="cache update"]
35
+ // CIL[DOC-MICRO logic_summary="Checks cache first, queries webhook_handlers table, caches result" notable_decisions="[]"]
36
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
37
+ // CIL[DOC-STABILITY stability="stable"]
38
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
39
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
40
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
41
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
42
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
43
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
44
+ export async function lookupHandler(
45
+ handlerName: string,
46
+ appId?: string | null,
47
+ accountId?: string | null
48
+ ): Promise<{ functionName: string } | null> {
49
+ const cacheKey = `${appId || 'null'}:${accountId || 'null'}:${handlerName}`
50
+ const cached = handlerCache.get(cacheKey)
39
51
  if (cached) {
40
52
  return { functionName: cached.functionName }
41
53
  }
42
54
 
43
- // Query database for handler registration
44
- const { data, error } = await adminDb
55
+ let query = adminDb
45
56
  .from('webhook_handlers')
46
- .select('name, function_name, is_active')
57
+ .select('name, function_name, is_active, is_deleted')
47
58
  .eq('name', handlerName)
48
59
  .eq('is_active', true)
49
- .single()
60
+ .eq('is_deleted', false)
61
+
62
+ if (appId !== undefined) {
63
+ query = query.eq('app_id', appId)
64
+ }
65
+ if (accountId !== undefined) {
66
+ query = query.eq('account_id', accountId)
67
+ }
68
+
69
+ const { data, error } = await query.single()
50
70
 
71
+ // Fallback to a global / system handler if no app- or account-scoped one exists.
51
72
  if (error || !data) {
52
- console.log(`[webhook-registry] Handler not found: ${handlerName}`)
53
- return null
73
+ const { data: fallbackData, error: fallbackError } = await adminDb
74
+ .from('webhook_handlers')
75
+ .select('name, function_name, is_active, is_deleted')
76
+ .eq('name', handlerName)
77
+ .eq('is_active', true)
78
+ .eq('is_deleted', false)
79
+ .is('app_id', null)
80
+ .is('account_id', null)
81
+ .single()
82
+
83
+ if (fallbackError || !fallbackData) {
84
+ console.log(`[webhook-registry] Handler not found: ${handlerName} (appId=${appId}, accountId=${accountId})`)
85
+ return null
86
+ }
87
+
88
+ handlerCache.set(cacheKey, {
89
+ functionName: fallbackData.function_name,
90
+ loaded: false
91
+ })
92
+
93
+ return { functionName: fallbackData.function_name }
54
94
  }
55
95
 
56
- // Cache the result
57
- handlerCache.set(handlerName, {
96
+ handlerCache.set(cacheKey, {
58
97
  functionName: data.function_name,
59
98
  loaded: false
60
99
  })
61
100
 
62
101
  return { functionName: data.function_name }
63
102
  }
64
-
65
- /**
66
- * Loads a webhook handler function dynamically.
67
- * Uses dynamic import to avoid static dependencies.
68
- *
69
- * @param functionName - The Netlify function name (e.g., "custom_cortex-handler")
70
- * @returns The handler function or null if not found
71
- */
103
+ // CIL[END chunk_id="webhookregistry_lookuphandler_1784020784"]
104
+ // CIL[BEGIN chunk_id="webhookregistry_loadhandler_1784020784" type="function" identity="loadHandler" parent="none"]
105
+ // CIL[DOC-MACRO purpose="Dynamically load webhook handler function from module"]
106
+ // CIL[DOC-RESPONSIBILITY responsibility="Import and validate handler function from file system"]
107
+ // CIL[DOC-CONTEXT module="webhook-registry" layer="shared" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/migrations/025_retype_threads_messages.sql\",\"\\\"]"]
108
+ // CIL[DOC-CONTRACT inputs="none" outputs="Function or null" errors="import errors" side_effects="module loading"]
109
+ // CIL[DOC-MICRO logic_summary="Dynamic import with handler/default export validation" notable_decisions="[]"]
110
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
111
+ // CIL[DOC-STABILITY stability="stable"]
112
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/principal.ts, .framework/migrations/025_retype_threads_messages.sql, \."]
113
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
114
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
115
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
116
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
117
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
72
118
  export async function loadHandler(functionName: string): Promise<Function | null> {
73
119
  try {
74
- // Dynamic import of the handler function
75
- // Functions are in the same directory after assembly
76
- const module = await import(`../${functionName}`)
120
+ const prefix = functionName.startsWith('custom/') ? '../../../' : '../'
121
+ const module = await import(`${prefix}${functionName}`)
77
122
 
78
- // Handler should be exported as 'handler' or default
79
- const handler = module.handler || module.default
123
+ const handler = module.adapt || module.handler || module.default
80
124
 
81
125
  if (typeof handler !== 'function') {
82
- console.error(`[webhook-registry] Export 'handler' not found in ${functionName}`)
126
+ console.error(`[webhook-registry] No 'adapt' or 'handler' export found in ${functionName}`)
83
127
  return null
84
128
  }
85
129
 
@@ -89,31 +133,64 @@ export async function loadHandler(functionName: string): Promise<Function | null
89
133
  return null
90
134
  }
91
135
  }
92
-
93
- /**
94
- * Resolves a webhook handler by name.
95
- * Combines lookup + load for convenience.
96
- *
97
- * @param handlerName - The handler identifier
98
- * @returns The handler function or null
99
- */
100
- export async function resolveHandler(handlerName: string): Promise<Function | null> {
101
- const metadata = await lookupHandler(handlerName)
136
+ // CIL[END chunk_id="webhookregistry_loadhandler_1784020784"]
137
+ // CIL[BEGIN chunk_id="webhookregistry_resolvehandler_1784020784" type="function" identity="resolveHandler" parent="none"]
138
+ // CIL[DOC-MACRO purpose="Resolve webhook handler function by name"]
139
+ // CIL[DOC-RESPONSIBILITY responsibility="Combine lookup and loading for complete handler resolution"]
140
+ // CIL[DOC-CONTEXT module="webhook-registry" layer="shared" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\".framework/migrations/025_retype_threads_messages.sql\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
141
+ // CIL[DOC-CONTRACT inputs="none" outputs="Function or null" errors="lookup/load errors" side_effects="cache update"]
142
+ // CIL[DOC-MICRO logic_summary="Looks up metadata then loads and returns handler function" notable_decisions="[]"]
143
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
144
+ // CIL[DOC-STABILITY stability="stable"]
145
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, .framework/migrations/025_retype_threads_messages.sql, .framework/functions/_shared/schema-utils.ts, \."]
146
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
147
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
148
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
149
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
150
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
151
+ export async function resolveHandler(
152
+ handlerName: string,
153
+ appId?: string | null,
154
+ accountId?: string | null
155
+ ): Promise<Function | null> {
156
+ const metadata = await lookupHandler(handlerName, appId, accountId)
102
157
  if (!metadata) return null
103
158
 
104
159
  return loadHandler(metadata.functionName)
105
160
  }
106
-
107
- /**
108
- * Clears the handler cache. Useful for testing or after deployments.
109
- */
161
+ // CIL[END chunk_id="webhookregistry_resolvehandler_1784020784"]
162
+ // CIL[BEGIN chunk_id="webhookregistry_clearhandlercache_1784020784" type="function" identity="clearHandlerCache" parent="none"]
163
+ // CIL[DOC-MACRO purpose="Clear webhook handler cache"]
164
+ // CIL[DOC-RESPONSIBILITY responsibility="Reset handler metadata cache for fresh lookups"]
165
+ // CIL[DOC-CONTEXT module="webhook-registry" layer="shared" related_files="[]"]
166
+ // CIL[DOC-CONTRACT inputs="none" outputs="void" errors="none" side_effects="cache cleared"]
167
+ // CIL[DOC-MICRO logic_summary="Clears Map cache to force fresh database queries" notable_decisions="[]"]
168
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
169
+ // CIL[DOC-STABILITY stability="stable"]
170
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: none."]
171
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
172
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
173
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
174
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
175
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
110
176
  export function clearHandlerCache(): void {
111
177
  handlerCache.clear()
112
178
  }
113
-
114
- /**
115
- * Lists all registered handlers (for debugging/admin).
116
- */
179
+ // CIL[END chunk_id="webhookregistry_clearhandlercache_1784020784"]
180
+ // CIL[BEGIN chunk_id="webhookregistry_listregisteredhandlers_1784020784" type="function" identity="listRegisteredHandlers" parent="none"]
181
+ // CIL[DOC-MACRO purpose="List all registered webhook handlers"]
182
+ // CIL[DOC-RESPONSIBILITY responsibility="Retrieve names of all active webhook handlers"]
183
+ // CIL[DOC-CONTEXT module="webhook-registry" layer="shared" related_files="[]"]
184
+ // CIL[DOC-CONTRACT inputs="none" outputs="string array" errors="database errors" side_effects="none"]
185
+ // CIL[DOC-MICRO logic_summary="Queries webhook_handlers table and returns active handler names" notable_decisions="[]"]
186
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
187
+ // CIL[DOC-STABILITY stability="stable"]
188
+ // CIL[DOC-VECTOR type="context" content="Layer: shared. Direct callers: 0. Direct calls: 0. Related files: none."]
189
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
190
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
191
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
192
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
193
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
117
194
  export async function listRegisteredHandlers(): Promise<string[]> {
118
195
  const { data, error } = await adminDb
119
196
  .from('webhook_handlers')
@@ -127,3 +204,4 @@ export async function listRegisteredHandlers(): Promise<string[]> {
127
204
 
128
205
  return data?.map(h => h.name) || []
129
206
  }
207
+ // CIL[END chunk_id="webhookregistry_listregisteredhandlers_1784020784"]