spine-framework 0.3.144 → 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 +20 -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,275 @@
1
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/shared/app-manifest.ts"]
2
+ // CIL[DOC-MACRO purpose="Shared TypeScript module for loading and merging app manifests from JSON files"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Declares AppManifest and NavItem interfaces and exposes loadManifest, clearManifestCache, and mergeWithManifest helpers"]
4
+ // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Provides shared manifest data types and loader/merger functions" 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 { readFileSync, realpathSync } from 'node:fs'
12
+ import { resolve, sep } from 'node:path'
13
+ // CIL[DOC-VECTOR type="context" content="purpose='Shared TypeScript module for loading and merging app manifests from JSON files'; No verified external callers; imports: none"]
14
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
15
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
16
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
17
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
18
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
19
+ // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:module_header:module_header"]
20
+
21
+
22
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:AppManifest:interface" type="interface" identity="AppManifest" parent="~/.framework/mcp/shared/app-manifest.ts"]
23
+ // CIL[DOC-MACRO purpose="Defines the typed contract for an app manifest JSON file"]
24
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe all configurable fields exposed by a Spine app manifest"]
25
+ // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
26
+ // CIL[DOC-CONTRACT inputs="none" outputs="AppManifest interface" errors="none" side_effects="none"]
27
+ // CIL[DOC-MICRO logic_summary="Property list for an app manifest including metadata, roles, routes, navigation, dependencies, and feature toggles" notable_decisions="[]"]
28
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
29
+ // CIL[DOC-STABILITY stability="stable"]
30
+ export interface AppManifest {
31
+ name: string
32
+ slug: string
33
+ description?: string
34
+ version?: string
35
+ required_roles: string[]
36
+ route_prefix?: string
37
+ renderer?: 'generic' | 'custom' | 'none'
38
+ routes: string[]
39
+ nav_items: NavItem[]
40
+ features?: string[]
41
+ dependencies?: string[]
42
+ entry_point: string
43
+ is_public?: boolean
44
+ auth_required?: boolean
45
+ preview_domain?: string
46
+ prod_domain?: string
47
+ }
48
+ // CIL[DOC-VECTOR type="context" content="purpose='Defines the typed contract for an app manifest JSON file'; No verified external callers; imports: none"]
49
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
50
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
51
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
52
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
53
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
54
+ // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:AppManifest:interface"]
55
+
56
+
57
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:NavItem:interface" type="interface" identity="NavItem" parent="~/.framework/mcp/shared/app-manifest.ts"]
58
+ // CIL[DOC-MACRO purpose="Defines the recursive navigation item contract for app manifests"]
59
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe a single navigation entry with optional children"]
60
+ // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
61
+ // CIL[DOC-CONTRACT inputs="none" outputs="NavItem interface" errors="none" side_effects="none"]
62
+ // CIL[DOC-MICRO logic_summary="Navigation item structure with title, path, icon, order, and nested children" notable_decisions="[]"]
63
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
64
+ // CIL[DOC-STABILITY stability="stable"]
65
+ export interface NavItem {
66
+ title: string
67
+ path: string
68
+ icon?: string
69
+ order?: number
70
+ children?: NavItem[]
71
+ }
72
+ // CIL[DOC-VECTOR type="context" content="purpose='Defines the recursive navigation item contract for app manifests'; No verified external callers; imports: none"]
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/app-manifest.ts:NavItem:interface"]
79
+
80
+
81
+
82
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:manifestCache:constant" type="constant" identity="manifestCache" parent="~/.framework/mcp/shared/app-manifest.ts"]
83
+ // CIL[DOC-MACRO purpose="In-memory cache for loaded app manifests keyed by file path"]
84
+ // CIL[DOC-RESPONSIBILITY responsibility="Store and reuse parsed manifest objects across loadManifest calls"]
85
+ // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
86
+ // CIL[DOC-CONTRACT inputs="canonical manifest path key and AppManifest value" outputs="cached manifest or undefined" errors="none" side_effects="reads and writes a module-level Map"]
87
+ // CIL[DOC-MICRO logic_summary="Uses a module-scoped Map keyed by canonical path to avoid repeated JSON parsing of the same manifest file" notable_decisions="[]"]
88
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
89
+ // CIL[DOC-STABILITY stability="stable"]
90
+ const manifestCache = new Map<string, AppManifest>()
91
+ // CIL[DOC-VECTOR type="context" content="purpose='In-memory cache for loaded app manifests keyed by file path'; No verified external callers; imports: none"]
92
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
93
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
94
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
95
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
96
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
97
+ // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:manifestCache:constant"]
98
+
99
+
100
+
101
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:repoRoot:function" type="function" identity="repoRoot" parent="~/.framework/mcp/shared/app-manifest.ts"]
102
+ // CIL[DOC-MACRO purpose="Resolve the repository root directory used to locate manifest files"]
103
+ // CIL[DOC-RESPONSIBILITY responsibility="Return the absolute repository root for manifest path resolution"]
104
+ // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
105
+ // CIL[DOC-CONTRACT inputs="none" outputs="string absolute path" errors="none" side_effects="reads process.env.REPO_PATH or process.cwd"]
106
+ // CIL[DOC-MICRO logic_summary="Prefers the REPO_PATH environment variable, falling back to the current working directory" notable_decisions="[]"]
107
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
108
+ // CIL[DOC-STABILITY stability="stable"]
109
+ function repoRoot(): string {
110
+ return process.env.REPO_PATH || process.cwd()
111
+ }
112
+ // CIL[DOC-VECTOR type="context" content="purpose='Resolve the repository root directory used to locate manifest files'; No verified external callers; imports: none"]
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/app-manifest.ts:repoRoot:function"]
119
+
120
+
121
+
122
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:loadManifest:function" type="function" identity="loadManifest" parent="~/.framework/mcp/shared/app-manifest.ts"]
123
+ // CIL[DOC-MACRO purpose="Load and parse an app manifest JSON file from a path relative to the repo root"]
124
+ // CIL[DOC-RESPONSIBILITY responsibility="Read, validate, and cache app manifests for downstream use"]
125
+ // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
126
+ // CIL[DOC-CONTRACT inputs="manifestPath: string relative path, projectRoot: optional root (defaults to REPO_PATH or cwd)" outputs="AppManifest | null" errors="returns null on path escapes, missing or invalid fields, or file read and parse failures" side_effects="reads the manifest file from disk and updates the in-memory cache keyed by canonical path; may log errors to console"]
127
+ // CIL[DOC-MICRO logic_summary="Canonicalizes project root and manifest path with realpathSync, rejects lexical or symlink escapes, checks the cache, parses the JSON, validates object shape, nonempty name, slug charset, and required_roles array, then caches by canonical path" notable_decisions="[]"]
128
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
129
+ // CIL[DOC-STABILITY stability="stable"]
130
+ export function loadManifest(
131
+ manifestPath: string,
132
+ projectRoot: string = resolve(repoRoot())
133
+ ): AppManifest | null {
134
+ try {
135
+ const root = realpathSync(resolve(projectRoot))
136
+ const lexical = resolve(root, manifestPath)
137
+ if (lexical !== root && !lexical.startsWith(root + sep)) {
138
+ console.error(`[app-manifest] Manifest path escapes project root: ${manifestPath}`)
139
+ return null
140
+ }
141
+ const canonical = realpathSync(lexical)
142
+ if (canonical !== root && !canonical.startsWith(root + sep)) {
143
+ console.error(`[app-manifest] Manifest resolves outside project root: ${manifestPath}`)
144
+ return null
145
+ }
146
+
147
+ if (manifestCache.has(canonical)) {
148
+ return manifestCache.get(canonical)!
149
+ }
150
+
151
+ const content = readFileSync(canonical, 'utf-8')
152
+ const manifest: AppManifest = JSON.parse(content)
153
+
154
+ if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) {
155
+ console.error(`[app-manifest] Invalid manifest at ${manifestPath}: root must be an object`)
156
+ return null
157
+ }
158
+
159
+ if (typeof manifest.name !== 'string' || !manifest.name.trim()) {
160
+ console.error(`[app-manifest] Invalid manifest at ${manifestPath}: missing name`)
161
+ return null
162
+ }
163
+
164
+ if (typeof manifest.slug !== 'string' || !/^[a-z][a-z0-9-]*$/.test(manifest.slug)) {
165
+ console.error(`[app-manifest] Invalid manifest at ${manifestPath}: missing or invalid slug`)
166
+ return null
167
+ }
168
+
169
+ if (manifest.required_roles === undefined || manifest.required_roles === null) {
170
+ manifest.required_roles = []
171
+ } else if (!Array.isArray(manifest.required_roles) || manifest.required_roles.some((r) => typeof r !== 'string' || !r.trim())) {
172
+ console.error(`[app-manifest] Invalid manifest at ${manifestPath}: required_roles must be an array of nonempty strings`)
173
+ return null
174
+ }
175
+
176
+ manifestCache.set(canonical, manifest)
177
+ return manifest
178
+ } catch (err) {
179
+ console.error(`[app-manifest] Failed to load ${manifestPath}:`, err)
180
+ return null
181
+ }
182
+ }
183
+ // CIL[DOC-VECTOR type="context" content="purpose='Load and parse an app manifest JSON file from a path relative to the repo root'; No verified external callers; imports: none"]
184
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
185
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
186
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
187
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
188
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
189
+ // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:loadManifest:function"]
190
+
191
+
192
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:clearManifestCache:function" type="function" identity="clearManifestCache" parent="~/.framework/mcp/shared/app-manifest.ts"]
193
+ // CIL[DOC-MACRO purpose="Clear the in-memory manifest cache"]
194
+ // CIL[DOC-RESPONSIBILITY responsibility="Allow callers to invalidate cached manifests so fresh files are loaded on the next call"]
195
+ // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
196
+ // CIL[DOC-CONTRACT inputs="none" outputs="void" errors="none" side_effects="clears the manifestCache Map"]
197
+ // CIL[DOC-MICRO logic_summary="Calls manifestCache.clear() to remove all entries" notable_decisions="[]"]
198
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
199
+ // CIL[DOC-STABILITY stability="stable"]
200
+ export function clearManifestCache(): void {
201
+ manifestCache.clear()
202
+ }
203
+ // CIL[DOC-VECTOR type="context" content="purpose='Clear the in-memory manifest cache'; No verified external callers; imports: none"]
204
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
205
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
206
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
207
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
208
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
209
+ // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:clearManifestCache:function"]
210
+
211
+
212
+ // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:mergeWithManifest:function" type="function" identity="mergeWithManifest" parent="~/.framework/mcp/shared/app-manifest.ts"]
213
+ // CIL[DOC-MACRO purpose="Merge a database app record with its corresponding manifest, preferring manifest values when present"]
214
+ // CIL[DOC-RESPONSIBILITY responsibility="Build a runtime app object from a database record and manifest file, with fallback to database values when the manifest is absent"]
215
+ // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
216
+ // CIL[DOC-CONTRACT inputs="dbRecord: any" outputs="merged record object | null" errors="returns null for missing dbRecord; warns on missing manifest" side_effects="loads a manifest via loadManifest; may log a warning to console"]
217
+ // CIL[DOC-MICRO logic_summary="Returns null for a falsy record. If config_source is not manifest or manifest_path is missing, returns a database-only record tagged _source=database preserving an existing required_roles array and deriving from min_role only when absent. Otherwise loads the manifest and composes a record using manifest values for slug, name, description, roles, routes, nav items, features, dependencies, version, is_public, auth_required, while preserving the full database record including id, is_active, is_system, route_prefix, renderer, config, account_id, pack_id, and ownership" notable_decisions="[]"]
218
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
219
+ // CIL[DOC-STABILITY stability="stable"]
220
+ export function mergeWithManifest(dbRecord: any): any {
221
+ if (!dbRecord) return null
222
+
223
+ const fallbackRoles = Array.isArray(dbRecord.required_roles)
224
+ ? dbRecord.required_roles
225
+ : dbRecord.min_role ? [dbRecord.min_role] : []
226
+
227
+ if (!dbRecord.manifest_path || dbRecord.config_source !== 'manifest') {
228
+ return {
229
+ ...dbRecord,
230
+ required_roles: fallbackRoles,
231
+ _source: 'database',
232
+ }
233
+ }
234
+
235
+ const manifest = loadManifest(dbRecord.manifest_path)
236
+ if (!manifest) {
237
+ console.warn(`[app-manifest] Could not load manifest for ${dbRecord.slug}, falling back to DB`)
238
+ return {
239
+ ...dbRecord,
240
+ required_roles: fallbackRoles,
241
+ _source: 'database (manifest missing)',
242
+ }
243
+ }
244
+
245
+ return {
246
+ ...dbRecord,
247
+ id: dbRecord.id,
248
+ slug: manifest.slug,
249
+ name: manifest.name,
250
+ description: manifest.description || dbRecord.description,
251
+ required_roles: manifest.required_roles,
252
+ min_role: manifest.required_roles[0] || null,
253
+ routes: manifest.routes,
254
+ nav_items: manifest.nav_items,
255
+ features: manifest.features || [],
256
+ dependencies: manifest.dependencies || [],
257
+ version: manifest.version,
258
+ is_active: dbRecord.is_active,
259
+ is_system: dbRecord.is_system,
260
+ is_public: manifest.is_public ?? false,
261
+ auth_required: manifest.auth_required ?? true,
262
+ account_id: dbRecord.account_id,
263
+ pack_id: dbRecord.pack_id,
264
+ ownership: dbRecord.ownership,
265
+ _source: 'manifest',
266
+ _manifest_path: dbRecord.manifest_path,
267
+ }
268
+ }
269
+ // CIL[DOC-VECTOR type="context" content="purpose='Merge a database app record with its corresponding manifest, preferring manifest values when present'; No verified external callers; imports: none"]
270
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
271
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
272
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
273
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
274
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
275
+ // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:mergeWithManifest:function"]