spine-framework 0.3.145 → 0.4.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 (451) hide show
  1. package/.env.example +76 -0
  2. package/.framework/.spine-manifest.json +19 -0
  3. package/.framework/cli/commands/agents.ts +61 -33
  4. package/.framework/cli/commands/auth.ts +60 -28
  5. package/.framework/cli/commands/create-app.ts +212 -80
  6. package/.framework/cli/commands/dev.ts +184 -68
  7. package/.framework/cli/commands/doctor.ts +324 -152
  8. package/.framework/cli/commands/generate.ts +119 -68
  9. package/.framework/cli/commands/init.ts +141 -242
  10. package/.framework/cli/commands/install-app.ts +1336 -314
  11. package/.framework/cli/commands/items.ts +31 -29
  12. package/.framework/cli/commands/migrate.ts +299 -156
  13. package/.framework/cli/commands/migrations.ts +62 -30
  14. package/.framework/cli/commands/pipelines.ts +31 -29
  15. package/.framework/cli/commands/status.ts +105 -45
  16. package/.framework/cli/commands/system.ts +47 -42
  17. package/.framework/cli/commands/test.ts +161 -102
  18. package/.framework/cli/commands/upgrade.ts +260 -0
  19. package/.framework/cli/commands/validate-app.ts +517 -161
  20. package/.framework/cli/context.ts +117 -85
  21. package/.framework/cli/env-loader.ts +74 -43
  22. package/.framework/cli/index.ts +70 -46
  23. package/.framework/cli/lib/project-files.ts +404 -0
  24. package/.framework/docs/guides/testing-guide.md +1 -1
  25. package/.framework/docs/runtime-types.md +72 -72
  26. package/.framework/functions/_shared/access.ts +84 -0
  27. package/.framework/functions/_shared/agent-runner.ts +5067 -1026
  28. package/.framework/functions/_shared/app-manifest.ts +214 -94
  29. package/.framework/functions/_shared/ast.ts +214 -0
  30. package/.framework/functions/_shared/audit.ts +91 -55
  31. package/.framework/functions/_shared/cil.ts +368 -127
  32. package/.framework/functions/_shared/db.ts +337 -68
  33. package/.framework/functions/_shared/funnel.ts +228 -0
  34. package/.framework/functions/_shared/geo.ts +105 -0
  35. package/.framework/functions/_shared/hash-api-key.ts +94 -17
  36. package/.framework/functions/_shared/index.ts +22 -224
  37. package/.framework/functions/_shared/kb.ts +832 -58
  38. package/.framework/functions/_shared/llm.ts +118 -18
  39. package/.framework/functions/_shared/logging.ts +317 -19
  40. package/.framework/functions/_shared/middleware.ts +701 -131
  41. package/.framework/functions/_shared/notify.ts +70 -0
  42. package/.framework/functions/_shared/outcomes.ts +34 -19
  43. package/.framework/functions/_shared/permissions.ts +501 -315
  44. package/.framework/functions/_shared/pipeline-runner.ts +704 -155
  45. package/.framework/functions/_shared/principal.ts +436 -263
  46. package/.framework/functions/_shared/rate-limit.ts +233 -0
  47. package/.framework/functions/_shared/resolve-credentials.ts +86 -19
  48. package/.framework/functions/_shared/resolve-ids.ts +203 -139
  49. package/.framework/functions/_shared/retry-deliveries.ts +51 -16
  50. package/.framework/functions/_shared/schema-utils.ts +602 -521
  51. package/.framework/functions/_shared/security.ts +345 -0
  52. package/.framework/functions/_shared/testing.ts +197 -172
  53. package/.framework/functions/_shared/tracing.ts +351 -21
  54. package/.framework/functions/_shared/trigger-engine.ts +425 -136
  55. package/.framework/functions/_shared/webhook-registration.ts +71 -70
  56. package/.framework/functions/_shared/webhook-registry.ts +126 -83
  57. package/.framework/functions/account-nodes.ts +30 -30
  58. package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
  59. package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
  60. package/.framework/functions/adapters/openai-outbound.ts +15 -16
  61. package/.framework/functions/admin-data.ts +596 -173
  62. package/.framework/functions/admin-funnel.ts +64 -60
  63. package/.framework/functions/admin-install-funnel.ts +84 -66
  64. package/.framework/functions/admin-signals.ts +69 -51
  65. package/.framework/functions/ai-agents.ts +431 -106
  66. package/.framework/functions/ai-interactions.ts +186 -112
  67. package/.framework/functions/api-keys.ts +107 -107
  68. package/.framework/functions/apps.ts +154 -136
  69. package/.framework/functions/auth.ts +83 -65
  70. package/.framework/functions/cil-agent-ingest.ts +189 -232
  71. package/.framework/functions/cil-agent.ts +433 -177
  72. package/.framework/functions/cil-callmap.ts +642 -430
  73. package/.framework/functions/cil-config.ts +139 -135
  74. package/.framework/functions/cil-context.ts +214 -127
  75. package/.framework/functions/cil-doc.ts +587 -458
  76. package/.framework/functions/cil-embeddings.ts +453 -364
  77. package/.framework/functions/cil-graph.ts +427 -142
  78. package/.framework/functions/cil-ingest.ts +1418 -1154
  79. package/.framework/functions/cil-pipeline.ts +276 -21
  80. package/.framework/functions/cil-project.ts +659 -132
  81. package/.framework/functions/cil-validate.ts +198 -164
  82. package/.framework/functions/debug-auth.ts +57 -55
  83. package/.framework/functions/deliveries.ts +80 -21
  84. package/.framework/functions/embeddings.ts +1023 -318
  85. package/.framework/functions/eval-harness.ts +146 -108
  86. package/.framework/functions/integration-outbound.ts +205 -75
  87. package/.framework/functions/integration-routes.ts +128 -23
  88. package/.framework/functions/integrations.ts +125 -100
  89. package/.framework/functions/invites.ts +1095 -460
  90. package/.framework/functions/item-progress.ts +158 -102
  91. package/.framework/functions/kb.ts +34 -10
  92. package/.framework/functions/logs.ts +133 -133
  93. package/.framework/functions/observability.ts +152 -122
  94. package/.framework/functions/pipeline-executions.ts +147 -132
  95. package/.framework/functions/pipelines.ts +134 -119
  96. package/.framework/functions/prompt-configs.ts +96 -80
  97. package/.framework/functions/roles.ts +112 -82
  98. package/.framework/functions/security.ts +450 -0
  99. package/.framework/functions/system-cron.ts +117 -80
  100. package/.framework/functions/system.ts +158 -98
  101. package/.framework/functions/tests.ts +29 -29
  102. package/.framework/functions/timers.ts +94 -95
  103. package/.framework/functions/trigger-scheduler.ts +10 -0
  104. package/.framework/functions/triggers.ts +179 -149
  105. package/.framework/functions/types.ts +137 -125
  106. package/.framework/mcp/index.ts +133 -0
  107. package/.framework/mcp/load-env.ts +60 -0
  108. package/.framework/mcp/shared/app-manifest.ts +275 -0
  109. package/.framework/mcp/shared/db.ts +477 -0
  110. package/.framework/mcp/shared/kb.ts +118 -0
  111. package/.framework/mcp/tools/architect.ts +431 -0
  112. package/.framework/mcp/tools/cil/context.ts +345 -0
  113. package/.framework/mcp/tools/cil/graph.ts +242 -0
  114. package/.framework/mcp/tools/cil/ingest.ts +1217 -0
  115. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
  116. package/.framework/mcp/tools/cil/pipeline.ts +767 -0
  117. package/.framework/mcp/tools/cil/project.ts +791 -0
  118. package/.framework/mcp/tools/cil/retrieval.ts +336 -0
  119. package/.framework/mcp/tools/cil/search-core.ts +454 -0
  120. package/.framework/mcp/tools/cil/search.ts +97 -0
  121. package/.framework/mcp/tools/cil/suggest.ts +186 -0
  122. package/.framework/mcp/tools/cil/validate.ts +1369 -0
  123. package/.framework/mcp/tools/kb/delete.ts +139 -0
  124. package/.framework/mcp/tools/kb/index.ts +52 -0
  125. package/.framework/mcp/tools/kb/ingest.ts +84 -0
  126. package/.framework/mcp/tools/kb/list-types.ts +102 -0
  127. package/.framework/mcp/tools/kb/publish.ts +100 -0
  128. package/.framework/mcp/tools/kb/reindex.ts +86 -0
  129. package/.framework/mcp/tools/kb/revoke.ts +85 -0
  130. package/.framework/mcp/tools/kb/search.ts +101 -0
  131. package/.framework/mcp/tools/kb/upsert.ts +125 -0
  132. package/.framework/mcp/tools/observability.ts +510 -0
  133. package/.framework/migrations/001_core_schema.sql +15 -0
  134. package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
  135. package/.framework/migrations/003_core_system_data.sql +16 -1
  136. package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
  137. package/.framework/migrations/005_core_observability.sql +17 -1
  138. package/.framework/migrations/006_security_hardening_rls.sql +15 -0
  139. package/.framework/migrations/007_kb_article_list.sql +17 -1
  140. package/.framework/migrations/008_items_target.sql +15 -0
  141. package/.framework/migrations/009_roles_slug_unique.sql +15 -0
  142. package/.framework/migrations/010_auth_user_trigger.sql +15 -0
  143. package/.framework/migrations/011_spine_system_account.sql +16 -0
  144. package/.framework/migrations/012_service_role_grants.sql +16 -0
  145. package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
  146. package/.framework/migrations/014_apps_required_roles.sql +16 -0
  147. package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
  148. package/.framework/migrations/016_cil_types.sql +281 -0
  149. package/.framework/migrations/017_cil_stable_ids.sql +37 -0
  150. package/.framework/migrations/018_runtime_tables.sql +129 -0
  151. package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
  152. package/.framework/migrations/020_schema_reconciliation.sql +67 -0
  153. package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
  154. package/.framework/migrations/032_cil_status_migration.sql +73 -0
  155. package/.framework/migrations/033_cil_versioning.sql +73 -0
  156. package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
  157. package/.framework/migrations/035_rate_limits.sql +55 -0
  158. package/.framework/migrations/036_demo_record_flags.sql +72 -0
  159. package/.framework/migrations/037_kb_types_canonical.sql +244 -0
  160. package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
  161. package/.framework/migrations/042_registration_hierarchy.sql +309 -0
  162. package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
  163. package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
  164. package/.framework/migrations/045_security_critical_rls.sql +139 -0
  165. package/.framework/migrations/046_security_missing_rls.sql +79 -0
  166. package/.framework/migrations/047_people_updated_by.sql +27 -0
  167. package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
  168. package/.framework/migrations/049_security_blocklist.sql +148 -0
  169. package/.framework/migrations/050_notifications.sql +49 -0
  170. package/.framework/migrations/051_message_agent_fields.sql +74 -0
  171. package/.framework/migrations/052_registration_security.sql +421 -0
  172. package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
  173. package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
  174. package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
  175. package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
  176. package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
  177. package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
  178. package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
  179. package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
  180. package/.framework/migrations/061_fk_dedup.sql +32 -0
  181. package/.framework/public/spine-logo.svg +10 -3
  182. package/.framework/scripts/app-install-cli.ts +190 -93
  183. package/.framework/scripts/assemble-frontend.sh +127 -44
  184. package/.framework/scripts/assemble-functions.sh +128 -30
  185. package/.framework/scripts/boundary-check.sh +6 -2
  186. package/.framework/scripts/build-manifest.sh +24 -68
  187. package/.framework/scripts/check-core-integrity.sh +15 -76
  188. package/.framework/scripts/checksum-manifest.mts +343 -0
  189. package/.framework/scripts/cil-migrate-markers.ts +403 -0
  190. package/.framework/scripts/fix-cil-markers.mjs +176 -0
  191. package/.framework/scripts/verify-integrity.sh +21 -57
  192. package/.framework/scripts/verify-manifest.mts +305 -0
  193. package/.framework/seeds/types/funnel_signal_use.json +74 -21
  194. package/.framework/seeds/types/spine_instance.json +73 -21
  195. package/.framework/src/App.tsx +118 -72
  196. package/.framework/src/apps/admin/index.tsx +855 -58
  197. package/.framework/src/components/AppWrapper.tsx +43 -45
  198. package/.framework/src/components/CustomAppLoader.tsx +160 -116
  199. package/.framework/src/components/admin/AdminListPage.tsx +46 -44
  200. package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
  201. package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
  202. package/.framework/src/components/admin/PageInstructions.tsx +98 -2
  203. package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
  204. package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
  205. package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
  206. package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
  207. package/.framework/src/components/app-sidebar.tsx +42 -45
  208. package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
  209. package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
  210. package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
  211. package/.framework/src/components/kb/KBArticleList.tsx +251 -10
  212. package/.framework/src/components/layout/AppShell.tsx +51 -45
  213. package/.framework/src/components/layout/Header.tsx +42 -43
  214. package/.framework/src/components/layout/Layout.tsx +46 -46
  215. package/.framework/src/components/layout/Sidebar.tsx +196 -96
  216. package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
  217. package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
  218. package/.framework/src/components/runtime/DataFilters.tsx +49 -74
  219. package/.framework/src/components/runtime/DataHeader.tsx +53 -32
  220. package/.framework/src/components/runtime/DataListPage.tsx +51 -155
  221. package/.framework/src/components/runtime/DataStats.tsx +66 -44
  222. package/.framework/src/components/runtime/DataTable.tsx +49 -149
  223. package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
  224. package/.framework/src/components/runtime/index.ts +119 -16
  225. package/.framework/src/components/search-form.tsx +46 -29
  226. package/.framework/src/components/shared/AgentView.tsx +65 -48
  227. package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
  228. package/.framework/src/components/shared/InviteManager.tsx +207 -97
  229. package/.framework/src/components/shared/MemberList.tsx +97 -0
  230. package/.framework/src/components/shared/SchemaFields.tsx +107 -86
  231. package/.framework/src/components/ui/DataTable.tsx +80 -68
  232. package/.framework/src/components/ui/Form.tsx +157 -146
  233. package/.framework/src/components/ui/ItemCard.tsx +74 -67
  234. package/.framework/src/components/ui/ItemListView.tsx +73 -68
  235. package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
  236. package/.framework/src/components/ui/Modal.tsx +78 -68
  237. package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
  238. package/.framework/src/components/ui/accordion.tsx +85 -86
  239. package/.framework/src/components/ui/alert-dialog.tsx +197 -184
  240. package/.framework/src/components/ui/alert.tsx +105 -94
  241. package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
  242. package/.framework/src/components/ui/avatar.tsx +122 -107
  243. package/.framework/src/components/ui/badge.tsx +60 -55
  244. package/.framework/src/components/ui/breadcrumb.tsx +127 -128
  245. package/.framework/src/components/ui/button-group.tsx +86 -72
  246. package/.framework/src/components/ui/button.tsx +71 -50
  247. package/.framework/src/components/ui/calendar.tsx +72 -57
  248. package/.framework/src/components/ui/card.tsx +136 -129
  249. package/.framework/src/components/ui/carousel.tsx +226 -107
  250. package/.framework/src/components/ui/chart.tsx +252 -147
  251. package/.framework/src/components/ui/checkbox.tsx +43 -44
  252. package/.framework/src/components/ui/collapsible.tsx +86 -71
  253. package/.framework/src/components/ui/combobox.tsx +282 -249
  254. package/.framework/src/components/ui/command.tsx +158 -146
  255. package/.framework/src/components/ui/context-menu.tsx +239 -240
  256. package/.framework/src/components/ui/dialog.tsx +174 -157
  257. package/.framework/src/components/ui/direction.tsx +72 -56
  258. package/.framework/src/components/ui/drawer.tsx +168 -169
  259. package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
  260. package/.framework/src/components/ui/empty.tsx +131 -120
  261. package/.framework/src/components/ui/field.tsx +205 -173
  262. package/.framework/src/components/ui/hover-card.tsx +71 -72
  263. package/.framework/src/components/ui/input-group.tsx +148 -133
  264. package/.framework/src/components/ui/input-otp.tsx +99 -86
  265. package/.framework/src/components/ui/input.tsx +43 -41
  266. package/.framework/src/components/ui/item.tsx +207 -185
  267. package/.framework/src/components/ui/kbd.tsx +57 -56
  268. package/.framework/src/components/ui/label.tsx +45 -41
  269. package/.framework/src/components/ui/menubar.tsx +268 -236
  270. package/.framework/src/components/ui/native-select.tsx +85 -86
  271. package/.framework/src/components/ui/navigation-menu.tsx +166 -156
  272. package/.framework/src/components/ui/pagination.tsx +131 -141
  273. package/.framework/src/components/ui/popover.tsx +125 -128
  274. package/.framework/src/components/ui/progress.tsx +47 -44
  275. package/.framework/src/components/ui/radio-group.tsx +60 -55
  276. package/.framework/src/components/ui/resizable.tsx +85 -72
  277. package/.framework/src/components/ui/scroll-area.tsx +57 -58
  278. package/.framework/src/components/ui/select.tsx +182 -169
  279. package/.framework/src/components/ui/separator.tsx +42 -43
  280. package/.framework/src/components/ui/sheet.tsx +170 -159
  281. package/.framework/src/components/ui/sidebar.tsx +395 -398
  282. package/.framework/src/components/ui/skeleton.tsx +42 -43
  283. package/.framework/src/components/ui/slider.tsx +61 -44
  284. package/.framework/src/components/ui/sonner.tsx +44 -44
  285. package/.framework/src/components/ui/spinner.tsx +47 -42
  286. package/.framework/src/components/ui/switch.tsx +56 -42
  287. package/.framework/src/components/ui/table-primitives.tsx +272 -132
  288. package/.framework/src/components/ui/table.tsx +140 -142
  289. package/.framework/src/components/ui/tabs.tsx +110 -93
  290. package/.framework/src/components/ui/textarea.tsx +43 -44
  291. package/.framework/src/components/ui/toggle-group.tsx +87 -71
  292. package/.framework/src/components/ui/toggle.tsx +56 -56
  293. package/.framework/src/components/ui/tooltip.tsx +99 -85
  294. package/.framework/src/contexts/AppContext.tsx +166 -114
  295. package/.framework/src/contexts/AuthContext.tsx +232 -137
  296. package/.framework/src/hooks/use-mobile.ts +43 -44
  297. package/.framework/src/hooks/useApi.ts +185 -172
  298. package/.framework/src/hooks/useAppPath.ts +31 -29
  299. package/.framework/src/hooks/useApps.ts +77 -42
  300. package/.framework/src/hooks/useEntityList.ts +66 -29
  301. package/.framework/src/hooks/useEntityRecord.ts +76 -32
  302. package/.framework/src/hooks/useForm.ts +62 -30
  303. package/.framework/src/hooks/useListSchema.ts +60 -43
  304. package/.framework/src/hooks/useSchemaRecord.ts +115 -95
  305. package/.framework/src/lib/api.ts +258 -134
  306. package/.framework/src/lib/registration.ts +181 -0
  307. package/.framework/src/lib/supabase.ts +118 -81
  308. package/.framework/src/lib/utils.ts +266 -266
  309. package/.framework/src/main.tsx +43 -44
  310. package/.framework/src/pages/DashboardPage.tsx +44 -43
  311. package/.framework/src/pages/NoAppPage.tsx +50 -0
  312. package/.framework/src/pages/NotFoundPage.tsx +32 -29
  313. package/.framework/src/pages/SetupPage.tsx +34 -33
  314. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
  315. package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
  316. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
  317. package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
  318. package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
  319. package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
  320. package/.framework/src/pages/admin/AppsPage.tsx +45 -42
  321. package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
  322. package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
  323. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
  324. package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
  325. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
  326. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
  327. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
  328. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
  329. package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
  330. package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
  331. package/.framework/src/pages/admin/LogsPage.tsx +87 -137
  332. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
  333. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
  334. package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
  335. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
  336. package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
  337. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
  338. package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
  339. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
  340. package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
  341. package/.framework/src/pages/admin/RolesPage.tsx +47 -164
  342. package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
  343. package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
  344. package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
  345. package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
  346. package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
  347. package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
  348. package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
  349. package/.framework/src/pages/admin/TimersPage.tsx +44 -42
  350. package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
  351. package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
  352. package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
  353. package/.framework/src/pages/admin/TypesPage.tsx +45 -42
  354. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
  355. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
  356. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
  357. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
  358. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
  359. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
  360. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
  361. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
  362. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
  363. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
  364. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
  365. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
  366. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  367. package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
  368. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
  369. package/.framework/src/pages/auth/LoginPage.tsx +38 -32
  370. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
  371. package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
  372. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
  373. package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
  374. package/.framework/src/types/auth.ts +101 -93
  375. package/.framework/src/types/types.ts +283 -262
  376. package/.framework/templates/project.json +87 -0
  377. package/.framework/templates/spine.config.neutral.json +7 -0
  378. package/.framework/tests/api/api-surface.test.ts +381 -0
  379. package/.framework/tests/fixtures/seed.ts +427 -0
  380. package/.framework/tests/fixtures/teardown.ts +228 -0
  381. package/.framework/tests/reporter.ts +351 -0
  382. package/.framework/tests/setup.ts +135 -0
  383. package/.framework/tests/ui/ui-sweep.ts +278 -0
  384. package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
  385. package/.framework/tests/unit/agent-runner.test.ts +2389 -0
  386. package/.framework/tests/unit/ai-interactions.test.ts +81 -0
  387. package/.framework/tests/unit/app-manifest.test.ts +359 -0
  388. package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
  389. package/.framework/tests/unit/cil-determinism.test.ts +85 -0
  390. package/.framework/tests/unit/core-isolation.test.ts +153 -0
  391. package/.framework/tests/unit/funnel-signals.test.ts +135 -0
  392. package/.framework/tests/unit/install-app.test.ts +1759 -0
  393. package/.framework/tests/unit/invites-security.test.ts +572 -0
  394. package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
  395. package/.framework/tests/unit/kb-search.test.ts +119 -0
  396. package/.framework/tests/unit/migrate.test.ts +509 -0
  397. package/.framework/tests/unit/notify.test.ts +136 -0
  398. package/.framework/tests/unit/permissions.test.ts +269 -0
  399. package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
  400. package/.framework/tests/unit/principal-cache.test.ts +138 -0
  401. package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
  402. package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
  403. package/.framework/tests/unit/schema-utils.test.ts +225 -0
  404. package/.framework/tests/unit/trigger-engine.test.ts +513 -0
  405. package/.framework/tests/unit/validate-app.test.ts +527 -0
  406. package/README.md +34 -3
  407. package/bin/spine-framework.cjs +1 -0
  408. package/config/tailwind.config.cjs +7 -0
  409. package/config/tsconfig.functions.json +42 -0
  410. package/config/tsconfig.json +37 -9
  411. package/config/vite.config.ts +31 -2
  412. package/netlify.toml +31 -3
  413. package/package.json +46 -29
  414. package/scripts/assemble-frontend.sh +127 -44
  415. package/scripts/assemble-functions.sh +127 -29
  416. package/scripts/boundary-check.sh +6 -2
  417. package/scripts/build-manifest.sh +24 -68
  418. package/scripts/checksum-manifest.mts +345 -0
  419. package/scripts/dev-clean.sh +86 -0
  420. package/scripts/dev-netlify.sh +49 -0
  421. package/scripts/netlify-dev-wrapper.sh +2 -0
  422. package/scripts/verify-install.ts +358 -0
  423. package/scripts/verify-integrity.sh +21 -57
  424. package/scripts/verify-manifest.mts +305 -0
  425. package/templates/project/gitignore +45 -0
  426. package/{config → templates/project}/package-lock.json +22335 -9366
  427. package/vitest.config.ts +46 -0
  428. package/.framework/public/spine.config.json +0 -91
  429. package/config/deno.lock +0 -108
  430. package/config/tsconfig.node.tsbuildinfo +0 -1
  431. package/config/tsconfig.tsbuildinfo +0 -1
  432. package/config/vite.config.d.ts +0 -2
  433. package/custom/.devin/AGENT.md +0 -357
  434. package/custom/.devin/skills/install-app/SKILL.md +0 -39
  435. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
  436. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
  437. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
  438. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
  439. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
  440. package/custom/.devin/workflows/app-install.yaml +0 -83
  441. package/custom/README.md +0 -79
  442. package/docs/README.md +0 -15
  443. package/scripts/app-install-cli.ts +0 -286
  444. package/scripts/check-core-integrity.sh +0 -82
  445. package/scripts/ingest-chunks.cjs +0 -202
  446. package/scripts/kb-chunk-parser.cjs +0 -312
  447. package/scripts/kb-chunk-parser.ts +0 -330
  448. package/scripts/kb-ingest-docs.ts +0 -203
  449. package/scripts/load-test-app-install.ts +0 -484
  450. package/scripts/test-login.js +0 -33
  451. package/spine.config.json +0 -91
