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
@@ -1,257 +1,163 @@
1
-
2
-
3
-
4
- // CIL[BEGIN chunk_id="init_moduleheader_1784069813" type="module_header" identity="module_header" parent="none"]
5
- // CIL[DOC-MACRO purpose="Module imports and constants for init command"]
6
- // CIL[DOC-RESPONSIBILITY responsibility="Provide filesystem utilities and path constants"]
7
- // CIL[DOC-CONTEXT module="cli.commands.init" layer="cli" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
8
- // CIL[DOC-CONTRACT inputs="none" outputs="constants" errors="none" side_effects="none"]
9
- // CIL[DOC-MICRO logic_summary="Imports Node.js fs, path modules and defines package/project root paths" notable_decisions="[]"]
10
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1
+ // CIL[BEGIN stable_id="~/.framework/cli/commands/init.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/cli/commands/init.ts"]
2
+ // CIL[DOC-AUDIENCE audience="internal"]
3
+ // CIL[DOC-MACRO purpose="Scaffold a new Spine Framework project into a directory"]
4
+ // CIL[DOC-RESPONSIBILITY responsibility="Copy the framework-owned file set from .framework/templates/project.json, generate package.json/package-lock.json/.gitignore/netlify.toml/spine.config.json, and write the frozen .spine-manifest.json with framework_version"]
5
+ // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/templates/project.json,.framework/cli/lib/project-files.ts,.framework/cli/commands/upgrade.ts"]
6
+ // CIL[DOC-CONTRACT inputs="[dir] (default cwd); spine-framework package on disk" outputs="project tree + frozen manifest" errors="exit 1 on existing .framework or missing package files" side_effects="writes <dir> only; no npm install, network, or DB access"]
7
+ // CIL[DOC-MICRO logic_summary="Framework-only scaffold — apps install themselves via their own installer (e.g. npx <app> install). netlify.toml carries only framework blocks; apps append their own custom_* sections. package.json gets the framework's full dep set inlined plus an exact spine-framework pin so `spine-framework upgrade` can re-sync this copy" notable_decisions="never writes .env (secrets) — prints instructions to copy .env.example; existing files are never overwritten except generated package.json/netlify.toml which merge"]
8
+ // CIL[DOC-CONFIDENCE pass="second" score="0.9" flags="none"]
11
9
  // CIL[DOC-STABILITY stability="stable"]
12
- // CIL[DOC-AUDIENCE audience="installer"]
13
- // CIL[DOC-VECTOR type="context" content="Layer: cli. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, \."]
14
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
15
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
16
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
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
10
  import type { Command } from 'commander'
20
- import { existsSync, mkdirSync, writeFileSync, copyFileSync, readdirSync, statSync, cpSync, readFileSync } from 'fs'
21
- import { resolve, dirname, join } from 'path'
11
+ import { existsSync, mkdirSync, writeFileSync, copyFileSync, readFileSync, readdirSync } from 'fs'
12
+ import { resolve, dirname, join, basename } from 'path'
22
13
  import { fileURLToPath } from 'url'
23
- import { execSync } from 'child_process'
24
-
14
+ import {
15
+ loadProjectProfile,
16
+ collectFrameworkFiles,
17
+ copyCollectedFiles,
18
+ renderNetlifyToml,
19
+ renderGitignore,
20
+ mergePackageJson,
21
+ writeFrozenManifest,
22
+ sanitizePackageName,
23
+ } from '../lib/project-files.ts'
24
+ // CIL[END stable_id="~/.framework/cli/commands/init.ts:module_header:module_header"]
25
+
26
+ // CIL[BEGIN stable_id="~/.framework/cli/commands/init.ts:paths:block" type="block" identity="paths" parent="~/.framework/cli/commands/init.ts"]
27
+ // CIL[DOC-MACRO purpose="ESM __filename/__dirname shim plus PACKAGE_ROOT — the spine-framework package root this init copies files from"]
28
+ // CIL[DOC-CONTEXT module="cli" layer="framework" related_files="package.json"]
29
+ // CIL[DOC-CONTRACT inputs="none" outputs="resolved path constants" errors="none" side_effects="none"]
30
+ // CIL[DOC-MICRO logic_summary="PACKAGE_ROOT resolves three levels up from commands/ — inside the vendored package payload" notable_decisions="computed at module load from import.meta.url, not cwd"]
31
+ // CIL[DOC-CONFIDENCE pass="first" score="0.95" flags="none"]
32
+ // CIL[DOC-STABILITY stability="stable"]
33
+ // CIL[DOC-AUDIENCE audience="developer"]
25
34
  const __filename = fileURLToPath(import.meta.url)
