spine-framework 0.4.3 → 0.5.0-rc.4

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 (320) hide show
  1. package/.env.example +13 -3
  2. package/.framework/cli/commands/bootstrap.ts +392 -0
  3. package/.framework/cli/commands/dev.ts +91 -218
  4. package/.framework/cli/commands/doctor.ts +132 -26
  5. package/.framework/cli/commands/generate.ts +38 -298
  6. package/.framework/cli/commands/init.ts +20 -1
  7. package/.framework/cli/commands/migrate.ts +36 -30
  8. package/.framework/cli/commands/migrations.ts +16 -56
  9. package/.framework/cli/commands/upgrade.ts +35 -0
  10. package/.framework/cli/commands/validate-schema.ts +147 -0
  11. package/.framework/cli/context.ts +223 -110
  12. package/.framework/cli/index.ts +6 -0
  13. package/.framework/cli/lib/project-files.ts +241 -1
  14. package/.framework/functions/_shared/agent-runner.ts +1000 -81
  15. package/.framework/functions/_shared/cil.ts +2 -1
  16. package/.framework/functions/_shared/db.ts +3 -6
  17. package/.framework/functions/_shared/hash-api-key.ts +183 -79
  18. package/.framework/functions/_shared/kb.ts +61 -7
  19. package/.framework/functions/_shared/logging.ts +562 -224
  20. package/.framework/functions/_shared/message-sequence.ts +53 -0
  21. package/.framework/functions/_shared/middleware.ts +47 -44
  22. package/.framework/functions/_shared/pipeline-runner.ts +150 -37
  23. package/.framework/functions/_shared/principal.ts +9 -6
  24. package/.framework/functions/_shared/trigger-engine.ts +149 -40
  25. package/.framework/functions/admin-data.ts +48 -31
  26. package/.framework/functions/ai-agents.ts +103 -33
  27. package/.framework/functions/api-keys.ts +301 -122
  28. package/.framework/functions/apps.ts +43 -26
  29. package/.framework/functions/cil-ingest.ts +48 -15
  30. package/.framework/functions/debug-auth.ts +14 -8
  31. package/.framework/functions/deliveries.ts +39 -12
  32. package/.framework/functions/embeddings.ts +145 -76
  33. package/.framework/functions/integration-outbound.ts +67 -27
  34. package/.framework/functions/integrations.ts +254 -127
  35. package/.framework/functions/logs.ts +273 -133
  36. package/.framework/functions/observability.ts +277 -147
  37. package/.framework/functions/pipeline-executions.ts +1 -1
  38. package/.framework/functions/pipeline-runner-background.ts +120 -0
  39. package/.framework/functions/pipelines.ts +14 -9
  40. package/.framework/functions/prompt-configs.ts +7 -4
  41. package/.framework/functions/roles.ts +8 -5
  42. package/.framework/functions/security.ts +30 -17
  43. package/.framework/functions/system-cron.ts +250 -128
  44. package/.framework/functions/tests.ts +7 -6
  45. package/.framework/functions/timers.ts +310 -107
  46. package/.framework/functions/trigger-scheduler.ts +65 -5
  47. package/.framework/functions/triggers.ts +28 -13
  48. package/.framework/functions/types.ts +13 -10
  49. package/.framework/migrations/064_episode_leases.sql +196 -0
  50. package/.framework/migrations/065_execution_tables_updated_at.sql +20 -0
  51. package/.framework/migrations/066_episode_steal_thread_merge.sql +148 -0
  52. package/.framework/migrations/067_episode_lease_stale_steal.sql +93 -0
  53. package/.framework/migrations/068_cron_schedule_timer_rpcs.sql +251 -0
  54. package/.framework/migrations/069_log_stats_window.sql +54 -0
  55. package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
  56. package/.framework/migrations/071_timer_interval_keys.sql +96 -0
  57. package/.framework/migrations/072_slug_autofill.sql +77 -0
  58. package/.framework/migrations/073_seed_member_roles.sql +26 -0
  59. package/.framework/schemas/spine.config.schema.json +62 -0
  60. package/.framework/src/App.tsx +3 -1
  61. package/.framework/src/apps/admin/index.tsx +1141 -775
  62. package/.framework/src/components/ErrorBoundary.tsx +136 -0
  63. package/.framework/src/components/admin/AdminListPage.tsx +81 -73
  64. package/.framework/src/components/admin/AdminSidebar.tsx +92 -81
  65. package/.framework/src/components/admin/EntitySelect.tsx +181 -0
  66. package/.framework/src/components/admin/PageInstructions.tsx +86 -127
  67. package/.framework/src/components/app-shell/GenericAppShell.tsx +3 -1
  68. package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
  69. package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
  70. package/.framework/src/components/auth/TurnstileWidget.tsx +9 -6
  71. package/.framework/src/components/kb/KBArticleEditor.tsx +49 -6
  72. package/.framework/src/components/layout/Layout.tsx +4 -2
  73. package/.framework/src/components/layout/Sidebar.tsx +304 -179
  74. package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
  75. package/.framework/src/components/runtime/DataHeader.tsx +96 -48
  76. package/.framework/src/components/runtime/DataListPage.tsx +3 -26
  77. package/.framework/src/components/runtime/DataStats.tsx +10 -10
  78. package/.framework/src/components/runtime/DataTable.tsx +12 -10
  79. package/.framework/src/components/ui/sheet.tsx +24 -26
  80. package/.framework/src/components/ui/textarea.tsx +74 -48
  81. package/.framework/src/hooks/useBranding.ts +47 -0
  82. package/.framework/src/hooks/useEntityList.ts +12 -9
  83. package/.framework/src/hooks/useListSchema.ts +108 -58
  84. package/.framework/src/instructions/README.md +57 -0
  85. package/.framework/src/instructions/ai-agents.md +69 -0
  86. package/.framework/src/instructions/alerts.md +80 -0
  87. package/.framework/src/instructions/api-keys.md +87 -0
  88. package/.framework/src/instructions/apps.md +77 -0
  89. package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
  90. package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
  91. package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
  92. package/.framework/src/instructions/concepts/automation.md +186 -0
  93. package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
  94. package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
  95. package/.framework/src/instructions/concepts/design-schema.md +152 -0
  96. package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
  97. package/.framework/src/instructions/concepts/observability.md +116 -0
  98. package/.framework/src/instructions/concepts/permissions.md +150 -0
  99. package/.framework/src/instructions/concepts/runtime-records.md +111 -0
  100. package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
  101. package/.framework/src/instructions/concepts/spine-way.md +172 -0
  102. package/.framework/src/instructions/deliveries.md +59 -0
  103. package/.framework/src/instructions/guide/00-orientation.md +106 -0
  104. package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
  105. package/.framework/src/instructions/guide/02-project-map.md +147 -0
  106. package/.framework/src/instructions/guide/03-domain-model.md +223 -0
  107. package/.framework/src/instructions/guide/04-first-app.md +227 -0
  108. package/.framework/src/instructions/guide/05-glossary.md +183 -0
  109. package/.framework/src/instructions/integrations.md +96 -0
  110. package/.framework/src/instructions/internal/cil-markers.md +83 -0
  111. package/.framework/src/instructions/invites.md +60 -0
  112. package/.framework/src/instructions/kb.md +80 -0
  113. package/.framework/src/instructions/logs.md +77 -0
  114. package/.framework/src/instructions/observability.md +61 -0
  115. package/.framework/src/instructions/operations/deployment.md +115 -0
  116. package/.framework/src/instructions/operations/migrations.md +125 -0
  117. package/.framework/src/instructions/operations/security-checklist.md +148 -0
  118. package/.framework/src/instructions/operations/troubleshooting.md +170 -0
  119. package/.framework/src/instructions/operations/upgrade.md +116 -0
  120. package/.framework/src/instructions/pipeline-executions.md +62 -0
  121. package/.framework/src/instructions/pipelines.md +78 -0
  122. package/.framework/src/instructions/prompts.md +95 -0
  123. package/.framework/src/instructions/reference/api/admin-data.md +162 -0
  124. package/.framework/src/instructions/reference/api/auth.md +113 -0
  125. package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
  126. package/.framework/src/instructions/reference/app-manifest.md +150 -0
  127. package/.framework/src/instructions/reference/cli.md +124 -0
  128. package/.framework/src/instructions/reference/database.md +132 -0
  129. package/.framework/src/instructions/reference/design-schema.md +280 -0
  130. package/.framework/src/instructions/reference/env-vars.md +133 -0
  131. package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
  132. package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
  133. package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
  134. package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
  135. package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
  136. package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
  137. package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
  138. package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
  139. package/.framework/src/instructions/reference/functions/apps.md +140 -0
  140. package/.framework/src/instructions/reference/functions/auth.md +99 -0
  141. package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
  142. package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
  143. package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
  144. package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
  145. package/.framework/src/instructions/reference/functions/index.md +103 -0
  146. package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
  147. package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
  148. package/.framework/src/instructions/reference/functions/integrations.md +130 -0
  149. package/.framework/src/instructions/reference/functions/invites.md +182 -0
  150. package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
  151. package/.framework/src/instructions/reference/functions/kb.md +166 -0
  152. package/.framework/src/instructions/reference/functions/logs.md +141 -0
  153. package/.framework/src/instructions/reference/functions/observability.md +105 -0
  154. package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
  155. package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
  156. package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
  157. package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
  158. package/.framework/src/instructions/reference/functions/roles.md +121 -0
  159. package/.framework/src/instructions/reference/functions/security.md +140 -0
  160. package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
  161. package/.framework/src/instructions/reference/functions/system.md +106 -0
  162. package/.framework/src/instructions/reference/functions/tests.md +97 -0
  163. package/.framework/src/instructions/reference/functions/timers.md +117 -0
  164. package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
  165. package/.framework/src/instructions/reference/functions/triggers.md +140 -0
  166. package/.framework/src/instructions/reference/functions/types.md +146 -0
  167. package/.framework/src/instructions/reference/seeds.md +126 -0
  168. package/.framework/src/instructions/reference/shared-modules.md +127 -0
  169. package/.framework/src/instructions/reference/spine-config.md +114 -0
  170. package/.framework/src/instructions/roles.md +80 -0
  171. package/.framework/src/instructions/runtime-detail.md +70 -0
  172. package/.framework/src/instructions/runtime-list.md +77 -0
  173. package/.framework/src/instructions/security.md +67 -0
  174. package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
  175. package/.framework/src/instructions/tasks/add-a-role.md +96 -0
  176. package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
  177. package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
  178. package/.framework/src/instructions/tasks/add-a-type.md +151 -0
  179. package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
  180. package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
  181. package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
  182. package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
  183. package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
  184. package/.framework/src/instructions/tasks/test-your-code.md +108 -0
  185. package/.framework/src/instructions/tasks/write-a-function.md +132 -0
  186. package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
  187. package/.framework/src/instructions/testing.md +59 -0
  188. package/.framework/src/instructions/timers.md +82 -0
  189. package/.framework/src/instructions/triggers.md +69 -0
  190. package/.framework/src/instructions/types.md +93 -0
  191. package/.framework/src/lib/branding.ts +128 -0
  192. package/.framework/src/pages/NoAppPage.tsx +3 -1
  193. package/.framework/src/pages/NotFoundPage.tsx +62 -31
  194. package/.framework/src/pages/SetupPage.tsx +5 -2
  195. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
  196. package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
  197. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
  198. package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
  199. package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
  200. package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
  201. package/.framework/src/pages/admin/AppsPage.tsx +104 -66
  202. package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
  203. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
  204. package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
  205. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
  206. package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
  207. package/.framework/src/pages/admin/LogsPage.tsx +144 -76
  208. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
  209. package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
  210. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
  211. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
  212. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
  213. package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
  214. package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
  215. package/.framework/src/pages/admin/RolesPage.tsx +86 -43
  216. package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
  217. package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
  218. package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
  219. package/.framework/src/pages/admin/TimersPage.tsx +90 -62
  220. package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
  221. package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
  222. package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
  223. package/.framework/src/pages/admin/TypesPage.tsx +90 -48
  224. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
  225. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
  226. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
  227. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
  228. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
  229. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
  230. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
  231. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
  232. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
  233. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
  234. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
  235. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
  236. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
  237. package/.framework/src/pages/auth/AuthConfirmPage.tsx +3 -1
  238. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +3 -1
  239. package/.framework/src/pages/auth/LoginPage.tsx +4 -2
  240. package/.framework/src/pages/auth/RegisterPage.tsx +3 -1
  241. package/.framework/templates/agent/AGENTS.md +150 -0
  242. package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
  243. package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
  244. package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
  245. package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
  246. package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
  247. package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
  248. package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
  249. package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
  250. package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
  251. package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
  252. package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
  253. package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
  254. package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
  255. package/.framework/templates/project.json +5 -1
  256. package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
  257. package/.framework/tests/unit/agent-files.test.ts +355 -0
  258. package/.framework/tests/unit/agent-runner.test.ts +496 -47
  259. package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
  260. package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
  261. package/.framework/tests/unit/bootstrap.test.ts +242 -0
  262. package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
  263. package/.framework/tests/unit/debug-auth.test.ts +38 -0
  264. package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
  265. package/.framework/tests/unit/episode-lease.test.ts +695 -0
  266. package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
  267. package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
  268. package/.framework/tests/unit/kb-ingest-lease.test.ts +19 -0
  269. package/.framework/tests/unit/logging-app-id.test.ts +75 -0
  270. package/.framework/tests/unit/pipeline-runner-background.test.ts +120 -0
  271. package/.framework/tests/unit/pipeline-runner.test.ts +153 -1
  272. package/.framework/tests/unit/principal-cache.test.ts +15 -0
  273. package/.framework/tests/unit/system-context-denial.test.ts +145 -0
  274. package/.framework/tests/unit/system-cron.test.ts +240 -0
  275. package/.framework/tests/unit/timers.test.ts +159 -0
  276. package/.framework/tests/unit/trigger-engine.test.ts +278 -91
  277. package/.framework/tests/unit/trigger-scheduler.test.ts +78 -0
  278. package/README.md +125 -166
  279. package/config/tsconfig.cli.json +2 -2
  280. package/netlify.toml +5 -0
  281. package/package.json +15 -4
  282. package/templates/project/package-lock.json +2 -2
  283. package/.framework/docs/admin-routes.md +0 -76
  284. package/.framework/docs/api-docs-progress.md +0 -38
  285. package/.framework/docs/api-governance.md +0 -146
  286. package/.framework/docs/api-testing-results.md +0 -212
  287. package/.framework/docs/assembly-launch-guide.md +0 -138
  288. package/.framework/docs/audit-results.md +0 -590
  289. package/.framework/docs/db-api-inventory.md +0 -95
  290. package/.framework/docs/gap-remediation-backlog.md +0 -103
  291. package/.framework/docs/ui-adoption-verification.md +0 -111
  292. package/.framework/docs/ui-api-coverage.md +0 -84
  293. package/.framework/docs/v2-compatibility-audit.md +0 -228
  294. package/.framework/mcp/index.ts +0 -133
  295. package/.framework/mcp/load-env.ts +0 -60
  296. package/.framework/mcp/shared/app-manifest.ts +0 -275
  297. package/.framework/mcp/shared/db.ts +0 -477
  298. package/.framework/mcp/shared/kb.ts +0 -118
  299. package/.framework/mcp/tools/architect.ts +0 -431
  300. package/.framework/mcp/tools/cil/context.ts +0 -345
  301. package/.framework/mcp/tools/cil/graph.ts +0 -242
  302. package/.framework/mcp/tools/cil/ingest.ts +0 -1217
  303. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
  304. package/.framework/mcp/tools/cil/pipeline.ts +0 -767
  305. package/.framework/mcp/tools/cil/project.ts +0 -791
  306. package/.framework/mcp/tools/cil/retrieval.ts +0 -336
  307. package/.framework/mcp/tools/cil/search-core.ts +0 -454
  308. package/.framework/mcp/tools/cil/search.ts +0 -97
  309. package/.framework/mcp/tools/cil/suggest.ts +0 -186
  310. package/.framework/mcp/tools/cil/validate.ts +0 -1369
  311. package/.framework/mcp/tools/kb/delete.ts +0 -139
  312. package/.framework/mcp/tools/kb/index.ts +0 -52
  313. package/.framework/mcp/tools/kb/ingest.ts +0 -84
  314. package/.framework/mcp/tools/kb/list-types.ts +0 -102
  315. package/.framework/mcp/tools/kb/publish.ts +0 -100
  316. package/.framework/mcp/tools/kb/reindex.ts +0 -86
  317. package/.framework/mcp/tools/kb/revoke.ts +0 -85
  318. package/.framework/mcp/tools/kb/search.ts +0 -101
  319. package/.framework/mcp/tools/kb/upsert.ts +0 -125
  320. package/.framework/mcp/tools/observability.ts +0 -510
