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
@@ -0,0 +1,477 @@
1
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/db.ts:mcp_db:file" type="file" identity="mcp_db" parent="~/.framework/mcp/shared/db.ts"]
2
+ // CIL[DOC-MACRO purpose="MCP admin-data proxy query builder and type resolver for the Spine framework."]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provides a fluent Query class that proxies Supabase-style requests to the admin-data Netlify function, plus helpers to resolve type and link type IDs."]
4
+ // CIL[DOC-CONTEXT module="mcp" layer="shared" related_files=".framework/mcp/shared/db.ts"]
5
+ // CIL[DOC-CONTRACT inputs="table names, filters, sort/limit options, insert/update/delete payloads" outputs="records or {data,error} shaped results" errors="Environment missing, network/HTTP errors, record not found" side_effects="Makes fetch calls to the Spine admin-data and function endpoints."]
6
+ // CIL[DOC-MICRO logic_summary="Builds URL query parameters, applies client-side filters/sorting, handles single/maybeSingle semantics, and routes apps/embeddings tables to dedicated function endpoints." notable_decisions="admin-data does not support upsert; apps/embeddings writes are rejected; RPC only supports match_embeddings."]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+
10
+ import { randomUUID } from 'node:crypto'
11
+
12
+ const SPINE_URL = process.env.SPINE_URL || process.env.URL || ''
13
+
14
+ const API_KEY = process.env.SPINE_API_KEY || process.env.SPINE_FRAMEWORK_API_KEY || ''
15
+
16
+ function baseUrl(): string {
17
+ if (!SPINE_URL) throw new Error('SPINE_URL environment variable is required')
18
+ return SPINE_URL.replace(/\/$/, '')
19
+ }
20
+
21
+ function headers(): Record<string, string> {
22
+ if (!API_KEY) throw new Error('SPINE_API_KEY environment variable is required')
23
+ return {
24
+ 'Content-Type': 'application/json',
25
+ 'X-Api-Key': API_KEY,
26
+ 'X-Request-ID': randomUUID(),
27
+ 'X-Source': 'spine-framework-mcp',
28
+ }
29
+ }
30
+
31
+ async function handleResponse<T>(res: Response): Promise<T> {
32
+ const body = await res.json().catch(() => ({}))
33
+ if (!res.ok) {
34
+ throw new Error(body?.error || body?.message || `request failed: ${res.status}`)
35
+ }
36
+ if (body && 'data' in body) {
37
+ return body.data as T
38
+ }
39
+ return body as T
40
+ }
41
+
42
+ async function fetchAdminData(
43
+ entity: string,
44
+ action: 'list' | 'get' | 'create' | 'update' | 'remove' | 'stats',
45
+ query: Record<string, any> = {},
46
+ body?: Record<string, any>
47
+ ): Promise<any> {
48
+ const methodMap: Record<string, string> = {
49
+ list: 'GET',
50
+ get: 'GET',
51
+ stats: 'GET',
52
+ create: 'POST',
53
+ update: 'PATCH',
54
+ remove: 'DELETE',
55
+ }
56
+ const method = methodMap[action]
57
+ const params: Record<string, any> = { ...query, action, entity, method }
58
+ const qs = new URLSearchParams(params as Record<string, string>).toString()
59
+ const init: RequestInit = { method, headers: headers() }
60
+ if (body && (action === 'create' || action === 'update')) {
61
+ init.body = JSON.stringify(body)
62
+ }
63
+ const res = await fetch(`${baseUrl()}/.netlify/functions/admin-data?${qs}`, init)
64
+ const data = await handleResponse<any>(res)
65
+ if (Array.isArray(data)) return data
66
+ return data
67
+ }
68
+
69
+ export async function fetchFunction(functionName: string, action: string, query: Record<string, any> = {}, body?: Record<string, any>): Promise<any> {
70
+ const method = body ? 'POST' : 'GET'
71
+ const params: Record<string, any> = { ...query, action, method }
72
+ const qs = new URLSearchParams(params as Record<string, string>).toString()
73
+ const init: RequestInit = { method, headers: headers() }
74
+ if (body) init.body = JSON.stringify(body)
75
+ const res = await fetch(`${baseUrl()}/.netlify/functions/${functionName}?${qs}`, init)
76
+ return handleResponse<any>(res)
77
+ }
78
+
79
+ type Filter = { key: string; op: string; value: any }
80
+
81
+ type Sort = { field: string; ascending: boolean }
82
+
83
+ class Query {
84
+ private table: string
85
+ private columns = '*'
86
+ private count = false
87
+ private head = false
88
+ private _single = false
89
+ private _maybeSingle = false
90
+ private filters: Filter[] = []
91
+ private sorts: Sort[] = []
92
+ private limitN?: number
93
+ private rangeFrom?: number
94
+ private rangeTo?: number
95
+ private insertData?: any
96
+ private updateData?: any
97
+ private deleteFlag = false
98
+ private selectAfterInsert = false
99
+
100
+ constructor(table: string) {
101
+ this.table = table
102
+ }
103
+
104
+ select(columns?: string, opts?: { count?: 'exact'; head?: boolean }) {
105
+ if (columns) this.columns = columns
106
+ if (opts) {
107
+ this.count = opts.count === 'exact'
108
+ this.head = !!opts.head
109
+ }
110
+ return this
111
+ }
112
+
113
+ eq(key: string, value: any) {
114
+ this.filters.push({ key, op: 'eq', value })
115
+ return this
116
+ }
117
+
118
+ filter(key: string, op: string, value: any) {
119
+ this.filters.push({ key, op, value })
120
+ return this
121
+ }
122
+
123
+ in(key: string, values: any[]) {
124
+ this.filters.push({ key, op: 'in', value: values })
125
+ return this
126
+ }
127
+
128
+ order(field: string, opts?: { ascending?: boolean }) {
129
+ this.sorts.push({ field, ascending: opts?.ascending !== false })
130
+ return this
131
+ }
132
+
133
+ limit(n: number) {
134
+ this.limitN = n
135
+ return this
136
+ }
137
+
138
+ range(from: number, to: number) {
139
+ this.rangeFrom = from
140
+ this.rangeTo = to
141
+ return this
142
+ }
143
+
144
+ ilike(key: string, value: any) {
145
+ this.filters.push({ key, op: 'ilike', value })
146
+ return this
147
+ }
148
+
149
+ lte(key: string, value: any) {
150
+ this.filters.push({ key, op: 'lte', value })
151
+ return this
152
+ }
153
+
154
+ gte(key: string, value: any) {
155
+ this.filters.push({ key, op: 'gte', value })
156
+ return this
157
+ }
158
+
159
+ neq(key: string, value: any) {
160
+ this.filters.push({ key, op: 'neq', value })
161
+ return this
162
+ }
163
+
164
+ maybeSingle() {
165
+ this._maybeSingle = true
166
+ return this
167
+ }
168
+
169
+ single() {
170
+ this._single = true
171
+ return this
172
+ }
173
+
174
+ insert(data: any) {
175
+ this.insertData = data
176
+ return this
177
+ }
178
+
179
+ update(data: any) {
180
+ this.updateData = data
181
+ return this
182
+ }
183
+
184
+ upsert(data: any) {
185
+ // admin-data does not support upsert; treat as create
186
+ this.insertData = data
187
+ return this
188
+ }
189
+
190
+ delete() {
191
+ this.deleteFlag = true
192
+ return this
193
+ }
194
+
195
+ contains(key: string, value: any) {
196
+ this.filters.push({ key, op: 'contains', value })
197
+ return this
198
+ }
199
+
200
+ then<TResult1 = any, TResult2 = never>(
201
+ onfulfilled?: ((value: any) => TResult1 | PromiseLike<TResult1>) | undefined | null,
202
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
203
+ ): Promise<TResult1 | TResult2> {
204
+ return this.execute().then(onfulfilled, onrejected)
205
+ }
206
+
207
+ private async execute(): Promise<any> {
208
+ if (this.table === 'apps') return this.executeApps()
209
+ if (this.table === 'embeddings') return this.executeEmbeddings()
210
+ return this.executeAdminData()
211
+ }
212
+
213
+ private async executeApps(): Promise<any> {
214
+ if (this.insertData || this.updateData || this.deleteFlag) {
215
+ throw new Error('apps write not supported through MCP proxy')
216
+ }
217
+ const idFilter = this.filters.find(f => f.key === 'id')
218
+ const slugFilter = this.filters.find(f => f.key === 'slug')
219
+ if (this._single || this._maybeSingle || idFilter || slugFilter) {
220
+ const q: Record<string, any> = {}
221
+ if (idFilter) q.id = idFilter.value
222
+ else if (slugFilter) q.slug = slugFilter.value
223
+ try {
224
+ const record = await fetchFunction('apps', 'get', q)
225
+ if (this._single && !record) throw new Error('App not found')
226
+ return { data: record || null, error: null }
227
+ } catch (err: any) {
228
+ if (this._maybeSingle && (err?.message?.includes('not found') || err?.message?.includes('Not found') || err?.message?.includes('not_found'))) {
229
+ return { data: null, error: null }
230
+ }
231
+ return { data: null, error: err }
232
+ }
233
+ }
234
+ const records = await fetchFunction('apps', 'list', { include_system: 'true', include_inactive: 'true' })
235
+ const filtered = this.applyClientFilters(records || [])
236
+ const sorted = this.applyClientSort(filtered)
237
+ return { data: sorted, error: null }
238
+ }
239
+
240
+ private async executeEmbeddings(): Promise<any> {
241
+ if (this.insertData || this.updateData || this.deleteFlag) {
242
+ throw new Error('embeddings write not supported through MCP proxy')
243
+ }
244
+ const q: Record<string, any> = {}
245
+ const modelFilter = this.filters.find(f => f.key === 'model_id')
246
+ const docFilter = this.filters.find(f => f.key === 'document_id')
247
+ if (modelFilter) q.model_id = modelFilter.value
248
+ if (docFilter) q.document_id = docFilter.value
249
+ if (this.limitN) q.limit = this.limitN
250
+ if (this.rangeFrom !== undefined) q.offset = this.rangeFrom
251
+ const records = await fetchFunction('embeddings', 'list', q)
252
+ return { data: records || [], error: null }
253
+ }
254
+
255
+ private async executeAdminData(): Promise<any> {
256
+ const entity = this.table
257
+ const idFilter = this.filters.find(f => f.key === 'id')
258
+ const hasIdFilter = !!idFilter
259
+
260
+ if (this.count && this.head) {
261
+ try {
262
+ const result = await fetchAdminData(entity, 'stats', {})
263
+ return { data: [], count: result?.count ?? 0, error: null }
264
+ } catch (err: any) {
265
+ return { data: [], count: 0, error: err }
266
+ }
267
+ }
268
+
269
+ if (this.insertData) {
270
+ const record = await fetchAdminData(entity, 'create', {}, this.insertData)
271
+ if (this.selectAfterInsert && this.columns === 'id') {
272
+ return { data: record ? { id: record.id } : record, error: null }
273
+ }
274
+ return { data: record, error: null }
275
+ }
276
+
277
+ if (this.updateData) {
278
+ if (!hasIdFilter) throw new Error('update requires id filter')
279
+ const record = await fetchAdminData(entity, 'update', { id: idFilter.value }, this.updateData)
280
+ return { data: record, error: null }
281
+ }
282
+
283
+ if (this.deleteFlag) {
284
+ if (hasIdFilter) {
285
+ const record = await fetchAdminData(entity, 'remove', { id: idFilter.value })
286
+ return { data: record, error: null }
287
+ }
288
+
289
+ // list with any eq filters we can push, then client-filter the rest
290
+ const params: Record<string, any> = {}
291
+ for (const f of this.filters) {
292
+ if (f.op === 'eq') params[f.key] = f.value
293
+ }
294
+ const records = await fetchAdminData(entity, 'list', { ...params, limit: 5000 })
295
+ const toDelete = this.applyClientFilters(records || [], this.filters)
296
+ for (const record of toDelete) {
297
+ await fetchAdminData(entity, 'remove', { id: record.id })
298
+ }
299
+ return { data: null, error: null }
300
+ }
301
+
302
+ if ((this._single || this._maybeSingle) && hasIdFilter) {
303
+ try {
304
+ const record = await fetchAdminData(entity, 'get', { id: idFilter.value })
305
+ if (this._single && !record) throw new Error('Record not found')
306
+ return { data: record || null, error: null }
307
+ } catch (err: any) {
308
+ if (this._maybeSingle) return { data: null, error: null }
309
+ return { data: null, error: err }
310
+ }
311
+ }
312
+
313
+ const inIdFilter = this.filters.find(f => f.key === 'id' && f.op === 'in')
314
+ if (inIdFilter) {
315
+ const records: any[] = []
316
+ for (const id of inIdFilter.value) {
317
+ try {
318
+ const record = await fetchAdminData(entity, 'get', { id })
319
+ if (record) records.push(record)
320
+ } catch {
321
+ // ignore missing
322
+ }
323
+ }
324
+ const otherFilters = this.filters.filter(f => !(f.key === 'id' && f.op === 'in'))
325
+ const filtered = this.applyClientFilters(records, otherFilters)
326
+ return { data: filtered, error: null }
327
+ }
328
+
329
+ const params: Record<string, any> = {}
330
+ for (const f of this.filters) {
331
+ if (f.op === 'eq') {
332
+ params[f.key] = f.value
333
+ } else if (f.op === 'ilike') {
334
+ params.search = f.value.replace(/%/g, '')
335
+ } else {
336
+ // other ops are not supported by admin-data list; will client-filter later
337
+ }
338
+ }
339
+ if (this.rangeFrom !== undefined && this.rangeTo !== undefined) {
340
+ params.offset = this.rangeFrom
341
+ params.limit = Math.max(0, this.rangeTo - this.rangeFrom)
342
+ }
343
+ if (this.limitN !== undefined) {
344
+ params.limit = this.limitN
345
+ }
346
+ if (this.sorts.length > 0) {
347
+ params.sort_field = this.sorts[0].field
348
+ params.sort_direction = this.sorts[0].ascending ? 'asc' : 'desc'
349
+ }
350
+
351
+ const records = await fetchAdminData(entity, 'list', params)
352
+ const filtered = this.applyClientFilters(records || [])
353
+
354
+ if (this._single) {
355
+ if (filtered.length === 0) throw new Error('Record not found')
356
+ if (filtered.length > 1) throw new Error('Multiple records found')
357
+ return { data: filtered[0], error: null }
358
+ }
359
+
360
+ if (this._maybeSingle) {
361
+ return { data: filtered[0] || null, error: null }
362
+ }
363
+
364
+ return { data: filtered, error: null }
365
+ }
366
+
367
+ private applyClientFilters(records: any[], filters = this.filters): any[] {
368
+ return records.filter(record => {
369
+ for (const f of filters) {
370
+ const value = this.getValue(record, f.key)
371
+ if (f.op === 'eq' && value !== f.value) return false
372
+ if (f.op === 'in' && !f.value.includes(value)) return false
373
+ if (f.op === 'ilike' && typeof value === 'string' && !value.toLowerCase().includes(String(f.value).toLowerCase().replace(/%/g, ''))) return false
374
+ if (f.op === 'lte' && value > f.value) return false
375
+ if (f.op === 'gte' && value < f.value) return false
376
+ if (f.op === 'neq' && value === f.value) return false
377
+ if (f.op === 'contains') {
378
+ if (Array.isArray(value) && !value.includes(f.value)) return false
379
+ if (typeof value === 'string' && !value.includes(f.value)) return false
380
+ }
381
+ }
382
+ return true
383
+ })
384
+ }
385
+
386
+ private applyClientSort(records: any[]): any[] {
387
+ if (this.sorts.length === 0) return records
388
+ const s = this.sorts[0]
389
+ return [...records].sort((a, b) => {
390
+ const av = this.getValue(a, s.field)
391
+ const bv = this.getValue(b, s.field)
392
+ if (av < bv) return s.ascending ? -1 : 1
393
+ if (av > bv) return s.ascending ? 1 : -1
394
+ return 0
395
+ })
396
+ }
397
+
398
+ private getValue(record: any, key: string): any {
399
+ if (key === 'id') return record.id
400
+ if (key in record) return record[key]
401
+ if (key.startsWith('data->>')) {
402
+ const field = key.slice(7)
403
+ return record.data?.[field]
404
+ }
405
+ if (key.startsWith('data->')) {
406
+ const path = key.slice(6)
407
+ return record.data?.[path]
408
+ }
409
+ return undefined
410
+ }
411
+ }
412
+
413
+ export const adminDb = {
414
+ from(table: string) {
415
+ return new Query(table)
416
+ },
417
+ async rpc(name: string, params: Record<string, any> = {}): Promise<any> {
418
+ if (name === 'match_embeddings') {
419
+ const result = await fetchFunction('embeddings', 'search-similar', {}, {
420
+ query_embedding: params.query_embedding,
421
+ model_id: params.model_id || 'text-embedding-3-small',
422
+ limit: params.match_count || params.limit || 10,
423
+ threshold: params.similarity_threshold || 0.15,
424
+ filter_account_ids: params.filter_account_ids ?? null,
425
+ filter_vector_type: params.filter_vector_type ?? null,
426
+ filter_item_types: params.filter_item_types ?? null,
427
+ filter_document_ids: params.filter_document_ids ?? null,
428
+ })
429
+ const rows = Array.isArray(result) ? result : (result?.results || [])
430
+ return { data: rows, error: null }
431
+ }
432
+ throw new Error(`RPC not supported through MCP proxy: ${name}`)
433
+ },
434
+ }
435
+
436
+ export async function resolveTypeRecord(kind: string, slug: string): Promise<any> {
437
+ const rows = await fetchAdminData('types', 'list', { kind, slug, limit: 1 })
438
+ const row = rows?.[0]
439
+ if (!row) throw new Error(`Type not found: ${kind}/${slug}`)
440
+ return {
441
+ id: row.id,
442
+ slug: row.slug,
443
+ kind: row.kind,
444
+ design_schema: row.design_schema || {},
445
+ validation_schema: row.validation_schema || {},
446
+ is_active: row.is_active ?? true,
447
+ }
448
+ }
449
+
450
+ export async function resolveTypeId(kind: string, slug: string): Promise<string> {
451
+ const record = await resolveTypeRecord(kind, slug)
452
+ return record.id
453
+ }
454
+
455
+ export async function resolveLinkTypeId(slug: string): Promise<string> {
456
+ const rows = await fetchAdminData('link_types', 'list', { slug, limit: 1 })
457
+ const row = rows?.[0]
458
+ if (!row) throw new Error(`Link type not found: ${slug}`)
459
+ return row.id
460
+ }
461
+
462
+ export async function resolveLinkTypeIds(slugs: string[]): Promise<Record<string, string>> {
463
+ const ids = await Promise.all(slugs.map(resolveLinkTypeId))
464
+ const result: Record<string, string> = {}
465
+ for (let i = 0; i < slugs.length; i++) {
466
+ result[slugs[i]] = ids[i]
467
+ }
468
+ return result
469
+ }
470
+
471
+ // CIL[DOC-VECTOR type="context" content="purpose='MCP admin-data proxy query builder and type resolver for the Spine framework.'; No verified external callers; imports: none"]
472
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
473
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
474
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
475
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
476
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
477
+ // CIL[END stable_id="~/.framework/mcp/shared/db.ts:mcp_db:file"]
@@ -0,0 +1,118 @@
1
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/kb.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/shared/kb.ts"]
2
+ // CIL[DOC-MACRO purpose="Shared MCP KB operation wrappers"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide thin async wrappers that route KB search/ingest/reindex/revoke/publish operations to the database fetch function"]
4
+ // CIL[DOC-CONTEXT module=".framework/mcp/shared/kb.ts" layer="mcp" related_files=".framework/mcp/shared/db.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none at module level" outputs="named KB operation exports" errors="none at module level" side_effects="none at module level"]
6
+ // CIL[DOC-MICRO logic_summary="Re-exports fetchFunction-bound helpers for the kb namespace" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="mcp"]
10
+
11
+ import { fetchFunction } from './db.js'
12
+ // CIL[DOC-VECTOR type="context" content="purpose='Shared MCP KB operation wrappers'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
13
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
14
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
15
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
16
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
17
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
18
+ // CIL[END stable_id="~/.framework/mcp/shared/kb.ts:module_header:module_header"]
19
+
20
+
21
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/kb.ts:kbsearch:function" type="function" identity="kbSearch" parent="~/.framework/mcp/shared/kb.ts"]
22
+ // CIL[DOC-MACRO purpose="Search the knowledge base"]
23
+ // CIL[DOC-RESPONSIBILITY responsibility="Delegate a KB search call to the database fetchFunction"]
24
+ // CIL[DOC-CONTEXT module=".framework/mcp/shared/kb.ts" layer="mcp" related_files=".framework/mcp/shared/db.ts,.framework/mcp/shared/kb.ts"]
25
+ // CIL[DOC-CONTRACT inputs="_ctx: any, body: Record<string, any>" outputs="Promise<any>" errors="propagates fetchFunction errors" side_effects="queries the KB search index"]
26
+ // CIL[DOC-MICRO logic_summary="Calls fetchFunction with the kb namespace, search action, empty static context, and the provided body" notable_decisions="[]"]
27
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
28
+ // CIL[DOC-STABILITY stability="stable"]
29
+ export async function kbSearch(_ctx: any, body: Record<string, any>): Promise<any> {
30
+ return fetchFunction('kb', 'search', {}, body)
31
+ }
32
+ // CIL[DOC-VECTOR type="context" content="purpose='Search the knowledge base'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
33
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
34
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
35
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
36
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
37
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
38
+ // CIL[END stable_id="~/.framework/mcp/shared/kb.ts:kbsearch:function"]
39
+
40
+
41
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/kb.ts:kbingest:function" type="function" identity="kbIngest" parent="~/.framework/mcp/shared/kb.ts"]
42
+ // CIL[DOC-MACRO purpose="Ingest content into the knowledge base"]
43
+ // CIL[DOC-RESPONSIBILITY responsibility="Delegate a KB ingest call to the database fetchFunction"]
44
+ // CIL[DOC-CONTEXT module=".framework/mcp/shared/kb.ts" layer="mcp" related_files=".framework/mcp/shared/db.ts,.framework/mcp/shared/kb.ts"]
45
+ // CIL[DOC-CONTRACT inputs="_ctx: any, body: Record<string, any>" outputs="Promise<any>" errors="propagates fetchFunction errors" side_effects="adds or updates KB records"]
46
+ // CIL[DOC-MICRO logic_summary="Calls fetchFunction with the kb namespace, ingest action, empty static context, and the provided body" notable_decisions="[]"]
47
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
48
+ // CIL[DOC-STABILITY stability="stable"]
49
+ export async function kbIngest(_ctx: any, body: Record<string, any>): Promise<any> {
50
+ return fetchFunction('kb', 'ingest', {}, body)
51
+ }
52
+ // CIL[DOC-VECTOR type="context" content="purpose='Ingest content into the knowledge base'; 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/shared/kb.ts:kbingest:function"]
59
+
60
+
61
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/kb.ts:kbreindex:function" type="function" identity="kbReindex" parent="~/.framework/mcp/shared/kb.ts"]
62
+ // CIL[DOC-MACRO purpose="Reindex the knowledge base"]
63
+ // CIL[DOC-RESPONSIBILITY responsibility="Delegate a KB reindex call to the database fetchFunction"]
64
+ // CIL[DOC-CONTEXT module=".framework/mcp/shared/kb.ts" layer="mcp" related_files=".framework/mcp/shared/db.ts,.framework/mcp/shared/kb.ts"]
65
+ // CIL[DOC-CONTRACT inputs="_ctx: any, body: Record<string, any>" outputs="Promise<any>" errors="propagates fetchFunction errors" side_effects="rebuilds the KB index"]
66
+ // CIL[DOC-MICRO logic_summary="Calls fetchFunction with the kb namespace, reindex action, empty static context, and the provided body" notable_decisions="[]"]
67
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
68
+ // CIL[DOC-STABILITY stability="stable"]
69
+ export async function kbReindex(_ctx: any, body: Record<string, any>): Promise<any> {
70
+ return fetchFunction('kb', 'reindex', {}, body)
71
+ }
72
+ // CIL[DOC-VECTOR type="context" content="purpose='Reindex the knowledge base'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
73
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
74
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
75
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
76
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
77
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
78
+ // CIL[END stable_id="~/.framework/mcp/shared/kb.ts:kbreindex:function"]
79
+
80
+
81
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/kb.ts:kbrevoke:function" type="function" identity="kbRevoke" parent="~/.framework/mcp/shared/kb.ts"]
82
+ // CIL[DOC-MACRO purpose="Revoke a knowledge base record"]
83
+ // CIL[DOC-RESPONSIBILITY responsibility="Delegate a KB revoke call to the database fetchFunction"]
84
+ // CIL[DOC-CONTEXT module=".framework/mcp/shared/kb.ts" layer="mcp" related_files=".framework/mcp/shared/db.ts,.framework/mcp/shared/kb.ts"]
85
+ // CIL[DOC-CONTRACT inputs="_ctx: any, body: Record<string, any>" outputs="Promise<any>" errors="propagates fetchFunction errors" side_effects="removes or invalidates the specified KB record"]
86
+ // CIL[DOC-MICRO logic_summary="Calls fetchFunction with the kb namespace, revoke action, empty static context, and the provided body" notable_decisions="[]"]
87
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
88
+ // CIL[DOC-STABILITY stability="stable"]
89
+ export async function kbRevoke(_ctx: any, body: Record<string, any>): Promise<any> {
90
+ return fetchFunction('kb', 'revoke', {}, body)
91
+ }
92
+ // CIL[DOC-VECTOR type="context" content="purpose='Revoke a knowledge base record'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
93
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
94
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
95
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
96
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
97
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
98
+ // CIL[END stable_id="~/.framework/mcp/shared/kb.ts:kbrevoke:function"]
99
+
100
+
101
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/kb.ts:kbpublish:function" type="function" identity="kbPublish" parent="~/.framework/mcp/shared/kb.ts"]
102
+ // CIL[DOC-MACRO purpose="Publish a knowledge base record"]
103
+ // CIL[DOC-RESPONSIBILITY responsibility="Delegate a KB publish call to the database fetchFunction"]
104
+ // CIL[DOC-CONTEXT module=".framework/mcp/shared/kb.ts" layer="mcp" related_files=".framework/mcp/shared/db.ts,.framework/mcp/shared/kb.ts"]
105
+ // CIL[DOC-CONTRACT inputs="_ctx: any, body: Record<string, any>" outputs="Promise<any>" errors="propagates fetchFunction errors" side_effects="publishes the specified KB record"]
106
+ // CIL[DOC-MICRO logic_summary="Calls fetchFunction with the kb namespace, publish action, empty static context, and the provided body" notable_decisions="[]"]
107
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
108
+ // CIL[DOC-STABILITY stability="stable"]
109
+ export async function kbPublish(_ctx: any, body: Record<string, any>): Promise<any> {
110
+ return fetchFunction('kb', 'publish', {}, body)
111
+ }
112
+ // CIL[DOC-VECTOR type="context" content="purpose='Publish a knowledge base record'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
113
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
114
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
115
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
116
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
117
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
118
+ // CIL[END stable_id="~/.framework/mcp/shared/kb.ts:kbpublish:function"]