@ultimat3/cli 29.4.0 → 30.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/CLAUDE.md +64 -40
- package/README.md +61 -11
- package/package.json +42 -28
- package/src/affected-tests.ts +97 -0
- package/src/affected-unowned.ts +43 -0
- package/src/affected.ts +25 -6
- package/src/app-boundaries.ts +29 -1
- package/src/app-evals.ts +12 -4
- package/src/app-load-unresolved.ts +62 -0
- package/src/app-load.ts +30 -37
- package/src/app-mcp.ts +14 -2
- package/src/app-module-graph.ts +232 -0
- package/src/app-reload-graph.ts +2 -2
- package/src/app-root.ts +37 -1
- package/src/bin.ts +1 -0
- package/src/boundary-findings.ts +6 -0
- package/src/budgets-freshness.ts +32 -0
- package/src/budgets.ts +20 -1
- package/src/build-capture-env.ts +9 -0
- package/src/cdp-shot-a11y.ts +2 -39
- package/src/ci-tested.ts +243 -0
- package/src/client-emit-customer-runtime.ts +139 -0
- package/src/client-emit-customer.ts +108 -0
- package/src/client-emit-drift.ts +72 -0
- package/src/client-emit-header.ts +67 -0
- package/src/client-emit-schemas.ts +175 -0
- package/src/client-emit-types.ts +121 -0
- package/src/client-emit-vendor.ts +146 -0
- package/src/client-errors-routes.ts +229 -0
- package/src/client-errors-script.ts +74 -0
- package/src/client-vitals-route.ts +197 -0
- package/src/client-vitals-script.ts +56 -0
- package/src/cmd-affected.ts +23 -0
- package/src/cmd-build-spec.ts +7 -1
- package/src/cmd-build.ts +35 -9
- package/src/cmd-ci-spec.ts +42 -6
- package/src/cmd-ci.ts +99 -2
- package/src/cmd-client-customer.ts +134 -0
- package/src/cmd-client-source.ts +81 -0
- package/src/cmd-client-spec.ts +48 -0
- package/src/cmd-client-write.ts +41 -0
- package/src/cmd-client.ts +111 -0
- package/src/cmd-db-recount.ts +120 -0
- package/src/cmd-db-spec.ts +36 -6
- package/src/cmd-db.ts +11 -3
- package/src/cmd-deploy-compose.ts +61 -3
- package/src/cmd-deploy-drain.ts +10 -2
- package/src/cmd-deploy-helm.ts +11 -0
- package/src/cmd-deploy-preflight.ts +118 -0
- package/src/cmd-deploy-spec.ts +58 -6
- package/src/cmd-deploy-verify.ts +380 -0
- package/src/cmd-deploy.ts +42 -9
- package/src/cmd-docs.ts +34 -4
- package/src/cmd-doctor.ts +66 -9
- package/src/cmd-drill-spec.ts +25 -0
- package/src/cmd-drill.ts +176 -0
- package/src/cmd-env-init.ts +102 -0
- package/src/cmd-env-spec.ts +10 -3
- package/src/cmd-env.ts +15 -10
- package/src/cmd-errors-recent.ts +60 -0
- package/src/cmd-errors-spec.ts +9 -1
- package/src/cmd-errors.ts +4 -0
- package/src/cmd-exercise-spec.ts +19 -0
- package/src/cmd-exercise.ts +129 -0
- package/src/cmd-generate-spec.ts +9 -1
- package/src/cmd-generate.ts +32 -27
- package/src/cmd-graph-load.ts +97 -0
- package/src/cmd-graph-spec.ts +16 -0
- package/src/cmd-graph.ts +73 -0
- package/src/cmd-i18n.ts +4 -1
- package/src/cmd-impact-spec.ts +13 -0
- package/src/cmd-impact.ts +64 -0
- package/src/cmd-jobs-resolve.ts +76 -0
- package/src/cmd-jobs-spec.ts +21 -2
- package/src/cmd-jobs.ts +10 -6
- package/src/cmd-mail-spec.ts +28 -0
- package/src/cmd-mail.ts +70 -0
- package/src/cmd-mcp-lock.ts +69 -0
- package/src/cmd-mcp-spec.ts +23 -4
- package/src/cmd-mcp.ts +17 -3
- package/src/cmd-new-spec.ts +8 -1
- package/src/cmd-new.ts +61 -9
- package/src/cmd-planned.ts +0 -6
- package/src/cmd-repro-spec.ts +31 -0
- package/src/cmd-repro.ts +174 -0
- package/src/cmd-stop-spec.ts +21 -0
- package/src/cmd-stop.ts +166 -0
- package/src/cmd-test-spec.ts +17 -4
- package/src/cmd-test.ts +70 -14
- package/src/cmd-upgrade-spec.ts +26 -0
- package/src/cmd-upgrade.ts +274 -0
- package/src/cmd-verify-spec.ts +3 -3
- package/src/db-backfill.ts +6 -0
- package/src/db-diagnostics.ts +106 -0
- package/src/db-generate.ts +9 -0
- package/src/db-reset-template.ts +1 -1
- package/src/db-rolling.ts +45 -0
- package/src/db-seed-generate.ts +188 -0
- package/src/deploy-verify-findings.ts +98 -0
- package/src/deploy-verify-flags.ts +109 -0
- package/src/deploy-verify-grade.ts +185 -0
- package/src/deploy-verify-queues.ts +53 -0
- package/src/dev-boot.ts +35 -15
- package/src/dev-child-watch.ts +16 -4
- package/src/dev-dashboard-guard.ts +8 -1
- package/src/dev-dashboard.ts +7 -0
- package/src/dev-lock-identity.ts +61 -0
- package/src/dev-lock-port-holder.ts +80 -0
- package/src/dev-lock-steal.ts +124 -0
- package/src/dev-lock.ts +92 -120
- package/src/dev-mail-templates.ts +51 -0
- package/src/dev-rebuild.ts +26 -2
- package/src/dev-route-table.ts +17 -0
- package/src/dev-supervisor.ts +5 -2
- package/src/dev-watch-tree.ts +11 -10
- package/src/dev-watch.ts +1 -1
- package/src/dispatch.ts +29 -6
- package/src/docs-section.ts +69 -0
- package/src/docs-sources.ts +100 -0
- package/src/doctor-auth.ts +11 -2
- package/src/doctor-chart-alerts.ts +55 -0
- package/src/doctor-pooler.ts +107 -0
- package/src/doctor-rolling.ts +35 -0
- package/src/doctor-row-security.ts +40 -0
- package/src/document-options.ts +13 -0
- package/src/drill-sync-lane.ts +25 -0
- package/src/drill-targets.ts +39 -0
- package/src/duplicate-packages.ts +1 -1
- package/src/env-production.ts +93 -0
- package/src/error-codes-shot.ts +59 -0
- package/src/error-codes-tooling.ts +29 -0
- package/src/error-codes.ts +100 -54
- package/src/error-contract.ts +2 -2
- package/src/errors.ts +22 -3
- package/src/exercise-database.ts +99 -0
- package/src/exercise-findings.ts +159 -0
- package/src/exercise-overrides.ts +42 -0
- package/src/exercise-registration.ts +58 -0
- package/src/exercise-static.ts +88 -0
- package/src/exercise-subject.ts +69 -0
- package/src/failure-capture-boot.ts +30 -0
- package/src/framework-env.ts +7 -1
- package/src/framework-schema.ts +72 -5
- package/src/generate-catalog-locales.ts +19 -0
- package/src/generate-chart-alerts.ts +156 -0
- package/src/generate-feature-required.ts +65 -0
- package/src/generate-feature.ts +83 -6
- package/src/generate-files.ts +24 -0
- package/src/generate-format-written.ts +32 -0
- package/src/generate-kinds.ts +6 -0
- package/src/generate-sign-in-config.ts +100 -0
- package/src/generate-sign-in-manifest.ts +28 -0
- package/src/generate-sign-in-mode.ts +101 -0
- package/src/generate-sign-in.ts +250 -0
- package/src/generate-write.ts +44 -7
- package/src/hand-rolled-socket.ts +72 -0
- package/src/i18n-app-key-shapes.ts +29 -0
- package/src/i18n-audit.ts +10 -3
- package/src/i18n-registration.ts +18 -3
- package/src/index.ts +2 -0
- package/src/island-bundle.ts +4 -3
- package/src/island-disposer.ts +116 -0
- package/src/island-realtime-state.ts +34 -6
- package/src/island-realtime.ts +6 -2
- package/src/island-routes.ts +3 -2
- package/src/isr-query-advice.ts +6 -11
- package/src/isr-query-guard.ts +4 -3
- package/src/job-budget.ts +95 -0
- package/src/jobs-json.ts +11 -0
- package/src/lint-findings.ts +104 -0
- package/src/local-cli.ts +34 -4
- package/src/loopback-host.ts +2 -2
- package/src/mail-preview-findings.ts +24 -0
- package/src/mcp-errors.ts +82 -2
- package/src/mcp-host.ts +11 -1
- package/src/mcp-lock-findings.ts +57 -0
- package/src/measure-paths.ts +12 -4
- package/src/measure-scope.ts +27 -13
- package/src/messages-client.ts +23 -0
- package/src/messages-db.ts +56 -0
- package/src/messages-gate.ts +107 -0
- package/src/messages-repro.ts +11 -0
- package/src/messages-shot.ts +51 -0
- package/src/messages-upgrade.ts +45 -0
- package/src/messages.ts +53 -178
- package/src/metrics-endpoint.ts +23 -5
- package/src/new-shapes-generate.ts +71 -0
- package/src/new-shapes.ts +63 -0
- package/src/openapi-compile-ir.ts +68 -0
- package/src/openapi-compile-schema.ts +284 -0
- package/src/openapi-compile.ts +273 -0
- package/src/openapi-refuse.ts +45 -0
- package/src/otlp-export.ts +2 -1
- package/src/output-findings.ts +123 -0
- package/src/output.ts +32 -8
- package/src/package-boundaries.ts +110 -0
- package/src/page-pins.ts +23 -0
- package/src/plain-routes.ts +13 -0
- package/src/prerender-entries.ts +59 -0
- package/src/prerender-heaviest.ts +27 -0
- package/src/prerender-preload.ts +6 -0
- package/src/prerender-report.ts +12 -0
- package/src/prerender-seo-reads.ts +38 -0
- package/src/prerender-served.ts +22 -7
- package/src/prerender-vitals.ts +42 -0
- package/src/prerender.ts +61 -32
- package/src/pwa-artifacts.ts +4 -3
- package/src/pwa-manifest-locales.ts +1 -1
- package/src/registry.ts +18 -0
- package/src/repro-bundle.ts +65 -0
- package/src/repro-errors.ts +47 -0
- package/src/repro-job.ts +72 -0
- package/src/repro-literal.ts +41 -0
- package/src/repro-request.ts +48 -0
- package/src/repro-write.ts +100 -0
- package/src/retain-sweep.ts +27 -0
- package/src/retained-assets-boot.ts +113 -0
- package/src/retained-assets-layout.ts +110 -0
- package/src/retained-assets-read.ts +142 -0
- package/src/retained-assets-sweep.ts +70 -0
- package/src/retained-assets.ts +171 -0
- package/src/revalidated-response.ts +8 -5
- package/src/role-replicator.ts +7 -1
- package/src/role-start-devices.ts +119 -0
- package/src/role-start-types.ts +6 -0
- package/src/role-start.ts +22 -5
- package/src/role-sync.ts +7 -1
- package/src/route-islands.ts +42 -0
- package/src/route-table.ts +2 -1
- package/src/row-security-boot.ts +58 -0
- package/src/row-security-wanted.ts +32 -0
- package/src/runtime-admin.ts +0 -1
- package/src/runtime-assets-site-cache.ts +55 -0
- package/src/runtime-assets-site.ts +136 -0
- package/src/runtime-assets.ts +99 -55
- package/src/runtime-bindings.ts +19 -3
- package/src/runtime-cache.ts +23 -14
- package/src/runtime-isr-outcome.ts +114 -60
- package/src/runtime-purge.ts +14 -2
- package/src/runtime-queue.ts +31 -4
- package/src/runtime-render-document.ts +204 -0
- package/src/runtime-render.ts +48 -198
- package/src/runtime-replica-position.ts +62 -0
- package/src/runtime-replica.ts +18 -3
- package/src/runtime-s3-path-style.ts +17 -0
- package/src/runtime-services.ts +19 -6
- package/src/runtime-statement-bound.ts +22 -0
- package/src/runtime-storage-upload.ts +9 -0
- package/src/runtime-storage.ts +41 -81
- package/src/schema-diff-views.ts +54 -0
- package/src/schema-diff.ts +21 -3
- package/src/schema-drift.ts +28 -9
- package/src/schema-dump-drift.ts +91 -7
- package/src/script-csp.ts +1 -1
- package/src/seo-cards.ts +26 -0
- package/src/seo-routes.ts +22 -8
- package/src/serve-boot.ts +54 -21
- package/src/serve-drain.ts +1 -0
- package/src/serve-env.ts +26 -8
- package/src/serve-retire.ts +12 -6
- package/src/serve-web.ts +42 -4
- package/src/serve.ts +9 -7
- package/src/site-asset-routes.ts +7 -1
- package/src/site-config.ts +4 -0
- package/src/site-llms-pages.ts +106 -0
- package/src/site-llms.ts +64 -0
- package/src/site-seo-write.ts +4 -2
- package/src/site-seo.ts +55 -6
- package/src/source-mtime.ts +50 -0
- package/src/static-capture-errors.ts +41 -0
- package/src/static-capture.ts +56 -0
- package/src/static-cards-serve.ts +39 -0
- package/src/static-cards.ts +93 -0
- package/src/static-document.ts +14 -13
- package/src/static-images.ts +115 -0
- package/src/stream-hole-scope.ts +55 -0
- package/src/style-bundle.ts +1 -1
- package/src/style-routes.ts +3 -2
- package/src/sw-precache-plan.ts +2 -2
- package/src/sw-routes.ts +2 -2
- package/src/templates/action-tests.ts +306 -0
- package/src/templates/action.ts +81 -269
- package/src/templates/backfill.ts +1 -1
- package/src/templates/entity.ts +21 -5
- package/src/templates/github/ci.yml.ts +8 -9
- package/src/templates/guard-bare-error.ts +2 -2
- package/src/templates/guard-error-declared.ts +263 -0
- package/src/templates/guard-native-confirm.ts +132 -0
- package/src/templates/guard-raw-fetch.ts +151 -0
- package/src/templates/guard-raw-interval.ts +121 -0
- package/src/templates/guard-repo-raw-sql.ts +71 -2
- package/src/templates/job.ts +1 -1
- package/src/templates/naming.ts +5 -0
- package/src/templates/pinned/docker-compose.yml +6 -0
- package/src/templates/pinned-images.ts +8 -0
- package/src/templates/policy.ts +85 -2
- package/src/templates/query.ts +70 -13
- package/src/templates/resource-create.ts +3 -1
- package/src/templates/resource-form-island.ts +15 -4
- package/src/templates/resource-page-db.ts +83 -0
- package/src/templates/resource-page.ts +161 -52
- package/src/templates/route.ts +4 -6
- package/src/templates/scaffold-app.ts +3 -0
- package/src/templates/scaffold-auth.ts +2 -1
- package/src/templates/scaffold-bin.ts +5 -52
- package/src/templates/scaffold-claude-agents.ts +19 -19
- package/src/templates/scaffold-claude-commands.ts +28 -31
- package/src/templates/scaffold-claude.ts +26 -23
- package/src/templates/scaffold-container-compose.ts +6 -1
- package/src/templates/scaffold-container.ts +24 -4
- package/src/templates/scaffold-dashboard-bare.ts +3 -3
- package/src/templates/scaffold-dashboard-example-tests.ts +49 -9
- package/src/templates/scaffold-dashboard-example-view.ts +156 -0
- package/src/templates/scaffold-dashboard-example.ts +43 -131
- package/src/templates/scaffold-dashboard-shared.ts +3 -7
- package/src/templates/scaffold-db-client.ts +20 -6
- package/src/templates/scaffold-db-package.ts +5 -14
- package/src/templates/scaffold-docs.ts +73 -57
- package/src/templates/scaffold-domain-package.ts +18 -14
- package/src/templates/scaffold-entries.ts +7 -2
- package/src/templates/scaffold-exercise.ts +37 -0
- package/src/templates/scaffold-guards.ts +13 -1
- package/src/templates/scaffold-helm-alerts.ts +234 -0
- package/src/templates/scaffold-helm-templates.ts +7 -5
- package/src/templates/scaffold-helm.ts +46 -12
- package/src/templates/scaffold-i18n.ts +6 -2
- package/src/templates/scaffold-mcp-endpoint.ts +182 -0
- package/src/templates/scaffold-mcp-json.ts +31 -0
- package/src/templates/scaffold-mcp-package.ts +59 -56
- package/src/templates/scaffold-repo.ts +7 -2
- package/src/templates/scaffold-shell.ts +45 -79
- package/src/templates/scaffold-test-services.ts +13 -5
- package/src/templates/shapes/api-keys.ts +170 -0
- package/src/templates/shapes/api.ts +101 -0
- package/src/templates/shapes/blog-site.ts +340 -0
- package/src/templates/shapes/blog-slice.ts +265 -0
- package/src/templates/shapes/blog.ts +114 -0
- package/src/templates/shapes/dashboard-detail.ts +242 -0
- package/src/templates/shapes/dashboard.ts +53 -0
- package/src/templates/shapes/index.ts +17 -0
- package/src/templates/shapes/overlay.ts +99 -0
- package/src/templates/shapes/shared-edits.ts +46 -0
- package/src/templates/sign-in-action-tests.ts +237 -0
- package/src/templates/sign-in-authenticator.ts +112 -0
- package/src/templates/sign-in-oidc.ts +189 -0
- package/src/templates/sign-in-pages.ts +148 -0
- package/src/templates/sign-in-password.ts +216 -0
- package/src/templates/sign-in-shared.ts +268 -0
- package/src/templates/slice-foundation.ts +70 -15
- package/src/test-batches.ts +1 -1
- package/src/test-database.ts +1 -1
- package/src/test-shards.ts +7 -1
- package/src/test-workers.ts +18 -12
- package/src/tool-gate-names.ts +34 -0
- package/src/upgrade-agents-link.ts +49 -0
- package/src/upgrade-bun-floor.ts +225 -0
- package/src/upgrade-gate.ts +228 -0
- package/src/upgrade-pins.ts +63 -0
- package/src/upgrade-plan.ts +214 -0
- package/src/upgrade-registry.ts +53 -0
- package/src/upgrade-report.ts +139 -0
- package/src/upgrade-root.ts +74 -0
- package/src/verify-budgets-build.ts +118 -0
- package/src/verify-checks.ts +67 -24
- package/src/verify-coverage-run.ts +1 -1
- package/src/verify-e2e-lane.ts +41 -0
- package/src/verify-exercise.ts +64 -0
- package/src/verify-floor.ts +41 -0
- package/src/verify-merge.ts +19 -4
- package/src/verify-role-load.ts +2 -0
- package/src/verify-run.ts +28 -8
- package/src/verify-shard.ts +12 -2
- package/src/verify-skip-ceiling.ts +87 -0
- package/src/verify-step.ts +5 -0
- package/src/verify-tests.ts +25 -5
- package/src/view-drift.ts +55 -0
- package/src/worker-bundle.ts +3 -2
- package/src/workspace-graph.ts +38 -19
- package/src/write-generated.ts +43 -0
- package/src/zone-boot.ts +20 -0
- package/wiki/Actions.md +342 -0
- package/wiki/Admin-Dashboard.md +432 -0
- package/wiki/Agents.md +958 -0
- package/wiki/Auth.md +195 -0
- package/wiki/Bare-VM.md +111 -0
- package/wiki/Batching-And-Preloading.md +136 -0
- package/wiki/Building-Your-Own-Base.md +203 -0
- package/wiki/CI-Parallel-Gate.md +220 -0
- package/wiki/CLI-Reference.md +1894 -0
- package/wiki/Caching-And-Invalidation.md +255 -0
- package/wiki/Client-Data.md +194 -0
- package/wiki/Client-Navigation.md +513 -0
- package/wiki/Compared.md +93 -0
- package/wiki/Configuration.md +868 -0
- package/wiki/Contributing.md +12 -0
- package/wiki/Deploy-Recipes.md +122 -0
- package/wiki/Deployment.md +508 -0
- package/wiki/Entities-And-Migrations.md +1116 -0
- package/wiki/FAQ.md +175 -0
- package/wiki/Feature-Flags.md +65 -0
- package/wiki/Getting-Started.md +221 -0
- package/wiki/Home.md +160 -0
- package/wiki/I18n.md +239 -0
- package/wiki/Installation.md +206 -0
- package/wiki/Interface-Rules.md +339 -0
- package/wiki/Jobs-And-Workflows.md +783 -0
- package/wiki/Known-Gaps.md +185 -0
- package/wiki/MCP-And-AI.md +753 -0
- package/wiki/Mail.md +138 -0
- package/wiki/Migrating-An-Existing-App.md +594 -0
- package/wiki/Migrating-From-Django.md +54 -0
- package/wiki/Migrating-From-Laravel.md +53 -0
- package/wiki/Migrating-From-Node-Drizzle.md +53 -0
- package/wiki/Migrating-From-Rails.md +53 -0
- package/wiki/Migrations-And-Backfills.md +552 -0
- package/wiki/Money.md +338 -0
- package/wiki/N-Plus-One-Detection.md +197 -0
- package/wiki/Notify.md +208 -0
- package/wiki/Observability.md +245 -0
- package/wiki/Outbound-HTTP.md +109 -0
- package/wiki/PWA-And-Offline.md +343 -0
- package/wiki/Policies-And-Authz.md +251 -0
- package/wiki/Project-Layout.md +150 -0
- package/wiki/Queries-And-Live-Queries.md +429 -0
- package/wiki/Realtime.md +734 -0
- package/wiki/Resource-Management.md +121 -0
- package/wiki/Routes-And-Render-Modes.md +521 -0
- package/wiki/SEO.md +288 -0
- package/wiki/Scheduled-Tasks.md +175 -0
- package/wiki/Scraping.md +493 -0
- package/wiki/Shapes.md +63 -0
- package/wiki/Stability.md +97 -0
- package/wiki/Static-Assets.md +166 -0
- package/wiki/Storage-And-Uploads.md +404 -0
- package/wiki/Testing.md +1314 -0
- package/wiki/The-Eight-Primitives.md +247 -0
- package/wiki/Theming.md +362 -0
- package/wiki/Timezones-And-Dates.md +194 -0
- package/wiki/Troubleshooting.md +163 -0
- package/wiki/Tutorial-01-First-App.md +289 -0
- package/wiki/Tutorial-02-First-Feature.md +339 -0
- package/wiki/Tutorial-03-Auth-And-Admin.md +379 -0
- package/wiki/Tutorial-04-Jobs-And-Realtime.md +263 -0
- package/wiki/Tutorial-05-Deploy-Free.md +231 -0
- package/wiki/Tutorial-06-Growing-Up.md +158 -0
- package/wiki/UI-Components.md +156 -0
- package/wiki/Upgrading.md +3667 -0
- package/src/stored-object-headers.ts +0 -43
package/CLAUDE.md
CHANGED
|
@@ -12,8 +12,8 @@ Commands: `bun test packages/cli` (from the repo root — the test preload lives
|
|
|
12
12
|
|
|
13
13
|
| Rule | Detail |
|
|
14
14
|
|---|---|
|
|
15
|
-
| Entry | `src/bin.ts` — argv, stdout, exit code only.
|
|
16
|
-
| Registry | `registry.ts`: every declaration static (`cmd-<name>-spec.ts`), every body `await import()`ed when that command runs.
|
|
15
|
+
| Entry | `src/bin.ts` — argv, stdout, exit code only. Full rule: `docs/history/cli.md` |
|
|
16
|
+
| Registry | `registry.ts`: every declaration static (`cmd-<name>-spec.ts`), every body `await import()`ed when that command runs. Full rule: `docs/history/cli.md` |
|
|
17
17
|
| Startup cost | `sass` loads on the first stylesheet compile (`@ultimat3/render`'s `compileStylesheet`), Babel on the first island transform (`solid-loader.ts`); both pinned by `*-lazy.test.ts` in a child process |
|
|
18
18
|
| Module names | `role-*` / `runtime-*` are booted by `serve.ts` in production; `dev-*` is `x dev`'s alone. Derived from the import graph by `module-naming.test.ts`, never listed |
|
|
19
19
|
| stdout / stderr | `write-line.ts`'s `writeLine` / `writeErrorLine` — synchronous fd writes, never `process.stdout.write` (truncates at the pipe buffer before `process.exit`). A `CommandResult` with `stream: 'stderr'` goes to fd 2 (`x mcp serve --transport stdio`) |
|
|
@@ -32,9 +32,9 @@ Commands: `bun test packages/cli` (from the repo root — the test preload lives
|
|
|
32
32
|
| Errors | codes + titles in `error-codes.ts`, a runnable line per code in `mcp-errors.ts` (typed over `CliErrorCode`), classes in `errors.ts` or beside their one thrower when `errors.ts` is at its ceiling. Never a bare `Error` |
|
|
33
33
|
| Subprocesses | only through `exec.ts`'s injectable `Runner`; `gh` through `ctx.runner` with a required `fix` |
|
|
34
34
|
| Templates | `templates/*.ts` return strings, pre-formatted for Biome (`wrap.ts`'s `wrapList` / `wrapImport` / `sortSpecifiers`); no fixture files on disk |
|
|
35
|
-
| Strings | rendered output through `messages.ts` (missing key renders `⟦key⟧`).
|
|
35
|
+
| Strings | rendered output through `messages.ts` (missing key renders `⟦key⟧`). Full rule: `docs/history/cli.md` |
|
|
36
36
|
| Facts | load the app (`app-load.ts`), then project a framework package's registry — never parse source for primitives, never re-derive a fact another package owns |
|
|
37
|
-
| Public API | `src/index.ts`, explicit re-exports only.
|
|
37
|
+
| Public API | `src/index.ts`, explicit re-exports only. Full rule: `docs/history/cli.md` |
|
|
38
38
|
|
|
39
39
|
## File map
|
|
40
40
|
|
|
@@ -42,101 +42,125 @@ Commands: `bun test packages/cli` (from the repo root — the test preload lives
|
|
|
42
42
|
|
|
43
43
|
| File | Job |
|
|
44
44
|
|---|---|
|
|
45
|
-
| `verify-checks.ts` / `verify-step.ts` / `verify-run.ts`
|
|
45
|
+
| `verify-checks.ts` / `verify-step.ts` / `verify-run.ts` / `verify-e2e-lane.ts` | steps, outcome, order (`BESIDE_SERIAL_SUITES`, e2e lane) |
|
|
46
|
+
| `verify-exercise.ts` / `cmd-exercise.ts` / `exercise-*.ts` | `exercise`: `x exercise --json` as a child, red on its findings |
|
|
46
47
|
| `verify-floor.ts` | `x.verify.json`: a floor step that ran zero tests is `X_VERIFY_SUITE_VANISHED` |
|
|
47
|
-
| `coverage-floor.ts` / `coverage-lcov.ts` / `coverage-source.ts` / `verify-coverage-run.ts` | an APP's `unit` step holds `coverage` in `x.verify.json` over its whole source tree
|
|
48
|
-
| `verify-deadline.ts` / `verify-stalled.ts` / `verify-progress.ts` | a step past its deadline is `X_VERIFY_STEP_TIMEOUT`: its children carry `ULTIMATE_VERIFY_STEP` and are killed by that tag; the finding names the test file `bun test` had not finished
|
|
48
|
+
| `coverage-floor.ts` / `coverage-lcov.ts` / `coverage-source.ts` / `verify-coverage-run.ts` | an APP's `unit` step holds `coverage` in `x.verify.json` over its whole source tree, in fixed slices, never `--parallel --coverage`; `coverage-lcov.ts` is the ONE lcov reader. Full rule: `docs/history/cli.md` |
|
|
49
|
+
| `verify-deadline.ts` / `verify-stalled.ts` / `verify-progress.ts` | a step past its deadline is `X_VERIFY_STEP_TIMEOUT`: its children carry `ULTIMATE_VERIFY_STEP` and are killed by that tag; the finding names the test file `bun test` had not finished. Full rule: `docs/history/cli.md` |
|
|
49
50
|
| `load-findings.ts` | module-load failures are reported once, by `manifest`; other steps point there |
|
|
50
|
-
| `boundary-findings.ts` / `app-boundaries.ts` / `boundary-cuts.ts` | surface + layer rules; a finding's `fix:` is the concrete cut |
|
|
51
|
-
| `app-transport.ts` / `browser-transport.ts` / `transport-calls.ts` / `import-closure.ts` / `server-barrels.ts` | `boundaries`, built in: one browser transport.
|
|
51
|
+
| `boundary-findings.ts` / `app-boundaries.ts` / `boundary-cuts.ts` / `package-boundaries.ts` | `package-boundaries.ts`: `X_BOUNDARY_PACKAGE_TO_APP`, its own read of `packages/`, never `readAppSources`. surface + layer rules; a finding's `fix:` is the concrete cut |
|
|
52
|
+
| `app-transport.ts` / `browser-transport.ts` / `transport-calls.ts` / `import-closure.ts` / `server-barrels.ts` | `boundaries`, built in: one browser transport. Never a `guards/` file: an app must not be able to delete it. Full rule: `docs/history/cli.md` |
|
|
52
53
|
| `guards.ts` / `guard-sources.ts` | an app's `guards/*.ts`, discovered, run on `boundaries`, held to the error contract; every `check(root, sources)` shares ONE walk, read and Sass compile per file (`GuardSources`) |
|
|
53
|
-
| `templates/scaffold-guards.ts` | `SHIPPED` — the one list of shipped guards: `x new` writes all, `x g guard <name>` writes one, `doctor-guards.ts` lists the ones an app lacks (a listing, never a finding).
|
|
54
|
+
| `templates/scaffold-guards.ts` | `SHIPPED` — the one list of the twenty-one shipped guards (`native-confirm` the newest): `x new` writes all, `x g guard <name>` writes one, `doctor-guards.ts` lists the ones an app lacks (a listing, never a finding). Full rule: `docs/history/cli.md` |
|
|
54
55
|
| `error-contract.ts` / `ts-scan.ts` / `fix-scan.ts` / `fix-imports.ts` / `fix-command.ts` / `fix-path.ts` | the `errors` step: every `fix:` names a runnable command, call or existing file |
|
|
55
|
-
| `workspace-checks.ts` / `test-only-shipped.ts` / `workspace-graph.ts` / `tsconfig-references.ts` / `publish-closure.ts` | `package-shape`, `filesize`.
|
|
56
|
-
| `app-permissions.ts` / `permission-grants.ts` / `app-permissions-borrowed.ts` / `app-permissions-site.ts` | `policy`: every permission granted or required is declared
|
|
56
|
+
| `workspace-checks.ts` / `test-only-shipped.ts` / `workspace-graph.ts` / `tsconfig-references.ts` / `publish-closure.ts` | `package-shape`, `filesize`. Full rule: `docs/history/cli.md` |
|
|
57
|
+
| `app-permissions.ts` / `permission-grants.ts` / `app-permissions-borrowed.ts` / `app-permissions-site.ts` | `policy`: every permission granted or required is declared and granted (`X_PERMISSION_UNGRANTED`, `X_PERMISSION_BORROWED`). Full rule: `docs/history/cli.md` |
|
|
57
58
|
| `job-registration.ts` | `manifest`: no job or task under a positional `anonymous-*` name (`X_JOB_UNREGISTERED`) |
|
|
58
|
-
| `unscanned-admin.ts` | `manifest`: a `defineAdmin()` outside the app scan (`apps/*/src/`) is `X_ADMIN_UNSCANNED
|
|
59
|
+
| `unscanned-admin.ts` | `manifest`: a `defineAdmin()` outside the app scan (`apps/*/src/`) is `X_ADMIN_UNSCANNED` |
|
|
60
|
+
| `tool-gate-names.ts` | `manifest`: a gate on no tool |
|
|
59
61
|
| `verify-role-load.ts` / `verify-role-load-probe.ts` | `manifest`: a child imports the app as a worker does, then the rest module by module; a registration only a document-reaching module makes is `X_ROLE_LOAD_INCOMPLETE` with the module and the import the API index lacks |
|
|
60
62
|
| `async-pages.ts` / `live-routes.ts` / `budgets.ts` / `budgets-unmeasured.ts` | `budgets` riders: an async `Page` with no `load`, a live read no island imports, bytes per route; an unweighed route's finding names a refused measurement actor and `defineMeasurementActor()` |
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `schema-
|
|
63
|
+
| `budgets-freshness.ts` / `verify-budgets-build.ts` | the step builds first when stats are missing, of an old rule, or older than source: `x build --target static --no-preflight --out .x/verify-static` through `ctx.runner` |
|
|
64
|
+
| `app-agents-md.ts` / `app-env.ts` / `app-openapi.ts` / `app-manifest.ts` | `manifest` and `contract-diff`. Full rule: `docs/history/cli.md` |
|
|
65
|
+
| `schema-drift.ts` / `drift.ts` / `drift-replica-identity.ts` / `db-destructive.ts` / `db-ungeneratable.ts` | `drift`: snapshot vs declarations, the source hash, the header markers. Full rule: `docs/history/cli.md` |
|
|
66
|
+
| `db-rolling.ts` / `doctor-rolling.ts` | `drift`'s fifth rail: what the previous release trips over (`X_MIGRATION_ROLLING_UNSAFE`, `@ultimat3/db`'s classifier), for migrations after `rollingSince` in `x.verify.json` (`x new` writes `"0"`). Full rule: `docs/history/cli.md` |
|
|
67
|
+
| `schema-dump-drift.ts` | also the dump-vs-newest-snapshot rail, no database (`X_DB_DRIFT`). Full rule: `docs/history/cli.md` |
|
|
64
68
|
| `i18n-registration.ts` / `i18n-audit.ts` / `admin-catalog-keys.ts` | `i18n`; a mounted admin's keys are `AdminApp.catalogKeys()`, asked of every app catalog — never re-derived here (`X_CATALOG_MISSING_KEYS`) |
|
|
65
69
|
| `error-unthrown.ts` / `unthrown-codes.ts` | host check: a registered code nothing throws is listed in `UNTHROWN_CODES` (a row's wording waives nothing); a listed code thrown again is `X_ERROR_CODE_UNTHROWN_STALE` |
|
|
70
|
+
| `lint-findings.ts` | `lint`: `biome check --reporter=json` as one finding per diagnostic |
|
|
71
|
+
| `i18n-app-key-shapes.ts` | every shape whose literal is a catalog key; `i18n-app-key-shapes.test.ts` reads `blocks`, so a new block reds until listed |
|
|
72
|
+
| `job-budget.ts` | `X_JOB_OUTLASTS_DRAIN`, the `manifest` step: a job's `timeout` against `workerBudgetMs(drain)`, read from the registry after `loadApp`, never from `x.manifest.json`, which carries no `timeoutMs` |
|
|
73
|
+
| `output-findings.ts` | render layer only: `runnableFix` (`bunx x`, decided by `dispatch.ts`'s `readerFor`) and `collapseFindings`. Throw sites keep `x …` |
|
|
74
|
+
| `app-load-unresolved.ts` | `X_APP_IMPORT_UNRESOLVED`, read by the scan, `findingFrom` and `x doctor`'s `snapshots` probe |
|
|
75
|
+
| `fix-truth.test.ts` / `fix-truth-fixture.ts` / `db-fix-truth.job.test.ts` | a printed fix, executed: each row breaks a scaffold, asserts the code and runs the line |
|
|
66
76
|
|
|
67
77
|
### Generators (`x g`, `x new`)
|
|
68
78
|
|
|
69
79
|
| File | Job |
|
|
70
80
|
|---|---|
|
|
71
81
|
| `cmd-generate.ts` / `generate-files.ts` / `generate-kinds.ts` / `generate-write.ts` | argv → pure file list → writes (conflict-checked, `merge: 'json'` / `'if-absent'`) |
|
|
82
|
+
| `write-generated.ts` | `x new`'s writer: a `link` file is a relative symlink, a copy only on a refusing win32 |
|
|
72
83
|
| `generate-feature.ts` | a `--feature` naming no slice is `X_FEATURE_UNKNOWN`; nothing invents an entity |
|
|
73
84
|
| `generate-shadow.ts` | a name whose type spelling a planned file also uses as a global or local type (`promise`, `row`), or whose camel VALUE a planned file both imports and declares (`x g job job`, TS2440), is `X_CLI_BAD_FLAG`, decided on the planned files |
|
|
74
85
|
| `generate-plural.ts` | a planned `entity.ts` in an already-plural slice (`posts` → `postses`) is `X_CLI_BAD_FLAG`; the fix names the singular |
|
|
75
86
|
| `generate-catalog-locales.ts` | `--locales` never starts a catalog in an app with any: a missing non-default locale is `X_CLI_BAD_FLAG`, `fix: x i18n add <locale>`; non-default values land `⟦…⟧`-marked (`seedCatalog`) |
|
|
76
87
|
| `app-name.ts` | `x new`'s slug is asked of core's `defineConfig`, never a copied pattern; refused with a suggested name (`9lives` → `app-9lives`, `a` → `a-app`, cut at 64) |
|
|
77
|
-
| `generate-grants.ts` | a written `policy.ts`
|
|
88
|
+
| `generate-grants.ts` | a written `policy.ts` or `entity.ts` declares and grants its permissions in `apps/web/shared/roles.ts`. Full rule: `docs/history/cli.md` |
|
|
78
89
|
| `api-registration.ts` | a written job or task is listed in `apps/web/api/index.ts` |
|
|
79
|
-
| `handle-registration.ts` / `workspace-dep-edit.ts` / `templates/scaffold-db-client.ts` | a written entity joins `
|
|
90
|
+
| `handle-registration.ts` / `workspace-dep-edit.ts` / `templates/scaffold-db-client.ts` | a written entity joins `entities` in `packages/db/src/client.ts` (`X_DB_HANDLE_UNREGISTERED` carries the lines). Full rule: `docs/history/cli.md` |
|
|
80
91
|
| `generated-imports.ts` | every sibling workspace a written file imports is declared in the manifest it landed under (`x g admin:page`'s `@<app>/i18n` in `apps/admin`) — `package-shape` would otherwise refuse the generator's own output (`X_WORKSPACE_DEP_UNDECLARED`) |
|
|
81
|
-
| `admin-registration.ts` / `templates/admin-catalog.ts` / `source-edit.ts` | `--admin`
|
|
82
|
-
| `app-artifacts.ts` | `x.manifest.json` + `openapi.json`, written together
|
|
83
|
-
| `templates/` | every emitted file; `scaffold-*.ts` for `x new`, one
|
|
92
|
+
| `admin-registration.ts` / `templates/admin-catalog.ts` / `source-edit.ts` | `--admin` wires the override it wrote into `admin.ts` (`X_ADMIN_RESOURCE_UNWIRED`) and the labels its screen reads. Full rule: `docs/history/cli.md` |
|
|
93
|
+
| `app-artifacts.ts` | `x.manifest.json` + `openapi.json`, written together (`x g`, `x manifest`) |
|
|
94
|
+
| `templates/` | every emitted file; `scaffold-*.ts` for `x new`, one per generator otherwise. See history |
|
|
95
|
+
| `generate-feature-required.ts` | `x g query`/`backfill` with no slice holding an `entity.ts` is `X_FEATURE_REQUIRED` |
|
|
96
|
+
| `generate-sign-in*.ts` | `x g sign-in`: one flag, no name; OIDC swaps only `x new`'s bytes |
|
|
97
|
+
| `generate-format-written.ts` | the app's Biome over the TypeScript a run created, best effort; `lint` judges |
|
|
98
|
+
| `templates/scaffold-mcp-json.ts` / `templates/scaffold-mcp-endpoint.ts` | `.mcp.json` (`bunx @ultimat3/cli mcp serve`, never `bunx x`) and the refusing `apps/web/mcp.ts` + `app/auth/agent-token.ts`; `scaffold-agents-md.test.ts` resolves every command `AGENTS.md` names |
|
|
84
99
|
|
|
85
100
|
### Boot (`x dev`, the container)
|
|
86
101
|
|
|
87
102
|
| File | Job |
|
|
88
103
|
|---|---|
|
|
89
|
-
| `serve.ts` / `serve-boot.ts` / `serve-entry.ts` / `serve-env.ts` | the production entry: roles from `ROLE`, bindings from env, `ROLE=migrate` = `x db migrate
|
|
90
|
-
| `role-load.ts` / `document-graph.ts` / `serve-web.ts` | a role imports what it runs: `ROLE_LOADS
|
|
104
|
+
| `serve.ts` / `serve-boot.ts` / `serve-entry.ts` / `serve-env.ts` | the production entry: roles from `ROLE`, bindings from env, `ROLE=migrate` = `x db migrate`; a module that fails to load stops it (`X_APP_MODULE_LOAD_FAILED`) |
|
|
105
|
+
| `role-load.ts` / `document-graph.ts` / `serve-web.ts` | a role imports what it runs: `ROLE_LOADS`, verified against `x.manifest.json` (`X_ROLE_LOAD_INCOMPLETE` imports everything); `serve-web.ts` behind `await import()`. Full rule: `docs/history/cli.md` |
|
|
91
106
|
| `module-imports.ts` | the files a module's source imports, resolved once for both graphs: `referenced` (reload) and `evaluated` (document) |
|
|
92
107
|
| `cmd-dev.ts` / `dev-boot.ts` / `dev-rebuild.ts` / `dev-route-table.ts` | `x dev`: the command (`cmd-dev.ts`, re-exports `startDev`); the boot — every role in one process, `/_x`, the watcher (`dev-boot.ts`); one save rebuilt as one generation (`dev-rebuild.ts`) |
|
|
93
108
|
| `runtime-bindings.ts` | which service each binding points at (embedded or external); events follow `realtime.transport` / `urlEnv` |
|
|
94
109
|
| `runtime-queue.ts` / `runtime-services.ts` / `runtime-bus.ts` | db + queue; every other accessor; the bus |
|
|
95
|
-
| `framework-schema-apply.ts` / `framework-schema-stamp.ts` | the framework tables: `ROLE=migrate`, `x dev` and every CLI command APPLY them in one transaction behind `MIGRATION_LOCK_KEY` (`pg_advisory_xact_lock`) with a bounded `lock_timeout
|
|
110
|
+
| `framework-schema-apply.ts` / `framework-schema-stamp.ts` | the framework tables: `ROLE=migrate`, `x dev` and every CLI command APPLY them in one transaction behind `MIGRATION_LOCK_KEY` (`pg_advisory_xact_lock`) with a bounded `lock_timeout`. Full rule: `docs/history/cli.md` |
|
|
96
111
|
| `runtime-isr.ts` | the ISR controller both boots serve through, ATTACHED to `invalidateTags` and released on stop (`attachedIsr`); `appRoutes` without one builds and attaches its own |
|
|
97
112
|
| `runtime-mfa-warning.ts` / `runtime-idempotency-scope.ts` | boot warnings an operator can act on: unsealed MFA secrets (web role, `x auth seal-mfa`), a per-process idempotency store after the app loaded |
|
|
98
|
-
| `app-config-load.ts` | the ONE reader of an app's `app.config.ts`: `loadAppConfig(root)` — the `config` export through core's `defineConfig`, so validated and default-merged; `undefined` with no file; no `config` object is `X_CONFIG_INVALID`.
|
|
113
|
+
| `app-config-load.ts` | the ONE reader of an app's `app.config.ts`: `loadAppConfig(root)` — the `config` export through core's `defineConfig`, so validated and default-merged; `undefined` with no file; no `config` object is `X_CONFIG_INVALID`. Full rule: `docs/history/cli.md` |
|
|
99
114
|
| `theme-brand.ts` | the ONE reader of an app's theme: `export const brand` in `apps/web/shared/theme.ts` (ui's `defineTheme`), inlined after the surface stylesheet with its hash in `style-src`; none → nothing emitted |
|
|
100
115
|
| `runtime-jobs.ts` / `runtime-realtime.ts` / `runtime-notify-retention.ts` / `runtime-cache.ts` / `runtime-purge.ts` / `runtime-replica.ts` | `app.config.ts` sections the boot obeys (`*Of(config)` over the one loaded config), and what each wires |
|
|
101
116
|
| `runtime-jobs.ts` (queues) | `jobs.queues` ∪ registered queues; `WORKER_QUEUES` = the EXACT set, each entry in that union or `X_WORKER_QUEUE_UNKNOWN`; `queue-unserved` warns the rest |
|
|
102
|
-
| `serve-retire.ts` / `dev-restart-retire.ts` | the worker retire
|
|
103
|
-
| `role-start.ts` / `role-start-types.ts` / `role-realtime.ts` | `--role` selection and start/stop for `web`, `sync`, `worker`, `scheduler`; `realtime.enabled: false` drops `sync` and `replicator
|
|
117
|
+
| `serve-retire.ts` / `dev-restart-retire.ts` | the worker retire, `stop()` claiming and aborting nothing: SIGUSR2 under `runRole`, and before a supervised `x dev` restart's drain (#677). Full rule: `docs/history/cli.md` |
|
|
118
|
+
| `role-start.ts` / `role-start-types.ts` / `role-realtime.ts` / `role-start-devices.ts` | `--role` selection and start/stop for `web`, `sync`, `worker`, `scheduler`; `realtime.enabled: false` drops `sync` and `replicator`; device mounts, swapped per path on save |
|
|
104
119
|
| `role-wake.ts` | the worker's LISTEN session (`@ultimat3/jobs`' `startQueueWake`) — worker role only, only over a client that `canListen` — and `queue_wake_live` |
|
|
105
120
|
| `role-sync.ts` / `role-replicator.ts` / `runtime-live-feed.ts` | the sync node, the change feed |
|
|
106
|
-
| `runtime-render.ts` / `runtime-isr-outcome.ts` / `route-islands.ts` / `runtime-assets.ts` / `runtime-storage.ts` / `runtime-hooks.ts` / `api-routes.ts` | the HTTP surface: pages
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
121
|
+
| `runtime-render.ts` / `runtime-render-document.ts` / `runtime-isr-outcome.ts` / `route-islands.ts` / `runtime-assets.ts` / `runtime-storage.ts` / `runtime-hooks.ts` / `api-routes.ts` | the HTTP surface: pages, `/icons` + `/media`, `/_storage`, authz, the app's API, bearer mounts and pages' bound `POST`s, mounted by BOTH boots. `isr` and `static` render as nobody. Full rule: `docs/history/cli.md` |
|
|
122
|
+
| `client-{errors,vitals}-*.ts` | `clientErrors` (and `.vitals`): the script on `app/` (vitals: listed) documents, its `POST` route, mounted by BOTH boots. Full rule: `docs/history/cli.md` |
|
|
123
|
+
| `retained-assets.ts` / `-layout.ts` / `-sweep.ts` / `-read.ts` / `-boot.ts` | `assets.retain`: the web boot publishes this build's hashed files before `/readyz`; `withRetainedAssets` answers an assets 404 a retained manifest names. `x dev` never wraps. Full rule: `docs/history/cli.md` |
|
|
124
|
+
| `runtime-overrides.ts` | the one field a host hands the framework a driver through — and `routes`, the plain routes for a wire format no primitive speaks (OAuth token endpoint); a webhook receiver needs no line here |
|
|
125
|
+
| `plain-routes.ts` | the plain routes both boots mount and `x routes` lists: `runtime.routes`, then every declared `webhookReceiver()`'s, each once |
|
|
109
126
|
| `app-openapi.ts` | `openapi.json` (complete when `defineApi({ openapi })` is declared) and each bearer mount's own document; staleness for all of them |
|
|
110
127
|
| `script-csp.ts` / `style-csp.ts` / `style-bundle.ts` / `page-sync.ts` / `worker-bundle.ts` | CSP hashes, the CSS file, the page's sync target and worker |
|
|
111
128
|
| `page-navigation.ts` | the client router for `navigation.client` surfaces — built, routed and named ONCE for `x dev`, the container and the static export; none opted in builds nothing |
|
|
112
|
-
| `page-speculation.ts` | Speculation Rules for documents WITHOUT the router (`navigation.speculation`):
|
|
129
|
+
| `page-speculation.ts` | Speculation Rules for documents WITHOUT the router (`navigation.speculation`): an allow-list of pure-read pages. Full rule: `docs/history/cli.md` |
|
|
113
130
|
| `static-document.ts` | a served `static` page: `304` on a matching `If-None-Match`, and (container only, `memoStatic`) the document kept after its first render. Never `x dev` — a save moves the stylesheet URL the kept document names |
|
|
114
|
-
| `island-bundle.ts` / `island-store.ts` / `island-sources.ts` / `island-realtime.ts` / `island-realtime-state.ts` / `island-runtime.ts` / `solid-loader.ts` | islands: one `Bun.build` each, source-addressed; the image build writes a verified store
|
|
115
|
-
| `local-cli.ts` / `local-cli-handoff.ts` | a global `x` hands over to the app's own CLI (`local-cli.ts` decides whether
|
|
131
|
+
| `island-bundle.ts` / `island-store.ts` / `island-sources.ts` / `island-realtime.ts` / `island-realtime-state.ts` / `island-runtime.ts` / `solid-loader.ts` | islands: one `Bun.build` each, source-addressed; the image build writes a verified store, and an edit since the build is a rebuild, never the old chunk |
|
|
132
|
+
| `local-cli.ts` / `local-cli-handoff.ts` | a global `x` hands over to the app's own CLI (`local-cli.ts` decides whether; `x upgrade` alone stays when the app's is strictly older — `upgrade-handover.test.ts`) |
|
|
116
133
|
| `serve-prebuilt.ts` / `serve-prebuilt-paths.ts` | the image's prebuilt store (`node_modules/.cache/ultimate`, never `.x/` — state, tmpfs): every role adopts its compiled stylesheets before importing the app; a boot that built an island or ran Sass logs `X_IMAGE_NOT_PREBUILT` once |
|
|
117
134
|
| `dev-*.ts` | `x dev` only: dashboard sources, traces, the N+1 ledger, the watcher, the reload, the lock, the port |
|
|
118
|
-
| `
|
|
135
|
+
| `cmd-stop.ts` / `cmd-stop-spec.ts` | `x stop`: the lock's pid only (its recorded start time must match), SIGTERM, then wait for pid gone and lock clear; Windows clears the lock (`drained: false`); `X_DEV_STOP_TIMEOUT` |
|
|
136
|
+
| `dev-dashboard-guard.ts` / `loopback-host.ts` | `/_x` answers a loopback `Host` only (`X_DEV_HOST_REFUSED`, 421 — DNS rebinding); the SQL panel runs on a same-origin `POST /_x/db` only, through admin's `readOnlySql` |
|
|
137
|
+
| `doctor-pooler.ts` / `runtime-statement-bound.ts` | the applied bound on demand (`data.statementBound`), a pooler's refusal as the one database finding; the one boot line, total. `startDb` hands `poolerFromEnv(env)` to both pools |
|
|
119
138
|
|
|
120
139
|
### Build and data
|
|
121
140
|
|
|
122
141
|
| File | Job |
|
|
123
142
|
|---|---|
|
|
124
143
|
| `cmd-build.ts` / `image-prepare.ts` | `x build`: static gate first; `docker` stamps `BUILD_ID`; `prebuilt` is the Dockerfile's own `RUN` — islands and stylesheets, written by the image's Bun at the image's paths, no gate and no subprocess |
|
|
125
|
-
| `prerender.ts` / `measure-scope.ts` / `static-report.ts` | the static export;
|
|
144
|
+
| `prerender.ts` / `measure-scope.ts` / `static-report.ts` / `static-*.ts` | the static export; a weigh-only render runs as core's `measurementActor()`, API in process (`withInProcessFetch`); SEO reads as nobody; `/_img/` + `/_og/` files; `--no-capture` the gate's |
|
|
126
145
|
| `sw-artifacts.ts` / `pwa-artifacts.ts` / `favicon.ts` | the service worker, the web manifest, `/favicon.ico` |
|
|
127
|
-
| `cmd-db.ts` / `migrations.ts` / `db-generate.ts` / `db-branch.ts` / `db-seed.ts` / `db-backfill.ts` / `db-subscribes.ts` / `db-accept-created.ts` | one migration engine for `x db` and `ROLE=migrate` |
|
|
128
|
-
| `db-
|
|
146
|
+
| `cmd-db.ts` / `migrations.ts` / `db-generate.ts` / `db-branch.ts` / `db-seed.ts` / `db-seed-generate.ts` / `db-backfill.ts` / `db-subscribes.ts` / `db-accept-created.ts` | one migration engine for `x db` and `ROLE=migrate` |
|
|
147
|
+
| `db-diagnostics.ts` | `x db diagnostics`: `startDb` (never `startQueue`, which applies the framework tables), `@ultimat3/db/diagnostics`'s `dbDiagnostics`, one table per section; exit 0 whatever it says; an embedded database `x dev` holds is `X_DEV_ALREADY_RUNNING` |
|
|
148
|
+
| `db-schema-dump.ts` / `db-schema-refresh.ts` / `db-replay-engine.ts` / `migration-extensions.ts` / `db-object-drift.ts` | the schema dump: replay on a scratch database (full rule: history), written by `x db gen` and `x db migrate`. `migration-extensions.ts` is also what `runtime-queue.ts` links `x dev`'s database with |
|
|
129
149
|
|
|
130
150
|
### Introspection and tools
|
|
131
151
|
|
|
132
152
|
| File | Job |
|
|
133
153
|
|---|---|
|
|
134
154
|
| `cmd-registries.ts` / `cmd-jobs.ts` / `cmd-tasks.ts` / `cmd-policy.ts` / `cmd-i18n.ts` | project a framework registry; each pairs CLI wiring with a facts module |
|
|
135
|
-
| `cmd-auth.ts` / `cmd-auth-spec.ts` / `doctor-auth.ts` | `x auth seal-mfa`:
|
|
136
|
-
| `cmd-mcp.ts` / `mcp-host.ts` / `mcp-errors.ts` / `mcp-db-target.ts` | `x mcp serve`:
|
|
155
|
+
| `cmd-auth.ts` / `cmd-auth-spec.ts` / `doctor-auth.ts` | `x auth seal-mfa`: seals plaintext `x_users.mfa_secret` through auth's `sealMfaSecrets` |
|
|
156
|
+
| `cmd-mcp.ts` / `mcp-host.ts` / `mcp-errors.ts` / `mcp-db-target.ts` | `x mcp serve`: 19 tools, two transports; a taken port is `X_PORT_IN_USE`; over HTTP a non-loopback Host is 421 `X_MCP_HOST_REFUSED` first, `GET`/`DELETE` http's 405. `mcp-test-run.ts` folds `bun test`'s `N errors` line and exit code into `tests.run` |
|
|
137
157
|
| `cmd-shot*.ts` / `cdp-shot-*.ts` / `browser-launcher*.ts` / `island-*` | `x shot` over raw CDP; `verdict.json` names its own blind spots. Not a gate step |
|
|
138
|
-
| `cmd-pr.ts` / `cmd-ci.ts` | GitHub through `gh`, parsed against a schema. Not gate steps |
|
|
158
|
+
| `cmd-pr.ts` / `cmd-ci.ts` / `ci-runs.ts` / `ci-tested.ts` | GitHub through `gh`, parsed against a schema. Not gate steps. `x ci tested` is a pure predicate over three injected reads; every doubt is `tested: false`, exit 0 |
|
|
139
159
|
| `error-catalog.ts` | imports every `@ultimat3/*` package so `x errors` answers for any code |
|
|
160
|
+
| `cmd-docs.ts` / `docs-sources.ts` / `docs-section.ts` | `x docs`: the app's `@ultimat3` scope plus the CLI's own (Bun's isolated layout), the wiki at `<cli>/wiki` (tarball) or `<cli>/../../wiki` (checkout); `Page#anchor` prints a whole section |
|
|
161
|
+
| `cmd-env-init.ts` / `env-production.ts` / `cmd-deploy-preflight.ts` | `x env init --production`, the one writer of `.env.production` (values from `cmd-deploy-compose.ts`); compose's pre-flight (`X_DEPLOY_ENV_MISSING`) and a failed step's container line |
|
|
162
|
+
| `cmd-upgrade.ts` / `upgrade-*.ts` | `x upgrade`: one major per run; declares no `requiresApp` (`upgrade-root.ts`), and with no app runs the root's `typecheck`/`test` scripts and says so in `data.proof`; `upgrade-agents-link.ts`: `data.agentsMd` |
|
|
163
|
+
| `cmd-deploy-verify.ts` / `deploy-verify-*.ts` | `x deploy verify`: the wait (samples, window, queues), the pure verdict, flags refused before a sample, the `--json` shape, the real sources (lazy, so the build verdict loads neither). `DATABASE_URL` from the env only, never `resolveServices` (full rule: history) |
|
|
140
164
|
|
|
141
165
|
## Adding a command
|
|
142
166
|
|
package/README.md
CHANGED
|
@@ -2,35 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
The `x` binary. One char during dev, one command per job, `--json` on every one of them.
|
|
4
4
|
|
|
5
|
+
`bun add @ultimat3/cli` · guide: [CLI Reference](https://github.com/developerz-ai/ultimate/wiki/CLI-Reference)
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
bunx create-ultimate myapp && cd myapp && bun run setup
|
|
9
|
+
bun run verify # x verify, the gate: green means shippable
|
|
10
|
+
```
|
|
11
|
+
|
|
5
12
|
## What it owns
|
|
6
13
|
|
|
7
14
|
Commands and the `x verify` step count, `As of 2026-08`:
|
|
8
15
|
|
|
9
16
|
| Command | Does | Notes |
|
|
10
17
|
|---|---|---|
|
|
11
|
-
| `x new <name>` | scaffolds the monorepo | interactive-free; auth, seeded DB, example route |
|
|
18
|
+
| `x new <name>` | scaffolds the monorepo | interactive-free; auth, seeded DB, example route. `--shape api\|blog\|dashboard` starts from an app shape instead ([Shapes](https://github.com/developerz-ai/ultimate/wiki/Shapes)) |
|
|
12
19
|
| `x dev` | every role in one process | embedded Postgres/events/storage, `/_x` mounted |
|
|
20
|
+
| `x stop` | ends this checkout's `x dev`: the pid `.x/dev.lock` names, nothing else | returns once the next `x dev` can boot; `X_DEV_STOP_TIMEOUT` past `--timeout` |
|
|
13
21
|
| `x build --target docker\|binary\|static` | one artifact | `ROLE` selects behaviour at start |
|
|
14
22
|
| `x build --target prebuilt` | the store a container boots from: island chunks, compiled stylesheets | a `RUN` line in the image build, never run by hand |
|
|
15
|
-
| `x verify` | **the gate** |
|
|
23
|
+
| `x verify` | **the gate** | 21 named steps, each with pass/fail + duration; `budgets` runs `x build --target static` first when its stats are missing or older than the source |
|
|
24
|
+
| `x exercise [<name>] [--seed n]` | every action, query and job run once on generated rows, no test written | a scratch database; `.x/exercise.json`; an `unreached` primitive is `X_CONTRACT_EXERCISE_UNREACHED` with the override to paste into `apps/web/exercise.ts` — the gate's `exercise` step |
|
|
25
|
+
| `x drill [<name>] [--list] [--budget-ms n]` | the app's roles as real processes on real services, each fault played through a proxy or a signal, judged on framework contracts only | a scratch database per drill; load = anonymous site pages plus every action an anonymous POST reaches (`data.skippedWrites` names the rest and why); `X_DRILL_FAILED` per property that did not hold, `X_DRILL_SERVICE_MISSING` before anything starts. Not a gate step — CI's `fault-drills` job runs three on `examples/dummy` |
|
|
16
26
|
| `x g <primitive> <name>` | scaffolds a primitive **with a passing test** | never a TODO stub |
|
|
17
27
|
| `x db gen\|migrate\|reset\|branch\|backfill` | everything DB | `branch` = copy-on-write clone + preview URL; `backfill` dry-runs unless `--write`. `x db studio` is **planned** — it parses, and exits `X_NOT_IMPLEMENTED` naming `/_x`'s db panel |
|
|
18
|
-
| `x mcp serve` | `@ultimat3/mcp`'s
|
|
28
|
+
| `x mcp serve` | `@ultimat3/mcp`'s 19 dev tools, over stdio or HTTP | one catalog, one scope set, both transports |
|
|
29
|
+
| `x upgrade` | one major per run: exact pins, the Bun floor, `bun install`, the gate; an `AGENTS.md` byte-identical to `CLAUDE.md` becomes a symlink to it, a different one is reported in `data.agentsMd` and left | the `--json` report names the wiki section, the guards that differ and what the gate still says ([fields](../../wiki/CLI-Reference.md#x-upgrade)); `bunx @ultimat3/cli@latest upgrade` in an app that predates it; pins with no `app.config.ts` still hop, and `data.proof` says what checked them |
|
|
19
30
|
| `x doctor` | environment, ports, drift, PWA prerequisites, `APP_URL` | every finding carries a fix command; probes the port `x dev` binds ([which one](../../wiki/CLI-Reference.md#x-doctor)); the framework's deploy secrets only where the machine names `staging`/`production` |
|
|
20
|
-
| `x deploy` | container deploy plan | compose or helm; zero platform primitives |
|
|
31
|
+
| `x deploy` | container deploy plan | compose or helm; zero platform primitives. Compose reads `.env.production` first (`X_DEPLOY_ENV_MISSING`). Helm carries `drain.*`, `drain.workerRetireMs` as `roles.worker.retireSeconds`, and `jobs.maxInFlight` as the worker's `targetAverageValue` |
|
|
32
|
+
| `x deploy verify` | production serves this build, holds it, and a worker of it claims every queue | samples `/readyz` through the load balancer, grades `x_job_workers` when `DATABASE_URL` is set; no platform API |
|
|
21
33
|
| `x manifest` / `x routes` | generated facts | `x.manifest.json`, `openapi.json`, route table |
|
|
22
34
|
| `x actions` / `x queries` / `x entities` | the declaration registries | `list` and `show <name>`, straight off the registries |
|
|
23
35
|
| `x tasks list\|show` | cron tasks | timezone and next run, off `registeredTasks()` |
|
|
24
36
|
| `x jobs list\|show\|retry\|cancel\|delete\|promote\|pause\|resume` | the queue | depth, dead letters, step traces, `retry --from-step`, `cancel --reason`; `list --json` pages as `rows`/`nextCursor`/`hasMore`; `drain` is planned (`X_NOT_IMPLEMENTED`) |
|
|
25
37
|
| `x test [type]` | one of the six test types, or all | same type rule as the gate; `--filter`, `--sample N` |
|
|
26
|
-
| `x env check\|example` | the typed environment `envSchema` declares | and the `.env.example` rendered from it, plus the framework's deploy-required secrets (`ULTIMATE_CURSOR_SECRET`, `STORAGE_SIGNING_SECRET` unless `S3_ENDPOINT` is set), which `check` asks for wherever the boot refuses them — outside `development`/`test`, or with no environment named |
|
|
38
|
+
| `x env check\|example\|init` | the typed environment `envSchema` declares; `init --production` writes `.env.production` for a compose deploy, secrets generated, never printed | and the `.env.example` rendered from it, plus the framework's deploy-required secrets (`ULTIMATE_CURSOR_SECRET`, `STORAGE_SIGNING_SECRET` unless `S3_ENDPOINT` is set), which `check` asks for wherever the boot refuses them — outside `development`/`test`, or with no environment named |
|
|
27
39
|
| `x auth seal-mfa` | one-shot auth maintenance | seals every `x_users.mfa_secret` still in the clear; idempotent, `{ sealed, alreadySealed, skipped }` |
|
|
28
40
|
| `x secrets show\|init\|edit\|set\|rotate` | the committed encrypted secrets | decrypted into the `envSchema` variables of the same names |
|
|
29
41
|
| `x policy list\|explain <subject>` | which clause decided a permission, and why | five packages print `x policy explain` as a denial's `fix:` |
|
|
30
42
|
| `x i18n check\|add\|sync` | catalogs: gaps, a new locale, key sync | all three of i18n's own error fixes name it |
|
|
31
43
|
| `x errors explain <CODE>` / `list` | the error table, programmatically | refuses an unregistered code instead of inventing one |
|
|
32
|
-
| `x
|
|
44
|
+
| `x repro <id> [--write] [--verify]` / `--list` / `--from` | a dead job or a captured 5xx as a red test in `repro/` | `--verify` answers `{ reproduced, code, fingerprint }`; a mismatch is `X_REPRO_NOT_REPRODUCED`, never a crash |
|
|
45
|
+
| `x docs "<question>"` | the framework docs and the wiki, offline | answered from the installed packages and the `wiki/` this tarball ships (`prepack`: `scripts/pack-cli-wiki.ts`), never the network; `x docs Upgrading#<anchor>` prints one whole section |
|
|
46
|
+
| `x graph [--from a --to b]` / `x impact <file\|primitive\|entity>` | the app as one typed graph (`@ultimat3/manifest`'s `buildGraph` over the loaded app, its module graph and `.x/exercise.json`) · what an edit reaches | every edge `declared`, `import` or `observed`; a miss is `X_GRAPH_NODE_UNKNOWN` with the nearest three; `x affected` in an app root adds `data.tests` by import closure ([details](../../wiki/CLI-Reference.md#x-graph--x-impact)) |
|
|
47
|
+
| `x client vendor <name>` / `x client customer --out <dir>` | one OpenAPI compiler (`openapi-compile.ts`), two emitters: a vendor's document into `apps/web/clients/<name>/` (`outbound()` + `t`), or the app's published document into a client with no framework import | every generated file is stamped with its source and body hash; `drift` raises `X_CLIENT_STALE` / `X_CLIENT_EDITED` ([flags](../../wiki/CLI-Reference.md#x-client)) |
|
|
33
48
|
| `x fix boundary <file>` | the minimal cut for a crossed surface boundary | prints the plan and the `git mv`; never rewrites a file |
|
|
49
|
+
| `x ci [runs]` / `x ci tested` | CI triage through `gh`; `tested`: may this push reuse a green PR run of the same tree | `tested` exits 0 on every answer, `data.tested`; any doubt is `false`, a full run ([conditions](../../wiki/CLI-Reference.md#x-pr--x-ci)) |
|
|
34
50
|
|
|
35
51
|
Everything in [CLI reference](../../wiki/CLI-Reference.md)'s planned table is also in the registry
|
|
36
52
|
and exits `X_NOT_IMPLEMENTED` with a `fix:` naming the closest shipped command — "not built yet"
|
|
@@ -61,6 +77,16 @@ weigh measures the page a holder of that role is served. Any other refusal (a mi
|
|
|
61
77
|
`TypeError` in `load`) keeps the generic `fix:` — the `unmeasured` list of
|
|
62
78
|
`x build --target static --json` — with the code already in the cause.
|
|
63
79
|
|
|
80
|
+
## `x build --target static`: images and cards as files
|
|
81
|
+
|
|
82
|
+
While the export renders, `@ultimat3/seo`'s static seam is installed (`static-capture.ts`). Every
|
|
83
|
+
`responsiveImage()` candidate an exported document names is written to `/_img/<hash>-<w>.<ext>`
|
|
84
|
+
(`static-images.ts`) — a `src` the export lacks is `X_IMAGE_SOURCE_UNREADABLE`, an `avif` is
|
|
85
|
+
`X_IMAGE_UNSUPPORTED`. Every `og.capture` card is photographed from its exported page at 1200 x 630
|
|
86
|
+
into `/_og/<path>.png` over the CLI's own CDP driver (`static-cards.ts`); no such page is
|
|
87
|
+
`X_SEO_CARD_ROUTE_UNKNOWN`, no browser `X_SEO_CARD_BROWSER_MISSING`. `--no-capture` stamps the same
|
|
88
|
+
tags and takes no picture: `x verify`'s build and the reference-app gate pass it. `As of 2026-11`.
|
|
89
|
+
|
|
64
90
|
## Which `x` runs
|
|
65
91
|
|
|
66
92
|
**The app's own.** `x` is a workspace dependency, and `bunx x` / the `package.json` scripts resolve
|
|
@@ -77,6 +103,9 @@ is a different file (`local-cli.ts`), prints one line on stderr saying so, and e
|
|
|
77
103
|
child's code; fd 1 is the child's alone, so a `--json` consumer sees one document. A workspace
|
|
78
104
|
symlink resolves to the same file and is not handed over (both tracked apps, and every scaffold
|
|
79
105
|
CI installs), and a compiled `x` keeps itself — its own path is not one `realpath` can resolve.
|
|
106
|
+
**`x upgrade` is the one exception:** an app's CLI strictly older than the invoked one keeps the
|
|
107
|
+
invoked one, so `bunx @ultimat3/cli@latest upgrade` works in an app whose own CLI has no such
|
|
108
|
+
command. It opens no second registry: it loads no app, and its gate is the installed CLI's.
|
|
80
109
|
`ULTIMATE_KEEP_GLOBAL_CLI=1` keeps the CLI that was invoked, for the one deliberate case: running a
|
|
81
110
|
checkout's `x` against an app pinned to an older release to see what the next one would say.
|
|
82
111
|
|
|
@@ -93,15 +122,15 @@ X_DB_DRIFT: schema differs from migrations
|
|
|
93
122
|
|
|
94
123
|
```sh
|
|
95
124
|
x verify --json
|
|
96
|
-
# {"ok":false,"command":"verify","summary":"1 of
|
|
125
|
+
# {"ok":false,"command":"verify","summary":"1 of 21 steps failed","steps":[...]}
|
|
97
126
|
```
|
|
98
127
|
|
|
99
128
|
## `x verify` steps
|
|
100
129
|
|
|
101
|
-
`typecheck lint boundaries filesize package-shape errors unit contract live job e2e eval
|
|
102
|
-
contract-diff budgets seo i18n policy manifest roadmap`
|
|
130
|
+
`typecheck lint boundaries filesize package-shape errors unit contract live job exercise e2e eval
|
|
131
|
+
drift contract-diff budgets seo i18n policy manifest roadmap`
|
|
103
132
|
|
|
104
|
-
|
|
133
|
+
21 steps, in cost order, defined once as `VERIFY_STEP_NAMES` (`verify-step.ts`) — the summary
|
|
105
134
|
count above is projected from that list, and the framework repo's own gate (`bun run verify`)
|
|
106
135
|
runs exactly it. A step with nothing to check here reports as skipped, never as
|
|
107
136
|
passed. Never bails early: an agent fixing three things needs all three findings from one run.
|
|
@@ -140,7 +169,7 @@ walked and read once however many guards ask, and `compiled(path)` is a styleshe
|
|
|
140
169
|
compiles it. Nothing registers a guard — the directory is the registration — and what a guard returns
|
|
141
170
|
is held to the same error contract shipped source is (`X_GUARD_INVALID`, `X_GUARD_FAILED`,
|
|
142
171
|
`X_GUARD_FINDING_INVALID`). `x g guard <name>` scaffolds one with its test — the shipped guard of
|
|
143
|
-
that name where there is one (`x new` writes all
|
|
172
|
+
that name where there is one (`x new` writes all twenty), the blank template otherwise — and
|
|
144
173
|
`x doctor` lists the shipped ones an app does not hold.
|
|
145
174
|
|
|
146
175
|
## Layout
|
|
@@ -169,6 +198,7 @@ that name where there is one (`x new` writes all seventeen), the blank template
|
|
|
169
198
|
| `app-manifest.ts` | `x.manifest.json`, projected by `@ultimat3/manifest` |
|
|
170
199
|
| `app-openapi.ts` | `openapi.json`, projected by `@ultimat3/action` |
|
|
171
200
|
| `app-boundaries.ts` | app import boundaries, over `@ultimat3/render`'s surface check |
|
|
201
|
+
| `package-boundaries.ts` | `boundaries`: a file under `packages/` importing `apps/` at runtime is `X_BOUNDARY_PACKAGE_TO_APP`; `packages/db/src/` may read an entity module |
|
|
172
202
|
| `app-transport.ts` / `browser-transport.ts` | one browser transport, on `boundaries` in every app: a raw `fetch(`, `new WebSocket(` or `new XMLHttpRequest(` in an island's closure is `X_BROWSER_TRANSPORT_BYPASS`; a server barrel there is `X_BROWSER_SERVER_BARREL` |
|
|
173
203
|
| `app-agents-md.ts` | `AGENTS.md` exists and stays short, over `@ultimat3/manifest`'s check |
|
|
174
204
|
| `serve.ts` | **what a container starts** — `runRole(options)`, the same boot `x dev` runs minus the watcher, `/_x` and `dev: true`. `x new`'s `apps/web/server.ts` is three lines that call it. `ROLE`, `PORT` and `HOST` are read from `env`; `role`, `port` and `hostname` on `ServeOptions` override each. `ROLE=worker` also retires on SIGUSR2 (`serve-retire.ts`, 25.0.0): stop claiming, finish every held job, abort nothing, drain, exit 0 — what the chart's opt-in `roles.worker.retireSeconds` `preStop` sends; core's `isRetiring()` is true from the signal on, and a SIGTERM mid-retire drains on `drain.workerDeadlineMs` when declared (`lifecycleForRole`); a no-op on Windows ([Deployment](../../wiki/Deployment.md#retiring-a-worker-before-sigterm)) |
|
|
@@ -179,11 +209,16 @@ that name where there is one (`x new` writes all seventeen), the blank template
|
|
|
179
209
|
| `dev-*.ts` | what `x dev` boots: services, runtime, routes, hooks, roles, the `/_x` mount |
|
|
180
210
|
| `island-bundle.ts` | every `*.island.tsx` built as its own entry point, content-hashed |
|
|
181
211
|
| `island-routes.ts` | the one route those chunks are served from, in dev and in the container |
|
|
212
|
+
| `retained-assets.ts` / `-sweep.ts` / `-read.ts` / `-layout.ts` / `-boot.ts` | `assets.retain`: the web boot publishes this build's hashed files to `x-build-assets/<app>/<environment>/` on a shared disk before `/readyz` (30 s deadline), sweeps to the newest `builds` without touching a concurrent publish, and `withRetainedAssets(routes, reader)` answers an asset route's 404 for any URL a retained manifest names — an open tab keeps its stylesheet and islands across a deploy |
|
|
213
|
+
| `client-errors-script.ts` / `client-errors-routes.ts` | `clientErrors.enabled`: `/x-client-errors.js` on every `app/` document (`DocumentOptions.appHead`, never `site/`), and `POST /_client-errors` — same-origin proven, 32 KiB, closed shape, the app's rate-limit store, an island id grouped on only when this build serves it — into `reportError(…, { source: 'browser' })` as `X_CLIENT_ERROR`. Both boots mount it beside `/_storage`; a static export warns ([Observability](../../wiki/Observability.md#browser-failures)) |
|
|
214
|
+
| `client-vitals-script.ts` / `client-vitals-route.ts` / `prerender-vitals.ts` | `clientErrors.vitals`: `/x-client-vitals.js` on documents of each listed surface (`app` by default; `DocumentOptions.appHead` / `siteHead`, composed with the error script by `clientScriptHeads`), and `POST /_client-vitals` — same origin, 4 KiB, 60 a minute per address, every outcome `204` — into `web_vital_seconds{route, metric}` / `web_vital_cls{route}` by route PATTERN. Both boots mount it; the build charges it to each listed route's `budget.js` as served ([Observability](../../wiki/Observability.md#real-user-timings)) |
|
|
182
215
|
| `mcp-host.ts` | the shell-side half of `@ultimat3/mcp`'s dev server — db, tests, logs, verify |
|
|
183
216
|
| `verify-step.ts` | the step shape, the step names, the host-check hook |
|
|
184
217
|
| `verify-tests.ts` | one `bun test` invocation per test type |
|
|
185
218
|
| `workspace-checks.ts` | file-size ceiling and package contract files |
|
|
186
219
|
| `drift.ts` `budgets.ts` | the checks `x verify` composes |
|
|
220
|
+
| `budgets-freshness.ts` `verify-budgets-build.ts` | whether `budgets` may read the stats on disk, and the build it runs when not |
|
|
221
|
+
| `cmd-stop.ts` | `x stop`: SIGTERM to the lock's pid, the wait, the Windows lock clear |
|
|
187
222
|
|
|
188
223
|
The CLI describes an app by **loading** it, never by parsing it: `action()`, `entity()`,
|
|
189
224
|
`job()` and `defineRoute()` register themselves, and `x manifest`, `x routes` and `x verify`
|
|
@@ -201,10 +236,25 @@ apps/web/{site,app}/<path>/page.tsx
|
|
|
201
236
|
apps/web/{site,app}/<path>/<name>.island.tsx # x g island <name> --at <dir>
|
|
202
237
|
apps/admin/app/admin/pages/<name>.tsx # x g admin:page <name> --permission p
|
|
203
238
|
guards/<name>.ts # x g guard <name>
|
|
239
|
+
apps/web/app/auth/{sign-in,actions,…} # x g sign-in --password | --oidc <provider>
|
|
240
|
+
apps/web/runtime.ts # …and the boot guard it calls
|
|
241
|
+
docker/helm/templates/{servicemonitor,alert-rules}.yaml # x g chart-alerts [--print]
|
|
204
242
|
```
|
|
205
243
|
|
|
206
244
|
Every emitted source has a `<file>.test.ts` beside it that passes on the first run.
|
|
207
245
|
|
|
246
|
+
`x g chart-alerts` takes no `<name>` either — `docker/helm/Chart.yaml` names the chart — and writes
|
|
247
|
+
only the monitoring templates and `values.yaml` blocks an older app chart lacks
|
|
248
|
+
(`generate-chart-alerts.ts`); `x doctor` lists them (`doctor-chart-alerts.ts`). `--print` is the
|
|
249
|
+
same rule table as plain Prometheus rule groups, for a loader outside Kubernetes.
|
|
250
|
+
|
|
251
|
+
`x g sign-in` takes no `<name>` — an app has one sign-in — and exactly one of `--password` or
|
|
252
|
+
`--oidc <provider>` (`generate-sign-in-mode.ts`). It writes through `writeFiles` like every
|
|
253
|
+
generator (a second run is `X_GENERATE_CONFLICT`), then edits `app.config.ts`
|
|
254
|
+
(`generate-sign-in-config.ts`) and, for OIDC, swaps `x new`'s authenticator only while it is
|
|
255
|
+
byte-for-byte `x new`'s (`generate-sign-in.ts`). `generate-sign-in.contract.test.ts` compiles,
|
|
256
|
+
lints and runs what both shapes leave; `e2e/sign-in.e2e.test.ts` signs in to a production boot.
|
|
257
|
+
|
|
208
258
|
## Errors
|
|
209
259
|
|
|
210
260
|
`X_CLI_UNKNOWN_COMMAND` `X_CLI_BAD_FLAG` `X_VERIFY_FAILED` `X_NOT_IN_APP` `X_BUN_VERSION`
|
package/package.json
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "30.1.0",
|
|
4
4
|
"description": "The `x` binary: new, dev, build, verify, generate, db, mcp, doctor, deploy",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ultimate",
|
|
7
|
+
"bun",
|
|
8
|
+
"framework",
|
|
9
|
+
"cli",
|
|
10
|
+
"generator",
|
|
11
|
+
"scaffold",
|
|
12
|
+
"verify",
|
|
13
|
+
"mcp"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/developerz-ai/ultimate/wiki/CLI-Reference",
|
|
5
16
|
"license": "MIT",
|
|
6
17
|
"type": "module",
|
|
7
18
|
"repository": {
|
|
@@ -25,6 +36,7 @@
|
|
|
25
36
|
"!src/**/*.test.ts",
|
|
26
37
|
"!src/**/*-fixture.ts",
|
|
27
38
|
"types",
|
|
39
|
+
"wiki/*.md",
|
|
28
40
|
"CLAUDE.md",
|
|
29
41
|
"README.md",
|
|
30
42
|
"LICENSE"
|
|
@@ -35,37 +47,39 @@
|
|
|
35
47
|
"scripts": {
|
|
36
48
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
37
49
|
"test": "bun test",
|
|
50
|
+
"prepack": "bun run ../../scripts/pack-cli-wiki.ts",
|
|
51
|
+
"postpack": "bun run ../../scripts/pack-cli-wiki.ts --clean",
|
|
38
52
|
"dev": "bun run src/bin.ts dev"
|
|
39
53
|
},
|
|
40
54
|
"dependencies": {
|
|
41
55
|
"@babel/core": "^8.0.7",
|
|
42
|
-
"@ultimat3/action": "
|
|
43
|
-
"@ultimat3/admin": "
|
|
44
|
-
"@ultimat3/ai": "
|
|
45
|
-
"@ultimat3/auth": "
|
|
46
|
-
"@ultimat3/cache": "
|
|
47
|
-
"@ultimat3/core": "
|
|
48
|
-
"@ultimat3/db": "
|
|
49
|
-
"@ultimat3/entity": "
|
|
50
|
-
"@ultimat3/flags": "
|
|
51
|
-
"@ultimat3/http": "
|
|
52
|
-
"@ultimat3/i18n": "
|
|
53
|
-
"@ultimat3/jobs": "
|
|
54
|
-
"@ultimat3/mail": "
|
|
55
|
-
"@ultimat3/manifest": "
|
|
56
|
-
"@ultimat3/mcp": "
|
|
57
|
-
"@ultimat3/money": "
|
|
58
|
-
"@ultimat3/notify": "
|
|
59
|
-
"@ultimat3/policy": "
|
|
60
|
-
"@ultimat3/pwa": "
|
|
61
|
-
"@ultimat3/query": "
|
|
62
|
-
"@ultimat3/realtime": "
|
|
63
|
-
"@ultimat3/render": "
|
|
64
|
-
"@ultimat3/schema": "
|
|
65
|
-
"@ultimat3/seo": "
|
|
66
|
-
"@ultimat3/storage": "
|
|
67
|
-
"@ultimat3/testing": "
|
|
68
|
-
"@ultimat3/time": "
|
|
56
|
+
"@ultimat3/action": "30.1.0",
|
|
57
|
+
"@ultimat3/admin": "30.1.0",
|
|
58
|
+
"@ultimat3/ai": "30.1.0",
|
|
59
|
+
"@ultimat3/auth": "30.1.0",
|
|
60
|
+
"@ultimat3/cache": "30.1.0",
|
|
61
|
+
"@ultimat3/core": "30.1.0",
|
|
62
|
+
"@ultimat3/db": "30.1.0",
|
|
63
|
+
"@ultimat3/entity": "30.1.0",
|
|
64
|
+
"@ultimat3/flags": "30.1.0",
|
|
65
|
+
"@ultimat3/http": "30.1.0",
|
|
66
|
+
"@ultimat3/i18n": "30.1.0",
|
|
67
|
+
"@ultimat3/jobs": "30.1.0",
|
|
68
|
+
"@ultimat3/mail": "30.1.0",
|
|
69
|
+
"@ultimat3/manifest": "30.1.0",
|
|
70
|
+
"@ultimat3/mcp": "30.1.0",
|
|
71
|
+
"@ultimat3/money": "30.1.0",
|
|
72
|
+
"@ultimat3/notify": "30.1.0",
|
|
73
|
+
"@ultimat3/policy": "30.1.0",
|
|
74
|
+
"@ultimat3/pwa": "30.1.0",
|
|
75
|
+
"@ultimat3/query": "30.1.0",
|
|
76
|
+
"@ultimat3/realtime": "30.1.0",
|
|
77
|
+
"@ultimat3/render": "30.1.0",
|
|
78
|
+
"@ultimat3/schema": "30.1.0",
|
|
79
|
+
"@ultimat3/seo": "30.1.0",
|
|
80
|
+
"@ultimat3/storage": "30.1.0",
|
|
81
|
+
"@ultimat3/testing": "30.1.0",
|
|
82
|
+
"@ultimat3/time": "30.1.0",
|
|
69
83
|
"babel-preset-solid": "^1.9.16"
|
|
70
84
|
}
|
|
71
85
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// `--affected` inside an app root: the test files a diff can break, by import closure. Every slice
|
|
2
|
+
// of an app shares `apps/web`, so the workspace answer (`affected.ts`) runs the whole app there;
|
|
3
|
+
// `selectTests` is the one rule that narrows further, and this file only maps paths onto it.
|
|
4
|
+
|
|
5
|
+
// why: Bun ships no path API; git reports paths from the checkout root, discovery from the cwd.
|
|
6
|
+
import { join, relative, resolve } from 'node:path';
|
|
7
|
+
import type { TestSelection } from './app-module-graph';
|
|
8
|
+
import { moduleFiles, selectTests } from './app-module-graph';
|
|
9
|
+
import { findAppRoot } from './app-root';
|
|
10
|
+
import type { JsonValue } from './output';
|
|
11
|
+
|
|
12
|
+
export interface AppTestScope extends TestSelection {
|
|
13
|
+
/** The app root, absolute: `tests` and `known` are relative to it. */
|
|
14
|
+
readonly app: string;
|
|
15
|
+
/** Every test file the module graph read, selected or not. */
|
|
16
|
+
readonly known: readonly string[];
|
|
17
|
+
/** How many changed files the selection was asked about. */
|
|
18
|
+
readonly changed: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const toPosix = (path: string): string => path.replace(/\\/g, '/');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* `selectTests` over the app `cwd` sits in, the diff re-rooted from the checkout onto the app. A
|
|
25
|
+
* changed file outside the app comes back `../…`, which `selectTests` already counts as forcing.
|
|
26
|
+
* `undefined` outside an app: a package monorepo's unit is the workspace.
|
|
27
|
+
*/
|
|
28
|
+
export async function appTestScope(
|
|
29
|
+
cwd: string,
|
|
30
|
+
checkout: string,
|
|
31
|
+
changed: readonly string[],
|
|
32
|
+
): Promise<AppTestScope | undefined> {
|
|
33
|
+
const found = findAppRoot(cwd);
|
|
34
|
+
if (found === undefined) return undefined;
|
|
35
|
+
const app = resolve(found.dir);
|
|
36
|
+
const inApp = changed.map((path) => toPosix(relative(app, join(resolve(checkout), path))));
|
|
37
|
+
const files = await moduleFiles(app);
|
|
38
|
+
return {
|
|
39
|
+
app,
|
|
40
|
+
known: files.filter((file) => file.test).map((file) => file.path),
|
|
41
|
+
changed: changed.length,
|
|
42
|
+
...selectTests(files, inApp),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Why a file runs: its import closure meets the diff, a changed file forced every test, or the
|
|
48
|
+
* module graph never read it.
|
|
49
|
+
*/
|
|
50
|
+
type Why = 'closure' | 'all' | 'unmapped';
|
|
51
|
+
|
|
52
|
+
export interface AppNarrowing<T> {
|
|
53
|
+
readonly kept: readonly T[];
|
|
54
|
+
/** `data.affected.tests` for `--json`: what was selected, and why. */
|
|
55
|
+
readonly json: JsonValue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The discovered files (relative to `cwd`) narrowed to the selection. A discovered test the graph
|
|
60
|
+
* never read — outside the globs `moduleFiles` scans — is KEPT: the graph cannot say it is safe
|
|
61
|
+
* to skip, and a skipped test the diff broke is a green run over a broken app.
|
|
62
|
+
*/
|
|
63
|
+
export function narrowToApp<T extends { readonly path: string }>(
|
|
64
|
+
discovered: readonly T[],
|
|
65
|
+
cwd: string,
|
|
66
|
+
scope: AppTestScope,
|
|
67
|
+
): AppNarrowing<T> {
|
|
68
|
+
const selected = new Set(scope.tests);
|
|
69
|
+
const known = new Set(scope.known);
|
|
70
|
+
const kept: T[] = [];
|
|
71
|
+
const files: { readonly path: string; readonly why: Why }[] = [];
|
|
72
|
+
for (const file of discovered) {
|
|
73
|
+
const inApp = toPosix(relative(scope.app, join(resolve(cwd), file.path)));
|
|
74
|
+
const why: Why | undefined = !known.has(inApp)
|
|
75
|
+
? 'unmapped'
|
|
76
|
+
: scope.all
|
|
77
|
+
? 'all'
|
|
78
|
+
: selected.has(inApp)
|
|
79
|
+
? 'closure'
|
|
80
|
+
: undefined;
|
|
81
|
+
if (why === undefined) continue;
|
|
82
|
+
kept.push(file);
|
|
83
|
+
files.push({ path: file.path, why });
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
kept,
|
|
87
|
+
json: {
|
|
88
|
+
app: scope.app,
|
|
89
|
+
all: scope.all,
|
|
90
|
+
reason: scope.all
|
|
91
|
+
? `all: ${scope.forcing.join(', ')}`
|
|
92
|
+
: `closure: ${scope.changed} changed file(s)`,
|
|
93
|
+
forcing: [...scope.forcing],
|
|
94
|
+
files,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|