@@ -1,18 +1,12 @@
1
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_module_header_1784235266" type="module_header" identity="module_header" parent="none"]
2
- // CIL[DOC-MACRO purpose="Module header and top-level exports for cortex.functions.custom_cil-agent"]
3
- // CIL[DOC-RESPONSIBILITY responsibility="Own module-level imports, exports, and configuration for cortex.functions.custom_cil-agent"]
4
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
5
- // CIL[DOC-CONTRACT inputs="none" outputs="module exports and side effects" errors="none" side_effects="none"]
6
- // CIL[DOC-MICRO logic_summary="Declares module scope, imports dependencies, and exports public surface of cortex.functions.custom_cil-agent" notable_decisions="[]"]
7
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/cil-agent.ts"]
2
+ // CIL[DOC-MACRO purpose="CIL agent Netlify function: answer codebase questions using tool-augmented retrieval."]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide ask, chat, tool, and tools endpoints for CIL-powered codebase Q&A."]
4
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts"]
5
+ // CIL[DOC-CONTRACT inputs="HTTP request context and JSON body" outputs="JSON answer with sources and tool calls" errors="Authentication, missing question, unknown action, LLM or database errors" side_effects="Reads chunk index and writes thread messages for chat"]
6
+ // CIL[DOC-MICRO logic_summary="Imports shared helpers and exports a single createHandler-wrapped endpoint that dispatches actions." notable_decisions="Uses environment URL as base for internal CIL API calls; action defaults to ask."]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
8
  // CIL[DOC-STABILITY stability="stable"]
