spine-framework 0.3.145 → 0.4.0

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 +5051 -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
@@ -0,0 +1,454 @@
1
+ /**
2
+ * @module search-core
3
+ * @audience both
4
+ * @layer shared-core
5
+ * @stability stable
6
+ *
7
+ * This module provides core search functionalities for the application, leveraging the admin database for data retrieval and manipulation. It serves as a critical component in the overall architecture, facilitating efficient search operations across various datasets. INVARIANT: The module assumes that the database is always accessible and properly configured for search queries.
8
+ *
9
+ * @seeAlso db.js (provides the database connection and operations needed for search functionality.)
10
+ * @seeAlso shared.js (contains shared utilities that may be used across different modules.)
11
+ *
12
+ * @cil-generated
13
+ */
14
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/tools/cil/search-core.ts"]
15
+ // CIL[DOC-MACRO purpose="Provides core search operations over the CIL chunk index"]
16
+ // CIL[DOC-RESPONSIBILITY responsibility="Expose title, content, semantic and hybrid search utilities for CIL chunks"]
17
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts"]
18
+ // CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="Database and network failures propagate to caller" side_effects="N/A"]
19
+ // CIL[DOC-MICRO logic_summary="Imports adminDb and exports normalizeIdentifier, buildSearchResult, titleSearch, contentSearch, embedQuery, semanticSearch and hybridSearch" notable_decisions="[]"]
20
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
21
+ // CIL[DOC-STABILITY stability="stable"]
22
+ // CIL[DOC-AUDIENCE audience="both"]
23
+ import { adminDb } from '../../shared/db.js'
24
+ // CIL[DOC-VECTOR type="context" content="purpose='Provides core search operations over the CIL chunk index'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
25
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
26
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
27
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
28
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
29
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
30
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:module_header:module_header"]
31
+
32
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:normalizeIdentifier:function" type="function" identity="normalizeIdentifier" parent="~/.framework/mcp/tools/cil/search-core.ts"]
33
+ // CIL[DOC-MACRO purpose="Normalize a string identifier to lowercase alphanumeric"]
34
+ // CIL[DOC-RESPONSIBILITY responsibility="Sanitize raw strings for consistent identifier comparison"]
35
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
36
+ // CIL[DOC-CONTRACT inputs="s: string" outputs="string" errors="N/A" side_effects="none"]
37
+ // CIL[DOC-MICRO logic_summary="Converts input to lowercase and removes all non-alphanumeric characters" notable_decisions="[]"]
38
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
39
+ // CIL[DOC-STABILITY stability="internal"]
40
+ /**
41
+ * Normalizes a string identifier by converting it to lowercase and removing all non-alphanumeric characters. This function ensures that identifiers are consistent and suitable for further processing.
42
+ *
43
+ * @inputSpec
44
+ * s: string (required) — the string identifier to normalize.
45
+ * @outputSpec string — the normalized identifier consisting only of lowercase alphanumeric characters.
46
+ * @sideEffects none
47
+ * @stability internal
48
+ * @cil-generated
49
+ */
50
+ export const normalizeIdentifier = (s: string) =>
51
+ s.toLowerCase().replace(/[^a-z0-9]/g, '')
52
+ // CIL[DOC-VECTOR type="context" content="purpose='Normalize a string identifier to lowercase alphanumeric'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
53
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
54
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
55
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
56
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
57
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
58
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:normalizeIdentifier:function"]
59
+
60
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:SearchResult:interface" type="interface" identity="SearchResult" parent="~/.framework/mcp/tools/cil/search-core.ts"]
61
+ // CIL[DOC-MACRO purpose="Defines the typed shape of a CIL search result"]
62
+ // CIL[DOC-RESPONSIBILITY responsibility="Standardize chunk metadata, scoring and content fields returned by search APIs"]
63
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
64
+ // CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="N/A" side_effects="N/A"]
65
+ // CIL[DOC-MICRO logic_summary="Declares fields including stable_id, macro, micro, code_content, match_type and similarity" notable_decisions="[]"]
66
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
67
+ // CIL[DOC-STABILITY stability="internal"]
68
+ /**
69
+ * The SearchResult interface defines the structure of a search result object, encapsulating various attributes related to search outcomes. It exists to standardize the representation of search results across the application.
70
+ *
71
+ * @sideEffects none
72
+ * @stability internal
73
+ * @cil-generated
74
+ */
75
+ export interface SearchResult {
76
+ id: string
77
+ stable_id: string
78
+ version_id: string | null
79
+ chunk_name: string
80
+ file_path: string
81
+ chunk_type: string
82
+ source_set_id: string | null
83
+ layer: string | null
84
+ macro: string
85
+ micro: string
86
+ input_spec: string
87
+ output_spec: string
88
+ side_effects: string
89
+ stability: string
90
+ tags: string
91
+ complexity: string
92
+ doc_confidence: string
93
+ validation_errors: string[]
94
+ code_content: string
95
+ similarity: number | null
96
+ match_type: 'content' | 'semantic' | 'text'
97
+ }
98
+ // CIL[DOC-VECTOR type="context" content="purpose='Defines the typed shape of a CIL search result'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
99
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
100
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
101
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
102
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
103
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
104
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:SearchResult:interface"]
105
+
106
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:buildSearchResult:function" type="function" identity="buildSearchResult" parent="~/.framework/mcp/tools/cil/search-core.ts"]
107
+ // CIL[DOC-MACRO purpose="Construct a SearchResult object from a raw chunk row"]
108
+ // CIL[DOC-RESPONSIBILITY responsibility="Map database chunk fields into a typed search result with sensible defaults"]
109
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
110
+ // CIL[DOC-CONTRACT inputs="chunk: any, match_type: SearchResult['match_type'], similarity: number | null (optional)" outputs="SearchResult" errors="N/A" side_effects="none"]
111
+ // CIL[DOC-MICRO logic_summary="Extracts chunk.data, applies defaults for missing metadata, and assembles the SearchResult" notable_decisions="[]"]
112
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
113
+ // CIL[DOC-STABILITY stability="internal"]
114
+ /**
115
+ * Builds a structured search result object from a given chunk of data, encapsulating various attributes for search functionality. This function is essential for transforming raw data into a standardized format for search results.
116
+ *
117
+ * @macro Function that constructs a search result object from a data chunk.
118
+ * @micro Extracts properties from the chunk and assigns default values where necessary.
119
+ * @inputSpec
120
+ * - chunk: any (required) — the data chunk containing search-related information.
121
+ * - match_type: SearchResult['match_type'] (required) — the type of match for the search result.
122
+ * - similarity: number | null (optional[nullable]) — a similarity score associated with the search result.
123
+ * @outputSpec SearchResult — an object containing structured search result data.
124
+ * @sideEffects none
125
+ * @stability internal
126
+ * @cil-generated
127
+ */
128
+ export function buildSearchResult(
129
+ chunk: any,
130
+ match_type: SearchResult['match_type'],
131
+ similarity: number | null = null,
132
+ ): SearchResult {
133
+ const d = chunk.data || {}
134
+ return {
135
+ id: chunk.id,
136
+ stable_id: d.stable_id || '',
137
+ version_id: d.version_id || null,
138
+ chunk_name: d.chunk_name || '',
139
+ file_path: d.file_path || '',
140
+ chunk_type: d.chunk_type || '',
141
+ source_set_id: d.source_set_id || null,
142
+ layer: d.layer || null,
143
+ macro: d.macro || '',
144
+ micro: d.micro || '',
145
+ input_spec: d.input_spec || '',
146
+ output_spec: d.output_spec || '',
147
+ side_effects: d.side_effects || '',
148
+ stability: d.stability || 'unknown',
149
+ tags: d.tags || '',
150
+ complexity: d.complexity || '',
151
+ doc_confidence: d.doc_confidence || 'unverified_legacy',
152
+ validation_errors: d.doc_validation_errors || [],
153
+ code_content: d.code_content || '',
154
+ similarity,
155
+ match_type,
156
+ }
157
+ }
158
+ // CIL[DOC-VECTOR type="context" content="purpose='Construct a SearchResult object from a raw chunk row'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
159
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
160
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
161
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
162
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
163
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
164
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:buildSearchResult:function"]
165
+
166
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:titleSearch:function" type="function" identity="titleSearch" parent="~/.framework/mcp/tools/cil/search-core.ts"]
167
+ // CIL[DOC-MACRO purpose="Case-insensitive title substring search over CIL chunks"]
168
+ // CIL[DOC-RESPONSIBILITY responsibility="Return chunks whose title contains the query"]
169
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
170
+ // CIL[DOC-CONTRACT inputs="q: string, project_id?: string, limit?: number" outputs="Promise<SearchResult[]>" errors="Database errors propagate" side_effects="Queries the items table"]
171
+ // CIL[DOC-MICRO logic_summary="Builds a Supabase query for active cil_chunks, optionally filters by project_id and maps rows to SearchResult" notable_decisions="[]"]
172
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
173
+ // CIL[DOC-STABILITY stability="internal"]
174
+ export async function titleSearch({
175
+ q,
176
+ project_id,
177
+ limit = 10,
178
+ }: {
179
+ q: string
180
+ project_id?: string
181
+ limit?: number
182
+ }): Promise<SearchResult[]> {
183
+ let qb = adminDb
184
+ .from('items')
185
+ .select('id, title, data')
186
+ .filter('data->>kb_type', 'eq', 'cil_chunk')
187
+ .eq('is_active', true)
188
+ .ilike('title', `%${q}%`)
189
+ .limit(limit)
190
+ if (project_id) qb = (qb as any).filter('data->>project_id', 'eq', project_id)
191
+
192
+ const { data } = await qb
193
+ return (data || []).map((c: any) => buildSearchResult(c, 'text', null))
194
+ }
195
+ // CIL[DOC-VECTOR type="context" content="purpose='Case-insensitive title substring search over CIL chunks'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
196
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
197
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
198
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
199
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
200
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
201
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:titleSearch:function"]
202
+
203
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:contentSearch:function" type="function" identity="contentSearch" parent="~/.framework/mcp/tools/cil/search-core.ts"]
204
+ // CIL[DOC-MACRO purpose="Score CIL chunks by keyword presence across metadata and code"]
205
+ // CIL[DOC-RESPONSIBILITY responsibility="Find the most relevant chunks for a free-text query using term scoring"]
206
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
207
+ // CIL[DOC-CONTRACT inputs="q: string, project_id?: string, limit?: number" outputs="Promise<SearchResult[]>" errors="N/A" side_effects="Queries the items table; may call titleSearch as fallback"]
208
+ // CIL[DOC-MICRO logic_summary="Fetches active chunks, scores matches in title, macro, micro, tags and code, boosts exact phrases, returns top results or titleSearch fallback" notable_decisions="[]"]
209
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
210
+ // CIL[DOC-STABILITY stability="internal"]
211
+ export async function contentSearch({
212
+ q,
213
+ project_id,
214
+ limit = 10,
215
+ }: {
216
+ q: string
217
+ project_id?: string
218
+ limit?: number
219
+ }): Promise<SearchResult[]> {
220
+ const pageLimit = 5000
221
+ let qb = adminDb
222
+ .from('items')
223
+ .select('id, title, data')
224
+ .filter('data->>kb_type', 'eq', 'cil_chunk')
225
+ .eq('is_active', true)
226
+ .order('updated_at', { ascending: false })
227
+ .limit(pageLimit)
228
+ if (project_id) qb = (qb as any).filter('data->>project_id', 'eq', project_id)
229
+
230
+ const { data: allChunks } = await qb
231
+
232
+ const terms = q.toLowerCase().split(/\s+/).filter(Boolean)
233
+ const normalizedTerms = terms
234
+ .map((t) => normalizeIdentifier(t))
235
+ .filter((t) => t.length >= 2)
236
+
237
+ if (normalizedTerms.length === 0) return titleSearch({ q, project_id, limit })
238
+
239
+ const scored = (allChunks || [])
240
+ .map((c: any) => {
241
+ const title = (c.title || '').toLowerCase()
242
+ const macro = (c.data?.macro || '').toLowerCase()
243
+ const micro = (c.data?.micro || '').toLowerCase()
244
+ const tags = (c.data?.tags || '').toLowerCase()
245
+ const codeContent = (c.data?.code_content || '').toLowerCase()
246
+
247
+ const normTitle = normalizeIdentifier(title)
248
+ const normMacro = normalizeIdentifier(macro)
249
+ const normMicro = normalizeIdentifier(micro)
250
+ const normTags = normalizeIdentifier(tags)
251
+ const normCode = normalizeIdentifier(codeContent)
252
+
253
+ let score = 0
254
+ for (const term of normalizedTerms) {
255
+ if (normTitle.includes(term)) score += 3
256
+ if (normMacro.includes(term)) score += 2
257
+ if (normMicro.includes(term)) score += 1
258
+ if (normTags.includes(term)) score += 1
259
+ if (normCode.includes(term)) {
260
+ const count = normCode.split(term).length - 1
261
+ score += Math.min(count, 3)
262
+ }
263
+ }
264
+
265
+ const phrase = q.toLowerCase()
266
+ const normPhrase = normalizeIdentifier(phrase)
267
+ if (codeContent.includes(phrase) || normCode.includes(normPhrase)) score += 5
268
+
269
+ return { chunk: c, score }
270
+ })
271
+ .filter(({ score }) => score > 0)
272
+ .sort((a, b) => b.score - a.score)
273
+ .slice(0, limit)
274
+
275
+ if (scored.length === 0) return titleSearch({ q, project_id, limit })
276
+
277
+ const maxScore = scored[0].score || 1
278
+ return scored.map(({ chunk, score }) =>
279
+ buildSearchResult(chunk, 'content', score / maxScore),
280
+ )
281
+ }
282
+ // CIL[DOC-VECTOR type="context" content="purpose='Score CIL chunks by keyword presence across metadata and code'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
283
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
284
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
285
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
286
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
287
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
288
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:contentSearch:function"]
289
+
290
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:embedQuery:function" type="function" identity="embedQuery" parent="~/.framework/mcp/tools/cil/search-core.ts"]
291
+ // CIL[DOC-MACRO purpose="Fetch an OpenAI embedding vector for a query string"]
292
+ // CIL[DOC-RESPONSIBILITY responsibility="Convert a search query into a JSON array vector string for semantic search"]
293
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
294
+ // CIL[DOC-CONTRACT inputs="q: string" outputs="Promise<string | null>" errors="Returns null on any API or parsing failure" side_effects="POST to the OpenAI embeddings endpoint"]
295
+ // CIL[DOC-MICRO logic_summary="Sends the query to the embeddings endpoint and serializes the returned vector as a JSON array string" notable_decisions="[]"]
296
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
297
+ // CIL[DOC-STABILITY stability="internal"]
298
+ /**
299
+ * The embedQuery function sends a query string to an external API to retrieve its embedding vector. It exists to facilitate the integration of OpenAI's embedding capabilities into the application.
300
+ *
301
+ * @macro Async function that retrieves text embeddings from an external API.
302
+ * @micro Constructs a POST request to the embeddings endpoint with the query string as input.
303
+ * @inputSpec
304
+ * - q: string (required) — the query string to be embedded.
305
+ * @outputSpec Promise<string | null> — returns the embedding vector as a string in JSON array format or null if an error occurs.
306
+ * @sideEffects makes an external API call to OpenAI's embeddings endpoint
307
+ * @stability internal
308
+ * @calls fetch
309
+ * @errorHandling returns null on any error during the API call or response processing
310
+ * @cil-generated
311
+ */
312
+ async function embedQuery(q: string): Promise<string | null> {
313
+ const apiKey = process.env.OPENAI_API_KEY || process.env.LLM_API_KEY
314
+ const baseUrl = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1'
315
+ if (!apiKey) return null
316
+ try {
317
+ const res = await fetch(`${baseUrl}/embeddings`, {
318
+ method: 'POST',
319
+ headers: {
320
+ 'Content-Type': 'application/json',
321
+ Authorization: `Bearer ${apiKey}`,
322
+ },
323
+ body: JSON.stringify({ model: 'text-embedding-3-small', input: [q] }),
324
+ })
325
+ if (!res.ok) return null
326
+ const j: any = await res.json()
327
+ const vec = j.data?.[0]?.embedding
328
+ if (!Array.isArray(vec)) return null
329
+ return `[${vec.join(',')}]`
330
+ } catch {
331
+ return null
332
+ }
333
+ }
334
+ // CIL[DOC-VECTOR type="context" content="purpose='Fetch an OpenAI embedding vector for a query string'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
335
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
336
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
337
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
338
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
339
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
340
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:embedQuery:function"]
341
+
342
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:semanticSearch:function" type="function" identity="semanticSearch" parent="~/.framework/mcp/tools/cil/search-core.ts"]
343
+ // CIL[DOC-MACRO purpose="Semantic search over CIL chunks using vector similarity"]
344
+ // CIL[DOC-RESPONSIBILITY responsibility="Return chunks semantically similar to the query using the match_embeddings RPC"]
345
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
346
+ // CIL[DOC-CONTRACT inputs="q: string, project_id?: string, limit?: number" outputs="Promise<SearchResult[]>" errors="Returns empty array on RPC failure or missing data" side_effects="Calls embedQuery and adminDb RPC"]
347
+ // CIL[DOC-MICRO logic_summary="Embeds the query, calls match_embeddings, fetches chunk records by id and maps results" notable_decisions="[]"]
348
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
349
+ // CIL[DOC-STABILITY stability="internal"]
350
+ export async function semanticSearch({
351
+ q,
352
+ project_id,
353
+ limit = 10,
354
+ }: {
355
+ q: string
356
+ project_id?: string
357
+ limit?: number
358
+ }): Promise<SearchResult[]> {
359
+ const vector = await embedQuery(q)
360
+ if (!vector) return []
361
+
362
+ const matchCount = limit * 3
363
+ let rpcResult: { data: any; error: any } | null = null
364
+ try {
365
+ rpcResult = await adminDb.rpc('match_embeddings', {
366
+ query_embedding: vector,
367
+ match_count: matchCount,
368
+ filter_account_ids: null,
369
+ filter_vector_type: null,
370
+ similarity_threshold: 0.15,
371
+ filter_item_types: ['cil_chunk'],
372
+ })
373
+ } catch (err: any) {
374
+ console.error('match_embeddings rpc failed:', err?.message || String(err))
375
+ return []
376
+ }
377
+
378
+ const { data, error } = rpcResult || { data: null, error: 'rpc call failed' }
379
+ if (error || !data || !data.length) return []
380
+
381
+ const docIds = data.map((d: any) => d.document_id)
382
+ let chunkQb = adminDb
383
+ .from('items')
384
+ .select('id, title, data')
385
+ .filter('data->>kb_type', 'eq', 'cil_chunk')
386
+ .eq('is_active', true)
387
+ .in('data->>stable_id', docIds)
388
+ if (project_id)
389
+ chunkQb = (chunkQb as any).filter('data->>project_id', 'eq', project_id)
390
+
391
+ const { data: chunks } = await chunkQb
392
+ const chunkMap = new Map((chunks || []).map((c: any) => [c.data?.stable_id, c]))
393
+
394
+ return (data as any[])
395
+ .map((d: any) => {
396
+ const c = chunkMap.get(d.document_id)
397
+ if (!c) return null
398
+ return buildSearchResult(c, 'semantic', d.similarity)
399
+ })
400
+ .filter(Boolean)
401
+ .slice(0, limit) as SearchResult[]
402
+ }
403
+ // CIL[DOC-VECTOR type="context" content="purpose='Semantic search over CIL chunks using vector similarity'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
404
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
405
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
406
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
407
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
408
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
409
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:semanticSearch:function"]
410
+
411
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:hybridSearch:function" type="function" identity="hybridSearch" parent="~/.framework/mcp/tools/cil/search-core.ts"]
412
+ // CIL[DOC-MACRO purpose="Combine content and semantic search results into a single ranked list"]
413
+ // CIL[DOC-RESPONSIBILITY responsibility="Merge and rank content-based and vector-based search results"]
414
+ // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
415
+ // CIL[DOC-CONTRACT inputs="q: string, project_id?: string, limit?: number" outputs="Promise<SearchResult[]>" errors="N/A" side_effects="Calls contentSearch and semanticSearch"]
416
+ // CIL[DOC-MICRO logic_summary="Runs both search strategies in parallel, merges results by id, sorts by similarity and slices to limit" notable_decisions="[]"]
417
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
418
+ // CIL[DOC-STABILITY stability="internal"]
419
+ export async function hybridSearch({
420
+ q,
421
+ project_id,
422
+ limit = 10,
423
+ }: {
424
+ q: string
425
+ project_id?: string
426
+ limit?: number
427
+ }): Promise<SearchResult[]> {
428
+ const [content, semantic] = await Promise.all([
429
+ contentSearch({ q, project_id, limit }),
430
+ semanticSearch({ q, project_id, limit }),
431
+ ])
432
+
433
+ const byId = new Map<string, SearchResult>()
434
+ for (const r of content) {
435
+ byId.set(r.id, r)
436
+ }
437
+ for (const r of semantic) {
438
+ const existing = byId.get(r.id)
439
+ if (!existing || (r.similarity ?? 0) > (existing.similarity ?? 0)) {
440
+ byId.set(r.id, r)
441
+ }
442
+ }
443
+
444
+ return Array.from(byId.values())
445
+ .sort((a, b) => (b.similarity ?? 0) - (a.similarity ?? 0))
446
+ .slice(0, limit)
447
+ }
448
+ // CIL[DOC-VECTOR type="context" content="purpose='Combine content and semantic search results into a single ranked list'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
449
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
450
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
451
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
452
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
453
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
454
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:hybridSearch:function"]
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @module search
3
+ * @audience both
4
+ * @layer shared-core
5
+ * @stability stable
6
+ *
7
+ * This module provides search functionality for the MCP framework, enabling content, semantic, and title-based searches. It acts as a bridge between the search core and the server, facilitating efficient query handling. INVARIANT: The search functions must always return results in a consistent format.
8
+ *
9
+ * @seeAlso search-core.js (contains the core search logic)
10
+ * @seeAlso @mcp/sdk (provides the server interface)
11
+ *
12
+ * @cil-generated
13
+ */
14
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/tools/cil/search.ts"]
15
+ // CIL[DOC-MACRO purpose="Provides search functionality for the MCP framework"]
16
+ // CIL[DOC-RESPONSIBILITY responsibility="Bridge the CIL search core and the MCP server by exporting the register function"]
17
+ // CIL[DOC-CONTEXT module="mcp-tools-cil" layer="shared-core" related_files=".framework/mcp/tools/cil/search-core.ts"]
18
+ // CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="N/A" side_effects="N/A"]
19
+ // CIL[DOC-MICRO logic_summary="Imports McpServer, zod and the search core, then exposes a register function for the MCP tool" notable_decisions="[]"]
20
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
21
+ // CIL[DOC-STABILITY stability="stable"]
22
+ // CIL[DOC-AUDIENCE audience="both"]
23
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
24
+ import { z } from 'zod'
25
+ import { contentSearch, semanticSearch, titleSearch } from './search-core.js'
26
+ // CIL[DOC-VECTOR type="context" content="purpose='Provides search functionality for the MCP framework'; No verified external callers; imports: .framework/mcp/tools/cil/search-core.ts"]
27
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
28
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
29
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
30
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
31
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
32
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search.ts:module_header:module_header"]
33
+
34
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search.ts:register:function" type="function" identity="register" parent="~/.framework/mcp/tools/cil/search.ts"]
35
+ // CIL[DOC-MACRO purpose="Register the spine_cil_search_chunks MCP tool and dispatch queries"]
36
+ // CIL[DOC-RESPONSIBILITY responsibility="Implement the tool handler that selects search mode and formats JSON results"]
37
+ // CIL[DOC-CONTEXT module="mcp-tools-cil" layer="shared-core" related_files=".framework/mcp/tools/cil/search-core.ts,.framework/mcp/tools/cil/search.ts"]
38
+ // CIL[DOC-CONTRACT inputs="server: McpServer" outputs="void" errors="Database and network failures propagate to caller" side_effects="registers tool on server and calls search functions"]
39
+ // CIL[DOC-MICRO logic_summary="Use server.registerTool with a zod schema, then dispatch semantic, text or hybrid search and return JSON text" notable_decisions="Hybrid merges content and semantic by similarity; falls back to title search if empty"]
40
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
41
+ // CIL[DOC-STABILITY stability="stable"]
42
+ export function register(server: McpServer) {
43
+
44
+ server.registerTool(
45
+ 'spine_cil_search_chunks',
46
+ {
47
+ description: 'Search for code chunks by purpose, behaviour, or name. Uses hybrid semantic + text search over all embedded chunks. Returns chunk_name, file_path, macro (purpose), chunk_type, doc_confidence, and similarity score.',
48
+ inputSchema: z.object({
49
+ q: z.string().describe('Search query — describe what the chunk does, e.g. "authenticate user and check roles"'),
50
+ project_id: z.string().optional().describe('Limit to a specific project UUID'),
51
+ mode: z.enum(['hybrid', 'semantic', 'text']).default('hybrid').optional().describe('hybrid = semantic + content; semantic = embedding only; text = name/path substring'),
52
+ limit: z.number().int().min(1).max(50).default(10).optional().describe('Max results to return'),
53
+ }),
54
+ },
55
+ async ({ q, project_id, mode, limit }) => {
56
+ let results: any[] = []
57
+
58
+ if (mode === 'semantic') {
59
+ results = await semanticSearch({ q, project_id, limit })
60
+ if (results.length === 0) results = await contentSearch({ q, project_id, limit })
61
+ } else if (mode === 'text') {
62
+ results = await titleSearch({ q, project_id, limit })
63
+ } else {
64
+ const [content, semantic] = await Promise.all([
65
+ contentSearch({ q, project_id, limit }),
66
+ semanticSearch({ q, project_id, limit }),
67
+ ])
68
+ const byId = new Map<string, any>()
69
+ for (const r of content) byId.set(r.id, r)
70
+ for (const r of semantic) {
71
+ const existing = byId.get(r.id)
72
+ if (!existing || (r.similarity ?? 0) > (existing.similarity ?? 0)) {
73
+ byId.set(r.id, r)
74
+ }
75
+ }
76
+ results = Array.from(byId.values())
77
+ .sort((a, b) => (b.similarity ?? 0) - (a.similarity ?? 0))
78
+ .slice(0, limit ?? 10)
79
+ if (results.length === 0) results = await titleSearch({ q, project_id, limit })
80
+ }
81
+
82
+ return {
83
+ content: [{
84
+ type: 'text',
85
+ text: JSON.stringify({ query: q, mode: mode ?? 'hybrid', count: results.length, results }, null, 2),
86
+ }],
87
+ }
88
+ }
89
+ )
90
+ }
91
+ // CIL[DOC-VECTOR type="context" content="purpose='Register the spine_cil_search_chunks MCP tool and dispatch queries'; No verified external callers; imports: .framework/mcp/tools/cil/search-core.ts"]
92
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
93
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
94
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
95
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
96
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
97
+ // CIL[END stable_id="~/.framework/mcp/tools/cil/search.ts:register:function"]