spine-framework 0.1.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 (385) hide show
  1. package/.framework/README.md +129 -0
  2. package/.framework/cli/bin.cjs +14 -0
  3. package/.framework/cli/commands/agents.ts +153 -0
  4. package/.framework/cli/commands/auth.ts +94 -0
  5. package/.framework/cli/commands/create-app.ts +185 -0
  6. package/.framework/cli/commands/dev.ts +295 -0
  7. package/.framework/cli/commands/doctor.ts +442 -0
  8. package/.framework/cli/commands/generate.ts +332 -0
  9. package/.framework/cli/commands/init.ts +272 -0
  10. package/.framework/cli/commands/install-app.ts +391 -0
  11. package/.framework/cli/commands/items.ts +253 -0
  12. package/.framework/cli/commands/migrations.ts +141 -0
  13. package/.framework/cli/commands/pipelines.ts +166 -0
  14. package/.framework/cli/commands/status.ts +197 -0
  15. package/.framework/cli/commands/system.ts +184 -0
  16. package/.framework/cli/commands/test.ts +227 -0
  17. package/.framework/cli/commands/uninstall-app.ts +166 -0
  18. package/.framework/cli/context.ts +268 -0
  19. package/.framework/cli/env-loader.ts +36 -0
  20. package/.framework/cli/index.ts +106 -0
  21. package/.framework/cli/welcome.cjs +45 -0
  22. package/.framework/docs/API.md +384 -0
  23. package/.framework/docs/STABILITY.md +52 -0
  24. package/.framework/docs/admin-routes.md +76 -0
  25. package/.framework/docs/api-docs-progress.md +38 -0
  26. package/.framework/docs/api-governance.md +146 -0
  27. package/.framework/docs/api-testing-results.md +212 -0
  28. package/.framework/docs/apis/admin-configs.md +567 -0
  29. package/.framework/docs/apis/admin-data.md +272 -0
  30. package/.framework/docs/apis/index.md +231 -0
  31. package/.framework/docs/apis/internal.md +295 -0
  32. package/.framework/docs/apis/runtime.md +537 -0
  33. package/.framework/docs/assembly-launch-guide.md +138 -0
  34. package/.framework/docs/audit-results.md +590 -0
  35. package/.framework/docs/authorization-model.md +170 -0
  36. package/.framework/docs/db-api-inventory.md +95 -0
  37. package/.framework/docs/examples/custom-app/README.md +77 -0
  38. package/.framework/docs/examples/custom-function/README.md +27 -0
  39. package/.framework/docs/examples/custom-function/handler.ts +48 -0
  40. package/.framework/docs/examples/custom-webhook/README.md +68 -0
  41. package/.framework/docs/gap-remediation-backlog.md +103 -0
  42. package/.framework/docs/guides/cli-guide.md +224 -0
  43. package/.framework/docs/guides/getting-started.md +103 -0
  44. package/.framework/docs/guides/import-guide.md +193 -0
  45. package/.framework/docs/guides/testing-guide.md +229 -0
  46. package/.framework/docs/permission-examples.md +326 -0
  47. package/.framework/docs/ui-adoption-verification.md +111 -0
  48. package/.framework/docs/ui-api-coverage.md +84 -0
  49. package/.framework/docs/v2-compatibility-audit.md +228 -0
  50. package/.framework/functions/.gitkeep +1 -0
  51. package/.framework/functions/_shared/agent-runner.ts +1097 -0
  52. package/.framework/functions/_shared/app-manifest.ts +184 -0
  53. package/.framework/functions/_shared/audit.ts +150 -0
  54. package/.framework/functions/_shared/db.ts +174 -0
  55. package/.framework/functions/_shared/index.ts +382 -0
  56. package/.framework/functions/_shared/middleware.ts +490 -0
  57. package/.framework/functions/_shared/permissions.ts +1325 -0
  58. package/.framework/functions/_shared/pipeline-runner.ts +731 -0
  59. package/.framework/functions/_shared/principal.ts +760 -0
  60. package/.framework/functions/_shared/schema-utils.ts +967 -0
  61. package/.framework/functions/_shared/testing.ts +258 -0
  62. package/.framework/functions/_shared/trigger-engine.ts +425 -0
  63. package/.framework/functions/_shared/webhook-registration.ts +168 -0
  64. package/.framework/functions/_shared/webhook-registry.ts +129 -0
  65. package/.framework/functions/account-nodes.ts +111 -0
  66. package/.framework/functions/admin-data.ts +606 -0
  67. package/.framework/functions/ai-agents.ts +323 -0
  68. package/.framework/functions/api-keys.ts +376 -0
  69. package/.framework/functions/apps.ts +483 -0
  70. package/.framework/functions/auth.ts +196 -0
  71. package/.framework/functions/debug-auth.ts +107 -0
  72. package/.framework/functions/embeddings.ts +556 -0
  73. package/.framework/functions/integration-routes.ts +523 -0
  74. package/.framework/functions/integrations.ts +319 -0
  75. package/.framework/functions/item-progress.ts +272 -0
  76. package/.framework/functions/logs.ts +438 -0
  77. package/.framework/functions/observability.ts +275 -0
  78. package/.framework/functions/pipeline-executions.ts +494 -0
  79. package/.framework/functions/pipelines.ts +485 -0
  80. package/.framework/functions/prompt-configs.ts +339 -0
  81. package/.framework/functions/roles.ts +387 -0
  82. package/.framework/functions/system-cron.ts +742 -0
  83. package/.framework/functions/system.ts +323 -0
  84. package/.framework/functions/tests.ts +119 -0
  85. package/.framework/functions/timers.ts +357 -0
  86. package/.framework/functions/triggers.ts +563 -0
  87. package/.framework/functions/types.ts +604 -0
  88. package/.framework/migrations/000_foundation.sql +1256 -0
  89. package/.framework/migrations/001_seed.sql +92 -0
  90. package/.framework/migrations/002_seed_constraints.sql +13 -0
  91. package/.framework/migrations/003_auth_user_trigger.sql +59 -0
  92. package/.framework/src/App.tsx +126 -0
  93. package/.framework/src/apps/admin/index.tsx +173 -0
  94. package/.framework/src/components/AppWrapper.tsx +56 -0
  95. package/.framework/src/components/CustomAppLoader.tsx +116 -0
  96. package/.framework/src/components/admin/AdminListPage.tsx +151 -0
  97. package/.framework/src/components/admin/AdminSidebar.tsx +166 -0
  98. package/.framework/src/components/admin/AdminStatsCard.tsx +62 -0
  99. package/.framework/src/components/admin/SortableTableHeader.tsx +42 -0
  100. package/.framework/src/components/app-shell/GenericAppShell.tsx +181 -0
  101. package/.framework/src/components/app-shell/GenericDetailPage.tsx +200 -0
  102. package/.framework/src/components/app-shell/GenericListPage.tsx +116 -0
  103. package/.framework/src/components/app-sidebar.tsx +228 -0
  104. package/.framework/src/components/auth/ProtectedRoute.tsx +88 -0
  105. package/.framework/src/components/layout/AppShell.tsx +91 -0
  106. package/.framework/src/components/layout/Header.tsx +88 -0
  107. package/.framework/src/components/layout/Layout.tsx +95 -0
  108. package/.framework/src/components/layout/Sidebar.tsx +329 -0
  109. package/.framework/src/components/runtime/DataDetailHeader.tsx +77 -0
  110. package/.framework/src/components/runtime/DataDetailPage.tsx +171 -0
  111. package/.framework/src/components/runtime/DataFilters.tsx +91 -0
  112. package/.framework/src/components/runtime/DataHeader.tsx +68 -0
  113. package/.framework/src/components/runtime/DataListPage.tsx +124 -0
  114. package/.framework/src/components/runtime/DataStats.tsx +70 -0
  115. package/.framework/src/components/runtime/DataTable.tsx +174 -0
  116. package/.framework/src/components/runtime/SchemaDetailForm.tsx +134 -0
  117. package/.framework/src/components/runtime/index.ts +18 -0
  118. package/.framework/src/components/search-form.tsx +29 -0
  119. package/.framework/src/components/shared/AgentView.tsx +213 -0
  120. package/.framework/src/components/shared/FieldRenderer.tsx +478 -0
  121. package/.framework/src/components/shared/SchemaFields.tsx +226 -0
  122. package/.framework/src/components/ui/DataTable.tsx +343 -0
  123. package/.framework/src/components/ui/Form.tsx +281 -0
  124. package/.framework/src/components/ui/ItemCard.tsx +296 -0
  125. package/.framework/src/components/ui/ItemListView.tsx +308 -0
  126. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -0
  127. package/.framework/src/components/ui/Modal.tsx +61 -0
  128. package/.framework/src/components/ui/RichTextEditor.tsx +210 -0
  129. package/.framework/src/components/ui/accordion.tsx +82 -0
  130. package/.framework/src/components/ui/alert-dialog.tsx +197 -0
  131. package/.framework/src/components/ui/alert.tsx +76 -0
  132. package/.framework/src/components/ui/aspect-ratio.tsx +11 -0
  133. package/.framework/src/components/ui/avatar.tsx +110 -0
  134. package/.framework/src/components/ui/badge.tsx +49 -0
  135. package/.framework/src/components/ui/breadcrumb.tsx +122 -0
  136. package/.framework/src/components/ui/button-group.tsx +83 -0
  137. package/.framework/src/components/ui/button.tsx +65 -0
  138. package/.framework/src/components/ui/calendar.tsx +222 -0
  139. package/.framework/src/components/ui/card.tsx +100 -0
  140. package/.framework/src/components/ui/carousel.tsx +240 -0
  141. package/.framework/src/components/ui/chart.tsx +373 -0
  142. package/.framework/src/components/ui/checkbox.tsx +31 -0
  143. package/.framework/src/components/ui/collapsible.tsx +33 -0
  144. package/.framework/src/components/ui/combobox.tsx +299 -0
  145. package/.framework/src/components/ui/command.tsx +193 -0
  146. package/.framework/src/components/ui/context-menu.tsx +261 -0
  147. package/.framework/src/components/ui/dialog.tsx +165 -0
  148. package/.framework/src/components/ui/direction.tsx +22 -0
  149. package/.framework/src/components/ui/drawer.tsx +132 -0
  150. package/.framework/src/components/ui/dropdown-menu.tsx +269 -0
  151. package/.framework/src/components/ui/empty.tsx +104 -0
  152. package/.framework/src/components/ui/field.tsx +238 -0
  153. package/.framework/src/components/ui/hover-card.tsx +42 -0
  154. package/.framework/src/components/ui/input-group.tsx +153 -0
  155. package/.framework/src/components/ui/input-otp.tsx +87 -0
  156. package/.framework/src/components/ui/input.tsx +19 -0
  157. package/.framework/src/components/ui/item.tsx +196 -0
  158. package/.framework/src/components/ui/kbd.tsx +26 -0
  159. package/.framework/src/components/ui/label.tsx +22 -0
  160. package/.framework/src/components/ui/menubar.tsx +277 -0
  161. package/.framework/src/components/ui/native-select.tsx +61 -0
  162. package/.framework/src/components/ui/navigation-menu.tsx +164 -0
  163. package/.framework/src/components/ui/pagination.tsx +129 -0
  164. package/.framework/src/components/ui/popover.tsx +87 -0
  165. package/.framework/src/components/ui/progress.tsx +31 -0
  166. package/.framework/src/components/ui/radio-group.tsx +42 -0
  167. package/.framework/src/components/ui/resizable.tsx +50 -0
  168. package/.framework/src/components/ui/scroll-area.tsx +53 -0
  169. package/.framework/src/components/ui/select.tsx +195 -0
  170. package/.framework/src/components/ui/separator.tsx +26 -0
  171. package/.framework/src/components/ui/sheet.tsx +145 -0
  172. package/.framework/src/components/ui/sidebar.tsx +706 -0
  173. package/.framework/src/components/ui/skeleton.tsx +13 -0
  174. package/.framework/src/components/ui/slider.tsx +59 -0
  175. package/.framework/src/components/ui/sonner.tsx +47 -0
  176. package/.framework/src/components/ui/spinner.tsx +10 -0
  177. package/.framework/src/components/ui/switch.tsx +33 -0
  178. package/.framework/src/components/ui/table-primitives.tsx +141 -0
  179. package/.framework/src/components/ui/table.tsx +114 -0
  180. package/.framework/src/components/ui/tabs.tsx +90 -0
  181. package/.framework/src/components/ui/textarea.tsx +18 -0
  182. package/.framework/src/components/ui/toggle-group.tsx +89 -0
  183. package/.framework/src/components/ui/toggle.tsx +45 -0
  184. package/.framework/src/components/ui/tooltip.tsx +57 -0
  185. package/.framework/src/contexts/AppContext.tsx +133 -0
  186. package/.framework/src/contexts/AuthContext.tsx +371 -0
  187. package/.framework/src/hooks/use-mobile.ts +19 -0
  188. package/.framework/src/hooks/useApi.ts +526 -0
  189. package/.framework/src/hooks/useApps.ts +114 -0
  190. package/.framework/src/hooks/useEntityList.ts +190 -0
  191. package/.framework/src/hooks/useEntityRecord.ts +308 -0
  192. package/.framework/src/hooks/useForm.ts +307 -0
  193. package/.framework/src/hooks/useListSchema.ts +264 -0
  194. package/.framework/src/hooks/useSchemaRecord.ts +223 -0
  195. package/.framework/src/index.css +128 -0
  196. package/.framework/src/lib/api.ts +156 -0
  197. package/.framework/src/lib/supabase.ts +94 -0
  198. package/.framework/src/lib/utils.ts +317 -0
  199. package/.framework/src/main.tsx +27 -0
  200. package/.framework/src/pages/DashboardPage.tsx +181 -0
  201. package/.framework/src/pages/NotFoundPage.tsx +39 -0
  202. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +161 -0
  203. package/.framework/src/pages/admin/AIAgentsPage.tsx +318 -0
  204. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +199 -0
  205. package/.framework/src/pages/admin/APIKeysPage.tsx +303 -0
  206. package/.framework/src/pages/admin/AlertsConfigPage.tsx +523 -0
  207. package/.framework/src/pages/admin/AppDetailPage.tsx +493 -0
  208. package/.framework/src/pages/admin/AppsPage.tsx +355 -0
  209. package/.framework/src/pages/admin/DesignedPage.tsx +491 -0
  210. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +534 -0
  211. package/.framework/src/pages/admin/EmbeddingsPage.tsx +424 -0
  212. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +176 -0
  213. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +109 -0
  214. package/.framework/src/pages/admin/IntegratedDashboard.tsx +402 -0
  215. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +187 -0
  216. package/.framework/src/pages/admin/IntegrationsPage.tsx +301 -0
  217. package/.framework/src/pages/admin/LogsPage.tsx +283 -0
  218. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +85 -0
  219. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +470 -0
  220. package/.framework/src/pages/admin/PipelineDetailPage.tsx +183 -0
  221. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +279 -0
  222. package/.framework/src/pages/admin/PipelinesPage.tsx +390 -0
  223. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +299 -0
  224. package/.framework/src/pages/admin/PromptConfigsPage.tsx +292 -0
  225. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +434 -0
  226. package/.framework/src/pages/admin/RoleDetailPage.tsx +273 -0
  227. package/.framework/src/pages/admin/RolesPage.tsx +292 -0
  228. package/.framework/src/pages/admin/SelectTestPage.tsx +61 -0
  229. package/.framework/src/pages/admin/ShadcnTestPage.tsx +588 -0
  230. package/.framework/src/pages/admin/SimpleDashboard.tsx +387 -0
  231. package/.framework/src/pages/admin/TestRunDetailPage.tsx +172 -0
  232. package/.framework/src/pages/admin/TestingDashboard.tsx +257 -0
  233. package/.framework/src/pages/admin/TimerDetailPage.tsx +151 -0
  234. package/.framework/src/pages/admin/TimersPage.tsx +376 -0
  235. package/.framework/src/pages/admin/TriggerDetailPage.tsx +149 -0
  236. package/.framework/src/pages/admin/TriggersPage.tsx +381 -0
  237. package/.framework/src/pages/admin/TypeDetailPage.tsx +694 -0
  238. package/.framework/src/pages/admin/TypesPage.tsx +295 -0
  239. package/.framework/src/pages/auth/LoginPage.tsx +188 -0
  240. package/.framework/src/pages/auth/RegisterPage.tsx +163 -0
  241. package/.framework/src/pages/spine-framework/APIPage.tsx +17 -0
  242. package/.framework/src/pages/spine-framework/CLIPage.tsx +25 -0
  243. package/.framework/src/types/auth.ts +125 -0
  244. package/.framework/src/types/types.ts +407 -0
  245. package/STRUCTURE.md +150 -0
  246. package/config/components.json +25 -0
  247. package/config/deno.lock +108 -0
  248. package/config/package-lock.json +17183 -0
  249. package/config/postcss.config.cjs +10 -0
  250. package/config/tailwind.config.cjs +78 -0
  251. package/config/tsconfig.build.json +32 -0
  252. package/config/tsconfig.cli.json +18 -0
  253. package/config/tsconfig.json +41 -0
  254. package/config/tsconfig.node.json +17 -0
  255. package/config/tsconfig.node.tsbuildinfo +1 -0
  256. package/config/tsconfig.tsbuildinfo +1 -0
  257. package/config/typedoc.json +16 -0
  258. package/config/vite.config.d.ts +2 -0
  259. package/config/vite.config.ts +72 -0
  260. package/dist/cli/commands/agents.d.ts +39 -0
  261. package/dist/cli/commands/agents.d.ts.map +1 -0
  262. package/dist/cli/commands/auth.d.ts +36 -0
  263. package/dist/cli/commands/auth.d.ts.map +1 -0
  264. package/dist/cli/commands/create-app.d.ts +23 -0
  265. package/dist/cli/commands/create-app.d.ts.map +1 -0
  266. package/dist/cli/commands/dev.d.ts +39 -0
  267. package/dist/cli/commands/dev.d.ts.map +1 -0
  268. package/dist/cli/commands/doctor.d.ts +42 -0
  269. package/dist/cli/commands/doctor.d.ts.map +1 -0
  270. package/dist/cli/commands/generate.d.ts +36 -0
  271. package/dist/cli/commands/generate.d.ts.map +1 -0
  272. package/dist/cli/commands/init.d.ts +30 -0
  273. package/dist/cli/commands/init.d.ts.map +1 -0
  274. package/dist/cli/commands/install-app.d.ts +30 -0
  275. package/dist/cli/commands/install-app.d.ts.map +1 -0
  276. package/dist/cli/commands/items.d.ts +45 -0
  277. package/dist/cli/commands/items.d.ts.map +1 -0
  278. package/dist/cli/commands/migrations.d.ts +41 -0
  279. package/dist/cli/commands/migrations.d.ts.map +1 -0
  280. package/dist/cli/commands/pipelines.d.ts +40 -0
  281. package/dist/cli/commands/pipelines.d.ts.map +1 -0
  282. package/dist/cli/commands/status.d.ts +23 -0
  283. package/dist/cli/commands/status.d.ts.map +1 -0
  284. package/dist/cli/commands/system.d.ts +29 -0
  285. package/dist/cli/commands/system.d.ts.map +1 -0
  286. package/dist/cli/commands/test.d.ts +46 -0
  287. package/dist/cli/commands/test.d.ts.map +1 -0
  288. package/dist/cli/commands/uninstall-app.d.ts +23 -0
  289. package/dist/cli/commands/uninstall-app.d.ts.map +1 -0
  290. package/dist/cli/context.d.ts +88 -0
  291. package/dist/cli/context.d.ts.map +1 -0
  292. package/dist/cli/env-loader.d.ts +14 -0
  293. package/dist/cli/env-loader.d.ts.map +1 -0
  294. package/dist/cli/index.d.ts +41 -0
  295. package/dist/cli/index.d.ts.map +1 -0
  296. package/dist/functions/_shared/agent-runner.d.ts +156 -0
  297. package/dist/functions/_shared/agent-runner.d.ts.map +1 -0
  298. package/dist/functions/_shared/app-manifest.d.ts +68 -0
  299. package/dist/functions/_shared/app-manifest.d.ts.map +1 -0
  300. package/dist/functions/_shared/audit.d.ts +91 -0
  301. package/dist/functions/_shared/audit.d.ts.map +1 -0
  302. package/dist/functions/_shared/db.d.ts +125 -0
  303. package/dist/functions/_shared/db.d.ts.map +1 -0
  304. package/dist/functions/_shared/index.d.ts +298 -0
  305. package/dist/functions/_shared/index.d.ts.map +1 -0
  306. package/dist/functions/_shared/middleware.d.ts +315 -0
  307. package/dist/functions/_shared/middleware.d.ts.map +1 -0
  308. package/dist/functions/_shared/permissions.d.ts +626 -0
  309. package/dist/functions/_shared/permissions.d.ts.map +1 -0
  310. package/dist/functions/_shared/pipeline-runner.d.ts +124 -0
  311. package/dist/functions/_shared/pipeline-runner.d.ts.map +1 -0
  312. package/dist/functions/_shared/principal.d.ts +284 -0
  313. package/dist/functions/_shared/principal.d.ts.map +1 -0
  314. package/dist/functions/_shared/schema-utils.d.ts +181 -0
  315. package/dist/functions/_shared/schema-utils.d.ts.map +1 -0
  316. package/dist/functions/_shared/testing.d.ts +172 -0
  317. package/dist/functions/_shared/testing.d.ts.map +1 -0
  318. package/dist/functions/_shared/trigger-engine.d.ts +140 -0
  319. package/dist/functions/_shared/trigger-engine.d.ts.map +1 -0
  320. package/dist/functions/_shared/webhook-registration.d.ts +81 -0
  321. package/dist/functions/_shared/webhook-registration.d.ts.map +1 -0
  322. package/dist/functions/_shared/webhook-registry.d.ts +57 -0
  323. package/dist/functions/_shared/webhook-registry.d.ts.map +1 -0
  324. package/dist/functions/account-nodes.d.ts +48 -0
  325. package/dist/functions/account-nodes.d.ts.map +1 -0
  326. package/dist/functions/admin-data.d.ts +178 -0
  327. package/dist/functions/admin-data.d.ts.map +1 -0
  328. package/dist/functions/ai-agents.d.ts +125 -0
  329. package/dist/functions/ai-agents.d.ts.map +1 -0
  330. package/dist/functions/api-keys.d.ts +140 -0
  331. package/dist/functions/api-keys.d.ts.map +1 -0
  332. package/dist/functions/apps.d.ts +163 -0
  333. package/dist/functions/apps.d.ts.map +1 -0
  334. package/dist/functions/auth.d.ts +74 -0
  335. package/dist/functions/auth.d.ts.map +1 -0
  336. package/dist/functions/debug-auth.d.ts +33 -0
  337. package/dist/functions/debug-auth.d.ts.map +1 -0
  338. package/dist/functions/embeddings.d.ts +205 -0
  339. package/dist/functions/embeddings.d.ts.map +1 -0
  340. package/dist/functions/integration-routes.d.ts +45 -0
  341. package/dist/functions/integration-routes.d.ts.map +1 -0
  342. package/dist/functions/integrations.d.ts +124 -0
  343. package/dist/functions/integrations.d.ts.map +1 -0
  344. package/dist/functions/item-progress.d.ts +41 -0
  345. package/dist/functions/item-progress.d.ts.map +1 -0
  346. package/dist/functions/logs.d.ts +162 -0
  347. package/dist/functions/logs.d.ts.map +1 -0
  348. package/dist/functions/observability.d.ts +123 -0
  349. package/dist/functions/observability.d.ts.map +1 -0
  350. package/dist/functions/pipeline-executions.d.ts +190 -0
  351. package/dist/functions/pipeline-executions.d.ts.map +1 -0
  352. package/dist/functions/pipelines.d.ts +171 -0
  353. package/dist/functions/pipelines.d.ts.map +1 -0
  354. package/dist/functions/prompt-configs.d.ts +125 -0
  355. package/dist/functions/prompt-configs.d.ts.map +1 -0
  356. package/dist/functions/roles.d.ts +118 -0
  357. package/dist/functions/roles.d.ts.map +1 -0
  358. package/dist/functions/system-cron.d.ts +65 -0
  359. package/dist/functions/system-cron.d.ts.map +1 -0
  360. package/dist/functions/system.d.ts +29 -0
  361. package/dist/functions/system.d.ts.map +1 -0
  362. package/dist/functions/tests.d.ts +28 -0
  363. package/dist/functions/tests.d.ts.map +1 -0
  364. package/dist/functions/timers.d.ts +139 -0
  365. package/dist/functions/timers.d.ts.map +1 -0
  366. package/dist/functions/triggers.d.ts +203 -0
  367. package/dist/functions/triggers.d.ts.map +1 -0
  368. package/dist/functions/types.d.ts +151 -0
  369. package/dist/functions/types.d.ts.map +1 -0
  370. package/dist/src/types/types.d.ts +364 -0
  371. package/dist/src/types/types.d.ts.map +1 -0
  372. package/package.json +192 -0
  373. package/scripts/app-install-cli.ts +286 -0
  374. package/scripts/assemble-frontend.sh +79 -0
  375. package/scripts/assemble-functions.sh +62 -0
  376. package/scripts/assemble.sh +35 -0
  377. package/scripts/boundary-check.sh +106 -0
  378. package/scripts/build-manifest.sh +80 -0
  379. package/scripts/check-core-integrity.sh +82 -0
  380. package/scripts/ingest-chunks.cjs +202 -0
  381. package/scripts/kb-chunk-parser.cjs +312 -0
  382. package/scripts/kb-chunk-parser.ts +330 -0
  383. package/scripts/load-test-app-install.ts +484 -0
  384. package/scripts/netlify-dev-wrapper.sh +22 -0
  385. package/scripts/verify-integrity.sh +69 -0