9
- // CIL[DOC-AUDIENCE audience="developer"]
10
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, \."]
11
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
12
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
13
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
14
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
15
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
9
+ // CIL[DOC-AUDIENCE audience="internal"]
16
10
 
17
11
 
18
12
 
@@ -21,7 +15,16 @@ import { createHandler } from './_shared/middleware'
21
15
  import { adminDb } from './_shared/db'
22
16
  import { resolveTypeId } from './_shared/resolve-ids'
23
17
  import { create as adminCreate } from './admin-data'
24
- import { callOpenAIChat, callOpenAIEmbeddings } from './_shared/llm'
18
+ import { callOpenAIChat } from './_shared/llm'
19
+ import { handler as cilGraphHandler } from './cil-graph'
20
+ import { SYSTEM_PRINCIPAL } from './_shared/principal'
21
+ // CIL[DOC-VECTOR type="context" content="purpose='CIL agent Netlify function: answer codebase questions using tool-augmented retrieval.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
22
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
23
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
24
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
25
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
26
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
27
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:module_header:module_header"]
25
28
 
26
29
 
27
30
 
@@ -30,21 +33,14 @@ import { callOpenAIChat, callOpenAIEmbeddings } from './_shared/llm'
30
33
 
31
34
 
32
35
 
33
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_module_header_1784235266"]
34
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_cil_tools_1784235266" type="variable" identity="cil_tools" parent="none"]
35
- // CIL[DOC-MACRO purpose="Defines cil_tools configuration or state in cortex.functions.custom_cil-agent"]
36
- // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for cil_tools"]
37
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
38
- // CIL[DOC-CONTRACT inputs="none" outputs="value of cil_tools" errors="none" side_effects="none"]
39
- // CIL[DOC-MICRO logic_summary="Declares cil_tools with initial value or constant binding used by cortex.functions.custom_cil-agent" notable_decisions="[]"]
40
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
36
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:CIL_TOOLS:constant" type="constant" identity="CIL_TOOLS" parent="~/.framework/functions/cil-agent.ts"]
37
+ // CIL[DOC-MACRO purpose="Define the JSON function schemas exposed to the LLM for CIL tool use."]
38
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide tool descriptions and parameters for chunk lookup, contract retrieval, blast radius, hash validation, gap report, and project status."]
39
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
40
+ // CIL[DOC-CONTRACT inputs="[]" outputs="any" errors="[]" side_effects="none"]
41
+ // CIL[DOC-MICRO logic_summary="Static array of function definitions with names, descriptions, and parameter schemas." notable_decisions=""]
42
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
41
43
  // CIL[DOC-STABILITY stability="stable"]