26
35
  const __dirname = dirname(__filename)
27
36
 
28
37
  const PACKAGE_ROOT = resolve(__dirname, '../../../')
29
- const PROJECT_ROOT = process.cwd()
30
- // CIL[END chunk_id="init_moduleheader_1784069813"]
31
- // CIL[BEGIN chunk_id="init_registerinitcommands_1784069813" type="function" identity="registerInitCommands" parent="none"]
32
- // CIL[DOC-MACRO purpose="Register init command with CLI program"]
33
- // CIL[DOC-RESPONSIBILITY responsibility="Scaffold new Spine Framework projects"]
34
- // CIL[DOC-CONTEXT module="cli.commands.init" layer="cli" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/migrations/015_simplify_apps_table.sql\",\".framework/src/components/ui/table-primitives.tsx\",\"\\\"]"]
35
- // CIL[DOC-CONTRACT inputs="none" outputs="CLI command registration" errors="init failures" side_effects="filesystem writes"]
36
- // CIL[DOC-MICRO logic_summary="Copies framework files, creates directories, writes package.json and config files" notable_decisions="[]"]
37
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
38
+ // CIL[END stable_id="~/.framework/cli/commands/init.ts:paths:block"]
39
+
40
+ // CIL[BEGIN stable_id="~/.framework/cli/commands/init.ts:registerInitCommands:function" type="function" identity="registerInitCommands" parent="~/.framework/cli/commands/init.ts"]
41
+ // CIL[DOC-MACRO purpose="Register the `init [dir]` command that scaffolds a neutral framework-only project"]
42
+ // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/cli/index.ts,.framework/cli/lib/project-files.ts"]
43
+ // CIL[DOC-CONTRACT inputs="program: Command; [dir] positional (default cwd)" outputs="project tree + frozen manifest" errors="exit 1 on existing .framework or template missing" side_effects="writes <dir> only"]
44
+ // CIL[DOC-MICRO logic_summary="Copies the profile fileset, creates the custom/ workspace, merges package.json with inlined framework deps + exact pin, writes lockfile/gitignore/netlify.toml/neutral spine.config.json, then freezes .spine-manifest.json" notable_decisions="framework-only by design — apps self-install afterwards via their own CLIs"]
45
+ // CIL[DOC-CONFIDENCE pass="first" score="0.9" flags="none"]
38
46
  // CIL[DOC-STABILITY stability="stable"]