@@ -0,0 +1,147 @@
1
+ // validate-schema — standalone design_schema validator.
2
+ //
3
+ // Ported from .framework/mcp/tools/architect.ts (the retired Spine MCP
4
+ // architect tools) so `spine-schema` and CI have a runnable validator without
5
+ // the MCP server. `validate-app` covers app packages (manifest/package.json/
6
+ // structure) — this command covers a single design_schema JSON file.
7
+
8
+ import type { Command } from 'commander'
9
+ import { readFileSync, existsSync } from 'fs'
10
+ import { resolve } from 'path'
11
+
12
+ const DATA_TYPES = new Set([
13
+ 'text', 'textarea', 'rich_text', 'email', 'phone', 'url', 'number', 'currency', 'range',
14
+ 'date', 'datetime', 'boolean', 'checkbox', 'select', 'multiselect', 'radio', 'color',
15
+ 'file', 'image', 'json', 'reference', 'address',
16
+ ])
17
+
18
+ const DISPLAY_TYPES = new Set([
19
+ 'text', 'input', 'textarea', 'rich_text', 'select', 'multiselect', 'radio', 'checkbox',
20
+ 'switch', 'date_picker', 'datetime_picker', 'color_picker', 'file_upload', 'image_upload',
21
+ 'range_slider', 'badge', 'timestamp', 'currency', 'number',
22
+ ])
23
+
24
+ /**
25
+ * Validate a design_schema object. `checkViews` additionally requires
26
+ * views.default_list / views.default_detail and scans every declared
27
+ * display_type — the generic runtime UI breaks without them.
28
+ */
29
+ export function validateDesignSchema(
30
+ schema: any,
31
+ opts: { checkViews?: boolean } = {},
32
+ ): { ok: boolean; errors: string[] } {
33
+ const checkViews = opts.checkViews ?? true
34
+ const errors: string[] = []
35
+ if (!schema || typeof schema !== 'object' || Array.isArray(schema)) {
36
+ errors.push('design_schema must be an object')
37
+ return { ok: false, errors }
38
+ }
39
+
40
+ const scope = schema.scope ?? 'account'
41
+ if (scope !== 'account' && scope !== 'platform') {
42
+ errors.push('scope must be "account" or "platform"')
43
+ }
44
+
45
+ if (!schema.fields || typeof schema.fields !== 'object' || Object.keys(schema.fields).length === 0) {
46
+ errors.push('fields is required and must contain at least one field definition')
47
+ }
48
+
49
+ for (const [key, field] of Object.entries(schema.fields || {})) {
50
+ if (!field || typeof field !== 'object') {
51
+ errors.push(`fields.${key} must be an object`)
52
+ continue
53
+ }
54
+ const f = field as any
55
+ if (!f.data_type) errors.push(`fields.${key} is missing data_type`)
56
+ else if (!DATA_TYPES.has(f.data_type)) errors.push(`fields.${key} has unknown data_type: ${f.data_type}`)
57
+ if (!f.label) errors.push(`fields.${key} is missing label`)
58
+ if (f.required === undefined) errors.push(`fields.${key} is missing required`)
59
+ if (['select', 'multiselect', 'radio'].includes(f.data_type) && (!f.options || !Array.isArray(f.options) || f.options.length === 0)) {
60
+ errors.push(`fields.${key} (${f.data_type}) requires options`)
61
+ }
62
+ }
63
+
64
+ if (!schema.record_permissions || typeof schema.record_permissions !== 'object') {
65
+ errors.push('record_permissions is required')
66
+ } else if (!Object.keys(schema.record_permissions).includes('system-admin') && !Object.keys(schema.record_permissions).includes('system_admin')) {
67
+ errors.push('record_permissions must grant at least system-admin or system_admin')
68
+ }
69
+
70
+ if (schema.views) {
71
+ if (schema.views.default_list) {
72
+ const list = schema.views.default_list
73
+ if (list.type !== 'list') errors.push('views.default_list.type must be "list"')
74
+ if (!list.fields || typeof list.fields !== 'object') errors.push('views.default_list.fields is required')
75
+ if (!list.default_sort) errors.push('views.default_list.default_sort is required')
76
+ }
77
+ if (schema.views.default_detail) {
78
+ const detail = schema.views.default_detail
79
+ if (detail.type !== 'detail') errors.push('views.default_detail.type must be "detail"')
80
+ }
81
+ }
82
+
83
+ if (checkViews && !schema.views) {
84
+ errors.push('views is required when check_views is true')
85
+ }
86
+ if (schema.views) {
87
+ if (checkViews && !schema.views.default_list) errors.push('views.default_list is required')
88
+ if (checkViews && !schema.views.default_detail) errors.push('views.default_detail is required')
89
+ for (const [viewName, view] of Object.entries(schema.views || {})) {
90
+ const v = view as any
91
+ if (!v || typeof v !== 'object') continue
92
+ for (const [fieldName, field] of Object.entries(v.fields || {})) {
93
+ const f = field as any
94
+ if (f && f.display_type && !DISPLAY_TYPES.has(f.display_type)) {
95
+ errors.push(`views.${viewName}.fields.${fieldName} has unknown display_type: ${f.display_type}`)
96
+ }
97
+ }
98
+ if (v.sections) {
99
+ for (const section of v.sections) {
100
+ for (const [fieldName, field] of Object.entries(section.fields || {})) {
101
+ const f = field as any
102
+ if (f && f.display_type && !DISPLAY_TYPES.has(f.display_type)) {
103
+ errors.push(`views.${viewName}.sections.*.fields.${fieldName} has unknown display_type: ${f.display_type}`)
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ return { ok: errors.length === 0, errors }
112
+ }
113
+
114
+ export function registerValidateSchemaCommands(program: Command) {
115
+ program
116
+ .command('validate-schema')
117
+ .description('Validate a design_schema JSON file against the Spine design-schema rules')
118
+ .argument('<file>', 'Path to a design_schema JSON file')
119
+ .option('--no-views', 'Skip the default_list/default_detail view requirements (custom apps)')
120
+ .option('--json', 'Output the result as JSON')
121
+ .action(async (file: string, opts: { views: boolean; json: boolean }) => {
122
+ const abs = resolve(file)
123
+ if (!existsSync(abs)) {
124
+ console.error(`❌ file not found: ${file}`)
125
+ process.exit(1)
126
+ }
127
+ let schema: any
128
+ try {
129
+ schema = JSON.parse(readFileSync(abs, 'utf8'))
130
+ } catch (err: any) {
131
+ console.error(`❌ ${file} is not valid JSON: ${err.message}`)
132
+ process.exit(1)
133
+ }
134
+
135
+ const result = validateDesignSchema(schema, { checkViews: opts.views })
136
+
137
+ if (opts.json) {
138
+ console.log(JSON.stringify({ ok: result.ok, error_count: result.errors.length, errors: result.errors }, null, 2))
139
+ } else if (result.ok) {
140
+ console.log(`✅ ${file}: design_schema is valid`)
141
+ } else {
142
+ console.error(`❌ ${file}: ${result.errors.length} design_schema error(s)`)
143
+ for (const e of result.errors) console.error(` - ${e}`)
144
+ }
145
+ if (!result.ok) process.exit(1)
146
+ })
147
+ }
@@ -1,67 +1,113 @@
1
1
  // CIL[BEGIN stable_id="~/.framework/cli/context.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/cli/context.ts"]
2
- // CIL[DOC-MACRO purpose="Defines shared CLI runtime context and helpers for spine commands."]
3
- // CIL[DOC-RESPONSIBILITY responsibility="Initialize CLI execution context, load environment, and expose result formatting and error handling helpers."]
4
- // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/functions/_shared/index.ts"]
5
- // CIL[DOC-CONTRACT inputs="command-line options and environment variables" outputs="CoreContext, formatted output, error handling" errors="Throws when required Supabase env vars are missing" side_effects="Reads .xenv and process.env"]
6
- // CIL[DOC-MICRO logic_summary="Imports dependencies, sets up ESM-compatible path constants, builds a CoreContext from env/JWT/API key, and provides output/error formatting." notable_decisions="Defaults to SYSTEM_PRINCIPAL; prioritizes API key auth over JWT over anonymous."]
7
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
- // CIL[DOC-STABILITY stability="stable"]
9
- // CIL[DOC-AUDIENCE audience="cli_engineers,framework_maintainers"]
2
+ /**
3
+ * @module context
4
+ * @audience both
5
+ * @layer shared-core
6
+ * @stability stable
7
+ *
8
+ * This module provides context management for the CLI, facilitating interactions with the core system and user databases. It serves as a foundational component for handling user authentication and data access. INVARIANT: The CoreContext must be initialized before any database operations are performed.
9
+ *
10
+ * @seeAlso functions/_shared/index.ts (contains shared core functionalities).
11
+ * @seeAlso functions/_shared/hash-api-key.ts (provides API key verification logic).
12
+ *
13
+ * @cil-generated
14
+ */
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
10
24
 
11
25
  import { readFileSync, existsSync } from 'fs'
12
26
  import { resolve, dirname } from 'path'
13
27
  import { fileURLToPath } from 'url'
14
28
  import { CoreContext, adminDb, SYSTEM_PRINCIPAL, Principal, getUserDb } from '../functions/_shared/index.ts'
15
- // CIL[DOC-VECTOR type="context" content="purpose='Defines shared CLI runtime context and helpers for spine commands.'; No verified external callers; imports: .framework/functions/_shared/index.ts"]
16
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
17
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
18
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
19
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
20
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
29
+ import { verifyApiKey } from '../functions/_shared/hash-api-key.ts'
21
30
  // CIL[END stable_id="~/.framework/cli/context.ts:module_header:module_header"]
22
31
 
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
23
47
  // CIL[BEGIN stable_id="~/.framework/cli/context.ts:__filename:constant" type="constant" identity="__filename" parent="~/.framework/cli/context.ts"]
24
- // CIL[DOC-MACRO purpose="Provides an ESM-compatible __filename constant for this module."]
25
- // CIL[DOC-RESPONSIBILITY responsibility="Resolve the current source file path from import.meta.url."]
26
- // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/cli/context.ts,.framework/functions/_shared/index.ts"]
27
- // CIL[DOC-CONTRACT inputs="import.meta.url" outputs="string absolute file path" errors="none" side_effects="none"]
28
- // CIL[DOC-MICRO logic_summary="Converts the module's URL to a file path with fileURLToPath." notable_decisions=""]
29
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
30
- // CIL[DOC-STABILITY stability="stable"]
48
+ /**
49
+ * __filename is a constant that holds the absolute path of the current module file, providing a reference to the file location for logging or resolving relative paths.
50
+ *
51
+ * @sideEffects none
52
+ * @stability internal
53
+ * @calls fileURLToPath
54
+ * @cil-generated
55
+ */
31
56
  const __filename = fileURLToPath(import.meta.url)
32
- // CIL[DOC-VECTOR type="context" content="purpose='Provides an ESM-compatible __filename constant for this module.'; No verified external callers; imports: .framework/functions/_shared/index.ts"]
33
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
34
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
35
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
36
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
37
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
38
57
  // CIL[END stable_id="~/.framework/cli/context.ts:__filename:constant"]
39
58
 
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
40
74
  // CIL[BEGIN stable_id="~/.framework/cli/context.ts:__dirname:constant" type="constant" identity="__dirname" parent="~/.framework/cli/context.ts"]
41
- // CIL[DOC-MACRO purpose="Provides an ESM-compatible __dirname constant for this module."]
42
- // CIL[DOC-RESPONSIBILITY responsibility="Resolve the directory containing this source file."]
43
- // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/cli/context.ts,.framework/functions/_shared/index.ts"]
44
- // CIL[DOC-CONTRACT inputs="__filename" outputs="string absolute directory path" errors="none" side_effects="none"]
45
- // CIL[DOC-MICRO logic_summary="Derives the parent directory of __filename using the dirname helper." notable_decisions=""]
46
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
47
- // CIL[DOC-STABILITY stability="stable"]
75
+ /**
76
+ * __dirname is a constant that holds the directory name of the current module, allowing for relative file path resolution. It exists to facilitate file operations within the module's directory context.
77
+ *
78
+ * @sideEffects none
79
+ * @stability internal
80
+ * @calls dirname
81
+ * @cil-generated
82
+ */
48
83
  const __dirname = dirname(__filename)
49
- // CIL[DOC-VECTOR type="context" content="purpose='Provides an ESM-compatible __dirname constant for this module.'; No verified external callers; imports: .framework/functions/_shared/index.ts"]
50
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
51
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
52
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
53
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
54
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
55
84
  // CIL[END stable_id="~/.framework/cli/context.ts:__dirname:constant"]
56
85
 
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
57
101
  // CIL[BEGIN stable_id="~/.framework/cli/context.ts:loadEnv:function" type="function" identity="loadEnv" parent="~/.framework/cli/context.ts"]
58
- // CIL[DOC-MACRO purpose="Loads local environment overrides from a .xenv file."]
59
- // CIL[DOC-RESPONSIBILITY responsibility="Read the framework .xenv file and populate process.env without overwriting existing values."]
60
- // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/cli/context.ts,.framework/functions/_shared/index.ts"]
61
- // CIL[DOC-CONTRACT inputs=".xenv file in the framework parent directory" outputs="Updated process.env" errors="none" side_effects="Mutates process.env for missing keys only"]
62
- // CIL[DOC-MICRO logic_summary="Resolves .xenv, reads its lines, ignores blank or comment lines, parses KEY=VALUE pairs, strips surrounding quotes, and sets only missing keys." notable_decisions="Existing process.env values are intentionally not overwritten."]
63
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
64
- // CIL[DOC-STABILITY stability="stable"]
102
+ /**
103
+ * Loads environment variables from a specified file into the process environment, ensuring that any variables defined in the file are available to the application at runtime.
104
+ *
105
+ * @outputSpec void
106
+ * @sideEffects Reads from the file system to load environment variables.
107
+ * @stability internal
108
+ * @calls resolve, existsSync, readFileSync
109
+ * @cil-generated
110
+ */
65
111
  function loadEnv() {
66
112
  const envPath = resolve(__dirname, '../.xenv')
67
113
  if (existsSync(envPath)) {
@@ -79,41 +125,66 @@ function loadEnv() {
79
125
  }
80
126
  }
81
127
  }
82
- // CIL[DOC-VECTOR type="context" content="purpose='Loads local environment overrides from a .xenv file.'; No verified external callers; imports: .framework/functions/_shared/index.ts"]
83
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
84
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
85
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
86
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
87
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
88
128
  // CIL[END stable_id="~/.framework/cli/context.ts:loadEnv:function"]
89
129
 
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
90
145
  // CIL[BEGIN stable_id="~/.framework/cli/context.ts:CliOptions:interface" type="interface" identity="CliOptions" parent="~/.framework/cli/context.ts"]
91
- // CIL[DOC-MACRO purpose="Declares the shape of options passed to CLI context builders."]
92
- // CIL[DOC-RESPONSIBILITY responsibility="Define the optional account parameter used by CLI commands."]
93
- // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/cli/context.ts,.framework/functions/_shared/index.ts"]
94
- // CIL[DOC-CONTRACT inputs="N/A" outputs="TypeScript interface" errors="N/A" side_effects="N/A"]
95
- // CIL[DOC-MICRO logic_summary="Contains an optional account property for scoping CLI invocations." notable_decisions=""]
96
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
97
- // CIL[DOC-STABILITY stability="stable"]
146
+ /**
147
+ * The CliOptions interface defines the structure for command-line interface options, allowing for optional configuration of an account string. It exists to standardize the way CLI options are handled within the module.
148
+ *
149
+ * @sideEffects none
150
+ * @stability internal
151
+ * @cil-generated
152
+ */
98
153
  export interface CliOptions {
99
154
  account?: string
100
155
  }
101
- // CIL[DOC-VECTOR type="context" content="purpose='Declares the shape of options passed to CLI context builders.'; No verified external callers; imports: .framework/functions/_shared/index.ts"]
102
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
103
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
104
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
105
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
106
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
107
156
  // CIL[END stable_id="~/.framework/cli/context.ts:CliOptions:interface"]
108
157
 
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+
167
+
168
+
169
+
170
+
171
+
172
+
109
173
  // CIL[BEGIN stable_id="~/.framework/cli/context.ts:buildCliContext:function" type="function" identity="buildCliContext" parent="~/.framework/cli/context.ts"]
110
- // CIL[DOC-MACRO purpose="Constructs a CoreContext for spine CLI commands from environment or credentials."]
111
- // CIL[DOC-RESPONSIBILITY responsibility="Load environment, validate required Supabase variables, resolve account/request IDs, authenticate via API key or JWT, and return a CoreContext."]
112
- // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/cli/context.ts,.framework/functions/_shared/index.ts"]
113
- // CIL[DOC-CONTRACT inputs="opts: CliOptions = {}" outputs="Promise<CoreContext>" errors="Throws if SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY are missing; throws on invalid API key or JWT" side_effects="Reads process.env; queries Supabase; calls crypto.randomUUID"]
114
- // CIL[DOC-MICRO logic_summary="Loads .xenv, asserts required Supabase env, picks account and request IDs, attempts API key auth, then JWT auth, then falls back to SYSTEM_PRINCIPAL." notable_decisions="API key auth takes precedence over JWT; account is resolved from opts, SPINE_CLI_ACCOUNT_ID, or the authenticated key record."]
115
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
116
- // CIL[DOC-STABILITY stability="stable"]
174
+ /**
175
+ * Builds a CLI context by validating environment variables and retrieving user or API key information. It ensures that the necessary credentials are available for subsequent operations.
176
+ *
177
+ * @macro Async function that constructs a CoreContext for CLI operations.
178
+ * @micro Validates environment variables and checks for either an API key or JWT to determine the principal and associated account.
179
+ * @inputSpec
180
+ * opts: CliOptions (optional) — options for building the CLI context.
181
+ * @outputSpec Promise<CoreContext> — returns a context object containing principal, accountId, database connection, and requestId.
182
+ * @throws Error — Missing required env vars: SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY; Error — Invalid or inactive SPINE_CLI_API_KEY; Error — Invalid or expired SPINE_CLI_JWT
183
+ * @sideEffects none
184
+ * @stability internal
185
+ * @calls adminDb.from('api_keys'), adminDb.from('people'), userDb.auth.getUser
186
+ * @cil-generated
187
+ */
117
188
  export async function buildCliContext(opts: CliOptions = {}): Promise<CoreContext> {
118
189
  loadEnv()
119
190
 
@@ -129,19 +200,30 @@ export async function buildCliContext(opts: CliOptions = {}): Promise<CoreContex
129
200
 
130
201
  const apiKey = process.env.SPINE_CLI_API_KEY
131
202
  if (apiKey) {
132
- const { data: keyRecord } = await adminDb
203
+ const keyPrefix = apiKey.slice(0, 8)
204
+
205
+ const { data: rows, error } = await adminDb
133
206
  .from('api_keys')
134
- .select('id, account_id, scopes, principal_id')
135
- .eq('key_hash', apiKey)
207
+ .select('id, account_id, scopes, key_hash, expires_at')
208
+ .eq('key_prefix', keyPrefix)
136
209
  .eq('is_active', true)
137
- .single()
210
+ .order('created_at', { ascending: false })
211
+ .limit(10)
212
+
213
+ const now = Date.now()
214
+ const keyRecord = !error && rows
215
+ ? rows.find((k: any) =>
216
+ (!k.expires_at || new Date(k.expires_at).getTime() >= now) &&
217
+ verifyApiKey(apiKey, k.key_hash)
218
+ )
219
+ : undefined
138
220
 
139
221
  if (!keyRecord) {
140
222
  throw new Error('Invalid or inactive SPINE_CLI_API_KEY')
141
223
  }
142
224
 
143
225
  const principal: Principal = {
144
- id: keyRecord.principal_id || keyRecord.id,
226
+ id: keyRecord.id,
145
227
  type: 'machine',
146
228
  accountId: keyRecord.account_id,
147
229
  scopes: keyRecord.scopes || [],
@@ -208,22 +290,38 @@ export async function buildCliContext(opts: CliOptions = {}): Promise<CoreContex
208
290
  requestId
209
291
  }
210
292
  }
211
- // CIL[DOC-VECTOR type="context" content="purpose='Constructs a CoreContext for spine CLI commands from environment or credentials.'; No verified external callers; imports: .framework/functions/_shared/index.ts"]
212
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
213
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
214
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
215
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
216
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
217
293
  // CIL[END stable_id="~/.framework/cli/context.ts:buildCliContext:function"]
218
294
 
295
+
296
+
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+
219
310
  // CIL[BEGIN stable_id="~/.framework/cli/context.ts:printResult:function" type="function" identity="printResult" parent="~/.framework/cli/context.ts"]
220
- // CIL[DOC-MACRO purpose="Prints CLI command results to stdout in human-readable or JSON form."]
221
- // CIL[DOC-RESPONSIBILITY responsibility="Format and emit command results based on the json option."]
222
- // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/cli/context.ts,.framework/functions/_shared/index.ts"]
223
- // CIL[DOC-CONTRACT inputs="data, opts" outputs="Formatted output to stdout" errors="none" side_effects="Writes to stdout"]
224
- // CIL[DOC-MICRO logic_summary="Takes data and opts. If opts.json is true, pretty-prints JSON; otherwise prints arrays as tables, objects as JSON, and primitives as plain text. Empty arrays print 'No results found.'" notable_decisions=""]
225
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
226
- // CIL[DOC-STABILITY stability="stable"]
311
+ /**
312
+ * Prints the result of the given data to the console in a readable format for CLI users. It provides flexibility to display data either as a formatted table or as JSON based on the provided options.
313
+ *
314
+ * @macro Utility function for displaying data in various formats.
315
+ * @micro Uses conditional checks to determine the format of the output based on the type of data and options provided.
316
+ * @inputSpec
317
+ * data: any — the data to be printed.
318
+ * opts: { json?: boolean } (optional) — options to control the output format.
319
+ * @outputSpec void
320
+ * @sideEffects prints to console
321
+ * @stability internal
322
+ * @calls console.log, console.table, JSON.stringify
323
+ * @cil-generated
324
+ */
227
325
  export function printResult(data: any, opts: { json?: boolean } = {}) {
228
326
  if (opts.json) {
229
327
  console.log(JSON.stringify(data, null, 2))
@@ -243,22 +341,36 @@ export function printResult(data: any, opts: { json?: boolean } = {}) {
243
341
  console.log(data)
244
342
  }
245
343
  }
246
- // CIL[DOC-VECTOR type="context" content="purpose='Prints CLI command results to stdout in human-readable or JSON form.'; No verified external callers; imports: .framework/functions/_shared/index.ts"]
247
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
248
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
249
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
250
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
251
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
252
344
  // CIL[END stable_id="~/.framework/cli/context.ts:printResult:function"]
253
345
 
346
+
347
+
348
+
349
+
350
+
351
+
352
+
353
+
354
+
355
+
356
+
357
+
358
+
359
+
360
+
254
361
  // CIL[BEGIN stable_id="~/.framework/cli/context.ts:handleError:function" type="function" identity="handleError" parent="~/.framework/cli/context.ts"]
255
- // CIL[DOC-MACRO purpose="Prints a friendly error message for known failure codes and exits the process."]
256
- // CIL[DOC-RESPONSIBILITY responsibility="Map known Postgres/Supabase error codes to readable messages and terminate with exit code 1."]
257
- // CIL[DOC-CONTEXT module="cli" layer="framework" related_files=".framework/cli/context.ts,.framework/functions/_shared/index.ts"]
258
- // CIL[DOC-CONTRACT inputs="error, context" outputs="Error message to stderr and process termination" errors="none" side_effects="Writes to stderr; calls process.exit(1)"]
259
- // CIL[DOC-MICRO logic_summary="Takes error and optional context. Extracts the message, prefixes with context when provided, maps PGRST116 to not-found and PGRST301 to permission-denied, prints the message, and exits." notable_decisions=""]
260
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
261
- // CIL[DOC-STABILITY stability="stable"]
362
+ /**
363
+ * The handleError function logs error messages to the console based on the error type and exits the process. It provides specific messages for known error codes and a general message for other errors.
364
+ *
365
+ * @inputSpec
366
+ * error: any (required) — the error object to handle.
367
+ * context: string (optional) — an optional context string for additional logging.
368
+ * @outputSpec none
369
+ * @sideEffects Logs error messages to the console and exits the process with status code 1.
370
+ * @stability internal
371
+ * @calls console.error, process.exit
372
+ * @cil-generated
373
+ */
262
374
  export function handleError(error: any, context?: string) {
263
375
  const message = error?.message || String(error)
264
376
  const contextStr = context ? `[${context}] ` : ''
@@ -273,10 +385,11 @@ export function handleError(error: any, context?: string) {
273
385
 
274
386
  process.exit(1)
275
387
  }
276
- // CIL[DOC-VECTOR type="context" content="purpose='Prints a friendly error message for known failure codes and exits the process.'; No verified external callers; imports: .framework/functions/_shared/index.ts"]
277
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
278
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
279
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
280
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
281
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
282
388
  // CIL[END stable_id="~/.framework/cli/context.ts:handleError:function"]
389
+
390
+
391
+
392
+
393
+
394
+
395
+
@@ -71,6 +71,7 @@ program
71
71
  const [
72
72
  { registerInitCommands },
73
73
  { registerMigrateCommands },
74
+ { registerBootstrapCommands },
74
75
  { registerInstallAppCommands },
75
76
  { registerStatusCommands },
76
77
  { registerAuthCommands },
@@ -85,10 +86,12 @@ const [
85
86
  { registerGenerateCommands },
86
87
  { registerCreateAppCommands },
87
88
  { registerValidateAppCommands },
89
+ { registerValidateSchemaCommands },
88
90
  { registerUpgradeCommands },
89
91
  ] = await Promise.all([
90
92
  import('./commands/init.ts'),
91
93
  import('./commands/migrate.ts'),
94
+ import('./commands/bootstrap.ts'),
92
95
  import('./commands/install-app.ts'),
93
96
  import('./commands/status.ts'),
94
97
  import('./commands/auth.ts'),
@@ -103,6 +106,7 @@ const [
103
106
  import('./commands/generate.ts'),
104
107
  import('./commands/create-app.ts'),
105
108
  import('./commands/validate-app.ts'),
109
+ import('./commands/validate-schema.ts'),
106
110
  import('./commands/upgrade.ts'),
107
111
  ])
108
112
  // CIL[DOC-VECTOR type="context" content="purpose='Dynamically import all CLI command modules'; No verified external callers; imports: .framework/cli/env-loader.ts"]
@@ -122,6 +126,7 @@ const [
122
126
  // CIL[DOC-STABILITY stability="stable"]
123
127
  registerInitCommands(program)
124
128
  registerMigrateCommands(program)
129
+ registerBootstrapCommands(program)
125
130
  registerInstallAppCommands(program)
126
131
  registerStatusCommands(program)
127
132
  registerAuthCommands(program)
@@ -136,6 +141,7 @@ registerSystemCommands(program)
136
141
  registerGenerateCommands(program)
137
142
  registerCreateAppCommands(program)
138
143
  registerValidateAppCommands(program)
144
+ registerValidateSchemaCommands(program)
139
145
  registerUpgradeCommands(program)
140
146
  // CIL[DOC-VECTOR type="context" content="purpose='Register all CLI commands with the program'; No verified external callers; imports: .framework/cli/env-loader.ts"]
141
147
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]