42
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
43
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
44
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
45
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
46
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
47
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
48
44
  const CIL_TOOLS = [
49
45
  {
50
46
  name: 'chunk_lookup',
@@ -115,6 +111,13 @@ const CIL_TOOLS = [
115
111
  },
116
112
  },
117
113
  ]
114
+ // CIL[DOC-VECTOR type="context" content="purpose='Define the JSON function schemas exposed to the LLM for CIL tool use.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
115
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
116
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
117
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
118
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
119
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
120
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:CIL_TOOLS:constant"]
118
121
 
119
122
 
120
123
 
@@ -122,21 +125,43 @@ const CIL_TOOLS = [
122
125
 
123
126
 
124
127
 
125
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_cil_tools_1784235266"]
126
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_dispatchtool_1784235266" type="function" identity="dispatchtool" parent="none"]
127
- // CIL[DOC-MACRO purpose="Implements dispatchtool logic in cortex.functions.custom_cil-agent"]
128
- // CIL[DOC-RESPONSIBILITY responsibility="Execute dispatchtool and return its computed result"]
129
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
130
- // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
131
- // CIL[DOC-MICRO logic_summary="Provides dispatchtool with dispatchTool( inputs, handling internal flow and returning a result" notable_decisions="[]"]
132
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
128
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:runcilgraphaction:function" type="function" identity="runCilGraphAction" parent="~/.framework/functions/cil-agent.ts"]
129
+ // CIL[DOC-MACRO purpose="Dispatch a cil-graph action internally as the system principal."]
130
+ // CIL[DOC-RESPONSIBILITY responsibility="Build a synthetic handler event and call the cil-graph handler so CIL agent tools can reuse the v2 graph/search logic."]
131
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/cil-graph.ts,.framework/functions/_shared/principal.ts,.framework/functions/cil-agent.ts"]
132
+ // CIL[DOC-CONTRACT inputs="query: Record<string, string | undefined>" outputs="Promise<any> (raw cil-graph action result)" errors="Propagates cil-graph handler exceptions" side_effects="none"]
133
+ // CIL[DOC-MICRO logic_summary="Construct an event with SYSTEM_PRINCIPAL and the requested query, then invoke the cil-graph handler." notable_decisions="Uses a synthetic requestId to satisfy createHandler internal-invoke bypass."]
134
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
133
135
  // CIL[DOC-STABILITY stability="stable"]
134
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
135
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
136
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
137
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
136
+ async function runCilGraphAction(query: Record<string, string | undefined>): Promise<any> {
137
+ const event = {
138
+ requestId: 'internal-cil-agent',
139
+ principal: SYSTEM_PRINCIPAL,
140
+ db: adminDb,
141
+ query: Object.fromEntries(Object.entries(query).filter(([, v]) => v !== undefined)) as Record<string, string>,
142
+ httpMethod: 'GET',
143
+ headers: {},
144
+ path: '/.netlify/functions/cil-graph',
145
+ body: null,
146
+ } as any
147
+ return cilGraphHandler(event, {})
148
+ }
149
+ // CIL[DOC-VECTOR type="context" content="purpose='Dispatch a cil-graph action internally as the system principal.'; No verified external callers; imports: .framework/functions/cil-graph.ts,.framework/functions/_shared/principal.ts"]
150
+ // CIL[DOC-VECTOR type="blast_radius" content="Local impact only; used by dispatchTool and retrieveChunkContext"]
151
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
152
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
138
153
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
139
154
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
155
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:runcilgraphaction:function"]
156
+
157
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:dispatchTool:function" type="function" identity="dispatchTool" parent="~/.framework/functions/cil-agent.ts"]
158
+ // CIL[DOC-MACRO purpose="Execute a named CIL tool by making local API calls or database queries."]
159
+ // CIL[DOC-RESPONSIBILITY responsibility="Resolve the requested tool to the corresponding CIL endpoint or database operation and return the result."]
160
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
161
+ // CIL[DOC-CONTRACT inputs="toolName: string, args: Record<string, any>, accountId: string" outputs="Tool-specific JSON result" errors="Unknown tool, network or database errors" side_effects="Queries internal CIL endpoints and the items table"]
162
+ // CIL[DOC-MICRO logic_summary="Switch on toolName and dispatch cil-graph actions through runCilGraphAction; use direct adminDb or fetch for remaining tools." notable_decisions="Avoids unauthenticated internal fetch by calling the cil-graph handler with a system principal."]
163
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
164
+ // CIL[DOC-STABILITY stability="stable"]
140
165
  async function dispatchTool(
141
166
  toolName: string,
142
167
  args: Record<string, any>,
@@ -146,24 +171,39 @@ async function dispatchTool(
146
171
 
147
172
  switch (toolName) {
148
173
  case 'chunk_lookup': {
149
- const params = new URLSearchParams({ action: 'search', q: args.q, mode: 'hybrid', limit: '5' })
150
- if (args.project_id) params.set('project_id', args.project_id)
151
- const res = await fetch(`${base}/.netlify/functions/cil-graph?${params}`)
152
- const data: any = await res.json()
153
- return { results: data?.results || data?.data?.results || [] }
174
+ const q: Record<string, string | undefined> = {
175
+ action: 'search',
176
+ q: args.q,
177
+ mode: 'hybrid',
178
+ limit: '5',
179
+ }
180
+ if (args.project_id) q.project_id = args.project_id
181
+ if (args.version_id) q.version_id = args.version_id
182
+ const res: any = await runCilGraphAction(q)
183
+ return { results: res?.results || [] }
154
184
  }
155
185
 
156
186
  case 'get_contract': {
157
- const res = await fetch(`${base}/.netlify/functions/cil-graph?action=get_chunk_contract&chunk_id=${args.chunk_id}`)
158
- const data: any = await res.json()
159
- return data?.contract || data?.data?.contract || {}
187
+ const q: Record<string, string | undefined> = {
188
+ action: 'get_chunk_contract',
189
+ chunk_id: args.chunk_id,
190
+ stable_id: args.stable_id,
191
+ }
192
+ if (args.version_id) q.version_id = args.version_id
193
+ const res: any = await runCilGraphAction(q)
194
+ return res?.contract || {}
160
195
  }
161
196
 
162
197
  case 'blast_radius': {
163
- const depth = args.max_depth || 3
164
- const res = await fetch(`${base}/.netlify/functions/cil-graph?action=get_blast_radius&chunk_id=${args.chunk_id}&max_depth=${depth}`)
165
- const data: any = await res.json()
166
- return { affected: data?.affected || data?.data?.affected || [], depth }
198
+ const depth = String(args.max_depth || 3)
199
+ const q: Record<string, string | undefined> = {
200
+ action: 'get_blast_radius',
201
+ chunk_id: args.chunk_id,
202
+ max_depth: depth,
203
+ }
204
+ if (args.version_id) q.version_id = args.version_id
205
+ const res: any = await runCilGraphAction(q)
206
+ return { affected: res?.affected || [], depth: args.max_depth || 3 }
167
207
  }
168
208
 
169
209
  case 'hash_validate': {
@@ -222,26 +262,26 @@ async function dispatchTool(
222
262
  return { error: `Unknown tool: ${toolName}` }
223
263
  }
224
264
  }
265
+ // CIL[DOC-VECTOR type="context" content="purpose='Execute a named CIL tool by making local API calls or database queries.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
266
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
267
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
268
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
269
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
270
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
271
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:dispatchTool:function"]
225
272
 
226
273
 
227
274
 
228
275
 
229
276
 
230
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_dispatchtool_1784235266"]
231
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_callllm_1784235266" type="function" identity="callllm" parent="none"]
232
- // CIL[DOC-MACRO purpose="Implements callllm logic in cortex.functions.custom_cil-agent"]
233
- // CIL[DOC-RESPONSIBILITY responsibility="Execute callllm and return its computed result"]
234
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
235
- // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
236
- // CIL[DOC-MICRO logic_summary="Provides callllm with callLLM( inputs, handling internal flow and returning a result" notable_decisions="[]"]
237
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
277
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:callLLM:function" type="function" identity="callLLM" parent="~/.framework/functions/cil-agent.ts"]
278
+ // CIL[DOC-MACRO purpose="Call the OpenAI chat completion endpoint with optional tool definitions."]
279
+ // CIL[DOC-RESPONSIBILITY responsibility="Format messages and tools and return the assistant content and any tool calls."]
280
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
281
+ // CIL[DOC-CONTRACT inputs="messages, tools, model" outputs="{ content: string, tool_calls?: any[] }" errors="LLM API errors" side_effects="Calls OpenAI chat API"]
282
+ // CIL[DOC-MICRO logic_summary="Build options, map tools to OpenAI function format, call chat, and extract choice." notable_decisions="Sets temperature 0.2 and max_tokens 1500; defaults tool_calls to undefined."]
283
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
238
284
  // CIL[DOC-STABILITY stability="stable"]
239
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
240
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
241
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
242
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
243
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
244
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
245
285
  async function callLLM(
246
286
  messages: { role: string; content: string }[],
247
287
  tools: any[],
@@ -260,64 +300,45 @@ async function callLLM(
260
300
  tool_calls: choice?.message?.tool_calls || undefined,
261
301
  }
262
302
  }
303
+ // CIL[DOC-VECTOR type="context" content="purpose='Call the OpenAI chat completion endpoint with optional tool definitions.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
304
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
305
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
306
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
307
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
308
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
309
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:callLLM:function"]
263
310
 
264
311
 
265
312
 
266
313
 
267
314
 
268
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_callllm_1784235266"]
269
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_retrievechunkcontext_1784235266" type="function" identity="retrievechunkcontext" parent="none"]
270
- // CIL[DOC-MACRO purpose="Implements retrievechunkcontext logic in cortex.functions.custom_cil-agent"]
271
- // CIL[DOC-RESPONSIBILITY responsibility="Execute retrievechunkcontext and return its computed result"]
272
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[]"]
273
- // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
274
- // CIL[DOC-MICRO logic_summary="Provides retrievechunkcontext with retrieveChunkContext( inputs, handling internal flow and returning a result" notable_decisions="[]"]
275
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
315
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:retrieveChunkContext:function" type="function" identity="retrieveChunkContext" parent="~/.framework/functions/cil-agent.ts"]
316
+ // CIL[DOC-MACRO purpose="Retrieve relevant chunk contracts to ground CIL agent answers using v2 graph/search."]
317
+ // CIL[DOC-RESPONSIBILITY responsibility="Call cil-graph hybrid search and format matching chunk contracts into a context string."]
318
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/cil-graph.ts,.framework/functions/_shared/principal.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
319
+ // CIL[DOC-CONTRACT inputs="query: string, projectId: string | null, accountId: string" outputs="Formatted context string of chunk contracts or empty string" errors="Graph search or formatting failures are caught and return an empty string" side_effects="Calls the cil-graph hybrid search action"]
320
+ // CIL[DOC-MICRO logic_summary="Dispatch a cil-graph search with the user query, then format macro/micro/contract fields and similarity scores." notable_decisions="Uses runCilGraphAction to reuse the same v2 search logic as the MCP tools; falls back to empty context on any error."]
321
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
276
322
  // CIL[DOC-STABILITY stability="stable"]
277
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
278
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
279
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
280
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
281
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
282
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
283
323
  async function retrieveChunkContext(
284
324
  query: string,
285
325
  projectId: string | null,
286
326
  accountId: string
287
327
  ): Promise<string> {
288
328
  try {
289
- const ej = await callOpenAIEmbeddings(undefined, [query], 'text-embedding-3-small')
290
- const vec = ej.data?.[0]?.embedding
291
- if (!vec) return ''
292
-
293
- const { data: matches } = await adminDb.rpc('match_embeddings', {
294
- query_embedding: `[${vec.join(',')}]`,
295
- match_count: 8,
296
- filter_vector_type: 'semantic',
297
- similarity_threshold: 0.2,
298
- filter_item_types: ['cil_chunk'],
299
- })
300
-
301
- if (!matches?.length) return ''
302
-
303
- const chunkIds = [...new Set((matches as any[]).map((m: any) => m.document_id))]
304
- let chunkQuery = adminDb
305
- .from('items')
306
- .select('id, data')
307
- .in('id', chunkIds)
308
-
309
- if (projectId) {
310
- chunkQuery = chunkQuery.filter('data->>project_id', 'eq', projectId)
329
+ const q: Record<string, string | undefined> = {
330
+ action: 'search',
331
+ q: query,
332
+ mode: 'hybrid',
333
+ limit: '16',
311
334
  }
312
-
313
- const { data: chunks } = await chunkQuery
314
- const chunkMap = new Map((chunks || []).map((c: any) => [c.id, c]))
335
+ if (projectId) q.project_id = projectId
336
+ const res: any = await runCilGraphAction(q)
337
+ const results = res?.results || []
338
+ if (!results.length) return ''
315
339
 
316
340
  const contextParts: string[] = []
317
- for (const m of (matches as any[])) {
318
- const chunk = chunkMap.get(m.document_id)
319
- if (!chunk) continue
320
- const d = chunk.data || {}
341
+ for (const d of results) {
321
342
  const parts = [
322
343
  `## ${d.chunk_name || 'unknown'} (${d.chunk_type || ''}) — ${d.file_path || ''}`,
323
344
  ]
@@ -327,7 +348,9 @@ async function retrieveChunkContext(
327
348
  if (d.output_spec) parts.push(`Returns: ${d.output_spec}`)
328
349
  if (d.side_effects) parts.push(`Side effects: ${d.side_effects}`)
329
350
  if (d.stability) parts.push(`Stability: ${d.stability}`)
330
- parts.push(`Similarity: ${(m.similarity * 100).toFixed(0)}%`)
351
+ if (d.similarity != null) {
352
+ parts.push(`Similarity: ${(d.similarity * 100).toFixed(0)}%`)
353
+ }
331
354
  contextParts.push(parts.join('\n'))
332
355
  }
333
356
 
@@ -336,57 +359,64 @@ async function retrieveChunkContext(
336
359
  return ''
337
360
  }
338
361
  }
362
+ // CIL[DOC-VECTOR type="context" content="purpose='Retrieve relevant chunk contracts to ground CIL agent answers using v2 graph/search.'; No verified external callers; imports: .framework/functions/cil-graph.ts,.framework/functions/_shared/principal.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
363
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
364
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
365
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
366
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
367
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
368
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:retrieveChunkContext:function"]
339
369
 
340
370
 
341
371
 
342
372
 
343
373
 
344
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_retrievechunkcontext_1784235266"]
345
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_system_prompt_1784235266" type="variable" identity="system_prompt" parent="none"]
346
- // CIL[DOC-MACRO purpose="Defines system_prompt configuration or state in cortex.functions.custom_cil-agent"]
347
- // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for system_prompt"]
348
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[]"]
349
- // CIL[DOC-CONTRACT inputs="none" outputs="value of system_prompt" errors="none" side_effects="none"]
350
- // CIL[DOC-MICRO logic_summary="Declares system_prompt with initial value or constant binding used by cortex.functions.custom_cil-agent" notable_decisions="[]"]
351
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
374
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:SYSTEM_PROMPT:constant" type="constant" identity="SYSTEM_PROMPT" parent="~/.framework/functions/cil-agent.ts"]
375
+ // CIL[DOC-MACRO purpose="System prompt that instructs the CIL assistant to synthesize prose answers from KB articles and code chunks without confabulating."]
376
+ // CIL[DOC-RESPONSIBILITY responsibility="Set the behavior and constraints for the CIL Q&A agent."]
377
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
378
+ // CIL[DOC-CONTRACT inputs="[]" outputs="any" errors="[]" side_effects="none"]
379
+ // CIL[DOC-MICRO logic_summary="Template string defining answer-first synthesis rules, inline [n] citation requirements, per-question-type routing, anti-confabulation constraints, call-edge caveat, and cited-only Sources format." notable_decisions="Synthesis over enumeration; [KB article]/[code chunk] labels bind to buildContext's excerpt tagging; question routing covers concept/how-to/example/where-is; explicit warning that empty blast_radius ≠ low impact for interfaces/types."]
380
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
352
381
  // CIL[DOC-STABILITY stability="stable"]
353
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
354
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
355
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
356
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
357
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
358
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
359
- const SYSTEM_PROMPT = `You are a Code Intelligence Layer assistant. You answer questions about this codebase using retrieved chunk contracts.
382
+ const SYSTEM_PROMPT = `You are the Spine Code Intelligence assistant. You answer questions about this codebase and the platform's architecture using retrieved evidence.
360
383
 
361
- Each chunk record contains: chunk_name, file_path, macro (purpose), micro (implementation detail), input_spec, output_spec, side_effects, and stability.
384
+ Evidence arrives as numbered excerpts [n], labeled:
385
+ - [KB article] — narrative documentation explaining concepts, mechanisms, rules, and worked examples.
386
+ - [code chunk] — implementation records: chunk_name, file_path, macro (purpose), contract fields, stability.
362
387
 
363
388
  Rules:
364
- - Ground your answer in the retrieved chunk contracts — do not invent APIs.
365
- - Cite chunk_name and file_path when referencing a specific function.
366
- - If no relevant chunk is found, say so explicitly.
367
- - For refactoring questions, always mention callers / blast radius if relevant.
368
- - Use the available tools to look up specifics you are not sure about.
369
- - Keep answers concise. Use markdown code blocks for examples.`
389
+ - Answer the question directly in prose first. Excerpts are evidence, not the answer's structure — synthesize across them rather than enumerating them.
390
+ - Cite inline: put [n] after each claim that relies on excerpt n or on a tool result. The Sources list at the end must contain only the [n] you actually cited. Never list an excerpt you did not use.
391
+ - Route by question type:
392
+ * Concept / "what is X": explain the mechanism from the KB — where it is stored, what is generated from it, what enforces or consumes it — then cite the implementing code chunks. Distinguish the database field or runtime record (e.g. \`design_schema\` on public.types) from the TypeScript type that merely describes it (e.g. \`DesignSchema\`).
393
+ * How-to / configure: give the concrete checklist of rules from the KB (required keys, constraints, gotchas). Do not give generic advice such as "understand the structure, test, iterate".
394
+ * Example / sample: if a complete example appears verbatim in an excerpt or tool result, paste it in full in a code block and cite it. If only a fragment was retrieved, call cil_fetch_document with that document_id to get the full text before answering. Never stitch fragments together and never invent JSON.
395
+ * Where-is / which files: call cil_chunk_lookup (it searches code content) and report chunk_name + file_path grouped by role (definition, generation, runtime enforcement, UI, tests). Mark files under /archive/ or /migrations/ as historical.
396
+ - Never invent JSON, schemas, config examples, or APIs. Only present code that appears verbatim in retrieved excerpts or tool results. If the evidence is missing, say exactly what is missing (e.g. "I found the concept article but not the example article") rather than generalizing.
397
+ - blast_radius and caller tools traverse CALL edges. Interfaces, types, and constants are imported, not called — an empty blast radius does NOT mean low impact. Chunk metadata such as "no verified external callers" is a call-graph artifact, not a fact about usage; never repeat it as one.
398
+ - On follow-up questions, answer what is new; do not restate your previous answer.
399
+ - End with "Sources:" listing only the cited excerpts as \`[n] title — file path\`.`
400
+ // CIL[DOC-VECTOR type="context" content="purpose='System prompt that instructs the CIL assistant to ground answers in retrieved chunk contracts.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
401
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
402
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
403
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
404
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
405
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
406
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:SYSTEM_PROMPT:constant"]
370
407
 
371
408
 
372
409
 
373
410
 
374
411
 
375
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_system_prompt_1784235266"]
376
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_runcilinference_1784235266" type="function" identity="runcilinference" parent="none"]
377
- // CIL[DOC-MACRO purpose="Implements runcilinference logic in cortex.functions.custom_cil-agent"]
378
- // CIL[DOC-RESPONSIBILITY responsibility="Execute runcilinference and return its computed result"]
379
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[]"]
380
- // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
381
- // CIL[DOC-MICRO logic_summary="Provides runcilinference with runCilInference( inputs, handling internal flow and returning a result" notable_decisions="[]"]
382
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
412
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:runCilInference:function" type="function" identity="runCilInference" parent="~/.framework/functions/cil-agent.ts"]
413
+ // CIL[DOC-MACRO purpose="Run a tool-augmented RAG conversation: embed, call LLM, dispatch tool calls, and synthesize an answer."]
414
+ // CIL[DOC-RESPONSIBILITY responsibility="Orchestrate retrieval, LLM calls, and tool execution for a single user turn."]
415
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
416
+ // CIL[DOC-CONTRACT inputs="question, projectId, history, accountId, model" outputs="{ answer, sources, tool_calls_made }" errors="LLM or tool execution errors" side_effects="Calls LLM and CIL tool endpoints; may write messages"]
417
+ // CIL[DOC-MICRO logic_summary="Retrieve context, build messages, loop up to MAX_TOOL_ITERS calling the LLM and dispatching any tool calls, then return an answer." notable_decisions="Sources extracted from RAG context by matching chunk name headings; uses spread to attach tool_calls to assistant messages."]
418
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
383
419
  // CIL[DOC-STABILITY stability="stable"]
384
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
385
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
386
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
387
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
388
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
389
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
390
420
  async function runCilInference(
391
421
  question: string,
392
422
  projectId: string | null,
@@ -456,55 +486,276 @@ async function runCilInference(
456
486
 
457
487
  return { answer: 'I exhausted my tool call budget. Please try a more specific question.', sources: [], tool_calls_made: toolCallsMade }
458
488
  }
489
+ // CIL[DOC-VECTOR type="context" content="purpose='Run a tool-augmented RAG conversation: embed, call LLM, dispatch tool calls, and synthesize an answer.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
490
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
491
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
492
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
493
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
494
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
495
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:runCilInference:function"]
459
496
 
460
497
 
461
498
 
462
499
 
463
500
 
464
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_runcilinference_1784235266"]
465
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_getplatformaccountid_1784235266" type="function" identity="getplatformaccountid" parent="none"]
466
- // CIL[DOC-MACRO purpose="Implements getplatformaccountid logic in cortex.functions.custom_cil-agent"]
467
- // CIL[DOC-RESPONSIBILITY responsibility="Execute getplatformaccountid and return its computed result"]
468
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[]"]
469
- // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
470
- // CIL[DOC-MICRO logic_summary="Provides getplatformaccountid with getPlatformAccountId( inputs, handling internal flow and returning a result" notable_decisions="[]"]
471
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
501
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:getPlatformAccountId:function" type="function" identity="getPlatformAccountId" parent="~/.framework/functions/cil-agent.ts"]
502
+ // CIL[DOC-MACRO purpose="Resolve the spine-system account id for unauthenticated platform requests."]
503
+ // CIL[DOC-RESPONSIBILITY responsibility="Return the id of the account with slug 'spine-system'."]
504
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
505
+ // CIL[DOC-CONTRACT inputs="[]" outputs="string account id or empty string" errors="Database errors are not caught" side_effects="Queries accounts table"]
506
+ // CIL[DOC-MICRO logic_summary="Select id from accounts where slug equals spine-system using adminDb.maybeSingle." notable_decisions=""]
507
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
472
508
  // CIL[DOC-STABILITY stability="stable"]
473
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
474
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
475
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
476
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
477
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
478
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
479
509
  async function getPlatformAccountId(): Promise<string> {
480
510
  const { data } = await adminDb.from('accounts').select('id').eq('slug', 'spine-system').maybeSingle()
481
511
  return data?.id || ''
482
512
  }
513
+ // CIL[DOC-VECTOR type="context" content="purpose='Resolve the spine-system account id for unauthenticated platform requests.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
514
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
515
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
516
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
517
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
518
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
519
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:getPlatformAccountId:function"]
520
+
521
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:ensureCilAgentConfig:function" type="function" identity="ensureCilAgentConfig" parent="~/.framework/functions/cil-agent.ts"]
522
+ // CIL[DOC-NOTE type="api_behavior" content="Bootstrap-owned rows carry metadata.managed_by='cil_agent' and are re-synced on each prepare (system_prompt, context_template, and managed metadata keys incl. retrieval_policy); unmarked rows are left untouched."]
523
+ // CIL[DOC-LEARNING topic="retrieval" content="Two item-embedding pipelines exist: embeddings.ts generate (vector_type = semantic/structure/...) and _shared/kb.ts kbIngest (vector_type = field name like 'content', item_type = type slug). retrieval_policy filters must name the values kbIngest writes, or kb articles are invisible to vector search."]
524
+ // CIL[DOC-MACRO purpose="Find-or-create the CIL Codebase Assistant ai_agent and cil_codebase_assistant prompt_config."]
525
+ // CIL[DOC-RESPONSIBILITY responsibility="Return ids for the agent and prompt config the CIL agent page should use, creating them with adminDb when absent."]
526
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/cil-agent.ts"]
527
+ // CIL[DOC-CONTRACT inputs="accountId: string" outputs="{ agentId, promptConfigId }" errors="Database insert errors propagate" side_effects="May insert ai_agents and prompt_configs rows; reads types for cil_retrievable declarations"]
528
+ // CIL[DOC-MICRO logic_summary="Resolve item types declaring functionality.kb.cil_retrievable into the default retrieval corpus (base: cil_chunk, kb_article); look up agent by name and prompt config by slug; insert seed-shaped rows when missing." notable_decisions="Reuses the module SYSTEM_PROMPT for the seeded agent; retrieval item_types come from type declarations, not a hardcoded corpus list."]
529
+ // CIL[DOC-CONFIDENCE pass="second" score="0.80" flags="none"]
530
+ // CIL[DOC-STABILITY stability="stable"]
531
+ async function ensureCilAgentConfig(accountId: string): Promise<{ agentId: string; promptConfigId: string }> {
532
+ const agentDefaults = {
533
+ description: 'Conversational agent that answers questions about the codebase using the Code Intelligence Layer.',
534
+ agent_type: 'rag',
535
+ model_config: { model: 'gpt-4o', temperature: 0.2, max_tokens: 4000 },
536
+ system_prompt: SYSTEM_PROMPT,
537
+ tools: [] as any[],
538
+ capabilities: ['rag_search', 'code_intelligence'],
539
+ constraints: { max_context_tokens: 12000 },
540
+ metadata: {
541
+ managed_by: 'cil_agent',
542
+ default_prompt_config_slug: 'cil_codebase_assistant',
543
+ },
544
+ }
545
+ // The default retrieval corpus is declared, not hardcoded: item types opt
546
+ // in via design_schema.functionality.kb.cil_retrievable === true. cil_chunk
547
+ // and kb_article are the framework base. This default is written once at
548
+ // agent provisioning (and re-synced for managed configs), so the extra read
549
+ // is cheap; a lookup failure falls back to the base corpus.
550
+ let declaredItemTypes: string[] = []
551
+ try {
552
+ const { data: kbTypes } = await adminDb
553
+ .from('types')
554
+ .select('slug')
555
+ .eq('design_schema->functionality->kb->>cil_retrievable', 'true')
556
+ declaredItemTypes = (kbTypes || []).map((t: any) => t.slug)
557
+ } catch (err: any) {
558
+ console.warn('cil_retrievable type lookup failed; using base corpus:', err?.message)
559
+ }
560
+ const defaultItemTypes = [...new Set(['cil_chunk', 'kb_article', ...declaredItemTypes])]
561
+
562
+ const contextTemplate =
563
+ "Answer using the numbered 'Relevant Information' excerpts and any tool results; cite them inline as [n]. Treat them as authoritative evidence even when a tool call returns zero results.\n" +
564
+ 'Lead with a synthesized answer, then a Sources list containing only the [n] you cited. Do not reproduce chunk metadata unless the user asked where code lives.'
565
+ const configDefaults = {
566
+ name: 'CIL Codebase Assistant',
567
+ context_template: contextTemplate,
568
+ model: 'gpt-4o',
569
+ temperature: 0.2,
570
+ max_tokens: 4000,
571
+ is_multi_turn: true,
572
+ max_history_messages: 10,
573
+ confidence_threshold: 0.3,
574
+ output_mode: 'text',
575
+ knowledge_sources: [] as any[],
576
+ available_tools: [] as string[],
577
+ metadata: {
578
+ managed_by: 'cil_agent',
579
+ max_turns: 6,
580
+ retrieval_policy: {
581
+ // kbIngest labels embeddings with the type slug (item_type) and the
582
+ // field name (vector_type), so both lists must include those values —
583
+ // 'content'/'title' here are kb field names, not CIL vector types.
584
+ item_types: defaultItemTypes,
585
+ vector_types: ['semantic', 'contract', 'content', 'title'],
586
+ max_security_level: 'internal',
587
+ require_approved: true,
588
+ },
589
+ },
590
+ }
483
591
 
592
+ let { data: agent } = await adminDb
593
+ .from('ai_agents')
594
+ .select('id, system_prompt, metadata')
595
+ .eq('name', 'CIL Codebase Assistant')
596
+ .eq('is_active', true)
597
+ .maybeSingle()
598
+ if (!agent?.id) {
599
+ const { data: created, error } = await adminDb
600
+ .from('ai_agents')
601
+ .insert({ account_id: accountId, name: 'CIL Codebase Assistant', ...agentDefaults, is_active: true })
602
+ .select('id')
603
+ .single()
604
+ if (error) throw error
605
+ agent = created
606
+ } else if (agent.metadata?.managed_by === 'cil_agent') {
607
+ await adminDb.from('ai_agents').update({
608
+ system_prompt: SYSTEM_PROMPT,
609
+ model_config: agentDefaults.model_config,
610
+ metadata: { ...(agent.metadata || {}), ...agentDefaults.metadata },
611
+ }).eq('id', agent.id)
612
+ }
484
613
 
614
+ let { data: pc } = await adminDb
615
+ .from('prompt_configs')
616
+ .select('id, context_template, metadata')
617
+ .eq('slug', 'cil_codebase_assistant')
618
+ .eq('is_active', true)
619
+ .maybeSingle()
620
+ if (!pc?.id) {
621
+ const { data: created, error } = await adminDb
622
+ .from('prompt_configs')
623
+ .insert({ account_id: accountId, slug: 'cil_codebase_assistant', ...configDefaults, is_active: true })
624
+ .select('id')
625
+ .single()
626
+ if (error) throw error
627
+ pc = created
628
+ } else if (pc.metadata?.managed_by === 'cil_agent') {
629
+ await adminDb.from('prompt_configs').update({
630
+ context_template: contextTemplate,
631
+ model: configDefaults.model,
632
+ temperature: configDefaults.temperature,
633
+ max_tokens: configDefaults.max_tokens,
634
+ metadata: { ...(pc.metadata || {}), ...configDefaults.metadata },
635
+ }).eq('id', pc.id)
636
+ }
485
637
 
638
+ return { agentId: agent.id, promptConfigId: pc.id }
639
+ }
640
+ // CIL[DOC-VECTOR type="context" content="purpose='Find-or-create the CIL Codebase Assistant ai_agent and prompt_config used by the CIL agent page.'; No verified external callers; imports: .framework/functions/_shared/db.ts"]
641
+ // CIL[DOC-VECTOR type="blast_radius" content="Local impact only; used by the prepare action"]
642
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
643
+ // CIL[DOC-VECTOR type="constraint" content="Bootstraps config records server-side so the admin CIL agent page works without an app seed"]
644
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
645
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
646
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:ensureCilAgentConfig:function"]
647
+
648
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:findOrCreateCilThread:function" type="function" identity="findOrCreateCilThread" parent="~/.framework/functions/cil-agent.ts"]
649
+ // CIL[DOC-LEARNING topic="schema" content="threads.target_type and target_id are NOT NULL, and (target_type, target_id, visibility) is unique — each conversation needs its own target record, so we create a lightweight items row per conversation rather than pointing every thread at the account."]
650
+ // CIL[DOC-MACRO purpose="Find-or-create the CIL agent conversation thread wired to the agent, prompt config, and CIL retrieval/tools."]
651
+ // CIL[DOC-RESPONSIBILITY responsibility="Return a thread id whose data carries agent_id, prompt_config_id, and cil_config for the new agent engine."]
652
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
653
+ // CIL[DOC-CONTRACT inputs="ctx, accountId, projectId, conversationId (optional), agentId, promptConfigId" outputs="thread id string" errors="Propagates admin-data create errors" side_effects="May create a threads record"]
654
+ // CIL[DOC-MICRO logic_summary="When conversationId is supplied, reuse the thread whose data.conversation_id matches; otherwise create a lightweight items row as the target, then a generic thread via admin-data." notable_decisions="Stores cil_config.enabled/use_cil_tools/project_ids so resolveAgentConfig augments retrieval and tools."]
655
+ // CIL[DOC-CONFIDENCE pass="second" score="0.80" flags="none"]
656
+ // CIL[DOC-STABILITY stability="stable"]
657
+ async function findOrCreateCilThread(
658
+ ctx: any,
659
+ accountId: string,
660
+ projectId: string | null,
661
+ conversationId: string | null,
662
+ agentId: string,
663
+ promptConfigId: string
664
+ ): Promise<string> {
665
+ const cilConfig = {
666
+ enabled: true,
667
+ project_ids: projectId ? [projectId] : [],
668
+ use_cil_tools: true,
669
+ }
486
670
 
671
+ if (conversationId) {
672
+ const { data: existing } = await adminDb
673
+ .from('threads')
674
+ .select('id, data')
675
+ .eq('account_id', accountId)
676
+ .filter('data->>conversation_id', 'eq', conversationId)
677
+ .limit(1)
678
+ const thread = existing?.[0]
679
+ if (thread?.id) {
680
+ const merged = { ...(thread.data || {}), agent_id: agentId, prompt_config_id: promptConfigId, cil_config: cilConfig }
681
+ await adminDb.from('threads').update({ data: merged }).eq('id', thread.id)
682
+ return thread.id
683
+ }
684
+ }
487
685
 
488
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_getplatformaccountid_1784235266"]
489
- // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_handler_1784235266" type="variable" identity="handler" parent="none"]
490
- // CIL[DOC-MACRO purpose="Defines handler configuration or state in cortex.functions.custom_cil-agent"]
491
- // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for handler"]
492
- // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent" layer="function" related_files="[]"]
493
- // CIL[DOC-CONTRACT inputs="none" outputs="value of handler" errors="none" side_effects="none"]
494
- // CIL[DOC-MICRO logic_summary="Declares handler with initial value or constant binding used by cortex.functions.custom_cil-agent" notable_decisions="[]"]
495
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
496
- // CIL[DOC-STABILITY stability="stable"]
497
- // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
498
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
499
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
500
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
686
+ // Threads are unique per (target_type, target_id, visibility), so each
687
+ // conversation gets its own lightweight items record as the thread target.
688
+ const target = await adminCreate(ctx, {
689
+ entity: 'items',
690
+ type_slug: 'item',
691
+ account_id: accountId,
692
+ title: 'CIL agent conversation',
693
+ status: 'active',
694
+ data: { conversation_id: conversationId },
695
+ })
696
+ if (!target?.id) throw new Error('Failed to create CIL agent conversation target')
697
+
698
+ const thread = await adminCreate(ctx, {
699
+ entity: 'threads',
700
+ type_slug: 'thread',
701
+ account_id: accountId,
702
+ target_type: 'items',
703
+ target_id: target.id,
704
+ title: 'CIL agent conversation',
705
+ visibility: 'internal',
706
+ status: 'active',
707
+ data: {
708
+ agent_id: agentId,
709
+ prompt_config_id: promptConfigId,
710
+ conversation_id: conversationId,
711
+ cil_config: cilConfig,
712
+ },
713
+ })
714
+ if (!thread?.id) throw new Error('Failed to create CIL agent thread')
715
+ return thread.id
716
+ }
717
+ // CIL[DOC-VECTOR type="context" content="purpose='Find-or-create the CIL agent conversation thread wired to the agent engine config.'; No verified external callers; imports: .framework/functions/_shared/db.ts,.framework/functions/admin-data.ts"]
718
+ // CIL[DOC-VECTOR type="blast_radius" content="Local impact only; used by the prepare action"]
719
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
720
+ // CIL[DOC-VECTOR type="constraint" content="Thread data must carry agent_id, prompt_config_id, and cil_config for resolveAgentConfig to wire the new engine"]
501
721
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
502
722
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
723
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:findOrCreateCilThread:function"]
724
+
725
+
726
+
727
+
728
+
729
+ // CIL[BEGIN stable_id="~/.framework/functions/cil-agent.ts:handler:constant" type="constant" identity="handler" parent="~/.framework/functions/cil-agent.ts"]
730
+ // CIL[DOC-MACRO purpose="Create the Netlify function handler for the CIL agent, dispatching ask/chat/tool/tools actions."]
731
+ // CIL[DOC-RESPONSIBILITY responsibility="Handle HTTP requests for CIL agent actions and return JSON responses or errors."]
732
+ // CIL[DOC-CONTEXT module="functions" layer="edge" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-ids.ts,.framework/functions/admin-data.ts,.framework/functions/cil-agent.ts"]
733
+ // CIL[DOC-CONTRACT inputs="HTTP request context and JSON body" outputs="JSON response object" errors="Authentication, missing parameters, unknown action, LLM or database errors" side_effects="Queries chunks and account; writes messages for chat threads"]
734
+ // CIL[DOC-MICRO logic_summary="createHandler wrapper that parses action, resolves account, dispatches to tools or runCilInference, and persists chat messages." notable_decisions="Defaults action to ask; supports human/assistant history for chat; uses resolveTypeId and adminCreate to store messages."]
735
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
736
+ // CIL[DOC-STABILITY stability="stable"]
503
737
  export const handler = createHandler(async (ctx, body) => {
504
738
  const action = ctx.query?.action || 'ask'
505
739
  const accountId = ctx.accountId || await getPlatformAccountId()
506
740
 
507
741
 
742
+ if (action === 'prepare') {
743
+ const projectId = body?.project_id || ctx.query?.project_id || null
744
+ const conversationId = body?.conversation_id || null
745
+ const runCtx = {
746
+ ...ctx,
747
+ accountId,
748
+ principal:
749
+ ctx.principal?.id && ctx.principal.id !== 'anonymous'
750
+ ? ctx.principal
751
+ : SYSTEM_PRINCIPAL,
752
+ }
753
+ const { agentId, promptConfigId } = await ensureCilAgentConfig(accountId)
754
+ const threadId = await findOrCreateCilThread(runCtx, accountId, projectId, conversationId, agentId, promptConfigId)
755
+ return { thread_id: threadId, agent_id: agentId, prompt_config_id: promptConfigId }
756
+ }
757
+
758
+
508
759
  if (action === 'tools') {
509
760
  return { tools: CIL_TOOLS }
510
761
  }
@@ -584,9 +835,14 @@ export const handler = createHandler(async (ctx, body) => {
584
835
  return { message, answer, sources, tool_calls_made, thread_id: threadId }
585
836
  }
586
837
 
587
- throw new Error(`Unknown action: ${action}. Valid: ask, chat, tool, tools`)
838
+ throw new Error(`Unknown action: ${action}. Valid: prepare, ask, chat, tool, tools`)
588
839
  })
840
+ // CIL[DOC-VECTOR type="context" content="purpose='Create the Netlify function handler for the CIL agent, dispatching ask/chat/tool/tools actions.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/resolve-ids.ts"]
841
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
842
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
843
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
844
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
845
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
846
+ // CIL[END stable_id="~/.framework/functions/cil-agent.ts:handler:constant"]
589
847
 
590
848
 
591
-
592
- // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_handler_1784235266"]