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,431 @@
1
+ // CIL[BEGIN stable_id="~/.framework/mcp/tools/architect.ts:architect:file" type="file" identity="architect" parent="~/.framework/mcp/tools/architect.ts"]
2
+ // CIL[DOC-MACRO purpose="Register architect MCP tools for Spine Way evaluation, design schema validation, and app manifest lookups."]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Expose MCP tools that evaluate proposals against Spine fundamentals, validate design schemas, and query installed app manifests."]
4
+ // CIL[DOC-CONTEXT module="mcp" layer="framework" related_files=".framework/mcp/shared/app-manifest.ts,.framework/mcp/shared/db.ts,.framework/mcp/tools/architect.ts"]
5
+ // CIL[DOC-CONTRACT inputs="server: McpServer; tool-specific parameters for proposal, primitive, fundamental, design_schema, app slug/id" outputs="JSON content with assessment, placement, validation errors, or app record" errors="Unknown fundamental; invalid design schema; missing app; Supabase query failures" side_effects="Reads public.apps via adminDb; no writes"]
6
+ // CIL[DOC-MICRO logic_summary="Registers six tools on the MCP server: evaluate proposals, core-vs-custom placement, get a fundamental, validate a design schema, list apps, and get an app merged with its manifest." notable_decisions="FUNDAMENTALS, DATA_TYPES, and DISPLAY_TYPES are hard-coded local maps; app queries use adminDb with manifest helper functions."]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+
10
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
11
+ import { z } from 'zod'
12
+ import { adminDb } from '../shared/db.js'
13
+ import { loadManifest, mergeWithManifest } from '../shared/app-manifest.js'
14
+
15
+ export function register(server: McpServer) {
16
+ server.registerTool(
17
+ 'spine_architect_evaluate',
18
+ {
19
+ description: 'Evaluate a code or design proposal against the Spine Way fundamentals and return a structured assessment with observations and recommendations.',
20
+ inputSchema: z.object({
21
+ proposal: z.string().describe('The proposal or change description to evaluate'),
22
+ against: z.array(z.string()).optional().describe('Specific fundamental names to evaluate against (optional)'),
23
+ }),
24
+ },
25
+ async ({ proposal, against }) => {
26
+
27
+
28
+ const observations = [
29
+ 'Core-vs-custom boundary: framework primitives live in .framework/, product-specific behavior lives in custom/apps/.',
30
+ 'Design schema completeness: every new runtime type needs fields, views, and record_permissions.',
31
+ 'Permission design: record_permissions are the base grant; field permissions are overrides only.',
32
+ 'CIL hygiene: code changes are followed by re-syncing CIL chunks, embeddings, and mappings.',
33
+ ]
34
+
35
+ if (against && against.length > 0) {
36
+ // A richer implementation would filter to the requested fundamentals.
37
+ }
38
+
39
+ return {
40
+ content: [{
41
+ type: 'text',
42
+ text: JSON.stringify({
43
+ proposal,
44
+ verdict: 'review',
45
+ observations,
46
+ recommendation: 'Re-read the Spine Way and the design-schema checklist before proceeding.',
47
+ }, null, 2),
48
+ }],
49
+ }
50
+ }
51
+ )
52
+
53
+ server.registerTool(
54
+ 'spine_core_vs_custom_check',
55
+ {
56
+ description: 'Advise whether a change belongs in the core .framework/ layer or a custom app in custom/apps/.',
57
+ inputSchema: z.object({
58
+ description: z.string().describe('What the change does'),
59
+ primitives: z.array(z.string()).optional().describe('Spine primitives it touches (e.g., types, roles, migrations, functions, components)'),
60
+ }),
61
+ },
62
+ async ({ description, primitives }) => {
63
+
64
+
65
+ const primitivesList = primitives?.join(', ') || 'none provided'
66
+
67
+
68
+
69
+ const lower = (description + ' ' + primitivesList).toLowerCase()
70
+
71
+
72
+
73
+
74
+
75
+ let placement = 'custom'
76
+
77
+
78
+
79
+
80
+
81
+
82
+ let reason = 'This looks like product-specific behavior that should live in a custom app.'
83
+
84
+
85
+ if (
86
+ lower.includes('migration') ||
87
+ lower.includes('rls') ||
88
+ lower.includes('rpc') ||
89
+ lower.includes('auth') ||
90
+ lower.includes('permission') ||
91
+ lower.includes('core primitive') ||
92
+ lower.includes('design schema') ||
93
+ lower.includes('shared component') ||
94
+ lower.includes('admin-data')
95
+ ) {
96
+ placement = 'core'
97
+ reason = 'This change touches framework-level primitives (data model, auth, permissions, migrations, shared runtime, or generic components) and should live in .framework/.'
98
+ }
99
+
100
+
101
+
102
+
103
+
104
+
105
+ return {
106
+ content: [{
107
+ type: 'text',
108
+ text: JSON.stringify({
109
+ description,
110
+ primitives: primitivesList,
111
+ placement,
112
+ reason,
113
+ boundary_rule: 'If it could be used by more than one app, it belongs in .framework/; if it is specific to one product workflow, it belongs in custom/apps/.',
114
+ }, null, 2),
115
+ }],
116
+ }
117
+ }
118
+ )
119
+
120
+
121
+
122
+ const FUNDAMENTALS: Record<string, { rule: string; guidance: string }> = {
123
+ 'core-never-imports-from-custom': {
124
+ rule: 'Core never imports from custom',
125
+ guidance: '.framework/ must not contain imports from custom/ or hardcoded custom app slugs. Custom code extends core through data or custom functions.',
126
+ },
127
+ 'custom-uses-core-aliases': {
128
+ rule: 'Custom code uses @core/* aliases, not relative paths into .framework/',
129
+ guidance: 'From custom apps: import from "@core/...". From custom functions after assembly: import from "./_shared/...".',
130
+ },
131
+ 'apps-register-through-public-apps': {
132
+ rule: 'Custom apps register through public.apps',
133
+ guidance: 'A custom app is defined by a manifest.json, installed via install-app, and represented as a row in public.apps.',
134
+ },
135
+ 'runtime-crud-through-admin-data': {
136
+ rule: 'Runtime record CRUD goes through /api/admin-data',
137
+ guidance: 'Use /api/admin-data for items, threads, messages, links, attachments, watchers. Do not write custom Netlify wrappers for runtime CRUD.',
138
+ },
139
+ 'types-define-behavior-via-design-schema': {
140
+ rule: 'Types define behavior via design_schema',
141
+ guidance: 'Domain logic belongs in the type\'s design_schema (fields, views, permissions, functionality). validation_schema is generated from it.',
142
+ },
143
+ 'record-permissions-are-base-grant': {
144
+ rule: 'record_permissions are the base grant; field permissions are overrides',
145
+ guidance: 'Start with the most restrictive record_permissions per role. Add fields.<name>.permissions only to loosen or further restrict a specific field.',
146
+ },
147
+ 'rls-enabled-and-correct': {
148
+ rule: 'RLS must be enabled with correct policies',
149
+ guidance: 'Every tenant/account table must have RLS. Policies use current_actor_id() and get_accessible_accounts(). Use adminDb only when bypassing RLS is necessary.',
150
+ },
151
+ 'migrations-idempotent-and-ordered': {
152
+ rule: 'Migrations are idempotent and ordered',
153
+ guidance: 'File naming: NNN_description.sql with unique 3-digit prefixes. Use IF NOT EXISTS, DROP POLICY IF EXISTS, ON CONFLICT DO NOTHING, and conditional DO $$ blocks.',
154
+ },
155
+ 'field-storage-follows-system-flag': {
156
+ rule: 'Field storage follows the system flag',
157
+ guidance: 'system: true fields are top-level record columns; non-system fields live inside record.data.<field>. Send payloads accordingly to /api/admin-data.',
158
+ },
159
+ 'secrets-on-backend-only': {
160
+ rule: 'Secrets and service keys stay on the backend',
161
+ guidance: 'Browser code uses VITE_SUPABASE_ANON_KEY and VITE_SUPABASE_URL only. Service keys and app secrets never appear in frontend code or committed env files.',
162
+ },
163
+ }
164
+
165
+
166
+
167
+ server.registerTool(
168
+ 'spine_get_fundamental',
169
+ {
170
+ description: 'Return a named Spine Way fundamental rule and guidance.',
171
+ inputSchema: z.object({
172
+ name: z.string().describe('Fundamental name, e.g. "core-never-imports-from-custom" or "record-permissions-are-base-grant"'),
173
+ }),
174
+ },
175
+ async ({ name }) => {
176
+
177
+
178
+ const fundamental = FUNDAMENTALS[name]
179
+
180
+ if (!fundamental) {
181
+ return {
182
+ content: [{
183
+ type: 'text',
184
+ text: JSON.stringify({
185
+ ok: false,
186
+ error: `Unknown fundamental: ${name}`,
187
+ available: Object.keys(FUNDAMENTALS),
188
+ }, null, 2),
189
+ }],
190
+ }
191
+
192
+ }
193
+ return {
194
+ content: [{
195
+ type: 'text',
196
+ text: JSON.stringify({ ok: true, name, ...fundamental }, null, 2),
197
+ }],
198
+ }
199
+ }
200
+ )
201
+
202
+
203
+
204
+ const DATA_TYPES = new Set([
205
+ 'text', 'textarea', 'rich_text', 'email', 'phone', 'url', 'number', 'currency', 'range',
206
+ 'date', 'datetime', 'boolean', 'checkbox', 'select', 'multiselect', 'radio', 'color',
207
+ 'file', 'image', 'json', 'reference', 'address',
208
+ ])
209
+
210
+
211
+
212
+
213
+ const DISPLAY_TYPES = new Set([
214
+ 'text', 'input', 'textarea', 'rich_text', 'select', 'multiselect', 'radio', 'checkbox',
215
+ 'switch', 'date_picker', 'datetime_picker', 'color_picker', 'file_upload', 'image_upload',
216
+ 'range_slider', 'badge', 'timestamp', 'currency', 'number',
217
+ ])
218
+
219
+
220
+
221
+ function validateDesignSchema(schema: any): { ok: boolean; errors: string[] } {
222
+ const errors: string[] = []
223
+ if (!schema || typeof schema !== 'object') {
224
+ errors.push('design_schema must be an object')
225
+ return { ok: false, errors }
226
+ }
227
+
228
+
229
+
230
+ const scope = schema.scope ?? 'account'
231
+ if (scope !== 'account' && scope !== 'platform') {
232
+ errors.push('scope must be "account" or "platform"')
233
+ }
234
+
235
+ if (!schema.fields || typeof schema.fields !== 'object' || Object.keys(schema.fields).length === 0) {
236
+ errors.push('fields is required and must contain at least one field definition')
237
+ }
238
+
239
+ for (const [key, field] of Object.entries(schema.fields || {})) {
240
+ if (!field || typeof field !== 'object') {
241
+ errors.push(`fields.${key} must be an object`)
242
+ continue
243
+ }
244
+ const f = field as any
245
+ if (!f.data_type) errors.push(`fields.${key} is missing data_type`)
246
+ else if (!DATA_TYPES.has(f.data_type)) errors.push(`fields.${key} has unknown data_type: ${f.data_type}`)
247
+ if (!f.label) errors.push(`fields.${key} is missing label`)
248
+ if (f.required === undefined) errors.push(`fields.${key} is missing required`)
249
+ if (['select', 'multiselect', 'radio'].includes(f.data_type) && (!f.options || !Array.isArray(f.options) || f.options.length === 0)) {
250
+ errors.push(`fields.${key} (${f.data_type}) requires options`)
251
+ }
252
+ }
253
+
254
+ if (!schema.record_permissions || typeof schema.record_permissions !== 'object') {
255
+ errors.push('record_permissions is required')
256
+ } else if (!Object.keys(schema.record_permissions).includes('system-admin') && !Object.keys(schema.record_permissions).includes('system_admin')) {
257
+ errors.push('record_permissions must grant at least system-admin or system_admin')
258
+ }
259
+
260
+ if (schema.views) {
261
+ if (schema.views.default_list) {
262
+ const list = schema.views.default_list
263
+ if (list.type !== 'list') errors.push('views.default_list.type must be "list"')
264
+ if (!list.fields || typeof list.fields !== 'object') errors.push('views.default_list.fields is required')
265
+ if (!list.default_sort) errors.push('views.default_list.default_sort is required')
266
+ }
267
+ if (schema.views.default_detail) {
268
+ const detail = schema.views.default_detail
269
+ if (detail.type !== 'detail') errors.push('views.default_detail.type must be "detail"')
270
+ }
271
+ }
272
+
273
+ return { ok: errors.length === 0, errors }
274
+ }
275
+
276
+ server.registerTool(
277
+ 'spine_design_schema_validate',
278
+ {
279
+ description: 'Validate a proposed design_schema against the Spine design-schema rules. Returns ok and a list of errors.',
280
+ inputSchema: z.object({
281
+ design_schema: z.record(z.any()).describe('The design_schema object to validate'),
282
+ check_views: z.boolean().default(true).optional().describe('Whether to require default_list and default_detail views'),
283
+ }),
284
+ },
285
+ async ({ design_schema, check_views }) => {
286
+
287
+
288
+ const result = validateDesignSchema(design_schema)
289
+
290
+ if (check_views && !design_schema.views) {
291
+ result.errors.push('views is required when check_views is true')
292
+ }
293
+
294
+ if (design_schema.views) {
295
+ if (check_views && !design_schema.views.default_list) result.errors.push('views.default_list is required')
296
+ if (check_views && !design_schema.views.default_detail) result.errors.push('views.default_detail is required')
297
+ for (const [viewName, view] of Object.entries(design_schema.views || {})) {
298
+
299
+
300
+ const v = view as any
301
+
302
+ if (!v || typeof v !== 'object') continue
303
+ for (const [fieldName, field] of Object.entries(v.fields || {})) {
304
+
305
+
306
+ const f = field as any
307
+
308
+ if (f && f.display_type && !DISPLAY_TYPES.has(f.display_type)) {
309
+ result.errors.push(`views.${viewName}.fields.${fieldName} has unknown display_type: ${f.display_type}`)
310
+ }
311
+
312
+
313
+ }
314
+ if (v.sections) {
315
+ for (const section of v.sections) {
316
+ for (const [fieldName, field] of Object.entries(section.fields || {})) {
317
+
318
+
319
+ const f = field as any
320
+
321
+ if (f && f.display_type && !DISPLAY_TYPES.has(f.display_type)) {
322
+ result.errors.push(`views.${viewName}.sections.*.fields.${fieldName} has unknown display_type: ${f.display_type}`)
323
+ }
324
+
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
330
+ return {
331
+ content: [{
332
+ type: 'text',
333
+ text: JSON.stringify({
334
+ ok: result.ok && result.errors.length === 0,
335
+ error_count: result.errors.length,
336
+ errors: result.errors,
337
+ }, null, 2),
338
+ }],
339
+ }
340
+ }
341
+ )
342
+
343
+ server.registerTool(
344
+ 'spine_app_manifest_list',
345
+ {
346
+ description: 'List installed apps from the public.apps table.',
347
+ inputSchema: z.object({
348
+ include_manifest: z.boolean().default(false).optional().describe('Load and include each app manifest.json content'),
349
+ }),
350
+ },
351
+ async ({ include_manifest }) => {
352
+ const { data, error } = await adminDb.from('apps').select('id, slug, name, description, app_type, renderer, manifest_path, is_active, route_prefix').order('name')
353
+ if (error) {
354
+ return { content: [{ type: 'text', text: JSON.stringify({ ok: false, error: error.message }) }] }
355
+ }
356
+
357
+
358
+
359
+ const apps = (data || []).map((app: any) => {
360
+ const base = {
361
+ id: app.id,
362
+ slug: app.slug,
363
+ name: app.name,
364
+ description: app.description || '',
365
+ app_type: app.app_type || '',
366
+ renderer: app.renderer || '',
367
+ manifest_path: app.manifest_path || '',
368
+ is_active: app.is_active ?? true,
369
+ route_prefix: app.route_prefix || '',
370
+ }
371
+ if (include_manifest && app.manifest_path) {
372
+ const manifest = loadManifest(app.manifest_path)
373
+ return { ...base, manifest: manifest || null }
374
+ }
375
+ return base
376
+ })
377
+
378
+
379
+ return { content: [{ type: 'text', text: JSON.stringify({ ok: true, count: apps.length, apps }, null, 2) }] }
380
+ }
381
+
382
+ )
383
+
384
+ server.registerTool(
385
+ 'spine_app_manifest_get',
386
+ {
387
+ description: 'Get one installed app by slug or id, optionally merged with its manifest.json.',
388
+ inputSchema: z.object({
389
+ slug: z.string().optional().describe('App slug'),
390
+ id: z.string().uuid().optional().describe('App UUID'),
391
+ }),
392
+ },
393
+ async ({ slug, id }) => {
394
+ if (!slug && !id) {
395
+ return { content: [{ type: 'text', text: JSON.stringify({ ok: false, error: 'Provide either slug or id' }) }] }
396
+ }
397
+
398
+
399
+
400
+
401
+ let query = adminDb.from('apps').select('*')
402
+
403
+
404
+ if (id) query = query.eq('id', id)
405
+ else query = query.eq('slug', slug)
406
+ const { data, error } = await query.maybeSingle()
407
+ if (error) {
408
+ return { content: [{ type: 'text', text: JSON.stringify({ ok: false, error: error.message }) }] }
409
+ }
410
+
411
+
412
+ if (!data) {
413
+ return { content: [{ type: 'text', text: JSON.stringify({ ok: false, error: `App not found: ${slug || id}` }) }] }
414
+ }
415
+
416
+
417
+ const merged = mergeWithManifest(data)
418
+
419
+ return { content: [{ type: 'text', text: JSON.stringify({ ok: true, app: merged }, null, 2) }] }
420
+ }
421
+
422
+ )
423
+ }
424
+
425
+ // CIL[DOC-VECTOR type="context" content="purpose='Register architect MCP tools for Spine Way evaluation, design schema validation, and app manifest lookups.'; No verified external callers; imports: .framework/mcp/shared/db.ts,.framework/mcp/shared/app-manifest.ts"]
426
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
427
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
428
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
429
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
430
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
431
+ // CIL[END stable_id="~/.framework/mcp/tools/architect.ts:architect:file"]