39
- // CIL[DOC-VECTOR type="context" content="Layer: cli. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, .framework/migrations/015_simplify_apps_table.sql, .framework/src/components/ui/table-primitives.tsx, \."]
40
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
41
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
42
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
43
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
44
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
47
+ // CIL[DOC-AUDIENCE audience="developer"]
45
48
  export function registerInitCommands(program: Command) {
46
49
  program
47
50
  .command('init')
48
- .description('Scaffold a new Spine Framework project in the current directory')
49
- .option('--force', 'Overwrite existing files', false)
50
- .action(async (opts) => {
51
- console.log('\nInitializing Spine Framework project...\n')
52
-
53
-
54
- const existingPkg = join(PROJECT_ROOT, 'package.json')
55
- if (existsSync(existingPkg) && !opts.force) {
56
- try {
57
- const pkg = JSON.parse(readFileSync(existingPkg, 'utf8'))
58
- const hasSpine = pkg.dependencies?.['spine-framework'] || pkg.devDependencies?.['spine-framework']
59
- const hasFramework = existsSync(join(PROJECT_ROOT, '.framework'))
60
- if (!hasSpine && !hasFramework && pkg.name !== 'spine-framework') {
61
- console.warn('Warning: package.json exists but does not appear to be a Spine project.')
62
- console.warn('Use --force to overwrite. Continuing with scaffold...\n')
63
- }
64
- } catch {}
65
- }
51
+ .description('Scaffold a new Spine Framework project')
52
+ .argument('[dir]', 'Target directory (default: current directory)')
53
+ .action(async (dirArg?: string) => {
54
+ const target = resolve(dirArg ?? process.cwd())
55
+ console.log(`\nInitializing Spine Framework project in ${target}\n`)
66
56
 
67
57
  try {
68
-
69
- console.log(' Copying .framework/...')
70
- const fwSrc = join(PACKAGE_ROOT, '.framework')
71
- const fwDest = join(PROJECT_ROOT, '.framework')
72
- if (!existsSync(fwDest)) {
73
- cpSync(fwSrc, fwDest, { recursive: true })
74
- console.log(' ✓ .framework/ copied')
75
- } else {
76
- console.log(' ○ .framework/ already exists, skipping')
58
+ if (existsSync(join(target, '.framework'))) {
59
+ console.error('❌ .framework/ already exists — this looks like a Spine project.')
60
+ console.error(' To update the framework, use: npx spine-framework upgrade')
61
+ process.exit(1)
77
62
  }
63
+ mkdirSync(target, { recursive: true })
78
64
 
79
-
80
- console.log(' Creating custom/ workspace...')
81
- const customDirs = [
82
- 'custom/apps',
83
- 'custom/functions',
84
- 'custom/components',
85
- 'custom/migrations',
86
- 'custom/tests',
87
- ]
88
- for (const dir of customDirs) {
89
- const full = join(PROJECT_ROOT, dir)
90
- if (!existsSync(full)) {
91
- mkdirSync(full, { recursive: true })
92
- }
93
- }
94
-
95
- const devinSrc = join(PACKAGE_ROOT, 'custom/.devin')
96
- const devinDest = join(PROJECT_ROOT, 'custom/.devin')
97
- if (existsSync(devinSrc) && !existsSync(devinDest)) {
98
- cpSync(devinSrc, devinDest, { recursive: true })
99
- }
100
- console.log(' ✓ custom/ workspace created')
65
+ const profile = loadProjectProfile(PACKAGE_ROOT)
66
+ const frameworkVersion = getPackageVersion()
67
+ const packageName = sanitizePackageName(basename(target))
101
68
 
102
-
103
- console.log(' Copying config files...')
104
- const configSrc = join(PACKAGE_ROOT, 'config')
105
- const configDest = join(PROJECT_ROOT, 'config')
106
- if (existsSync(configSrc) && !existsSync(configDest)) {
107
- cpSync(configSrc, configDest, { recursive: true })
108
- console.log(' ✓ config/ copied')
109
- }
69
+ // 1. Framework-owned files (same relative layout in the package and the project)
70
+ console.log(' Copying framework files...')
71
+ const files = collectFrameworkFiles(PACKAGE_ROOT, profile)
72
+ copyCollectedFiles(files, target)
73
+ console.log(` ✓ ${files.length} files copied`)
110
74
 
111
-
112
- console.log(' Copying scripts/...')
113
- const scriptsSrc = join(PACKAGE_ROOT, 'scripts')
114
- const scriptsDest = join(PROJECT_ROOT, 'scripts')
115
- if (existsSync(scriptsSrc) && !existsSync(scriptsDest)) {
116
- cpSync(scriptsSrc, scriptsDest, { recursive: true })
117
- console.log(' ✓ scripts/ copied')
75
+ // 2. App workspace skeleton — apps own everything under custom/
76
+ for (const dir of ['custom/apps', 'custom/functions', 'custom/components', 'custom/migrations', 'custom/tests']) {
77
+ mkdirSync(join(target, dir), { recursive: true })
118
78
  }
79
+ console.log(' ✓ custom/ workspace created')
119
80
 
120
-
121
- const netlifyTomlSrc = join(PACKAGE_ROOT, 'netlify.toml')
122
- if (existsSync(netlifyTomlSrc) && !existsSync(join(PROJECT_ROOT, 'netlify.toml'))) {
123
- copyFileSync(netlifyTomlSrc, join(PROJECT_ROOT, 'netlify.toml'))
124
- console.log(' ✓ netlify.toml copied')
81
+ // 3. package.json — framework deps inlined (matching the framework snapshot)
82
+ // plus an exact spine-framework pin so `upgrade` can re-sync later.
83
+ const existingPkgPath = join(target, 'package.json')
84
+ let existingPkg: Record<string, any> | undefined
85
+ if (existsSync(existingPkgPath)) {
86
+ try { existingPkg = JSON.parse(readFileSync(existingPkgPath, 'utf8')) } catch {}
125
87
  }
88
+ const srcPkg = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'))
89
+ const merged = mergePackageJson({
90
+ existing: existingPkg,
91
+ name: packageName,
92
+ description: 'Spine Framework project',
93
+ scripts: profile.package_scripts,
94
+ newDependencies: srcPkg.dependencies ?? {},
95
+ newDevDependencies: srcPkg.devDependencies ?? {},
96
+ spineVersion: frameworkVersion,
97
+ })
98
+ writeFileSync(existingPkgPath, merged.text)
99
+ console.log(' ✓ package.json written')
126
100
 
127
-
128
- const spineConfigSrc = join(PACKAGE_ROOT, 'spine.config.json')
129
- const spineConfigDest = join(PROJECT_ROOT, 'spine.config.json')
130
- if (existsSync(spineConfigSrc) && !existsSync(spineConfigDest)) {
131
- copyFileSync(spineConfigSrc, spineConfigDest)
132
- console.log(' ✓ spine.config.json copied')
133
- } else if (existsSync(spineConfigDest) && !JSON.parse(readFileSync(spineConfigDest, 'utf8'))?.registration?.default_app_by_role) {
134
- console.log(' ⚠ Existing spine.config.json does not have default_app_by_role; consider updating it')
101
+ // 4. package-lock.json — verified lock tree shipped under templates/project/
102
+ const lockTemplate = join(PACKAGE_ROOT, 'templates/project/package-lock.json')
103
+ if (existsSync(lockTemplate)) {
104
+ const lock = JSON.parse(readFileSync(lockTemplate, 'utf8'))
105
+ lock.name = packageName
106
+ if (lock.packages?.['']) lock.packages[''].name = packageName
107
+ writeFileSync(join(target, 'package-lock.json'), JSON.stringify(lock, null, 2) + '\n')
108
+ console.log(' ✓ package-lock.json written (verified dependency set)')
109
+ } else {
110
+ console.log(' ○ package-lock template not shipped — npm install will resolve deps')
135
111
  }
136
112
 
137
-
138
- console.log(' Writing package.json...')
139
- const projectName = PROJECT_ROOT.split('/').pop() || 'my-spine-project'
140
- const pkgJson = {
141
- name: projectName,
142
- version: '0.1.0',
143
- private: true,
144
- type: 'module',
145
- scripts: {
146
- dev: 'netlify dev',
147
- assemble: 'bash scripts/assemble.sh',
148
- 'assemble:frontend': 'bash scripts/assemble-frontend.sh',
149
- 'assemble:functions': 'bash scripts/assemble-functions.sh',
150
- build: 'npm run assemble && vite build --config config/vite.config.ts',
151
- verify: 'bash scripts/verify-integrity.sh',
152
- test: 'vitest run',
153
- },
154
- dependencies: {
155
- 'spine-framework': `^${getPackageVersion()}`,
156
- },
157
- devDependencies: {
158
- '@netlify/functions': '^2.8.2',
159
- '@supabase/supabase-js': '^2.49.1',
160
- '@tailwindcss/typography': '^0.5.19',
161
- '@types/node': '^22.12.0',
162
- '@types/react': '^18.3.18',
163
- '@types/react-dom': '^18.3.5',
164
- '@vitejs/plugin-react': '^4.3.4',
165
- 'autoprefixer': '^10.4.20',
166
- 'postcss': '^8.5.1',
167
- 'tailwindcss': '^3.4.17',
168
- 'tsx': '^4.21.0',
169
- 'typescript': '~5.6.2',
170
- 'vite': '^6.0.11',
171
- 'vitest': '^2.1.9',
172
- },
173
- }
174
-
175
- let finalPkg = pkgJson
176
- if (existsSync(join(PROJECT_ROOT, 'package.json'))) {
177
- try {
178
- const existing = JSON.parse(readFileSync(join(PROJECT_ROOT, 'package.json'), 'utf8'))
179
- finalPkg = {
180
- ...pkgJson,
181
- name: existing.name || pkgJson.name,
182
- version: existing.version || pkgJson.version,
183
-
184
- dependencies: { ...existing.dependencies, ...pkgJson.dependencies },
185
-
186
- devDependencies: { ...pkgJson.devDependencies, ...existing.devDependencies },
187
- }
188
- } catch {}
113
+ // 5. .gitignore — from packed template; .env.example stays tracked
114
+ const gitignoreTemplate = join(PACKAGE_ROOT, 'templates/project/gitignore')
115
+ const gitignoreDest = join(target, '.gitignore')
116
+ if (!existsSync(gitignoreDest) && existsSync(gitignoreTemplate)) {
117
+ writeFileSync(gitignoreDest, renderGitignore(readFileSync(gitignoreTemplate, 'utf8')))
118
+ console.log(' ✓ .gitignore written')
119
+ } else if (existsSync(gitignoreDest)) {
120
+ console.log(' ○ .gitignore already exists, skipping')
189
121
  }
190
- writeFileSync(
191
- join(PROJECT_ROOT, 'package.json'),
192
- JSON.stringify(finalPkg, null, 2) + '\n'
193
- )
194
- console.log(' ✓ package.json written')
195
122
 
196
-
197
- console.log(' Writing .env template...')
198
- if (!existsSync(join(PROJECT_ROOT, '.env'))) {
199
- const envTemplate = [
200
- '# Supabase credentials',
201
- '# Get these from: Supabase Dashboard → Your Project → Settings → API',
202
- '# Replace the values below — do not leave them blank or as placeholders',
203
- 'SUPABASE_URL=',
204
- 'SUPABASE_ANON_KEY=',
205
- 'SUPABASE_SERVICE_ROLE_KEY=',
206
- 'SUPABASE_DB_PASSWORD=',
207
- '',
208
- '# Vite (browser-safe) — copy from above',
209
- 'VITE_SUPABASE_URL=',
210
- 'VITE_SUPABASE_ANON_KEY=',
211
- 'VITE_DB_SCHEMA=public',
212
- 'VITE_APP_NAME=Spine',
213
- '',
214
- ].join('\n')
215
- writeFileSync(join(PROJECT_ROOT, '.env'), envTemplate)
216
- console.log(' ✓ .env template written')
217
- } else {
218
- console.log(' ○ .env already exists, skipping')
123
+ // 6. netlify.toml — framework blocks only; preserves any existing custom_* sections
124
+ const netlifySrc = join(PACKAGE_ROOT, 'netlify.toml')
125
+ const netlifyDest = join(target, 'netlify.toml')
126
+ const existingToml = existsSync(netlifyDest) ? readFileSync(netlifyDest, 'utf8') : undefined
127
+ if (existsSync(netlifySrc)) {
128
+ writeFileSync(netlifyDest, renderNetlifyToml(readFileSync(netlifySrc, 'utf8'), existingToml))
129
+ console.log(' ✓ netlify.toml written')
219
130
  }
220
131
 
221
-
222
- if (!existsSync(join(PROJECT_ROOT, '.gitignore'))) {
223
- const gitignore = [
224
- 'node_modules',
225
- 'dist',
226
- '.assembled/',
227
- '.netlify',
228
- '.env',
229
- '.env.local',
230
- '.env.production',
231
- '*.log',
232
- '.DS_Store',
233
- '*.tsbuildinfo',
234
- '.vite',
235
- ].join('\n') + '\n'
236
- writeFileSync(join(PROJECT_ROOT, '.gitignore'), gitignore)
237
- console.log(' ✓ .gitignore written')
132
+ // 7. spine.config.json — neutral template; apps register themselves at install
133
+ const spineConfigSrc = join(PACKAGE_ROOT, '.framework', 'templates', 'spine.config.neutral.json')
134
+ const spineConfigDest = join(target, 'spine.config.json')
135
+ if (existsSync(spineConfigSrc) && !existsSync(spineConfigDest)) {
136
+ copyFileSync(spineConfigSrc, spineConfigDest)
137
+ console.log(' ✓ spine.config.json written (neutral template)')
238
138
  }
239
139
 
240
-
241
- let pkgVersion = 'unknown'
242
- try {
243
- const pkgJson = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'))
244
- pkgVersion = pkgJson.version ?? 'unknown'
245
- } catch { /* non-fatal */ }
140
+ // 8. Frozen integrity manifest — version + framework-owned dep inventory
141
+ const manifest = writeFrozenManifest({
142
+ projectRoot: target,
143
+ frameworkVersion,
144
+ frameworkDeps: merged.frameworkDeps,
145
+ })
146
+ console.log(` ✓ .spine-manifest.json written (${manifest.fileCount} protected files, frozen)`)
246
147
 
247
- console.log(`\n✅ Project initialized! (spine-framework@${pkgVersion})\n`)
148
+ console.log(`\n✅ Spine Framework ${frameworkVersion} project initialized\n`)
248
149
  console.log('Next steps:')
249
- console.log(' 1. Edit .env with your Supabase credentials')
250
- console.log(' 2. Run: npm install (installs vite, typescript, and other dev tools)')
251
- console.log(' 3. Run: npx spine-framework migrate')
252
- console.log(' 4. Run: npm run assemble && netlify dev')
150
+ if (!existsSync(join(target, '.env'))) {
151
+ console.log(' 1. cp .env.example .env — fill in your Supabase credentials')
152
+ } else {
153
+ console.log(' 1. Verify .env contains your Supabase credentials')
154
+ }
155
+ console.log(' 2. npm install')
156
+ console.log(' 3. npm run verify')
157
+ console.log(' 4. Install an app, e.g.: npx <app-package> install')
158
+ console.log(' 5. npx spine-framework migrate')
159
+ console.log(' 6. npm run dev:netlify')
253
160
  console.log()
254
-
255
161
  } catch (err: any) {
256
162
  console.error('\n❌ Init failed:', err.message)
257
163
  if (process.env.SPINE_CLI_DEBUG) console.error(err.stack)
@@ -259,29 +165,22 @@ export function registerInitCommands(program: Command) {
259
165
  }
260
166
  })
261
167
  }
262
- // CIL[END chunk_id="init_registerinitcommands_1784069813"]
263
- // CIL[BEGIN chunk_id="init_getpackageversion_1784069813" type="function" identity="getPackageVersion" parent="none"]
264
- // CIL[DOC-MACRO purpose="Get package version from package.json"]
265
- // CIL[DOC-RESPONSIBILITY responsibility="Read and return framework version"]
266
- // CIL[DOC-CONTEXT module="cli.commands.init" layer="cli" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
267
- // CIL[DOC-CONTRACT inputs="none" outputs="version string" errors="file read errors" side_effects="none"]
268
- // CIL[DOC-MICRO logic_summary="Reads package.json and returns version with fallback to 0.3.0" notable_decisions="[]"]
269
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
168
+ // CIL[END stable_id="~/.framework/cli/commands/init.ts:registerInitCommands:function"]
169
+
170
+ // CIL[BEGIN stable_id="~/.framework/cli/commands/init.ts:getPackageVersion:function" type="function" identity="getPackageVersion" parent="~/.framework/cli/commands/init.ts"]
171
+ // CIL[DOC-MACRO purpose="Read the running package's version — becomes the project's frozen framework_version"]
172
+ // CIL[DOC-CONTEXT module="cli" layer="framework" related_files="package.json"]
173
+ // CIL[DOC-CONTRACT inputs="none" outputs="semver string" errors="returns '0.0.0' when package.json unreadable" side_effects="none"]
174
+ // CIL[DOC-MICRO logic_summary="Reads PACKAGE_ROOT/package.json — the vendored CLI always ships its own manifest" notable_decisions="0.0.0 fallback is defensive only"]
175
+ // CIL[DOC-CONFIDENCE pass="first" score="0.95" flags="none"]
270
176
  // CIL[DOC-STABILITY stability="stable"]
271
- // CIL[DOC-VECTOR type="context" content="Layer: cli. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, \."]
272
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
273
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
274
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
275
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
276
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
177
+ // CIL[DOC-AUDIENCE audience="developer"]
277
178
  function getPackageVersion(): string {
278
179
  try {
279
- const pkg = JSON.parse(
280
- readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8')
281
- )
282
- return pkg.version || '0.3.0'
180
+ const pkg = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'))
181
+ return pkg.version || '0.0.0'
283
182
  } catch {
284
- return '0.3.0'
183
+ return '0.0.0'
285
184
  }
286
185
  }
287
- // CIL[END chunk_id="init_getpackageversion_1784069813"]
186
+ // CIL[END stable_id="~/.framework/cli/commands/init.ts:getPackageVersion:function"]