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,141 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * @module cli/commands/migrations
4
+ * @audience installer
5
+ * @layer cli
6
+ * @stability stable
7
+ *
8
+ * `spine migrations` command group. Read-only inspection of the migration
9
+ * state. Does NOT apply or roll back migrations — use the Supabase CLI for
10
+ * that. These commands are intended for verifying the state of a deployed
11
+ * instance during setup or debugging.
12
+ *
13
+ * **Commands:**
14
+ * | Subcommand | Description |
15
+ * |-----------------------|-----------------------------------------------------|
16
+ * | `migrations list` | Show all applied migrations from `schema_migrations`|
17
+ * | `migrations status` | Diff local `.sql` files against applied migrations |
18
+ *
19
+ * **Authorization:** Uses `adminDb` (service-role) with an explicit
20
+ * `.schema('public')` override to reach `schema_migrations`. Requires
21
+ * `SUPABASE_SERVICE_ROLE_KEY` with public schema access.
22
+ *
23
+ * **Usage:**
24
+ * ```bash
25
+ * spine migrations list
26
+ * spine migrations status
27
+ * spine migrations status --json
28
+ * ```
29
+ *
30
+ * @seeAlso v2-core/migrations/ (local .sql migration files)
31
+ * @seeAlso cli/context.ts (buildCliContext)
32
+ */
33
+
34
+ import type { Command } from 'commander'
35
+ import { readdirSync, existsSync } from 'fs'
36
+ import { resolve, dirname } from 'path'
37
+ import { fileURLToPath } from 'url'
38
+ import { buildCliContext, printResult, handleError } from '../context.ts'
39
+ import { adminDb } from '../../functions/_shared/index.ts'
40
+
41
+ const __filename = fileURLToPath(import.meta.url)
42
+ const __dirname = dirname(__filename)
43
+
44
+ /**
45
+ * Registers the `migrations` subcommand group on the root Commander program.
46
+ *
47
+ * @param program - The root `spine` Commander instance
48
+ * @sideEffects Adds `migrations list` and `migrations status` subcommands to `program`
49
+ * @calledBy cli/index.ts
50
+ */
51
+ export function registerMigrationCommands(program: Command) {
52
+ const migrations = program
53
+ .command('migrations')
54
+ .description('Database migration inspection')
55
+
56
+ migrations
57
+ .command('list')
58
+ .description('List applied migrations from supabase schema_migrations')
59
+ .option('--json', 'Output as JSON')
60
+ .action(async (opts) => {
61
+ try {
62
+ await buildCliContext()
63
+
64
+ const { data, error } = await adminDb
65
+ .schema('supabase_migrations' as any)
66
+ .from('schema_migrations' as any)
67
+ .select('version, name, executed_at')
68
+ .order('version', { ascending: true })
69
+
70
+ if (error) {
71
+ throw new Error(
72
+ `Could not query migrations: ${error.message}\n` +
73
+ 'Ensure SUPABASE_SERVICE_ROLE_KEY has access to the public schema.'
74
+ )
75
+ }
76
+
77
+ printResult(data || [], { json: opts.json })
78
+ } catch (err: any) {
79
+ handleError(err)
80
+ }
81
+ })
82
+
83
+ migrations
84
+ .command('status')
85
+ .description('Compare local migration files against applied migrations')
86
+ .option('--json', 'Output as JSON')
87
+ .action(async (opts) => {
88
+ try {
89
+ await buildCliContext()
90
+
91
+ const migrationsDir = resolve(__dirname, '../../migrations')
92
+
93
+ if (!existsSync(migrationsDir)) {
94
+ throw new Error(`Migrations directory not found: ${migrationsDir}`)
95
+ }
96
+
97
+ const localFiles = readdirSync(migrationsDir)
98
+ .filter((f: string) => f.endsWith('.sql'))
99
+ .sort()
100
+
101
+ const { data: applied, error } = await adminDb
102
+ .schema('supabase_migrations' as any)
103
+ .from('schema_migrations' as any)
104
+ .select('version')
105
+
106
+ if (error) {
107
+ throw new Error(`Could not query migrations: ${error.message}`)
108
+ }
109
+
110
+ const appliedVersions = new Set(
111
+ (applied || []).map((r: any) => r.version)
112
+ )
113
+
114
+ const status = localFiles.map((file: string) => {
115
+ const version = file.replace('.sql', '')
116
+ const isApplied = appliedVersions.has(version)
117
+ return {
118
+ file,
119
+ version,
120
+ status: isApplied ? 'applied' : 'pending'
121
+ }
122
+ })
123
+
124
+ if (opts.json) {
125
+ console.log(JSON.stringify(status, null, 2))
126
+ } else {
127
+ console.log('\nMigration Status')
128
+ console.log('─'.repeat(60))
129
+ for (const m of status as Array<{file: string; status: string}>) {
130
+ const icon = m.status === 'applied' ? '✓' : '○'
131
+ console.log(` ${icon} ${m.file.padEnd(40)} ${m.status}`)
132
+ }
133
+ const pending = status.filter(m => m.status === 'pending').length
134
+ console.log(`\n ${status.length - pending} applied, ${pending} pending`)
135
+ console.log()
136
+ }
137
+ } catch (err: any) {
138
+ handleError(err)
139
+ }
140
+ })
141
+ }
@@ -0,0 +1,166 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * @module cli/commands/pipelines
4
+ * @audience installer
5
+ * @layer cli
6
+ * @stability stable
7
+ *
8
+ * `spine pipelines` command group. Lists, inspects, and triggers pipeline
9
+ * execution directly from the terminal or an agentic IDE. `pipelines run`
10
+ * calls `runPipeline` — the same function used by API handlers and timers —
11
+ * so CLI executions are fully recorded in `pipeline_executions`.
12
+ *
13
+ * **Commands:**
14
+ * | Subcommand | Description |
15
+ * |---------------------------------------|------------------------------------------|
16
+ * | `pipelines list [--account] [--all]` | List active (or all) pipelines |
17
+ * | `pipelines get <id>` | Show pipeline details |
18
+ * | `pipelines run <id> [--data <json>]` | Execute a pipeline and show stage output |
19
+ * | `pipelines executions <id>` | List recent executions for a pipeline |
20
+ *
21
+ * **Usage:**
22
+ * ```bash
23
+ * spine pipelines list --account <id>
24
+ * spine pipelines run <uuid> --data '{"key":"value"}' --json
25
+ * spine pipelines executions <uuid> --limit 20
26
+ * ```
27
+ *
28
+ * @seeAlso cli/context.ts (buildCliContext)
29
+ * @seeAlso functions/_shared/pipeline-runner.ts (runPipeline)
30
+ * @seeAlso functions/pipeline-executions.ts (API query endpoint)
31
+ */
32
+
33
+ import type { Command } from 'commander'
34
+ import { buildCliContext, printResult, handleError } from '../context.ts'
35
+ import { runPipeline, adminDb } from '../../functions/_shared/index.ts'
36
+
37
+ /**
38
+ * Registers the `pipelines` subcommand group on the root Commander program.
39
+ *
40
+ * @param program - The root `spine` Commander instance
41
+ * @sideEffects Adds `pipelines list/get/run/executions` subcommands to `program`
42
+ * @calledBy cli/index.ts
43
+ */
44
+ export function registerPipelineCommands(program: Command) {
45
+ const pipelines = program
46
+ .command('pipelines')
47
+ .description('Pipeline management and execution')
48
+
49
+ pipelines
50
+ .command('list')
51
+ .description('List all active pipelines')
52
+ .option('--account <id>', 'Filter by account ID')
53
+ .option('--json', 'Output as JSON')
54
+ .option('--all', 'Include inactive pipelines')
55
+ .action(async (opts) => {
56
+ try {
57
+ const ctx = await buildCliContext({ account: opts.account })
58
+
59
+ let query = adminDb
60
+ .from('pipelines')
61
+ .select('id, name, description, is_active, created_at')
62
+ .order('name')
63
+
64
+ if (!opts.all) {
65
+ query = query.eq('is_active', true)
66
+ }
67
+
68
+ if (ctx.accountId) {
69
+ query = query.eq('account_id', ctx.accountId)
70
+ }
71
+
72
+ const { data, error } = await query
73
+
74
+ if (error) throw new Error(error.message)
75
+ printResult(data || [], { json: opts.json })
76
+ } catch (err: any) {
77
+ handleError(err)
78
+ }
79
+ })
80
+
81
+ pipelines
82
+ .command('get <id>')
83
+ .description('Show pipeline details')
84
+ .option('--json', 'Output as JSON')
85
+ .action(async (id, opts) => {
86
+ try {
87
+ await buildCliContext()
88
+
89
+ const { data, error } = await adminDb
90
+ .from('pipelines')
91
+ .select('*')
92
+ .eq('id', id)
93
+ .single()
94
+
95
+ if (error || !data) throw new Error(error?.message || `Pipeline not found: ${id}`)
96
+ printResult(data, { json: opts.json })
97
+ } catch (err: any) {
98
+ handleError(err)
99
+ }
100
+ })
101
+
102
+ pipelines
103
+ .command('run <id>')
104
+ .description('Execute a pipeline')
105
+ .option('--data <json>', 'Trigger data as JSON string', '{}')
106
+ .option('--account <id>', 'Account scope for the execution')
107
+ .option('--json', 'Output result as JSON')
108
+ .action(async (id, opts) => {
109
+ try {
110
+ const ctx = await buildCliContext({ account: opts.account })
111
+
112
+ let triggerData: any = {}
113
+ try {
114
+ triggerData = JSON.parse(opts.data)
115
+ } catch {
116
+ throw new Error(`--data must be valid JSON. Got: ${opts.data}`)
117
+ }
118
+
119
+ console.log(`Running pipeline ${id}...`)
120
+ const result = await runPipeline(id, triggerData, ctx)
121
+
122
+ if (opts.json) {
123
+ console.log(JSON.stringify(result, null, 2))
124
+ } else {
125
+ const icon = result.status === 'completed' ? '✓' : '✗'
126
+ console.log(`\n${icon} Pipeline ${result.status}`)
127
+ console.log(` Execution ID: ${result.executionId}`)
128
+ console.log(` Duration: ${result.durationMs}ms`)
129
+ console.log(` Stages: ${result.stages.length}`)
130
+ result.stages.forEach((s: any, i: number) => {
131
+ const stageIcon = s.status === 'success' ? '✓' : s.status === 'skipped' ? '○' : '✗'
132
+ console.log(` ${stageIcon} [${i}] ${s.stageType} (${s.durationMs}ms)${s.error ? ` — ${s.error}` : ''}`)
133
+ })
134
+ if (result.error) {
135
+ console.log(`\n Error: ${result.error}`)
136
+ }
137
+ console.log()
138
+ }
139
+ } catch (err: any) {
140
+ handleError(err)
141
+ }
142
+ })
143
+
144
+ pipelines
145
+ .command('executions <id>')
146
+ .description('List recent executions for a pipeline')
147
+ .option('--limit <n>', 'Number of executions to show', '10')
148
+ .option('--json', 'Output as JSON')
149
+ .action(async (id, opts) => {
150
+ try {
151
+ await buildCliContext()
152
+
153
+ const { data, error } = await adminDb
154
+ .from('pipeline_executions')
155
+ .select('id, status, started_at, completed_at, duration_ms, error_message')
156
+ .eq('pipeline_id', id)
157
+ .order('started_at', { ascending: false })
158
+ .limit(parseInt(opts.limit))
159
+
160
+ if (error) throw new Error(error.message)
161
+ printResult(data || [], { json: opts.json })
162
+ } catch (err: any) {
163
+ handleError(err)
164
+ }
165
+ })
166
+ }
@@ -0,0 +1,197 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * @module cli/commands/status
4
+ * @audience installer
5
+ * @layer cli
6
+ * @stability stable
7
+ *
8
+ * `spine-framework status` — Show the current state of the Spine installation.
9
+ *
10
+ * Displays:
11
+ * - Database connection status
12
+ * - Installed apps and their seed state
13
+ * - Migration history
14
+ * - Webhook handler registrations
15
+ *
16
+ * **Usage:**
17
+ * ```bash
18
+ * spine-framework status
19
+ * spine-framework status --json
20
+ * ```
21
+ */
22
+
23
+ import type { Command } from 'commander'
24
+ import { existsSync, readdirSync } from 'fs'
25
+ import { resolve, dirname } from 'path'
26
+ import { fileURLToPath } from 'url'
27
+ import { adminDb } from '../../functions/_shared/index.ts'
28
+ import { discoverManifests } from '../../functions/_shared/app-manifest.ts'
29
+
30
+ const __filename = fileURLToPath(import.meta.url)
31
+ const __dirname = dirname(__filename)
32
+ const PROJECT_ROOT = resolve(__dirname, '../../../')
33
+
34
+ interface StatusOptions {
35
+ json: boolean
36
+ }
37
+
38
+ interface StatusReport {
39
+ database: { connected: boolean; error?: string }
40
+ apps: Array<{ slug: string; name: string; hasManifest: boolean; hasSeed: boolean; installed: boolean }>
41
+ webhookHandlers: Array<{ name: string; functionName: string; isActive: boolean }>
42
+ typeCounts: { total: number; byApp: Record<string, number> }
43
+ }
44
+
45
+ async function gatherStatus(): Promise<StatusReport> {
46
+ const report: StatusReport = {
47
+ database: { connected: false },
48
+ apps: [],
49
+ webhookHandlers: [],
50
+ typeCounts: { total: 0, byApp: {} },
51
+ }
52
+
53
+ // 1. Database connection
54
+ try {
55
+ const { data, error } = await adminDb
56
+ .from('apps')
57
+ .select('slug')
58
+ .limit(1)
59
+
60
+ if (error) {
61
+ report.database = { connected: false, error: error.message }
62
+ } else {
63
+ report.database = { connected: true }
64
+ }
65
+ } catch (err: any) {
66
+ report.database = { connected: false, error: err.message }
67
+ return report
68
+ }
69
+
70
+ // 2. Apps — merge filesystem + database
71
+ const manifests = discoverManifests()
72
+ const { data: dbApps } = await adminDb
73
+ .from('apps')
74
+ .select('slug, name, is_active')
75
+ .eq('is_active', true)
76
+ .order('slug')
77
+
78
+ const { data: installations } = await adminDb
79
+ .from('app_installations')
80
+ .select('app_slug, is_enabled')
81
+
82
+ const installedSlugs = new Set(
83
+ (installations || []).filter(i => i.is_enabled).map(i => i.app_slug)
84
+ )
85
+
86
+ const allSlugs = new Set([
87
+ ...manifests.map(m => m.slug),
88
+ ...(dbApps || []).map(a => a.slug).filter(s => s !== 'spine-core'),
89
+ ])
90
+
91
+ for (const slug of allSlugs) {
92
+ const manifest = manifests.find(m => m.slug === slug)
93
+ const dbApp = dbApps?.find(a => a.slug === slug)
94
+ const seedDir = resolve(PROJECT_ROOT, `custom/apps/${slug}/seed`)
95
+
96
+ report.apps.push({
97
+ slug,
98
+ name: dbApp?.name || slug,
99
+ hasManifest: !!manifest,
100
+ hasSeed: existsSync(seedDir) && readdirSync(seedDir).some(f => f.endsWith('.json')),
101
+ installed: installedSlugs.has(slug),
102
+ })
103
+ }
104
+
105
+ // 3. Webhook handlers
106
+ const { data: handlers } = await adminDb
107
+ .from('webhook_handlers')
108
+ .select('name, function_name, is_active')
109
+ .order('name')
110
+
111
+ report.webhookHandlers = (handlers || []).map(h => ({
112
+ name: h.name,
113
+ functionName: h.function_name,
114
+ isActive: h.is_active,
115
+ }))
116
+
117
+ // 4. Type counts by app
118
+ const { data: types } = await adminDb
119
+ .from('types')
120
+ .select('slug, app_id, apps!inner(slug)')
121
+ .eq('is_active', true)
122
+
123
+ report.typeCounts.total = types?.length || 0
124
+ for (const t of types || []) {
125
+ const appSlug = (t as any).apps?.slug || 'unassigned'
126
+ report.typeCounts.byApp[appSlug] = (report.typeCounts.byApp[appSlug] || 0) + 1
127
+ }
128
+
129
+ return report
130
+ }
131
+
132
+ function printStatus(report: StatusReport): void {
133
+ console.log('\n🔍 Spine Framework Status\n')
134
+
135
+ // Database
136
+ if (report.database.connected) {
137
+ console.log(' 📡 Database: ✅ Connected')
138
+ } else {
139
+ console.log(` 📡 Database: ❌ ${report.database.error || 'Not connected'}`)
140
+ return
141
+ }
142
+
143
+ // Apps
144
+ console.log(`\n 📱 Apps (${report.apps.length}):`)
145
+ if (report.apps.length === 0) {
146
+ console.log(' (none)')
147
+ } else {
148
+ for (const app of report.apps) {
149
+ const status = [
150
+ app.hasManifest ? '📋 manifest' : '',
151
+ app.hasSeed ? '🌱 seed' : '',
152
+ app.installed ? '✅ installed' : '⬜ not installed',
153
+ ].filter(Boolean).join(' ')
154
+ console.log(` ${app.slug.padEnd(24)} ${status}`)
155
+ }
156
+ }
157
+
158
+ // Webhook handlers
159
+ console.log(`\n 🔗 Webhook Handlers (${report.webhookHandlers.length}):`)
160
+ if (report.webhookHandlers.length === 0) {
161
+ console.log(' (none)')
162
+ } else {
163
+ for (const h of report.webhookHandlers) {
164
+ const status = h.isActive ? '✅' : '❌'
165
+ console.log(` ${status} ${h.name.padEnd(24)} → ${h.functionName}`)
166
+ }
167
+ }
168
+
169
+ // Types
170
+ console.log(`\n 📊 Types (${report.typeCounts.total} total):`)
171
+ for (const [app, count] of Object.entries(report.typeCounts.byApp).sort()) {
172
+ console.log(` ${app.padEnd(24)} ${count} types`)
173
+ }
174
+
175
+ console.log('')
176
+ }
177
+
178
+ export function registerStatusCommands(program: Command) {
179
+ program
180
+ .command('status')
181
+ .description('Show the current state of the Spine installation')
182
+ .option('--json', 'Output as JSON', false)
183
+ .action(async (opts: StatusOptions) => {
184
+ try {
185
+ const report = await gatherStatus()
186
+ if (opts.json) {
187
+ console.log(JSON.stringify(report, null, 2))
188
+ } else {
189
+ printStatus(report)
190
+ }
191
+ } catch (err: any) {
192
+ console.error('Error:', err.message)
193
+ if (process.env.SPINE_CLI_DEBUG) console.error(err.stack)
194
+ process.exit(1)
195
+ }
196
+ })
197
+ }
@@ -0,0 +1,184 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * @module cli/commands/system
4
+ * @audience installer
5
+ * @layer cli
6
+ * @stability stable
7
+ *
8
+ * `spine system` command — CLI interface to system discovery endpoints.
9
+ * Queries the running Spine instance for manifest, health, and OpenAPI spec.
10
+ *
11
+ * **Commands:**
12
+ * | Subcommand | Description |
13
+ * |-------------------------|-------------------------------------------------------|
14
+ * | `system manifest` | Fetch and display system manifest |
15
+ * | `system health` | Fetch and display health check results |
16
+ * | `system openapi` | Fetch OpenAPI spec (outputs JSON) |
17
+ * | `system --json` | Output as JSON for all subcommands |
18
+ *
19
+ * **Usage:**
20
+ * ```bash
21
+ * spine system manifest
22
+ * spine system health --json
23
+ * spine system openapi > openapi.json
24
+ * ```
25
+ *
26
+ * @seeAlso functions/system.ts (HTTP endpoints this CLI consumes)
27
+ */
28
+
29
+ import type { Command } from 'commander'
30
+ import { buildCliContext, printResult, handleError } from '../context.ts'
31
+
32
+ // ─── API CLIENT ────────────────────────────────────────────────────────────
33
+
34
+ async function fetchSystemEndpoint(ctx: any, action: string): Promise<any> {
35
+ const supabaseUrl = process.env.SUPABASE_URL
36
+ if (!supabaseUrl) {
37
+ throw new Error('SUPABASE_URL not configured')
38
+ }
39
+
40
+ // Construct the Netlify function URL
41
+ // When running locally, this is http://localhost:8888/.netlify/functions/system
42
+ // We'll try localhost:8888 first, then fall back to production URL if configured
43
+ const localUrl = 'http://localhost:8888/.netlify/functions/system'
44
+ const url = `${localUrl}?action=${action}`
45
+
46
+ try {
47
+ const response = await fetch(url, {
48
+ method: 'GET',
49
+ headers: {
50
+ 'Accept': 'application/json',
51
+ 'x-app-id': 'cli-system'
52
+ }
53
+ })
54
+
55
+ if (!response.ok) {
56
+ const text = await response.text()
57
+ throw new Error(`HTTP ${response.status}: ${text}`)
58
+ }
59
+
60
+ return await response.json()
61
+ } catch (err: any) {
62
+ // If local fails, try direct Supabase function invoke (for production)
63
+ if (err.message.includes('fetch failed') || err.message.includes('ECONNREFUSED')) {
64
+ throw new Error(
65
+ 'Cannot connect to local dev server. ' +
66
+ 'Ensure `spine dev` or `netlify dev` is running on port 8888.'
67
+ )
68
+ }
69
+ throw err
70
+ }
71
+ }
72
+
73
+ // ─── COMMAND REGISTRATION ────────────────────────────────────────────────
74
+
75
+ export function registerSystemCommands(program: Command) {
76
+ const system = program
77
+ .command('system')
78
+ .description('System discovery and health commands')
79
+
80
+ system
81
+ .command('manifest')
82
+ .description('Fetch system manifest (version, functions, migrations)')
83
+ .option('--json', 'Output as JSON')
84
+ .action(async (opts) => {
85
+ try {
86
+ const ctx = await buildCliContext()
87
+ const result = await fetchSystemEndpoint(ctx, 'manifest')
88
+
89
+ if (opts.json) {
90
+ console.log(JSON.stringify(result, null, 2))
91
+ } else {
92
+ console.log('\n📋 Spine System Manifest')
93
+ console.log('─'.repeat(50))
94
+
95
+ if (result.data) {
96
+ const m = result.data
97
+ console.log(`Version: ${m.version}`)
98
+ console.log(`Schema: ${m.schema}`)
99
+ console.log(`Migrations: ${m.migrations?.applied || 0} applied` +
100
+ (m.migrations?.pending ? `, ${m.migrations.pending} pending` : ''))
101
+ console.log(`Functions: ${m.functions?.length || 0} endpoints`)
102
+ console.log(`Integrity: ${m.integrity?.verified ? '✓ verified' : '⚠ not verified'}`)
103
+
104
+ if (m.functions?.length > 0) {
105
+ console.log('\nAvailable Functions:')
106
+ for (const fn of m.functions.slice(0, 10)) {
107
+ console.log(` • ${fn.name} (${fn.methods.join(',')})`)
108
+ }
109
+ if (m.functions.length > 10) {
110
+ console.log(` ... and ${m.functions.length - 10} more`)
111
+ }
112
+ }
113
+ } else {
114
+ console.log('No manifest data returned')
115
+ }
116
+ console.log()
117
+ }
118
+ } catch (err: any) {
119
+ handleError(err)
120
+ }
121
+ })
122
+
123
+ system
124
+ .command('health')
125
+ .description('Fetch health check status')
126
+ .option('--json', 'Output as JSON')
127
+ .action(async (opts) => {
128
+ try {
129
+ const ctx = await buildCliContext()
130
+ const result = await fetchSystemEndpoint(ctx, 'health')
131
+
132
+ if (opts.json) {
133
+ console.log(JSON.stringify(result, null, 2))
134
+ } else {
135
+ console.log('\n🏥 Spine Health Check')
136
+ console.log('─'.repeat(50))
137
+
138
+ if (result.data) {
139
+ const h = result.data
140
+ const statusIcon = h.status === 'healthy' ? '✓' :
141
+ h.status === 'degraded' ? '⚠' : '✗'
142
+ console.log(`Status: ${statusIcon} ${h.status.toUpperCase()}`)
143
+ console.log()
144
+
145
+ if (h.checks) {
146
+ for (const [name, check] of Object.entries(h.checks)) {
147
+ const c = check as any
148
+ const icon = c.connected || c.current || c.verified ? '✓' :
149
+ c.status === 'passed' ? '✓' : '⚠'
150
+ console.log(`${icon} ${name}:`)
151
+ if (c.latency_ms !== undefined) {
152
+ console.log(` latency: ${c.latency_ms}ms`)
153
+ }
154
+ if (c.applied !== undefined) {
155
+ console.log(` applied: ${c.applied}, pending: ${c.pending}`)
156
+ }
157
+ if (c.last_suite) {
158
+ console.log(` last run: ${c.last_suite} (${c.last_status})`)
159
+ }
160
+ }
161
+ }
162
+ } else {
163
+ console.log('No health data returned')
164
+ }
165
+ console.log()
166
+ }
167
+ } catch (err: any) {
168
+ handleError(err)
169
+ }
170
+ })
171
+
172
+ system
173
+ .command('openapi')
174
+ .description('Fetch OpenAPI specification')
175
+ .action(async () => {
176
+ try {
177
+ const ctx = await buildCliContext()
178
+ const result = await fetchSystemEndpoint(ctx, 'openapi')
179
+ console.log(JSON.stringify(result.data || result, null, 2))
180
+ } catch (err: any) {
181
+ handleError(err)
182
+ }
183
+ })
184
+ }