@@ -0,0 +1,484 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ /**
4
+ * Load Testing for App Installation System
5
+ * Tests performance with large installations and concurrent operations
6
+ */
7
+
8
+ import { readFileSync, existsSync } from 'fs'
9
+ import { resolve, dirname } from 'path'
10
+ import { program } from 'commander'
11
+ import yaml from 'js-yaml'
12
+ import { performance } from 'perf_hooks'
13
+
14
+ // Fix __dirname for ES modules
15
+ import { fileURLToPath } from 'url'
16
+ const __filename = fileURLToPath(import.meta.url)
17
+ const __dirname = dirname(__filename)
18
+
19
+ interface LoadTestConfig {
20
+ concurrentInstalls: number
21
+ totalApps: number
22
+ appComplexity: 'simple' | 'medium' | 'complex'
23
+ testDuration: number // seconds
24
+ reportInterval: number // seconds
25
+ }
26
+
27
+ interface TestResult {
28
+ appId: string
29
+ startTime: number
30
+ endTime: number
31
+ duration: number
32
+ success: boolean
33
+ error?: string
34
+ steps: {
35
+ validation: number
36
+ packInstallation: number
37
+ appCreation: number
38
+ migrations: number
39
+ verification: number
40
+ }
41
+ }
42
+
43
+ interface LoadTestReport {
44
+ config: LoadTestConfig
45
+ results: TestResult[]
46
+ summary: {
47
+ totalTests: number
48
+ successfulTests: number
49
+ failedTests: number
50
+ averageDuration: number
51
+ minDuration: number
52
+ maxDuration: number
53
+ throughput: number // tests per second
54
+ errors: Array<{ error: string; count: number }>
55
+ }
56
+ performance: {
57
+ validation: { avg: number; min: number; max: number }
58
+ packInstallation: { avg: number; min: number; max: number }
59
+ appCreation: { avg: number; min: number; max: number }
60
+ migrations: { avg: number; min: number; max: number }
61
+ verification: { avg: number; min: number; max: number }
62
+ }
63
+ }
64
+
65
+ class LoadTestRunner {
66
+ private config: LoadTestConfig
67
+ private results: TestResult[] = []
68
+ private running = false
69
+ private startTime = 0
70
+
71
+ constructor(config: LoadTestConfig) {
72
+ this.config = config
73
+ }
74
+
75
+ /**
76
+ * Generate test app installation YAML
77
+ */
78
+ private generateTestApp(index: number): string {
79
+ const complexity = this.config.appComplexity
80
+ const baseApp = {
81
+ app: {
82
+ name: `Load Test App ${index}`,
83
+ slug: `load-test-app-${index}`,
84
+ version: "1.0.0",
85
+ external_app_id: `load-test-${index}`,
86
+ description: `Load testing app ${index}`,
87
+ author: "Load Test Runner"
88
+ },
89
+ installation: {
90
+ pack_installation: {
91
+ account_id: "${TARGET_ACCOUNT_ID}",
92
+ external_app_id: `load-test-${index}`,
93
+ external_app_version: "1.0.0",
94
+ install_mode: "full",
95
+ manifest_version: 1
96
+ },
97
+ app_creation: [
98
+ {
99
+ slug: `load-test-app-${index}`,
100
+ name: `Load Test App ${index}`,
101
+ installed_pack_id: "${PACK_INSTALLATION_ID}",
102
+ min_role: "member",
103
+ nav_items: [
104
+ {
105
+ key: "dashboard",
106
+ to: `/load-test-${index}`,
107
+ label: "Dashboard",
108
+ icon: "layout-dashboard",
109
+ min_role: "member"
110
+ }
111
+ ]
112
+ }
113
+ ],
114
+ migrations: [],
115
+ verification: [
116
+ { check: "app_definition_exists", slug: `load-test-app-${index}` }
117
+ ]
118
+ }
119
+ }
120
+
121
+ // Add complexity-based migrations
122
+ if (complexity === 'medium') {
123
+ baseApp.installation.migrations = [
124
+ {
125
+ file: `migrations/001_app_${index}_setup.sql`,
126
+ description: `Create app ${index} item types and views`,
127
+ rollback_file: `migrations/rollback_001_app_${index}_setup.sql`
128
+ },
129
+ {
130
+ file: `migrations/002_app_${index}_data.sql`,
131
+ description: `Seed app ${index} categories and templates`,
132
+ dependencies: [`001_app_${index}_setup`]
133
+ }
134
+ ]
135
+ baseApp.installation.verification.push(
136
+ { check: "item_type_exists", slug: `app_${index}_item` },
137
+ { check: "view_exists", slug: `app_${index}_dashboard` }
138
+ )
139
+ } else if (complexity === 'complex') {
140
+ baseApp.installation.migrations = [
141
+ {
142
+ file: `migrations/001_app_${index}_setup.sql`,
143
+ description: `Create app ${index} item types and views`,
144
+ rollback_file: `migrations/rollback_001_app_${index}_setup.sql`
145
+ },
146
+ {
147
+ file: `migrations/002_app_${index}_tables.sql`,
148
+ description: `Create app ${index} custom tables`,
149
+ dependencies: [`001_app_${index}_setup`]
150
+ },
151
+ {
152
+ file: `migrations/003_app_${index}_data.sql`,
153
+ description: `Seed app ${index} categories and templates`,
154
+ dependencies: [`001_app_${index}_setup`, `002_app_${index}_tables`]
155
+ },
156
+ {
157
+ file: `migrations/004_app_${index}_automations.sql`,
158
+ description: `Create app ${index} automation rules`,
159
+ dependencies: [`002_app_${index}_tables`, `003_app_${index}_data`]
160
+ }
161
+ ]
162
+ baseApp.installation.verification.push(
163
+ { check: "item_type_exists", slug: `app_${index}_item` },
164
+ { check: "view_exists", slug: `app_${index}_dashboard` },
165
+ { check: "view_exists", slug: `app_${index}_list` },
166
+ { check: "integration_exists", integration_id: `app_${index}_integration` }
167
+ )
168
+ baseApp.installation.app_creation[0].nav_items.push(
169
+ { key: "list", to: `/load-test-${index}/list`, label: "List", icon: "list", min_role: "member" },
170
+ { key: "settings", to: `/load-test-${index}/settings`, label: "Settings", icon: "settings", min_role: "admin" }
171
+ )
172
+ }
173
+
174
+ return yaml.dump(baseApp)
175
+ }
176
+
177
+ /**
178
+ * Simulate app installation steps
179
+ */
180
+ private async simulateInstallation(appIndex: number): Promise<TestResult> {
181
+ const result: TestResult = {
182
+ appId: `load-test-app-${appIndex}`,
183
+ startTime: performance.now(),
184
+ endTime: 0,
185
+ duration: 0,
186
+ success: false,
187
+ steps: {
188
+ validation: 0,
189
+ packInstallation: 0,
190
+ appCreation: 0,
191
+ migrations: 0,
192
+ verification: 0
193
+ }
194
+ }
195
+
196
+ try {
197
+ // Generate test app YAML
198
+ const appYaml = this.generateTestApp(appIndex)
199
+
200
+ // Step 1: Validation (simulate schema validation)
201
+ const validationStart = performance.now()
202
+ await this.simulateValidation(appYaml)
203
+ result.steps.validation = performance.now() - validationStart
204
+
205
+ // Step 2: Pack Installation
206
+ const packStart = performance.now()
207
+ await this.simulatePackInstallation(result.appId)
208
+ result.steps.packInstallation = performance.now() - packStart
209
+
210
+ // Step 3: App Creation
211
+ const appStart = performance.now()
212
+ await this.simulateAppCreation(result.appId)
213
+ result.steps.appCreation = performance.now() - appStart
214
+
215
+ // Step 4: Migrations
216
+ const migrationsStart = performance.now()
217
+ const migrationCount = this.config.appComplexity === 'simple' ? 0 :
218
+ this.config.appComplexity === 'medium' ? 2 : 4
219
+ await this.simulateMigrations(result.appId, migrationCount)
220
+ result.steps.migrations = performance.now() - migrationsStart
221
+
222
+ // Step 5: Verification
223
+ const verificationStart = performance.now()
224
+ const verificationCount = this.config.appComplexity === 'simple' ? 1 :
225
+ this.config.appComplexity === 'medium' ? 3 : 5
226
+ await this.simulateVerification(result.appId, verificationCount)
227
+ result.steps.verification = performance.now() - verificationStart
228
+
229
+ result.success = true
230
+ } catch (error) {
231
+ result.error = error instanceof Error ? error.message : String(error)
232
+ }
233
+
234
+ result.endTime = performance.now()
235
+ result.duration = result.endTime - result.startTime
236
+
237
+ return result
238
+ }
239
+
240
+ /**
241
+ * Simulate validation step
242
+ */
243
+ private async simulateValidation(appYaml: string): Promise<void> {
244
+ // Simulate YAML parsing and schema validation
245
+ const complexity = this.config.appComplexity
246
+ const delay = complexity === 'simple' ? 10 : complexity === 'medium' ? 25 : 50
247
+
248
+ await this.sleep(delay)
249
+
250
+ // Parse YAML to simulate actual validation work
251
+ yaml.load(appYaml)
252
+ }
253
+
254
+ /**
255
+ * Simulate pack installation
256
+ */
257
+ private async simulatePackInstallation(appId: string): Promise<void> {
258
+ // Simulate database insert for installed_packs
259
+ const complexity = this.config.appComplexity
260
+ const delay = complexity === 'simple' ? 20 : complexity === 'medium' ? 40 : 80
261
+
262
+ await this.sleep(delay)
263
+ }
264
+
265
+ /**
266
+ * Simulate app creation
267
+ */
268
+ private async simulateAppCreation(appId: string): Promise<void> {
269
+ // Simulate app_definitions creation
270
+ const complexity = this.config.appComplexity
271
+ const delay = complexity === 'simple' ? 15 : complexity === 'medium' ? 30 : 60
272
+
273
+ await this.sleep(delay)
274
+ }
275
+
276
+ /**
277
+ * Simulate migrations
278
+ */
279
+ private async simulateMigrations(appId: string, count: number): Promise<void> {
280
+ // Simulate running SQL migrations
281
+ for (let i = 0; i < count; i++) {
282
+ const delay = this.config.appComplexity === 'simple' ? 10 :
283
+ this.config.appComplexity === 'medium' ? 25 : 50
284
+ await this.sleep(delay)
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Simulate verification steps
290
+ */
291
+ private async simulateVerification(appId: string, count: number): Promise<void> {
292
+ // Simulate verification checks
293
+ for (let i = 0; i < count; i++) {
294
+ await this.sleep(5)
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Sleep helper
300
+ */
301
+ private sleep(ms: number): Promise<void> {
302
+ return new Promise(resolve => setTimeout(resolve, ms))
303
+ }
304
+
305
+ /**
306
+ * Run concurrent load test
307
+ */
308
+ async runLoadTest(): Promise<LoadTestReport> {
309
+ console.log(`🚀 Starting load test...`)
310
+ console.log(`Configuration:`, this.config)
311
+
312
+ this.running = true
313
+ this.startTime = performance.now()
314
+ this.results = []
315
+
316
+ const concurrentBatches = Math.ceil(this.config.totalApps / this.config.concurrentInstalls)
317
+
318
+ for (let batch = 0; batch < concurrentBatches; batch++) {
319
+ const startIndex = batch * this.config.concurrentInstalls
320
+ const endIndex = Math.min(startIndex + this.config.concurrentInstalls, this.config.totalApps)
321
+ const batchSize = endIndex - startIndex
322
+
323
+ console.log(`📦 Running batch ${batch + 1}/${concurrentBatches} (${batchSize} apps)`)
324
+
325
+ // Run installations concurrently
326
+ const batchPromises = []
327
+ for (let i = startIndex; i < endIndex; i++) {
328
+ batchPromises.push(this.simulateInstallation(i))
329
+ }
330
+
331
+ const batchResults = await Promise.all(batchPromises)
332
+ this.results.push(...batchResults)
333
+
334
+ // Report progress
335
+ const completed = this.results.length
336
+ const successRate = (this.results.filter(r => r.success).length / this.results.length * 100).toFixed(1)
337
+ console.log(`✅ Completed ${completed}/${this.config.totalApps} apps (${successRate}% success rate)`)
338
+
339
+ // Check if we should stop due to time limit
340
+ const elapsed = (performance.now() - this.startTime) / 1000
341
+ if (elapsed >= this.config.testDuration) {
342
+ console.log(`⏰ Time limit reached, stopping test`)
343
+ break
344
+ }
345
+ }
346
+
347
+ this.running = false
348
+ return this.generateReport()
349
+ }
350
+
351
+ /**
352
+ * Generate comprehensive report
353
+ */
354
+ private generateReport(): LoadTestReport {
355
+ const successfulTests = this.results.filter(r => r.success)
356
+ const failedTests = this.results.filter(r => !r.success)
357
+
358
+ const durations = successfulTests.map(r => r.duration)
359
+ const avgDuration = durations.length > 0 ? durations.reduce((a, b) => a + b, 0) / durations.length : 0
360
+ const minDuration = durations.length > 0 ? Math.min(...durations) : 0
361
+ const maxDuration = durations.length > 0 ? Math.max(...durations) : 0
362
+
363
+ const totalElapsed = (performance.now() - this.startTime) / 1000
364
+ const throughput = this.results.length / totalElapsed
365
+
366
+ // Error aggregation
367
+ const errorMap = new Map<string, number>()
368
+ for (const test of failedTests) {
369
+ const error = test.error || 'Unknown error'
370
+ errorMap.set(error, (errorMap.get(error) || 0) + 1)
371
+ }
372
+
373
+ const errors = Array.from(errorMap.entries()).map(([error, count]) => ({ error, count }))
374
+
375
+ // Step performance analysis
376
+ const stepPerformance = {
377
+ validation: this.calculateStepPerformance('validation'),
378
+ packInstallation: this.calculateStepPerformance('packInstallation'),
379
+ appCreation: this.calculateStepPerformance('appCreation'),
380
+ migrations: this.calculateStepPerformance('migrations'),
381
+ verification: this.calculateStepPerformance('verification')
382
+ }
383
+
384
+ return {
385
+ config: this.config,
386
+ results: this.results,
387
+ summary: {
388
+ totalTests: this.results.length,
389
+ successfulTests: successfulTests.length,
390
+ failedTests: failedTests.length,
391
+ averageDuration: avgDuration,
392
+ minDuration,
393
+ maxDuration,
394
+ throughput,
395
+ errors
396
+ },
397
+ performance: stepPerformance
398
+ }
399
+ }
400
+
401
+ /**
402
+ * Calculate performance metrics for a specific step
403
+ */
404
+ private calculateStepPerformance(step: keyof TestResult['steps']) {
405
+ const values = this.results.filter(r => r.success).map(r => r.steps[step])
406
+ return {
407
+ avg: values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : 0,
408
+ min: values.length > 0 ? Math.min(...values) : 0,
409
+ max: values.length > 0 ? Math.max(...values) : 0
410
+ }
411
+ }
412
+ }
413
+
414
+ /**
415
+ * Pretty print report
416
+ */
417
+ function printReport(report: LoadTestReport): void {
418
+ console.log('\n' + '='.repeat(80))
419
+ console.log('📊 LOAD TEST REPORT')
420
+ console.log('='.repeat(80))
421
+
422
+ console.log('\n🔧 Configuration:')
423
+ console.log(` Concurrent Installs: ${report.config.concurrentInstalls}`)
424
+ console.log(` Total Apps: ${report.config.totalApps}`)
425
+ console.log(` App Complexity: ${report.config.appComplexity}`)
426
+ console.log(` Test Duration: ${report.config.testDuration}s`)
427
+
428
+ console.log('\n📈 Summary:')
429
+ console.log(` Total Tests: ${report.summary.totalTests}`)
430
+ console.log(` Successful: ${report.summary.successfulTests} (${(report.summary.successfulTests / report.summary.totalTests * 100).toFixed(1)}%)`)
431
+ console.log(` Failed: ${report.summary.failedTests} (${(report.summary.failedTests / report.summary.totalTests * 100).toFixed(1)}%)`)
432
+ console.log(` Average Duration: ${report.summary.averageDuration.toFixed(2)}ms`)
433
+ console.log(` Min Duration: ${report.summary.minDuration.toFixed(2)}ms`)
434
+ console.log(` Max Duration: ${report.summary.maxDuration.toFixed(2)}ms`)
435
+ console.log(` Throughput: ${report.summary.throughput.toFixed(2)} tests/second`)
436
+
437
+ if (report.summary.errors.length > 0) {
438
+ console.log('\n❌ Errors:')
439
+ report.summary.errors.forEach(({ error, count }) => {
440
+ console.log(` ${error}: ${count}`)
441
+ })
442
+ }
443
+
444
+ console.log('\n⚡ Step Performance:')
445
+ Object.entries(report.performance).forEach(([step, perf]) => {
446
+ console.log(` ${step}:`)
447
+ console.log(` Avg: ${perf.avg.toFixed(2)}ms`)
448
+ console.log(` Min: ${perf.min.toFixed(2)}ms`)
449
+ console.log(` Max: ${perf.max.toFixed(2)}ms`)
450
+ })
451
+
452
+ console.log('\n' + '='.repeat(80))
453
+ }
454
+
455
+ // CLI setup
456
+ program
457
+ .name('load-test-app-install')
458
+ .description('Load testing for Spine app installation system')
459
+ .version('1.0.0')
460
+ .option('-c, --concurrent <number>', 'Number of concurrent installations', '10')
461
+ .option('-t, --total <number>', 'Total number of apps to install', '100')
462
+ .option('-x, --complexity <type>', 'App complexity (simple, medium, complex)', 'medium')
463
+ .option('-d, --duration <seconds>', 'Maximum test duration in seconds', '300')
464
+ .option('-r, --report-interval <seconds>', 'Progress report interval', '10')
465
+ .action(async (options) => {
466
+ const config: LoadTestConfig = {
467
+ concurrentInstalls: parseInt(options.concurrent),
468
+ totalApps: parseInt(options.total),
469
+ appComplexity: options.complexity as 'simple' | 'medium' | 'complex',
470
+ testDuration: parseInt(options.duration),
471
+ reportInterval: parseInt(options.reportInterval)
472
+ }
473
+
474
+ const runner = new LoadTestRunner(config)
475
+ const report = await runner.runLoadTest()
476
+ printReport(report)
477
+
478
+ // Exit with error code if there were failures
479
+ if (report.summary.failedTests > 0) {
480
+ process.exit(1)
481
+ }
482
+ })
483
+
484
+ program.parse()
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Netlify Dev Wrapper - Start dev server for Spine.
4
+ #
5
+ # Purpose: Execute Vite directly to avoid npx/npm indirection issues under Netlify CLI.
6
+ # - Called by: netlify dev (via netlify.toml [dev].command)
7
+ # - .framework/ is the working core directory
8
+ #
9
+ # Integration: Part of the development workflow, bridges Netlify CLI and Vite.
10
+ #
11
+ # Dependencies: vite, netlify CLI
12
+
13
+ set -euo pipefail
14
+
15
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
16
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
17
+
18
+ echo "Starting Netlify dev for Spine..."
19
+
20
+ # Start Vite dev server directly (.assembled/src is now the root)
21
+ echo " Starting Vite on port 3001..."
22
+ exec "$PROJECT_ROOT/node_modules/.bin/vite" --config "$PROJECT_ROOT/config/vite.config.ts"
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Core Integrity Verifier - Verify core files against the build manifest.
4
+ # SPINE_INTEGRITY=warn → log warnings (default, dev-friendly)
5
+ # SPINE_INTEGRITY=enforce → fail build on mismatch
6
+
7
+ set -euo pipefail
8
+
9
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
10
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
11
+ MANIFEST_FILE="$PROJECT_ROOT/.spine-manifest.json"
12
+
13
+ INTEGRITY_MODE="${SPINE_INTEGRITY:-warn}"
14
+
15
+ if [ ! -f "$MANIFEST_FILE" ]; then
16
+ echo "⚠️ No manifest found at $MANIFEST_FILE — run build-manifest.sh first"
17
+ if [ "$INTEGRITY_MODE" = "enforce" ]; then exit 1; fi
18
+ exit 0
19
+ fi
20
+
21
+ echo "🔒 Verifying core integrity (mode: $INTEGRITY_MODE)"
22
+
23
+ MISMATCHES=0
24
+ MISSING=0
25
+
26
+ # Parse each file:hash pair from manifest
27
+ while IFS=: read -r file_path expected_hash; do
28
+ # Strip quotes and whitespace
29
+ file_path=$(echo "$file_path" | tr -d '"' | xargs)
30
+ expected_hash=$(echo "$expected_hash" | tr -d '"' | xargs)
31
+
32
+ FULL_PATH="$PROJECT_ROOT/$file_path"
33
+
34
+ if [ ! -f "$FULL_PATH" ]; then
35
+ echo " ✗ MISSING: $file_path"
36
+ MISSING=$((MISSING + 1))
37
+ continue
38
+ fi
39
+
40
+ ACTUAL_HASH=$(shasum -a 256 "$FULL_PATH" | cut -d' ' -f1)
41
+
42
+ if [ "$ACTUAL_HASH" != "$expected_hash" ]; then
43
+ echo " ✗ MODIFIED: $file_path"
44
+ MISMATCHES=$((MISMATCHES + 1))
45
+ fi
46
+ done < <(cat "$MANIFEST_FILE" | python3 -c "
47
+ import json, sys
48
+ data = json.load(sys.stdin)
49
+ for k, v in data.get('hashes', {}).items():
50
+ print(f'{k}:{v}')
51
+ " 2>/dev/null || echo "")
52
+
53
+ TOTAL=$((MISMATCHES + MISSING))
54
+
55
+ if [ "$TOTAL" -eq 0 ]; then
56
+ echo "✅ All core files match manifest"
57
+ exit 0
58
+ fi
59
+
60
+ echo ""
61
+ echo "⚠️ $MISMATCHES modified, $MISSING missing ($TOTAL total issues)"
62
+
63
+ if [ "$INTEGRITY_MODE" = "enforce" ]; then
64
+ echo "❌ Build failed: core integrity check failed (SPINE_INTEGRITY=enforce)"
65
+ exit 1
66
+ else
67
+ echo "⚠️ Continuing with warnings (SPINE_INTEGRITY=warn)"
68
+ exit 0
69
+ fi