spine-framework 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.framework/README.md +129 -0
- package/.framework/cli/bin.cjs +14 -0
- package/.framework/cli/commands/agents.ts +153 -0
- package/.framework/cli/commands/auth.ts +94 -0
- package/.framework/cli/commands/create-app.ts +185 -0
- package/.framework/cli/commands/dev.ts +295 -0
- package/.framework/cli/commands/doctor.ts +442 -0
- package/.framework/cli/commands/generate.ts +332 -0
- package/.framework/cli/commands/init.ts +272 -0
- package/.framework/cli/commands/install-app.ts +391 -0
- package/.framework/cli/commands/items.ts +253 -0
- package/.framework/cli/commands/migrations.ts +141 -0
- package/.framework/cli/commands/pipelines.ts +166 -0
- package/.framework/cli/commands/status.ts +197 -0
- package/.framework/cli/commands/system.ts +184 -0
- package/.framework/cli/commands/test.ts +227 -0
- package/.framework/cli/commands/uninstall-app.ts +166 -0
- package/.framework/cli/context.ts +268 -0
- package/.framework/cli/env-loader.ts +36 -0
- package/.framework/cli/index.ts +106 -0
- package/.framework/cli/welcome.cjs +45 -0
- package/.framework/docs/API.md +384 -0
- package/.framework/docs/STABILITY.md +52 -0
- package/.framework/docs/admin-routes.md +76 -0
- package/.framework/docs/api-docs-progress.md +38 -0
- package/.framework/docs/api-governance.md +146 -0
- package/.framework/docs/api-testing-results.md +212 -0
- package/.framework/docs/apis/admin-configs.md +567 -0
- package/.framework/docs/apis/admin-data.md +272 -0
- package/.framework/docs/apis/index.md +231 -0
- package/.framework/docs/apis/internal.md +295 -0
- package/.framework/docs/apis/runtime.md +537 -0
- package/.framework/docs/assembly-launch-guide.md +138 -0
- package/.framework/docs/audit-results.md +590 -0
- package/.framework/docs/authorization-model.md +170 -0
- package/.framework/docs/db-api-inventory.md +95 -0
- package/.framework/docs/examples/custom-app/README.md +77 -0
- package/.framework/docs/examples/custom-function/README.md +27 -0
- package/.framework/docs/examples/custom-function/handler.ts +48 -0
- package/.framework/docs/examples/custom-webhook/README.md +68 -0
- package/.framework/docs/gap-remediation-backlog.md +103 -0
- package/.framework/docs/guides/cli-guide.md +224 -0
- package/.framework/docs/guides/getting-started.md +103 -0
- package/.framework/docs/guides/import-guide.md +193 -0
- package/.framework/docs/guides/testing-guide.md +229 -0
- package/.framework/docs/permission-examples.md +326 -0
- package/.framework/docs/ui-adoption-verification.md +111 -0
- package/.framework/docs/ui-api-coverage.md +84 -0
- package/.framework/docs/v2-compatibility-audit.md +228 -0
- package/.framework/functions/.gitkeep +1 -0
- package/.framework/functions/_shared/agent-runner.ts +1097 -0
- package/.framework/functions/_shared/app-manifest.ts +184 -0
- package/.framework/functions/_shared/audit.ts +150 -0
- package/.framework/functions/_shared/db.ts +174 -0
- package/.framework/functions/_shared/index.ts +382 -0
- package/.framework/functions/_shared/middleware.ts +490 -0
- package/.framework/functions/_shared/permissions.ts +1325 -0
- package/.framework/functions/_shared/pipeline-runner.ts +731 -0
- package/.framework/functions/_shared/principal.ts +760 -0
- package/.framework/functions/_shared/schema-utils.ts +967 -0
- package/.framework/functions/_shared/testing.ts +258 -0
- package/.framework/functions/_shared/trigger-engine.ts +425 -0
- package/.framework/functions/_shared/webhook-registration.ts +168 -0
- package/.framework/functions/_shared/webhook-registry.ts +129 -0
- package/.framework/functions/account-nodes.ts +111 -0
- package/.framework/functions/admin-data.ts +606 -0
- package/.framework/functions/ai-agents.ts +323 -0
- package/.framework/functions/api-keys.ts +376 -0
- package/.framework/functions/apps.ts +483 -0
- package/.framework/functions/auth.ts +196 -0
- package/.framework/functions/debug-auth.ts +107 -0
- package/.framework/functions/embeddings.ts +556 -0
- package/.framework/functions/integration-routes.ts +523 -0
- package/.framework/functions/integrations.ts +319 -0
- package/.framework/functions/item-progress.ts +272 -0
- package/.framework/functions/logs.ts +438 -0
- package/.framework/functions/observability.ts +275 -0
- package/.framework/functions/pipeline-executions.ts +494 -0
- package/.framework/functions/pipelines.ts +485 -0
- package/.framework/functions/prompt-configs.ts +339 -0
- package/.framework/functions/roles.ts +387 -0
- package/.framework/functions/system-cron.ts +742 -0
- package/.framework/functions/system.ts +323 -0
- package/.framework/functions/tests.ts +119 -0
- package/.framework/functions/timers.ts +357 -0
- package/.framework/functions/triggers.ts +563 -0
- package/.framework/functions/types.ts +604 -0
- package/.framework/migrations/000_foundation.sql +1256 -0
- package/.framework/migrations/001_seed.sql +92 -0
- package/.framework/migrations/002_seed_constraints.sql +13 -0
- package/.framework/migrations/003_auth_user_trigger.sql +59 -0
- package/.framework/src/App.tsx +126 -0
- package/.framework/src/apps/admin/index.tsx +173 -0
- package/.framework/src/components/AppWrapper.tsx +56 -0
- package/.framework/src/components/CustomAppLoader.tsx +116 -0
- package/.framework/src/components/admin/AdminListPage.tsx +151 -0
- package/.framework/src/components/admin/AdminSidebar.tsx +166 -0
- package/.framework/src/components/admin/AdminStatsCard.tsx +62 -0
- package/.framework/src/components/admin/SortableTableHeader.tsx +42 -0
- package/.framework/src/components/app-shell/GenericAppShell.tsx +181 -0
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +200 -0
- package/.framework/src/components/app-shell/GenericListPage.tsx +116 -0
- package/.framework/src/components/app-sidebar.tsx +228 -0
- package/.framework/src/components/auth/ProtectedRoute.tsx +88 -0
- package/.framework/src/components/layout/AppShell.tsx +91 -0
- package/.framework/src/components/layout/Header.tsx +88 -0
- package/.framework/src/components/layout/Layout.tsx +95 -0
- package/.framework/src/components/layout/Sidebar.tsx +329 -0
- package/.framework/src/components/runtime/DataDetailHeader.tsx +77 -0
- package/.framework/src/components/runtime/DataDetailPage.tsx +171 -0
- package/.framework/src/components/runtime/DataFilters.tsx +91 -0
- package/.framework/src/components/runtime/DataHeader.tsx +68 -0
- package/.framework/src/components/runtime/DataListPage.tsx +124 -0
- package/.framework/src/components/runtime/DataStats.tsx +70 -0
- package/.framework/src/components/runtime/DataTable.tsx +174 -0
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +134 -0
- package/.framework/src/components/runtime/index.ts +18 -0
- package/.framework/src/components/search-form.tsx +29 -0
- package/.framework/src/components/shared/AgentView.tsx +213 -0
- package/.framework/src/components/shared/FieldRenderer.tsx +478 -0
- package/.framework/src/components/shared/SchemaFields.tsx +226 -0
- package/.framework/src/components/ui/DataTable.tsx +343 -0
- package/.framework/src/components/ui/Form.tsx +281 -0
- package/.framework/src/components/ui/ItemCard.tsx +296 -0
- package/.framework/src/components/ui/ItemListView.tsx +308 -0
- package/.framework/src/components/ui/LoadingSpinner.tsx +52 -0
- package/.framework/src/components/ui/Modal.tsx +61 -0
- package/.framework/src/components/ui/RichTextEditor.tsx +210 -0
- package/.framework/src/components/ui/accordion.tsx +82 -0
- package/.framework/src/components/ui/alert-dialog.tsx +197 -0
- package/.framework/src/components/ui/alert.tsx +76 -0
- package/.framework/src/components/ui/aspect-ratio.tsx +11 -0
- package/.framework/src/components/ui/avatar.tsx +110 -0
- package/.framework/src/components/ui/badge.tsx +49 -0
- package/.framework/src/components/ui/breadcrumb.tsx +122 -0
- package/.framework/src/components/ui/button-group.tsx +83 -0
- package/.framework/src/components/ui/button.tsx +65 -0
- package/.framework/src/components/ui/calendar.tsx +222 -0
- package/.framework/src/components/ui/card.tsx +100 -0
- package/.framework/src/components/ui/carousel.tsx +240 -0
- package/.framework/src/components/ui/chart.tsx +373 -0
- package/.framework/src/components/ui/checkbox.tsx +31 -0
- package/.framework/src/components/ui/collapsible.tsx +33 -0
- package/.framework/src/components/ui/combobox.tsx +299 -0
- package/.framework/src/components/ui/command.tsx +193 -0
- package/.framework/src/components/ui/context-menu.tsx +261 -0
- package/.framework/src/components/ui/dialog.tsx +165 -0
- package/.framework/src/components/ui/direction.tsx +22 -0
- package/.framework/src/components/ui/drawer.tsx +132 -0
- package/.framework/src/components/ui/dropdown-menu.tsx +269 -0
- package/.framework/src/components/ui/empty.tsx +104 -0
- package/.framework/src/components/ui/field.tsx +238 -0
- package/.framework/src/components/ui/hover-card.tsx +42 -0
- package/.framework/src/components/ui/input-group.tsx +153 -0
- package/.framework/src/components/ui/input-otp.tsx +87 -0
- package/.framework/src/components/ui/input.tsx +19 -0
- package/.framework/src/components/ui/item.tsx +196 -0
- package/.framework/src/components/ui/kbd.tsx +26 -0
- package/.framework/src/components/ui/label.tsx +22 -0
- package/.framework/src/components/ui/menubar.tsx +277 -0
- package/.framework/src/components/ui/native-select.tsx +61 -0
- package/.framework/src/components/ui/navigation-menu.tsx +164 -0
- package/.framework/src/components/ui/pagination.tsx +129 -0
- package/.framework/src/components/ui/popover.tsx +87 -0
- package/.framework/src/components/ui/progress.tsx +31 -0
- package/.framework/src/components/ui/radio-group.tsx +42 -0
- package/.framework/src/components/ui/resizable.tsx +50 -0
- package/.framework/src/components/ui/scroll-area.tsx +53 -0
- package/.framework/src/components/ui/select.tsx +195 -0
- package/.framework/src/components/ui/separator.tsx +26 -0
- package/.framework/src/components/ui/sheet.tsx +145 -0
- package/.framework/src/components/ui/sidebar.tsx +706 -0
- package/.framework/src/components/ui/skeleton.tsx +13 -0
- package/.framework/src/components/ui/slider.tsx +59 -0
- package/.framework/src/components/ui/sonner.tsx +47 -0
- package/.framework/src/components/ui/spinner.tsx +10 -0
- package/.framework/src/components/ui/switch.tsx +33 -0
- package/.framework/src/components/ui/table-primitives.tsx +141 -0
- package/.framework/src/components/ui/table.tsx +114 -0
- package/.framework/src/components/ui/tabs.tsx +90 -0
- package/.framework/src/components/ui/textarea.tsx +18 -0
- package/.framework/src/components/ui/toggle-group.tsx +89 -0
- package/.framework/src/components/ui/toggle.tsx +45 -0
- package/.framework/src/components/ui/tooltip.tsx +57 -0
- package/.framework/src/contexts/AppContext.tsx +133 -0
- package/.framework/src/contexts/AuthContext.tsx +371 -0
- package/.framework/src/hooks/use-mobile.ts +19 -0
- package/.framework/src/hooks/useApi.ts +526 -0
- package/.framework/src/hooks/useApps.ts +114 -0
- package/.framework/src/hooks/useEntityList.ts +190 -0
- package/.framework/src/hooks/useEntityRecord.ts +308 -0
- package/.framework/src/hooks/useForm.ts +307 -0
- package/.framework/src/hooks/useListSchema.ts +264 -0
- package/.framework/src/hooks/useSchemaRecord.ts +223 -0
- package/.framework/src/index.css +128 -0
- package/.framework/src/lib/api.ts +156 -0
- package/.framework/src/lib/supabase.ts +94 -0
- package/.framework/src/lib/utils.ts +317 -0
- package/.framework/src/main.tsx +27 -0
- package/.framework/src/pages/DashboardPage.tsx +181 -0
- package/.framework/src/pages/NotFoundPage.tsx +39 -0
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +161 -0
- package/.framework/src/pages/admin/AIAgentsPage.tsx +318 -0
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +199 -0
- package/.framework/src/pages/admin/APIKeysPage.tsx +303 -0
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +523 -0
- package/.framework/src/pages/admin/AppDetailPage.tsx +493 -0
- package/.framework/src/pages/admin/AppsPage.tsx +355 -0
- package/.framework/src/pages/admin/DesignedPage.tsx +491 -0
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +534 -0
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +424 -0
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +176 -0
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +109 -0
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +402 -0
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +187 -0
- package/.framework/src/pages/admin/IntegrationsPage.tsx +301 -0
- package/.framework/src/pages/admin/LogsPage.tsx +283 -0
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +85 -0
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +470 -0
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +183 -0
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +279 -0
- package/.framework/src/pages/admin/PipelinesPage.tsx +390 -0
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +299 -0
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +292 -0
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +434 -0
- package/.framework/src/pages/admin/RoleDetailPage.tsx +273 -0
- package/.framework/src/pages/admin/RolesPage.tsx +292 -0
- package/.framework/src/pages/admin/SelectTestPage.tsx +61 -0
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +588 -0
- package/.framework/src/pages/admin/SimpleDashboard.tsx +387 -0
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +172 -0
- package/.framework/src/pages/admin/TestingDashboard.tsx +257 -0
- package/.framework/src/pages/admin/TimerDetailPage.tsx +151 -0
- package/.framework/src/pages/admin/TimersPage.tsx +376 -0
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +149 -0
- package/.framework/src/pages/admin/TriggersPage.tsx +381 -0
- package/.framework/src/pages/admin/TypeDetailPage.tsx +694 -0
- package/.framework/src/pages/admin/TypesPage.tsx +295 -0
- package/.framework/src/pages/auth/LoginPage.tsx +188 -0
- package/.framework/src/pages/auth/RegisterPage.tsx +163 -0
- package/.framework/src/pages/spine-framework/APIPage.tsx +17 -0
- package/.framework/src/pages/spine-framework/CLIPage.tsx +25 -0
- package/.framework/src/types/auth.ts +125 -0
- package/.framework/src/types/types.ts +407 -0
- package/STRUCTURE.md +150 -0
- package/config/components.json +25 -0
- package/config/deno.lock +108 -0
- package/config/package-lock.json +17183 -0
- package/config/postcss.config.cjs +10 -0
- package/config/tailwind.config.cjs +78 -0
- package/config/tsconfig.build.json +32 -0
- package/config/tsconfig.cli.json +18 -0
- package/config/tsconfig.json +41 -0
- package/config/tsconfig.node.json +17 -0
- package/config/tsconfig.node.tsbuildinfo +1 -0
- package/config/tsconfig.tsbuildinfo +1 -0
- package/config/typedoc.json +16 -0
- package/config/vite.config.d.ts +2 -0
- package/config/vite.config.ts +72 -0
- package/dist/cli/commands/agents.d.ts +39 -0
- package/dist/cli/commands/agents.d.ts.map +1 -0
- package/dist/cli/commands/auth.d.ts +36 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/create-app.d.ts +23 -0
- package/dist/cli/commands/create-app.d.ts.map +1 -0
- package/dist/cli/commands/dev.d.ts +39 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/doctor.d.ts +42 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/generate.d.ts +36 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/init.d.ts +30 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/install-app.d.ts +30 -0
- package/dist/cli/commands/install-app.d.ts.map +1 -0
- package/dist/cli/commands/items.d.ts +45 -0
- package/dist/cli/commands/items.d.ts.map +1 -0
- package/dist/cli/commands/migrations.d.ts +41 -0
- package/dist/cli/commands/migrations.d.ts.map +1 -0
- package/dist/cli/commands/pipelines.d.ts +40 -0
- package/dist/cli/commands/pipelines.d.ts.map +1 -0
- package/dist/cli/commands/status.d.ts +23 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/system.d.ts +29 -0
- package/dist/cli/commands/system.d.ts.map +1 -0
- package/dist/cli/commands/test.d.ts +46 -0
- package/dist/cli/commands/test.d.ts.map +1 -0
- package/dist/cli/commands/uninstall-app.d.ts +23 -0
- package/dist/cli/commands/uninstall-app.d.ts.map +1 -0
- package/dist/cli/context.d.ts +88 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/env-loader.d.ts +14 -0
- package/dist/cli/env-loader.d.ts.map +1 -0
- package/dist/cli/index.d.ts +41 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/functions/_shared/agent-runner.d.ts +156 -0
- package/dist/functions/_shared/agent-runner.d.ts.map +1 -0
- package/dist/functions/_shared/app-manifest.d.ts +68 -0
- package/dist/functions/_shared/app-manifest.d.ts.map +1 -0
- package/dist/functions/_shared/audit.d.ts +91 -0
- package/dist/functions/_shared/audit.d.ts.map +1 -0
- package/dist/functions/_shared/db.d.ts +125 -0
- package/dist/functions/_shared/db.d.ts.map +1 -0
- package/dist/functions/_shared/index.d.ts +298 -0
- package/dist/functions/_shared/index.d.ts.map +1 -0
- package/dist/functions/_shared/middleware.d.ts +315 -0
- package/dist/functions/_shared/middleware.d.ts.map +1 -0
- package/dist/functions/_shared/permissions.d.ts +626 -0
- package/dist/functions/_shared/permissions.d.ts.map +1 -0
- package/dist/functions/_shared/pipeline-runner.d.ts +124 -0
- package/dist/functions/_shared/pipeline-runner.d.ts.map +1 -0
- package/dist/functions/_shared/principal.d.ts +284 -0
- package/dist/functions/_shared/principal.d.ts.map +1 -0
- package/dist/functions/_shared/schema-utils.d.ts +181 -0
- package/dist/functions/_shared/schema-utils.d.ts.map +1 -0
- package/dist/functions/_shared/testing.d.ts +172 -0
- package/dist/functions/_shared/testing.d.ts.map +1 -0
- package/dist/functions/_shared/trigger-engine.d.ts +140 -0
- package/dist/functions/_shared/trigger-engine.d.ts.map +1 -0
- package/dist/functions/_shared/webhook-registration.d.ts +81 -0
- package/dist/functions/_shared/webhook-registration.d.ts.map +1 -0
- package/dist/functions/_shared/webhook-registry.d.ts +57 -0
- package/dist/functions/_shared/webhook-registry.d.ts.map +1 -0
- package/dist/functions/account-nodes.d.ts +48 -0
- package/dist/functions/account-nodes.d.ts.map +1 -0
- package/dist/functions/admin-data.d.ts +178 -0
- package/dist/functions/admin-data.d.ts.map +1 -0
- package/dist/functions/ai-agents.d.ts +125 -0
- package/dist/functions/ai-agents.d.ts.map +1 -0
- package/dist/functions/api-keys.d.ts +140 -0
- package/dist/functions/api-keys.d.ts.map +1 -0
- package/dist/functions/apps.d.ts +163 -0
- package/dist/functions/apps.d.ts.map +1 -0
- package/dist/functions/auth.d.ts +74 -0
- package/dist/functions/auth.d.ts.map +1 -0
- package/dist/functions/debug-auth.d.ts +33 -0
- package/dist/functions/debug-auth.d.ts.map +1 -0
- package/dist/functions/embeddings.d.ts +205 -0
- package/dist/functions/embeddings.d.ts.map +1 -0
- package/dist/functions/integration-routes.d.ts +45 -0
- package/dist/functions/integration-routes.d.ts.map +1 -0
- package/dist/functions/integrations.d.ts +124 -0
- package/dist/functions/integrations.d.ts.map +1 -0
- package/dist/functions/item-progress.d.ts +41 -0
- package/dist/functions/item-progress.d.ts.map +1 -0
- package/dist/functions/logs.d.ts +162 -0
- package/dist/functions/logs.d.ts.map +1 -0
- package/dist/functions/observability.d.ts +123 -0
- package/dist/functions/observability.d.ts.map +1 -0
- package/dist/functions/pipeline-executions.d.ts +190 -0
- package/dist/functions/pipeline-executions.d.ts.map +1 -0
- package/dist/functions/pipelines.d.ts +171 -0
- package/dist/functions/pipelines.d.ts.map +1 -0
- package/dist/functions/prompt-configs.d.ts +125 -0
- package/dist/functions/prompt-configs.d.ts.map +1 -0
- package/dist/functions/roles.d.ts +118 -0
- package/dist/functions/roles.d.ts.map +1 -0
- package/dist/functions/system-cron.d.ts +65 -0
- package/dist/functions/system-cron.d.ts.map +1 -0
- package/dist/functions/system.d.ts +29 -0
- package/dist/functions/system.d.ts.map +1 -0
- package/dist/functions/tests.d.ts +28 -0
- package/dist/functions/tests.d.ts.map +1 -0
- package/dist/functions/timers.d.ts +139 -0
- package/dist/functions/timers.d.ts.map +1 -0
- package/dist/functions/triggers.d.ts +203 -0
- package/dist/functions/triggers.d.ts.map +1 -0
- package/dist/functions/types.d.ts +151 -0
- package/dist/functions/types.d.ts.map +1 -0
- package/dist/src/types/types.d.ts +364 -0
- package/dist/src/types/types.d.ts.map +1 -0
- package/package.json +192 -0
- package/scripts/app-install-cli.ts +286 -0
- package/scripts/assemble-frontend.sh +79 -0
- package/scripts/assemble-functions.sh +62 -0
- package/scripts/assemble.sh +35 -0
- package/scripts/boundary-check.sh +106 -0
- package/scripts/build-manifest.sh +80 -0
- package/scripts/check-core-integrity.sh +82 -0
- package/scripts/ingest-chunks.cjs +202 -0
- package/scripts/kb-chunk-parser.cjs +312 -0
- package/scripts/kb-chunk-parser.ts +330 -0
- package/scripts/load-test-app-install.ts +484 -0
- package/scripts/netlify-dev-wrapper.sh +22 -0
- package/scripts/verify-integrity.sh +69 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module scripts/app-install-cli
|
|
5
|
+
* @audience installer
|
|
6
|
+
* @layer cli
|
|
7
|
+
* @stability orphaned
|
|
8
|
+
*
|
|
9
|
+
* Spine App Installation CLI - Validates and executes app installation instruction files.
|
|
10
|
+
* **ORPHANED**: References non-existent schema and template files at `../docs/app-installation/`.
|
|
11
|
+
*
|
|
12
|
+
* **Intended Purpose**: Validate YAML instruction files against JSON schema and execute
|
|
13
|
+
* multi-step app installations (pack installation, app creation, migrations, verification).
|
|
14
|
+
*
|
|
15
|
+
* **Current State**: Cannot function - missing required schema.json and template files.
|
|
16
|
+
*
|
|
17
|
+
* **Dependencies**: commander, js-yaml, ajv for CLI operations and validation.
|
|
18
|
+
*
|
|
19
|
+
* @tags orphaned, cli, app-installation, validation
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { readFileSync, existsSync, writeFileSync } from 'fs'
|
|
23
|
+
import { resolve, dirname } from 'path'
|
|
24
|
+
import { program } from 'commander'
|
|
25
|
+
import yaml from 'js-yaml'
|
|
26
|
+
import Ajv from 'ajv'
|
|
27
|
+
import { fileURLToPath } from 'url'
|
|
28
|
+
|
|
29
|
+
// Fix __dirname for ES modules
|
|
30
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
31
|
+
const __dirname = dirname(__filename)
|
|
32
|
+
|
|
33
|
+
// Load JSON schema
|
|
34
|
+
const schemaPath = resolve(__dirname, '../docs/app-installation/schema.json')
|
|
35
|
+
const schema = JSON.parse(readFileSync(schemaPath, 'utf8'))
|
|
36
|
+
|
|
37
|
+
const ajv = new Ajv()
|
|
38
|
+
const validate = ajv.compile(schema)
|
|
39
|
+
|
|
40
|
+
interface InstallationContext {
|
|
41
|
+
TARGET_ACCOUNT_ID?: string
|
|
42
|
+
PACK_INSTALLATION_ID?: string
|
|
43
|
+
[key: string]: string | undefined
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ─── CHUNK_START: APP_INSTALL_CLI_SUBSTITUTE_VARIABLES ──────────────────────────────────────────────
|
|
47
|
+
/**
|
|
48
|
+
* @chunk-id APP_INSTALL_CLI_SUBSTITUTE_VARIABLES_1_0_0
|
|
49
|
+
* @version 1.0.0
|
|
50
|
+
* @hash 122ca9e63f2310e8a01f76dc9c962319d8e267d8737c39895425440489a747bd
|
|
51
|
+
* @macro Variable Substitution Engine
|
|
52
|
+
* @micro Recursively replaces ${VAR} placeholders with context values
|
|
53
|
+
* @inputs obj: any — Object containing ${VAR} placeholders
|
|
54
|
+
* @inputs context: InstallationContext — Variable name to value mapping
|
|
55
|
+
* @outputs any — Object with all placeholders substituted
|
|
56
|
+
* @depends-on [none]
|
|
57
|
+
* @depended-by [validateInstructionFile, executeInstallation]
|
|
58
|
+
* @side-effects [none]
|
|
59
|
+
* @tags orphaned, variable-substitution, template-engine
|
|
60
|
+
*/
|
|
61
|
+
function substituteVariables(obj: any, context: InstallationContext): any {
|
|
62
|
+
if (typeof obj === 'string') {
|
|
63
|
+
return obj.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
64
|
+
return context[varName] || match
|
|
65
|
+
})
|
|
66
|
+
} else if (Array.isArray(obj)) {
|
|
67
|
+
return obj.map(item => substituteVariables(item, context))
|
|
68
|
+
} else if (obj && typeof obj === 'object') {
|
|
69
|
+
const result: any = {}
|
|
70
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
71
|
+
result[key] = substituteVariables(value, context)
|
|
72
|
+
}
|
|
73
|
+
return result
|
|
74
|
+
}
|
|
75
|
+
return obj
|
|
76
|
+
}
|
|
77
|
+
// ─── CHUNK_END: APP_INSTALL_CLI_SUBSTITUTE_VARIABLES ────────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
// ─── CHUNK_START: APP_INSTALL_CLI_VALIDATE_INSTRUCTION_FILE ──────────────────────────────────────────────
|
|
80
|
+
/**
|
|
81
|
+
* @chunk-id APP_INSTALL_CLI_VALIDATE_INSTRUCTION_FILE_1_0_0
|
|
82
|
+
* @version 1.0.0
|
|
83
|
+
* @hash c673609fd3442632d832e0c4c3ef2dbda0a51e381bb469e55b7e2cc59005b5e2
|
|
84
|
+
* @macro Installation File Validation
|
|
85
|
+
* @micro Validates YAML instruction files against JSON schema
|
|
86
|
+
* @inputs filePath: string — Path to YAML instruction file
|
|
87
|
+
* @outputs boolean — true if valid, false otherwise
|
|
88
|
+
* @depends-on [schema, validate, substituteVariables]
|
|
89
|
+
* @depended-by [executeInstallation]
|
|
90
|
+
* @side-effects [console output, file system reads]
|
|
91
|
+
* @tags orphaned, validation, yaml, json-schema
|
|
92
|
+
*/
|
|
93
|
+
async function validateInstructionFile(filePath: string): Promise<void> {
|
|
94
|
+
try {
|
|
95
|
+
console.log(`🔍 Validating ${filePath}...`)
|
|
96
|
+
|
|
97
|
+
if (!existsSync(filePath)) {
|
|
98
|
+
console.error(`❌ File not found: ${filePath}`)
|
|
99
|
+
process.exit(1)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const content = readFileSync(filePath, 'utf8')
|
|
103
|
+
const data = yaml.load(content) as any
|
|
104
|
+
|
|
105
|
+
// Validate against schema
|
|
106
|
+
if (!validate(data)) {
|
|
107
|
+
console.error('❌ Validation failed:')
|
|
108
|
+
console.error(JSON.stringify(validate.errors, null, 2))
|
|
109
|
+
process.exit(1)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log('✅ Schema validation passed')
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error(`❌ Error validating ${filePath}:`, error)
|
|
115
|
+
process.exit(1)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// ─── CHUNK_END: APP_INSTALL_CLI_VALIDATE_INSTRUCTION_FILE ────────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
// ─── CHUNK_START: APP_INSTALL_CLI_EXECUTE_INSTALLATION ──────────────────────────────────────────────
|
|
121
|
+
/**
|
|
122
|
+
* @chunk-id APP_INSTALL_CLI_EXECUTE_INSTALLATION_1_0_0
|
|
123
|
+
* @version 1.0.0
|
|
124
|
+
* @hash c84aa57769569e4b00ebde4d8b29b7059e6b0d6e8eb3d82cfa51c15e1451e04a
|
|
125
|
+
* @macro Multi-Step App Installation Executor
|
|
126
|
+
* @micro Orchestrates pack installation, app creation, migrations, and verification
|
|
127
|
+
* @inputs filePath: string — Path to YAML instruction file
|
|
128
|
+
* @inputs options: any — CLI options including accountId
|
|
129
|
+
* @outputs void — Console output only
|
|
130
|
+
* @depends-on [validateInstructionFile, substituteVariables, yaml, fs]
|
|
131
|
+
* @depended-by [CLI program command handler]
|
|
132
|
+
* @side-effects [console output, file system reads, process.exit on failure]
|
|
133
|
+
* @tags orphaned, installation, orchestration, multi-step
|
|
134
|
+
*/
|
|
135
|
+
async function executeInstallation(filePath: string, options: any): Promise<void> {
|
|
136
|
+
try {
|
|
137
|
+
console.log(`🚀 Executing installation from ${filePath}...`)
|
|
138
|
+
|
|
139
|
+
// First validate
|
|
140
|
+
await validateInstructionFile(filePath)
|
|
141
|
+
|
|
142
|
+
const content = readFileSync(filePath, 'utf8')
|
|
143
|
+
const instructions = yaml.load(content) as any
|
|
144
|
+
|
|
145
|
+
// Set up context
|
|
146
|
+
const context: InstallationContext = {
|
|
147
|
+
TARGET_ACCOUNT_ID: options.accountId,
|
|
148
|
+
...instructions.variables
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
console.log('📋 Installation plan:')
|
|
152
|
+
console.log(` App: ${instructions.app.name} v${instructions.app.version}`)
|
|
153
|
+
console.log(` Target Account: ${context.TARGET_ACCOUNT_ID}`)
|
|
154
|
+
console.log()
|
|
155
|
+
|
|
156
|
+
// Step 1: Pack installation
|
|
157
|
+
console.log('📦 Step 1: Installing pack...')
|
|
158
|
+
const packInstall = substituteVariables(instructions.installation.pack_installation, context)
|
|
159
|
+
console.log(' Pack installation config:', JSON.stringify(packInstall, null, 2))
|
|
160
|
+
|
|
161
|
+
// Simulate pack installation - in real implementation, this would call the API
|
|
162
|
+
const packInstallationId = 'simulated-pack-id-' + Date.now()
|
|
163
|
+
context.PACK_INSTALLATION_ID = packInstallationId
|
|
164
|
+
console.log(` ✅ Pack installed with ID: ${packInstallationId}`)
|
|
165
|
+
|
|
166
|
+
// Step 2: App creation
|
|
167
|
+
console.log('⚙️ Step 2: Creating app definitions...')
|
|
168
|
+
if (instructions.installation.app_creation) {
|
|
169
|
+
for (const appDef of instructions.installation.app_creation) {
|
|
170
|
+
const appConfig = substituteVariables(appDef, context)
|
|
171
|
+
console.log(` Creating app: ${appConfig.slug}`)
|
|
172
|
+
console.log(' App config:', JSON.stringify(appConfig, null, 2))
|
|
173
|
+
console.log(` ✅ App ${appConfig.slug} created`)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Step 3: Migrations
|
|
178
|
+
console.log('🔄 Step 3: Running migrations...')
|
|
179
|
+
if (instructions.installation.migrations) {
|
|
180
|
+
for (const migration of instructions.installation.migrations) {
|
|
181
|
+
console.log(` Running migration: ${migration.file}`)
|
|
182
|
+
console.log(` Description: ${migration.description}`)
|
|
183
|
+
if (migration.dependencies) {
|
|
184
|
+
console.log(` Dependencies: ${migration.dependencies.join(', ')}`)
|
|
185
|
+
}
|
|
186
|
+
console.log(` ✅ Migration completed`)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Step 4: Verification
|
|
191
|
+
console.log('✅ Step 4: Verifying installation...')
|
|
192
|
+
if (instructions.installation.verification) {
|
|
193
|
+
for (const verification of instructions.installation.verification) {
|
|
194
|
+
console.log(` Verifying: ${verification.check}`)
|
|
195
|
+
if (verification.slug) console.log(` Slug: ${verification.slug}`)
|
|
196
|
+
if (verification.integration_id) console.log(` Integration: ${verification.integration_id}`)
|
|
197
|
+
console.log(` ✅ Verification passed`)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
console.log()
|
|
202
|
+
console.log('🎉 Installation completed successfully!')
|
|
203
|
+
console.log(`📱 App "${instructions.app.name}" is ready to use`)
|
|
204
|
+
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error('❌ Installation failed:', error)
|
|
207
|
+
process.exit(1)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// ─── CHUNK_END: APP_INSTALL_CLI_EXECUTE_INSTALLATION ────────────────────────────────────────────────
|
|
211
|
+
|
|
212
|
+
// ─── CHUNK_START: APP_INSTALL_CLI_GENERATE_TEMPLATE ──────────────────────────────────────────────
|
|
213
|
+
/**
|
|
214
|
+
* @chunk-id APP_INSTALL_CLI_GENERATE_TEMPLATE_1_0_0
|
|
215
|
+
* @version 1.0.0
|
|
216
|
+
* @hash 4ea17e0556f329f835cec106f09cb570c9e4ea8a92bc82e5fe9ccf4b5dd52aa9
|
|
217
|
+
* @macro Template Generator
|
|
218
|
+
* @micro Outputs YAML templates for app installations or migrations
|
|
219
|
+
* @inputs type: string — Template type ("app" or "migration")
|
|
220
|
+
* @inputs options: any — CLI options including output file path
|
|
221
|
+
* @outputs void — Console output or file write
|
|
222
|
+
* @depends-on [fs, path]
|
|
223
|
+
* @depended-by [CLI program command handler]
|
|
224
|
+
* @side-effects [console output, file system reads/writes, process.exit on failure]
|
|
225
|
+
* @tags orphaned, template-generation, yaml, cli
|
|
226
|
+
*/
|
|
227
|
+
async function generateTemplate(type: string, options: any): Promise<void> {
|
|
228
|
+
try {
|
|
229
|
+
const templateDir = resolve(__dirname, '../docs/app-installation/templates')
|
|
230
|
+
let templateFile: string
|
|
231
|
+
|
|
232
|
+
switch (type) {
|
|
233
|
+
case 'app':
|
|
234
|
+
templateFile = resolve(templateDir, 'app-install.yaml')
|
|
235
|
+
break
|
|
236
|
+
case 'migration':
|
|
237
|
+
templateFile = resolve(templateDir, 'migration.yaml')
|
|
238
|
+
break
|
|
239
|
+
default:
|
|
240
|
+
console.error('❌ Unknown template type. Use "app" or "migration"')
|
|
241
|
+
process.exit(1)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const template = readFileSync(templateFile, 'utf8')
|
|
245
|
+
|
|
246
|
+
if (options.output) {
|
|
247
|
+
writeFileSync(options.output, template)
|
|
248
|
+
console.log(`✅ Template generated: ${options.output}`)
|
|
249
|
+
} else {
|
|
250
|
+
console.log(template)
|
|
251
|
+
}
|
|
252
|
+
} catch (error) {
|
|
253
|
+
console.error('❌ Error generating template:', error)
|
|
254
|
+
process.exit(1)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// ─── CHUNK_END: APP_INSTALL_CLI_GENERATE_TEMPLATE ────────────────────────────────────────────────
|
|
258
|
+
|
|
259
|
+
// CLI setup
|
|
260
|
+
program
|
|
261
|
+
.name('app-install-cli')
|
|
262
|
+
.description('Spine App Installation CLI - Validate and execute app installation instructions')
|
|
263
|
+
.version('1.0.0')
|
|
264
|
+
|
|
265
|
+
program
|
|
266
|
+
.command('validate')
|
|
267
|
+
.description('Validate an instruction file against the schema')
|
|
268
|
+
.argument('<file>', 'Instruction file path')
|
|
269
|
+
.action(validateInstructionFile)
|
|
270
|
+
|
|
271
|
+
program
|
|
272
|
+
.command('install')
|
|
273
|
+
.description('Execute app installation from instruction file')
|
|
274
|
+
.argument('<file>', 'Instruction file path')
|
|
275
|
+
.option('-a, --account-id <id>', 'Target account ID')
|
|
276
|
+
.option('-d, --dry-run', 'Simulate installation without making changes')
|
|
277
|
+
.action(executeInstallation)
|
|
278
|
+
|
|
279
|
+
program
|
|
280
|
+
.command('template')
|
|
281
|
+
.description('Generate a new instruction template')
|
|
282
|
+
.argument('<type>', 'Template type: app or migration')
|
|
283
|
+
.option('-o, --output <path>', 'Output file path (optional, prints to stdout)')
|
|
284
|
+
.action(generateTemplate)
|
|
285
|
+
|
|
286
|
+
program.parse()
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Frontend Assembly - Merge .framework/src + custom/apps/*/src → .assembled/src
|
|
4
|
+
#
|
|
5
|
+
# Purpose: Create unified frontend source directory for Vite build process.
|
|
6
|
+
# - .framework/src is the canonical Spine frontend
|
|
7
|
+
# - custom/apps/*/src are your application sources
|
|
8
|
+
# - Vite expects a single src directory, so we assemble at build time
|
|
9
|
+
#
|
|
10
|
+
# Process:
|
|
11
|
+
# 1. Clean target directory
|
|
12
|
+
# 2. Copy core src files
|
|
13
|
+
# 3. Overlay custom src files (overwrites existing)
|
|
14
|
+
#
|
|
15
|
+
# Dependencies: standard bash utilities, find, cp, rsync
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
20
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
21
|
+
|
|
22
|
+
CORE_SRC_DIR="$PROJECT_ROOT/.framework/src"
|
|
23
|
+
CUSTOM_SRC_DIR="$PROJECT_ROOT/custom/apps"
|
|
24
|
+
TARGET_SRC_DIR="$PROJECT_ROOT/.assembled/src"
|
|
25
|
+
|
|
26
|
+
echo "🔧 Assembling frontend → $TARGET_SRC_DIR"
|
|
27
|
+
|
|
28
|
+
# 1. Clean target (except .gitkeep if exists)
|
|
29
|
+
if [ -d "$TARGET_SRC_DIR" ]; then
|
|
30
|
+
find "$TARGET_SRC_DIR" -mindepth 1 -not -name '.gitkeep' -delete 2>/dev/null || true
|
|
31
|
+
else
|
|
32
|
+
mkdir -p "$TARGET_SRC_DIR"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# 2. Copy core src (base layer)
|
|
36
|
+
if [ -d "$CORE_SRC_DIR" ]; then
|
|
37
|
+
# Ensure subdirectories are copied properly
|
|
38
|
+
cp -r "$CORE_SRC_DIR"/* "$TARGET_SRC_DIR"/ 2>/dev/null || true
|
|
39
|
+
echo " ✓ Core: $(find "$CORE_SRC_DIR" -name '*.tsx' -o -name '*.ts' -o -name '*.css' | wc -l | tr -d ' ') files"
|
|
40
|
+
else
|
|
41
|
+
echo " ⚠ Core: $CORE_SRC_DIR not found"
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# 4. Copy public files from .framework
|
|
45
|
+
if [ -f "$PROJECT_ROOT/.framework/index.html" ]; then
|
|
46
|
+
# Copy and fix the script src path for assembled structure
|
|
47
|
+
sed 's|/src/main.tsx|./main.tsx|g' "$PROJECT_ROOT/.framework/index.html" > "$TARGET_SRC_DIR/index.html"
|
|
48
|
+
echo " ✓ Core: index.html (paths fixed)"
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# 3. Copy public assets from .framework → assembled public dir (Vite serves from <root>/public)
|
|
52
|
+
if [ -d "$PROJECT_ROOT/.framework/public" ]; then
|
|
53
|
+
mkdir -p "$TARGET_SRC_DIR/public"
|
|
54
|
+
cp -r "$PROJECT_ROOT/.framework/public"/* "$TARGET_SRC_DIR/public/" 2>/dev/null || true
|
|
55
|
+
echo " ✓ Core: $(find "$PROJECT_ROOT/.framework/public" -type f | wc -l | tr -d ' ') public files"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# 3.5. Copy _redirects to Vite-served directory for Netlify dev
|
|
59
|
+
if [ -f "$PROJECT_ROOT/.framework/public/_redirects" ]; then
|
|
60
|
+
cp "$PROJECT_ROOT/.framework/public/_redirects" "$TARGET_SRC_DIR/_redirects"
|
|
61
|
+
echo " ✓ Core: _redirects copied to Vite-served directory for Netlify dev"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# 6. Overlay custom src (overrides + additions)
|
|
65
|
+
if [ -d "$CUSTOM_SRC_DIR" ]; then
|
|
66
|
+
# Copy files and subdirectories
|
|
67
|
+
cp -r "$CUSTOM_SRC_DIR"/* "$TARGET_SRC_DIR"/ 2>/dev/null || true
|
|
68
|
+
|
|
69
|
+
# Handle subdirectories properly
|
|
70
|
+
find "$CUSTOM_SRC_DIR" -mindepth 1 -type d -exec sh -c 'dir="$1"; base=$(basename "$dir"); mkdir -p "'"$TARGET_SRC_DIR"'/$base" && cp -r "$dir"/* "'"$TARGET_SRC_DIR"'/$base/"' _ {} \; 2>/dev/null || true
|
|
71
|
+
|
|
72
|
+
CUSTOM_COUNT=$(find "$CUSTOM_SRC_DIR" -name '*.tsx' -o -name '*.ts' -o -name '*.css' 2>/dev/null | wc -l | tr -d ' ')
|
|
73
|
+
echo " ✓ Custom: $CUSTOM_COUNT files"
|
|
74
|
+
else
|
|
75
|
+
echo " ○ Custom: (empty)"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo " ✓ Assembled: $(find "$TARGET_SRC_DIR" -name '*.tsx' -o -name '*.ts' -o -name '*.css' | wc -l | tr -d ' ') total files"
|
|
79
|
+
echo "✅ Done"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Functions Assembly - Merge .framework + custom functions into .assembled/
|
|
4
|
+
#
|
|
5
|
+
# Purpose: Create unified functions directory for Netlify deployment.
|
|
6
|
+
# - .framework/functions are the canonical Spine runtime
|
|
7
|
+
# - custom/functions are your custom extensions
|
|
8
|
+
# - Netlify requires a single functions directory, so we assemble at build time
|
|
9
|
+
#
|
|
10
|
+
# Process:
|
|
11
|
+
# 1. Assemble into temp directory first (prevents Netlify observing half-deleted dir)
|
|
12
|
+
# 2. Copy core functions
|
|
13
|
+
# 3. Overlay custom functions (overwrites existing)
|
|
14
|
+
# 4. Atomic move to target directory
|
|
15
|
+
#
|
|
16
|
+
# Dependencies: standard bash utilities, find, cp, rsync, mv
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
21
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
22
|
+
|
|
23
|
+
CORE_DIR="$PROJECT_ROOT/.framework/functions"
|
|
24
|
+
CUSTOM_DIR="$PROJECT_ROOT/custom"
|
|
25
|
+
TARGET_DIR="$PROJECT_ROOT/.assembled/netlify/functions"
|
|
26
|
+
TMP_DIR="$PROJECT_ROOT/.functions-assemble-tmp"
|
|
27
|
+
|
|
28
|
+
echo "🔧 Assembling functions → $TARGET_DIR"
|
|
29
|
+
|
|
30
|
+
# 1. Assemble into a temp directory first so Netlify never observes a half-deleted functions dir
|
|
31
|
+
rm -rf "$TMP_DIR"
|
|
32
|
+
mkdir -p "$TMP_DIR"
|
|
33
|
+
|
|
34
|
+
# 2. Copy core functions (base layer), excluding _quarantine and test files
|
|
35
|
+
if [ -d "$CORE_DIR" ]; then
|
|
36
|
+
# Copy all files except _quarantine directory and test files (*-test.ts, *.test.ts)
|
|
37
|
+
find "$CORE_DIR" -maxdepth 1 -name '*.ts' ! -name '*-test.ts' ! -name '*.test.ts' -exec cp {} "$TMP_DIR"/ \;
|
|
38
|
+
# Copy subdirectories except _quarantine
|
|
39
|
+
find "$CORE_DIR" -maxdepth 1 -mindepth 1 -type d ! -name '_quarantine' -exec cp -r {} "$TMP_DIR"/ \;
|
|
40
|
+
echo " ✓ Core: $(find "$CORE_DIR" -name '*.ts' | grep -v '_quarantine' | grep -v '\-test\.ts$' | grep -v '\.test\.ts$' | wc -l | tr -d ' ') files"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# 3. Overlay custom functions (overrides + additions), excluding test files
|
|
44
|
+
CUSTOM_COUNT=0
|
|
45
|
+
if [ -d "$CUSTOM_DIR/functions" ]; then
|
|
46
|
+
# Copy all files except test files (*-test.ts, *.test.ts)
|
|
47
|
+
find "$CUSTOM_DIR/functions" -maxdepth 1 -name '*.ts' ! -name '*-test.ts' ! -name '*.test.ts' -exec cp {} "$TMP_DIR"/ \; 2>/dev/null || true
|
|
48
|
+
# Copy subdirectories if any
|
|
49
|
+
find "$CUSTOM_DIR/functions" -mindepth 1 -type d -exec sh -c 'dir="$1"; base=$(basename "$dir"); mkdir -p "'"$TMP_DIR"'/$base" && cp -r "$dir"/* "'"$TMP_DIR"'/$base/"' _ {} \; 2>/dev/null || true
|
|
50
|
+
CUSTOM_COUNT=$(find "$CUSTOM_DIR/functions" -name '*.ts' ! -name '*-test.ts' ! -name '*.test.ts' 2>/dev/null | wc -l | tr -d ' ')
|
|
51
|
+
echo " ✓ Custom: $CUSTOM_COUNT files"
|
|
52
|
+
else
|
|
53
|
+
echo " ○ Custom: (empty)"
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# 4. Atomically swap temp into place
|
|
57
|
+
rm -rf "$TARGET_DIR"
|
|
58
|
+
mkdir -p "$(dirname "$TARGET_DIR")"
|
|
59
|
+
mv "$TMP_DIR" "$TARGET_DIR"
|
|
60
|
+
|
|
61
|
+
echo " ✓ Assembled: $(find "$TARGET_DIR" -name '*.ts' ! -name '*-test.ts' ! -name '*.test.ts' | wc -l | tr -d ' ') total functions"
|
|
62
|
+
echo "✅ Done"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Assembly Orchestrator - Assemble .framework + custom into .assembled/
|
|
4
|
+
#
|
|
5
|
+
# Purpose: Main assembly script that orchestrates the complete build process.
|
|
6
|
+
# - Calls frontend and functions assembly scripts
|
|
7
|
+
# - Removes stale dist/ to prevent Netlify CLI conflicts
|
|
8
|
+
# - Coordinates multi-step assembly process
|
|
9
|
+
#
|
|
10
|
+
# Process:
|
|
11
|
+
# 1. Clean dist/ directory
|
|
12
|
+
# 2. Assemble functions to .assembled/netlify/functions/
|
|
13
|
+
# 3. Assemble frontend to .assembled/src/
|
|
14
|
+
#
|
|
15
|
+
# Dependencies: assemble-functions.sh, assemble-frontend.sh
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
20
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
21
|
+
|
|
22
|
+
echo "Assembling Spine..."
|
|
23
|
+
|
|
24
|
+
# Remove stale dist/ so Netlify CLI never reads its _redirects during dev
|
|
25
|
+
rm -rf "$PROJECT_ROOT/dist"
|
|
26
|
+
|
|
27
|
+
# Step 1: Assemble functions
|
|
28
|
+
echo "Assembling functions..."
|
|
29
|
+
bash "$SCRIPT_DIR/assemble-functions.sh"
|
|
30
|
+
|
|
31
|
+
# Step 2: Assemble frontend
|
|
32
|
+
echo "Assembling frontend..."
|
|
33
|
+
bash "$SCRIPT_DIR/assemble-frontend.sh"
|
|
34
|
+
|
|
35
|
+
echo "Spine assembly complete"
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Boundary Check Script
|
|
4
|
+
#
|
|
5
|
+
# Prevents Core→Custom violations by blocking PRs that import custom code
|
|
6
|
+
# into the core framework. This enforces the architectural boundary where
|
|
7
|
+
# Core provides mechanism and Custom provides data.
|
|
8
|
+
#
|
|
9
|
+
# Usage: ./scripts/boundary-check.sh
|
|
10
|
+
# Exit code: 0 if clean, 1 if violations found
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
set -e
|
|
14
|
+
|
|
15
|
+
echo "🔍 Checking Core→Custom boundary violations..."
|
|
16
|
+
echo ""
|
|
17
|
+
|
|
18
|
+
VIOLATIONS=0
|
|
19
|
+
|
|
20
|
+
# Check 1: Core importing from custom/ directory
|
|
21
|
+
echo "1. Checking for imports from custom/ in core..."
|
|
22
|
+
if grep -r "from.*custom/\|import.*@custom" .framework/ --include="*.ts" --include="*.tsx" --exclude-dir=tests 2>/dev/null; then
|
|
23
|
+
echo " ❌ FAIL: Core files import from custom/"
|
|
24
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
25
|
+
else
|
|
26
|
+
echo " ✅ PASS: No custom/ imports in core"
|
|
27
|
+
fi
|
|
28
|
+
echo ""
|
|
29
|
+
|
|
30
|
+
# Check 2: Core importing custom_ prefixed modules
|
|
31
|
+
echo "2. Checking for custom_ module imports in core..."
|
|
32
|
+
if grep -r "from.*custom_\|import.*custom_" .framework/ --include="*.ts" --include="*.tsx" 2>/dev/null; then
|
|
33
|
+
echo " ❌ FAIL: Core files import custom_ modules"
|
|
34
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
35
|
+
else
|
|
36
|
+
echo " ✅ PASS: No custom_ imports in core"
|
|
37
|
+
fi
|
|
38
|
+
echo ""
|
|
39
|
+
|
|
40
|
+
# Check 2b: Custom apps using relative paths to .framework/ (should use @core alias instead)
|
|
41
|
+
echo "2b. Checking custom apps use @core alias (not relative paths to .framework/)..."
|
|
42
|
+
if grep -r "from.*\.\./.*\.framework\|from.*\.framework/" custom/ --include="*.ts" --include="*.tsx" 2>/dev/null; then
|
|
43
|
+
echo " ❌ FAIL: Custom apps use relative paths to .framework/ — use @core alias instead"
|
|
44
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
45
|
+
else
|
|
46
|
+
echo " ✅ PASS: Custom apps use @core alias correctly"
|
|
47
|
+
fi
|
|
48
|
+
echo ""
|
|
49
|
+
|
|
50
|
+
# Check 3: App-specific references in core
|
|
51
|
+
echo "3. Checking for app-specific references in core..."
|
|
52
|
+
APP_REFS=$(grep -r "cortex\|funnel\|support-triage\|kb-chunker\|portal-signals" .framework/src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v "manifest.json\|webhook-registry" || true)
|
|
53
|
+
if [ -n "$APP_REFS" ]; then
|
|
54
|
+
echo " ❌ FAIL: App-specific references found in core:"
|
|
55
|
+
echo "$APP_REFS"
|
|
56
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
57
|
+
else
|
|
58
|
+
echo " ✅ PASS: No app-specific references in core"
|
|
59
|
+
fi
|
|
60
|
+
echo ""
|
|
61
|
+
|
|
62
|
+
# Check 4: Verify manifest files exist for custom apps
|
|
63
|
+
echo "4. Checking custom apps have manifest.json..."
|
|
64
|
+
MANIFEST_COUNT=$(find custom/apps -name "manifest.json" | wc -l)
|
|
65
|
+
if [ "$MANIFEST_COUNT" -eq 0 ]; then
|
|
66
|
+
echo " ⚠️ WARNING: No manifest.json files found in custom/apps/"
|
|
67
|
+
else
|
|
68
|
+
echo " ✅ PASS: $MANIFEST_COUNT manifest.json files found"
|
|
69
|
+
find custom/apps -name "manifest.json" | while read -r manifest; do
|
|
70
|
+
echo " - $manifest"
|
|
71
|
+
done
|
|
72
|
+
fi
|
|
73
|
+
echo ""
|
|
74
|
+
|
|
75
|
+
# Check 5: Verify webhook registry is used (not static imports)
|
|
76
|
+
echo "5. Checking integration-routes uses dynamic registry..."
|
|
77
|
+
if grep -q "webhookHandlers\|custom_webhook-handlers" .framework/functions/integration-routes.ts 2>/dev/null; then
|
|
78
|
+
echo " ❌ FAIL: integration-routes still uses static imports"
|
|
79
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
80
|
+
else
|
|
81
|
+
echo " ✅ PASS: integration-routes uses dynamic registry"
|
|
82
|
+
fi
|
|
83
|
+
echo ""
|
|
84
|
+
|
|
85
|
+
# Check 6: Sidebar components should not be in core
|
|
86
|
+
echo "6. Checking app-specific components removed from core..."
|
|
87
|
+
if [ -d ".framework/src/components/cortex" ] || [ -d ".framework/src/components/crm" ]; then
|
|
88
|
+
echo " ❌ FAIL: App-specific component directories still exist in core"
|
|
89
|
+
ls -la .framework/src/components/ | grep -E "cortex|crm" || true
|
|
90
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
91
|
+
else
|
|
92
|
+
echo " ✅ PASS: App-specific component directories removed from core"
|
|
93
|
+
fi
|
|
94
|
+
echo ""
|
|
95
|
+
|
|
96
|
+
# Summary
|
|
97
|
+
echo "========================================"
|
|
98
|
+
if [ $VIOLATIONS -eq 0 ]; then
|
|
99
|
+
echo "✅ ALL CHECKS PASSED"
|
|
100
|
+
echo "Core→Custom boundary is clean."
|
|
101
|
+
exit 0
|
|
102
|
+
else
|
|
103
|
+
echo "❌ $VIOLATIONS VIOLATION(S) FOUND"
|
|
104
|
+
echo "Fix violations before merging."
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module scripts/build-manifest
|
|
5
|
+
* @audience installer
|
|
6
|
+
* @layer build
|
|
7
|
+
* @stability orphaned
|
|
8
|
+
*
|
|
9
|
+
* Build Manifest Generator - Generate a signed manifest of core file hashes.
|
|
10
|
+
* **ORPHANED**: References non-existent `core/` directory (should be `v2-core/`).
|
|
11
|
+
*
|
|
12
|
+
* **Intended Purpose**: Used for build-time integrity verification.
|
|
13
|
+
* - In dev mode (SPINE_INTEGRITY=warn), mismatches log warnings
|
|
14
|
+
* - In production (SPINE_INTEGRITY=enforce), mismatches fail the build
|
|
15
|
+
*
|
|
16
|
+
* **Current State**: Cannot function - references wrong directory paths.
|
|
17
|
+
*
|
|
18
|
+
* **Dependencies**: shasum, standard bash utilities
|
|
19
|
+
*
|
|
20
|
+
* @tags orphaned, build, integrity, manifest, verification
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
26
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
27
|
+
|
|
28
|
+
CORE_DIR="$PROJECT_ROOT/.framework"
|
|
29
|
+
CORE_SRC_DIR="$PROJECT_ROOT/.framework/src"
|
|
30
|
+
MANIFEST_FILE="$PROJECT_ROOT/.spine-manifest.json"
|
|
31
|
+
|
|
32
|
+
INTEGRITY_MODE="${SPINE_INTEGRITY:-warn}"
|
|
33
|
+
|
|
34
|
+
echo "🔒 Generating core integrity manifest (mode: $INTEGRITY_MODE)"
|
|
35
|
+
|
|
36
|
+
# Collect hashes of all core files
|
|
37
|
+
HASHES="{"
|
|
38
|
+
FIRST=true
|
|
39
|
+
|
|
40
|
+
# Core functions
|
|
41
|
+
while IFS= read -r -d '' file; do
|
|
42
|
+
REL_PATH="${file#$PROJECT_ROOT/}"
|
|
43
|
+
HASH=$(shasum -a 256 "$file" | cut -d' ' -f1)
|
|
44
|
+
if [ "$FIRST" = true ]; then
|
|
45
|
+
FIRST=false
|
|
46
|
+
else
|
|
47
|
+
HASHES="$HASHES,"
|
|
48
|
+
fi
|
|
49
|
+
HASHES="$HASHES\"$REL_PATH\":\"$HASH\""
|
|
50
|
+
done < <(find "$CORE_DIR" -type f -name '*.ts' -print0 | sort -z)
|
|
51
|
+
|
|
52
|
+
# Core src components (shared, layout, hooks, lib)
|
|
53
|
+
for SUBDIR in components/shared components/layout hooks lib; do
|
|
54
|
+
DIR="$CORE_SRC_DIR/$SUBDIR"
|
|
55
|
+
if [ -d "$DIR" ]; then
|
|
56
|
+
while IFS= read -r -d '' file; do
|
|
57
|
+
REL_PATH="${file#$PROJECT_ROOT/}"
|
|
58
|
+
HASH=$(shasum -a 256 "$file" | cut -d' ' -f1)
|
|
59
|
+
HASHES="$HASHES,\"$REL_PATH\":\"$HASH\""
|
|
60
|
+
done < <(find "$DIR" -type f \( -name '*.ts' -o -name '*.tsx' \) -print0 | sort -z)
|
|
61
|
+
fi
|
|
62
|
+
done
|
|
63
|
+
|
|
64
|
+
HASHES="$HASHES}"
|
|
65
|
+
|
|
66
|
+
# Write manifest
|
|
67
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
68
|
+
cat > "$MANIFEST_FILE" <<EOF
|
|
69
|
+
{
|
|
70
|
+
"version": "1",
|
|
71
|
+
"generated_at": "$TIMESTAMP",
|
|
72
|
+
"integrity_mode": "$INTEGRITY_MODE",
|
|
73
|
+
"file_count": $(echo "$HASHES" | tr ',' '\n' | wc -l | tr -d ' '),
|
|
74
|
+
"hashes": $HASHES
|
|
75
|
+
}
|
|
76
|
+
EOF
|
|
77
|
+
|
|
78
|
+
echo " ✓ Manifest written to $MANIFEST_FILE"
|
|
79
|
+
echo " ✓ $(echo "$HASHES" | tr ',' '\n' | wc -l | tr -d ' ') files hashed"
|
|
80
|
+
echo "✅ Done"
|