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.
- package/.env.example +13 -3
- package/.framework/cli/commands/bootstrap.ts +392 -0
- package/.framework/cli/commands/dev.ts +91 -218
- package/.framework/cli/commands/doctor.ts +132 -26
- package/.framework/cli/commands/generate.ts +38 -298
- package/.framework/cli/commands/init.ts +20 -1
- package/.framework/cli/commands/migrate.ts +36 -30
- package/.framework/cli/commands/migrations.ts +16 -56
- package/.framework/cli/commands/upgrade.ts +35 -0
- package/.framework/cli/commands/validate-schema.ts +147 -0
- package/.framework/cli/context.ts +223 -110
- package/.framework/cli/index.ts +6 -0
- package/.framework/cli/lib/project-files.ts +241 -1
- package/.framework/functions/_shared/agent-runner.ts +1000 -81
- package/.framework/functions/_shared/cil.ts +2 -1
- package/.framework/functions/_shared/db.ts +3 -6
- package/.framework/functions/_shared/hash-api-key.ts +183 -79
- package/.framework/functions/_shared/kb.ts +61 -7
- package/.framework/functions/_shared/logging.ts +562 -224
- package/.framework/functions/_shared/message-sequence.ts +53 -0
- package/.framework/functions/_shared/middleware.ts +47 -44
- package/.framework/functions/_shared/pipeline-runner.ts +150 -37
- package/.framework/functions/_shared/principal.ts +9 -6
- package/.framework/functions/_shared/trigger-engine.ts +149 -40
- package/.framework/functions/admin-data.ts +48 -31
- package/.framework/functions/ai-agents.ts +103 -33
- package/.framework/functions/api-keys.ts +301 -122
- package/.framework/functions/apps.ts +43 -26
- package/.framework/functions/cil-ingest.ts +48 -15
- package/.framework/functions/debug-auth.ts +14 -8
- package/.framework/functions/deliveries.ts +39 -12
- package/.framework/functions/embeddings.ts +145 -76
- package/.framework/functions/integration-outbound.ts +67 -27
- package/.framework/functions/integrations.ts +254 -127
- package/.framework/functions/logs.ts +273 -133
- package/.framework/functions/observability.ts +277 -147
- package/.framework/functions/pipeline-executions.ts +1 -1
- package/.framework/functions/pipeline-runner-background.ts +120 -0
- package/.framework/functions/pipelines.ts +14 -9
- package/.framework/functions/prompt-configs.ts +7 -4
- package/.framework/functions/roles.ts +8 -5
- package/.framework/functions/security.ts +30 -17
- package/.framework/functions/system-cron.ts +250 -128
- package/.framework/functions/tests.ts +7 -6
- package/.framework/functions/timers.ts +310 -107
- package/.framework/functions/trigger-scheduler.ts +65 -5
- package/.framework/functions/triggers.ts +28 -13
- package/.framework/functions/types.ts +13 -10
- package/.framework/migrations/064_episode_leases.sql +196 -0
- package/.framework/migrations/065_execution_tables_updated_at.sql +20 -0
- package/.framework/migrations/066_episode_steal_thread_merge.sql +148 -0
- package/.framework/migrations/067_episode_lease_stale_steal.sql +93 -0
- package/.framework/migrations/068_cron_schedule_timer_rpcs.sql +251 -0
- package/.framework/migrations/069_log_stats_window.sql +54 -0
- package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
- package/.framework/migrations/071_timer_interval_keys.sql +96 -0
- package/.framework/migrations/072_slug_autofill.sql +77 -0
- package/.framework/migrations/073_seed_member_roles.sql +26 -0
- package/.framework/schemas/spine.config.schema.json +62 -0
- package/.framework/src/App.tsx +3 -1
- package/.framework/src/apps/admin/index.tsx +1141 -775
- package/.framework/src/components/ErrorBoundary.tsx +136 -0
- package/.framework/src/components/admin/AdminListPage.tsx +81 -73
- package/.framework/src/components/admin/AdminSidebar.tsx +92 -81
- package/.framework/src/components/admin/EntitySelect.tsx +181 -0
- package/.framework/src/components/admin/PageInstructions.tsx +86 -127
- package/.framework/src/components/app-shell/GenericAppShell.tsx +3 -1
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
- package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
- package/.framework/src/components/auth/TurnstileWidget.tsx +9 -6
- package/.framework/src/components/kb/KBArticleEditor.tsx +49 -6
- package/.framework/src/components/layout/Layout.tsx +4 -2
- package/.framework/src/components/layout/Sidebar.tsx +304 -179
- package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
- package/.framework/src/components/runtime/DataHeader.tsx +96 -48
- package/.framework/src/components/runtime/DataListPage.tsx +3 -26
- package/.framework/src/components/runtime/DataStats.tsx +10 -10
- package/.framework/src/components/runtime/DataTable.tsx +12 -10
- package/.framework/src/components/ui/sheet.tsx +24 -26
- package/.framework/src/components/ui/textarea.tsx +74 -48
- package/.framework/src/hooks/useBranding.ts +47 -0
- package/.framework/src/hooks/useEntityList.ts +12 -9
- package/.framework/src/hooks/useListSchema.ts +108 -58
- package/.framework/src/instructions/README.md +57 -0
- package/.framework/src/instructions/ai-agents.md +69 -0
- package/.framework/src/instructions/alerts.md +80 -0
- package/.framework/src/instructions/api-keys.md +87 -0
- package/.framework/src/instructions/apps.md +77 -0
- package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
- package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
- package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
- package/.framework/src/instructions/concepts/automation.md +186 -0
- package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
- package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
- package/.framework/src/instructions/concepts/design-schema.md +152 -0
- package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
- package/.framework/src/instructions/concepts/observability.md +116 -0
- package/.framework/src/instructions/concepts/permissions.md +150 -0
- package/.framework/src/instructions/concepts/runtime-records.md +111 -0
- package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
- package/.framework/src/instructions/concepts/spine-way.md +172 -0
- package/.framework/src/instructions/deliveries.md +59 -0
- package/.framework/src/instructions/guide/00-orientation.md +106 -0
- package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
- package/.framework/src/instructions/guide/02-project-map.md +147 -0
- package/.framework/src/instructions/guide/03-domain-model.md +223 -0
- package/.framework/src/instructions/guide/04-first-app.md +227 -0
- package/.framework/src/instructions/guide/05-glossary.md +183 -0
- package/.framework/src/instructions/integrations.md +96 -0
- package/.framework/src/instructions/internal/cil-markers.md +83 -0
- package/.framework/src/instructions/invites.md +60 -0
- package/.framework/src/instructions/kb.md +80 -0
- package/.framework/src/instructions/logs.md +77 -0
- package/.framework/src/instructions/observability.md +61 -0
- package/.framework/src/instructions/operations/deployment.md +115 -0
- package/.framework/src/instructions/operations/migrations.md +125 -0
- package/.framework/src/instructions/operations/security-checklist.md +148 -0
- package/.framework/src/instructions/operations/troubleshooting.md +170 -0
- package/.framework/src/instructions/operations/upgrade.md +116 -0
- package/.framework/src/instructions/pipeline-executions.md +62 -0
- package/.framework/src/instructions/pipelines.md +78 -0
- package/.framework/src/instructions/prompts.md +95 -0
- package/.framework/src/instructions/reference/api/admin-data.md +162 -0
- package/.framework/src/instructions/reference/api/auth.md +113 -0
- package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
- package/.framework/src/instructions/reference/app-manifest.md +150 -0
- package/.framework/src/instructions/reference/cli.md +124 -0
- package/.framework/src/instructions/reference/database.md +132 -0
- package/.framework/src/instructions/reference/design-schema.md +280 -0
- package/.framework/src/instructions/reference/env-vars.md +133 -0
- package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
- package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
- package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
- package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
- package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
- package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
- package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
- package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
- package/.framework/src/instructions/reference/functions/apps.md +140 -0
- package/.framework/src/instructions/reference/functions/auth.md +99 -0
- package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
- package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
- package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
- package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
- package/.framework/src/instructions/reference/functions/index.md +103 -0
- package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
- package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
- package/.framework/src/instructions/reference/functions/integrations.md +130 -0
- package/.framework/src/instructions/reference/functions/invites.md +182 -0
- package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
- package/.framework/src/instructions/reference/functions/kb.md +166 -0
- package/.framework/src/instructions/reference/functions/logs.md +141 -0
- package/.framework/src/instructions/reference/functions/observability.md +105 -0
- package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
- package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
- package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
- package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
- package/.framework/src/instructions/reference/functions/roles.md +121 -0
- package/.framework/src/instructions/reference/functions/security.md +140 -0
- package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
- package/.framework/src/instructions/reference/functions/system.md +106 -0
- package/.framework/src/instructions/reference/functions/tests.md +97 -0
- package/.framework/src/instructions/reference/functions/timers.md +117 -0
- package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
- package/.framework/src/instructions/reference/functions/triggers.md +140 -0
- package/.framework/src/instructions/reference/functions/types.md +146 -0
- package/.framework/src/instructions/reference/seeds.md +126 -0
- package/.framework/src/instructions/reference/shared-modules.md +127 -0
- package/.framework/src/instructions/reference/spine-config.md +114 -0
- package/.framework/src/instructions/roles.md +80 -0
- package/.framework/src/instructions/runtime-detail.md +70 -0
- package/.framework/src/instructions/runtime-list.md +77 -0
- package/.framework/src/instructions/security.md +67 -0
- package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
- package/.framework/src/instructions/tasks/add-a-role.md +96 -0
- package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
- package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
- package/.framework/src/instructions/tasks/add-a-type.md +151 -0
- package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
- package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
- package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
- package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
- package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
- package/.framework/src/instructions/tasks/test-your-code.md +108 -0
- package/.framework/src/instructions/tasks/write-a-function.md +132 -0
- package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
- package/.framework/src/instructions/testing.md +59 -0
- package/.framework/src/instructions/timers.md +82 -0
- package/.framework/src/instructions/triggers.md +69 -0
- package/.framework/src/instructions/types.md +93 -0
- package/.framework/src/lib/branding.ts +128 -0
- package/.framework/src/pages/NoAppPage.tsx +3 -1
- package/.framework/src/pages/NotFoundPage.tsx +62 -31
- package/.framework/src/pages/SetupPage.tsx +5 -2
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
- package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
- package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
- package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
- package/.framework/src/pages/admin/AppsPage.tsx +104 -66
- package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
- package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
- package/.framework/src/pages/admin/LogsPage.tsx +144 -76
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
- package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
- package/.framework/src/pages/admin/RolesPage.tsx +86 -43
- package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
- package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
- package/.framework/src/pages/admin/TimersPage.tsx +90 -62
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
- package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
- package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
- package/.framework/src/pages/admin/TypesPage.tsx +90 -48
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +3 -1
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +3 -1
- package/.framework/src/pages/auth/LoginPage.tsx +4 -2
- package/.framework/src/pages/auth/RegisterPage.tsx +3 -1
- package/.framework/templates/agent/AGENTS.md +150 -0
- package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
- package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
- package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
- package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
- package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
- package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
- package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
- package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
- package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
- package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
- package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
- package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
- package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
- package/.framework/templates/project.json +5 -1
- package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
- package/.framework/tests/unit/agent-files.test.ts +355 -0
- package/.framework/tests/unit/agent-runner.test.ts +496 -47
- package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
- package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
- package/.framework/tests/unit/bootstrap.test.ts +242 -0
- package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
- package/.framework/tests/unit/debug-auth.test.ts +38 -0
- package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
- package/.framework/tests/unit/episode-lease.test.ts +695 -0
- package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
- package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +19 -0
- package/.framework/tests/unit/logging-app-id.test.ts +75 -0
- package/.framework/tests/unit/pipeline-runner-background.test.ts +120 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +153 -1
- package/.framework/tests/unit/principal-cache.test.ts +15 -0
- package/.framework/tests/unit/system-context-denial.test.ts +145 -0
- package/.framework/tests/unit/system-cron.test.ts +240 -0
- package/.framework/tests/unit/timers.test.ts +159 -0
- package/.framework/tests/unit/trigger-engine.test.ts +278 -91
- package/.framework/tests/unit/trigger-scheduler.test.ts +78 -0
- package/README.md +125 -166
- package/config/tsconfig.cli.json +2 -2
- package/netlify.toml +5 -0
- package/package.json +15 -4
- package/templates/project/package-lock.json +2 -2
- package/.framework/docs/admin-routes.md +0 -76
- package/.framework/docs/api-docs-progress.md +0 -38
- package/.framework/docs/api-governance.md +0 -146
- package/.framework/docs/api-testing-results.md +0 -212
- package/.framework/docs/assembly-launch-guide.md +0 -138
- package/.framework/docs/audit-results.md +0 -590
- package/.framework/docs/db-api-inventory.md +0 -95
- package/.framework/docs/gap-remediation-backlog.md +0 -103
- package/.framework/docs/ui-adoption-verification.md +0 -111
- package/.framework/docs/ui-api-coverage.md +0 -84
- package/.framework/docs/v2-compatibility-audit.md +0 -228
- package/.framework/mcp/index.ts +0 -133
- package/.framework/mcp/load-env.ts +0 -60
- package/.framework/mcp/shared/app-manifest.ts +0 -275
- package/.framework/mcp/shared/db.ts +0 -477
- package/.framework/mcp/shared/kb.ts +0 -118
- package/.framework/mcp/tools/architect.ts +0 -431
- package/.framework/mcp/tools/cil/context.ts +0 -345
- package/.framework/mcp/tools/cil/graph.ts +0 -242
- package/.framework/mcp/tools/cil/ingest.ts +0 -1217
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
- package/.framework/mcp/tools/cil/pipeline.ts +0 -767
- package/.framework/mcp/tools/cil/project.ts +0 -791
- package/.framework/mcp/tools/cil/retrieval.ts +0 -336
- package/.framework/mcp/tools/cil/search-core.ts +0 -454
- package/.framework/mcp/tools/cil/search.ts +0 -97
- package/.framework/mcp/tools/cil/suggest.ts +0 -186
- package/.framework/mcp/tools/cil/validate.ts +0 -1369
- package/.framework/mcp/tools/kb/delete.ts +0 -139
- package/.framework/mcp/tools/kb/index.ts +0 -52
- package/.framework/mcp/tools/kb/ingest.ts +0 -84
- package/.framework/mcp/tools/kb/list-types.ts +0 -102
- package/.framework/mcp/tools/kb/publish.ts +0 -100
- package/.framework/mcp/tools/kb/reindex.ts +0 -86
- package/.framework/mcp/tools/kb/revoke.ts +0 -85
- package/.framework/mcp/tools/kb/search.ts +0 -101
- package/.framework/mcp/tools/kb/upsert.ts +0 -125
- 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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
|
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,
|
|
135
|
-
.eq('
|
|
207
|
+
.select('id, account_id, scopes, key_hash, expires_at')
|
|
208
|
+
.eq('key_prefix', keyPrefix)
|
|
136
209
|
.eq('is_active', true)
|
|
137
|
-
.
|
|
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.
|
|
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
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
+
|
package/.framework/cli/index.ts
CHANGED
|
@@ -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"]
|