@ultimat3/cli 29.4.0 → 30.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/CLAUDE.md +64 -40
  2. package/README.md +61 -11
  3. package/package.json +42 -28
  4. package/src/affected-tests.ts +97 -0
  5. package/src/affected-unowned.ts +43 -0
  6. package/src/affected.ts +25 -6
  7. package/src/app-boundaries.ts +29 -1
  8. package/src/app-evals.ts +12 -4
  9. package/src/app-load-unresolved.ts +62 -0
  10. package/src/app-load.ts +30 -37
  11. package/src/app-mcp.ts +14 -2
  12. package/src/app-module-graph.ts +232 -0
  13. package/src/app-reload-graph.ts +2 -2
  14. package/src/app-root.ts +37 -1
  15. package/src/bin.ts +1 -0
  16. package/src/boundary-findings.ts +6 -0
  17. package/src/budgets-freshness.ts +32 -0
  18. package/src/budgets.ts +20 -1
  19. package/src/build-capture-env.ts +9 -0
  20. package/src/cdp-shot-a11y.ts +2 -39
  21. package/src/ci-tested.ts +243 -0
  22. package/src/client-emit-customer-runtime.ts +139 -0
  23. package/src/client-emit-customer.ts +108 -0
  24. package/src/client-emit-drift.ts +72 -0
  25. package/src/client-emit-header.ts +67 -0
  26. package/src/client-emit-schemas.ts +175 -0
  27. package/src/client-emit-types.ts +121 -0
  28. package/src/client-emit-vendor.ts +146 -0
  29. package/src/client-errors-routes.ts +229 -0
  30. package/src/client-errors-script.ts +74 -0
  31. package/src/client-vitals-route.ts +197 -0
  32. package/src/client-vitals-script.ts +56 -0
  33. package/src/cmd-affected.ts +23 -0
  34. package/src/cmd-build-spec.ts +7 -1
  35. package/src/cmd-build.ts +35 -9
  36. package/src/cmd-ci-spec.ts +42 -6
  37. package/src/cmd-ci.ts +99 -2
  38. package/src/cmd-client-customer.ts +134 -0
  39. package/src/cmd-client-source.ts +81 -0
  40. package/src/cmd-client-spec.ts +48 -0
  41. package/src/cmd-client-write.ts +41 -0
  42. package/src/cmd-client.ts +111 -0
  43. package/src/cmd-db-recount.ts +120 -0
  44. package/src/cmd-db-spec.ts +36 -6
  45. package/src/cmd-db.ts +11 -3
  46. package/src/cmd-deploy-compose.ts +61 -3
  47. package/src/cmd-deploy-drain.ts +10 -2
  48. package/src/cmd-deploy-helm.ts +11 -0
  49. package/src/cmd-deploy-preflight.ts +118 -0
  50. package/src/cmd-deploy-spec.ts +58 -6
  51. package/src/cmd-deploy-verify.ts +380 -0
  52. package/src/cmd-deploy.ts +42 -9
  53. package/src/cmd-docs.ts +34 -4
  54. package/src/cmd-doctor.ts +66 -9
  55. package/src/cmd-drill-spec.ts +25 -0
  56. package/src/cmd-drill.ts +176 -0
  57. package/src/cmd-env-init.ts +102 -0
  58. package/src/cmd-env-spec.ts +10 -3
  59. package/src/cmd-env.ts +15 -10
  60. package/src/cmd-errors-recent.ts +60 -0
  61. package/src/cmd-errors-spec.ts +9 -1
  62. package/src/cmd-errors.ts +4 -0
  63. package/src/cmd-exercise-spec.ts +19 -0
  64. package/src/cmd-exercise.ts +129 -0
  65. package/src/cmd-generate-spec.ts +9 -1
  66. package/src/cmd-generate.ts +32 -27
  67. package/src/cmd-graph-load.ts +97 -0
  68. package/src/cmd-graph-spec.ts +16 -0
  69. package/src/cmd-graph.ts +73 -0
  70. package/src/cmd-i18n.ts +4 -1
  71. package/src/cmd-impact-spec.ts +13 -0
  72. package/src/cmd-impact.ts +64 -0
  73. package/src/cmd-jobs-resolve.ts +76 -0
  74. package/src/cmd-jobs-spec.ts +21 -2
  75. package/src/cmd-jobs.ts +10 -6
  76. package/src/cmd-mail-spec.ts +28 -0
  77. package/src/cmd-mail.ts +70 -0
  78. package/src/cmd-mcp-lock.ts +69 -0
  79. package/src/cmd-mcp-spec.ts +23 -4
  80. package/src/cmd-mcp.ts +17 -3
  81. package/src/cmd-new-spec.ts +8 -1
  82. package/src/cmd-new.ts +61 -9
  83. package/src/cmd-planned.ts +0 -6
  84. package/src/cmd-repro-spec.ts +31 -0
  85. package/src/cmd-repro.ts +174 -0
  86. package/src/cmd-stop-spec.ts +21 -0
  87. package/src/cmd-stop.ts +166 -0
  88. package/src/cmd-test-spec.ts +17 -4
  89. package/src/cmd-test.ts +70 -14
  90. package/src/cmd-upgrade-spec.ts +26 -0
  91. package/src/cmd-upgrade.ts +274 -0
  92. package/src/cmd-verify-spec.ts +3 -3
  93. package/src/db-backfill.ts +6 -0
  94. package/src/db-diagnostics.ts +106 -0
  95. package/src/db-generate.ts +9 -0
  96. package/src/db-reset-template.ts +1 -1
  97. package/src/db-rolling.ts +45 -0
  98. package/src/db-seed-generate.ts +188 -0
  99. package/src/deploy-verify-findings.ts +98 -0
  100. package/src/deploy-verify-flags.ts +109 -0
  101. package/src/deploy-verify-grade.ts +185 -0
  102. package/src/deploy-verify-queues.ts +53 -0
  103. package/src/dev-boot.ts +35 -15
  104. package/src/dev-child-watch.ts +16 -4
  105. package/src/dev-dashboard-guard.ts +8 -1
  106. package/src/dev-dashboard.ts +7 -0
  107. package/src/dev-lock-identity.ts +61 -0
  108. package/src/dev-lock-port-holder.ts +80 -0
  109. package/src/dev-lock-steal.ts +124 -0
  110. package/src/dev-lock.ts +92 -120
  111. package/src/dev-mail-templates.ts +51 -0
  112. package/src/dev-rebuild.ts +26 -2
  113. package/src/dev-route-table.ts +17 -0
  114. package/src/dev-supervisor.ts +5 -2
  115. package/src/dev-watch-tree.ts +11 -10
  116. package/src/dev-watch.ts +1 -1
  117. package/src/dispatch.ts +29 -6
  118. package/src/docs-section.ts +69 -0
  119. package/src/docs-sources.ts +100 -0
  120. package/src/doctor-auth.ts +11 -2
  121. package/src/doctor-chart-alerts.ts +55 -0
  122. package/src/doctor-pooler.ts +107 -0
  123. package/src/doctor-rolling.ts +35 -0
  124. package/src/doctor-row-security.ts +40 -0
  125. package/src/document-options.ts +13 -0
  126. package/src/drill-sync-lane.ts +25 -0
  127. package/src/drill-targets.ts +39 -0
  128. package/src/duplicate-packages.ts +1 -1
  129. package/src/env-production.ts +93 -0
  130. package/src/error-codes-shot.ts +59 -0
  131. package/src/error-codes-tooling.ts +29 -0
  132. package/src/error-codes.ts +100 -54
  133. package/src/error-contract.ts +2 -2
  134. package/src/errors.ts +22 -3
  135. package/src/exercise-database.ts +99 -0
  136. package/src/exercise-findings.ts +159 -0
  137. package/src/exercise-overrides.ts +42 -0
  138. package/src/exercise-registration.ts +58 -0
  139. package/src/exercise-static.ts +88 -0
  140. package/src/exercise-subject.ts +69 -0
  141. package/src/failure-capture-boot.ts +30 -0
  142. package/src/framework-env.ts +7 -1
  143. package/src/framework-schema.ts +72 -5
  144. package/src/generate-catalog-locales.ts +19 -0
  145. package/src/generate-chart-alerts.ts +156 -0
  146. package/src/generate-feature-required.ts +65 -0
  147. package/src/generate-feature.ts +83 -6
  148. package/src/generate-files.ts +24 -0
  149. package/src/generate-format-written.ts +32 -0
  150. package/src/generate-kinds.ts +6 -0
  151. package/src/generate-sign-in-config.ts +100 -0
  152. package/src/generate-sign-in-manifest.ts +28 -0
  153. package/src/generate-sign-in-mode.ts +101 -0
  154. package/src/generate-sign-in.ts +250 -0
  155. package/src/generate-write.ts +44 -7
  156. package/src/hand-rolled-socket.ts +72 -0
  157. package/src/i18n-app-key-shapes.ts +29 -0
  158. package/src/i18n-audit.ts +10 -3
  159. package/src/i18n-registration.ts +18 -3
  160. package/src/index.ts +2 -0
  161. package/src/island-bundle.ts +4 -3
  162. package/src/island-disposer.ts +116 -0
  163. package/src/island-realtime-state.ts +34 -6
  164. package/src/island-realtime.ts +6 -2
  165. package/src/island-routes.ts +3 -2
  166. package/src/isr-query-advice.ts +6 -11
  167. package/src/isr-query-guard.ts +4 -3
  168. package/src/job-budget.ts +95 -0
  169. package/src/jobs-json.ts +11 -0
  170. package/src/lint-findings.ts +104 -0
  171. package/src/local-cli.ts +34 -4
  172. package/src/loopback-host.ts +2 -2
  173. package/src/mail-preview-findings.ts +24 -0
  174. package/src/mcp-errors.ts +82 -2
  175. package/src/mcp-host.ts +11 -1
  176. package/src/mcp-lock-findings.ts +57 -0
  177. package/src/measure-paths.ts +12 -4
  178. package/src/measure-scope.ts +27 -13
  179. package/src/messages-client.ts +23 -0
  180. package/src/messages-db.ts +56 -0
  181. package/src/messages-gate.ts +107 -0
  182. package/src/messages-repro.ts +11 -0
  183. package/src/messages-shot.ts +51 -0
  184. package/src/messages-upgrade.ts +45 -0
  185. package/src/messages.ts +53 -178
  186. package/src/metrics-endpoint.ts +23 -5
  187. package/src/new-shapes-generate.ts +71 -0
  188. package/src/new-shapes.ts +63 -0
  189. package/src/openapi-compile-ir.ts +68 -0
  190. package/src/openapi-compile-schema.ts +284 -0
  191. package/src/openapi-compile.ts +273 -0
  192. package/src/openapi-refuse.ts +45 -0
  193. package/src/otlp-export.ts +2 -1
  194. package/src/output-findings.ts +123 -0
  195. package/src/output.ts +32 -8
  196. package/src/package-boundaries.ts +110 -0
  197. package/src/page-pins.ts +23 -0
  198. package/src/plain-routes.ts +13 -0
  199. package/src/prerender-entries.ts +59 -0
  200. package/src/prerender-heaviest.ts +27 -0
  201. package/src/prerender-preload.ts +6 -0
  202. package/src/prerender-report.ts +12 -0
  203. package/src/prerender-seo-reads.ts +38 -0
  204. package/src/prerender-served.ts +22 -7
  205. package/src/prerender-vitals.ts +42 -0
  206. package/src/prerender.ts +61 -32
  207. package/src/pwa-artifacts.ts +4 -3
  208. package/src/pwa-manifest-locales.ts +1 -1
  209. package/src/registry.ts +18 -0
  210. package/src/repro-bundle.ts +65 -0
  211. package/src/repro-errors.ts +47 -0
  212. package/src/repro-job.ts +72 -0
  213. package/src/repro-literal.ts +41 -0
  214. package/src/repro-request.ts +48 -0
  215. package/src/repro-write.ts +100 -0
  216. package/src/retain-sweep.ts +27 -0
  217. package/src/retained-assets-boot.ts +113 -0
  218. package/src/retained-assets-layout.ts +110 -0
  219. package/src/retained-assets-read.ts +142 -0
  220. package/src/retained-assets-sweep.ts +70 -0
  221. package/src/retained-assets.ts +171 -0
  222. package/src/revalidated-response.ts +8 -5
  223. package/src/role-replicator.ts +7 -1
  224. package/src/role-start-devices.ts +119 -0
  225. package/src/role-start-types.ts +6 -0
  226. package/src/role-start.ts +22 -5
  227. package/src/role-sync.ts +7 -1
  228. package/src/route-islands.ts +42 -0
  229. package/src/route-table.ts +2 -1
  230. package/src/row-security-boot.ts +58 -0
  231. package/src/row-security-wanted.ts +32 -0
  232. package/src/runtime-admin.ts +0 -1
  233. package/src/runtime-assets-site-cache.ts +55 -0
  234. package/src/runtime-assets-site.ts +136 -0
  235. package/src/runtime-assets.ts +99 -55
  236. package/src/runtime-bindings.ts +19 -3
  237. package/src/runtime-cache.ts +23 -14
  238. package/src/runtime-isr-outcome.ts +114 -60
  239. package/src/runtime-purge.ts +14 -2
  240. package/src/runtime-queue.ts +31 -4
  241. package/src/runtime-render-document.ts +204 -0
  242. package/src/runtime-render.ts +48 -198
  243. package/src/runtime-replica-position.ts +62 -0
  244. package/src/runtime-replica.ts +18 -3
  245. package/src/runtime-s3-path-style.ts +17 -0
  246. package/src/runtime-services.ts +19 -6
  247. package/src/runtime-statement-bound.ts +22 -0
  248. package/src/runtime-storage-upload.ts +9 -0
  249. package/src/runtime-storage.ts +41 -81
  250. package/src/schema-diff-views.ts +54 -0
  251. package/src/schema-diff.ts +21 -3
  252. package/src/schema-drift.ts +28 -9
  253. package/src/schema-dump-drift.ts +91 -7
  254. package/src/script-csp.ts +1 -1
  255. package/src/seo-cards.ts +26 -0
  256. package/src/seo-routes.ts +22 -8
  257. package/src/serve-boot.ts +54 -21
  258. package/src/serve-drain.ts +1 -0
  259. package/src/serve-env.ts +26 -8
  260. package/src/serve-retire.ts +12 -6
  261. package/src/serve-web.ts +42 -4
  262. package/src/serve.ts +9 -7
  263. package/src/site-asset-routes.ts +7 -1
  264. package/src/site-config.ts +4 -0
  265. package/src/site-llms-pages.ts +106 -0
  266. package/src/site-llms.ts +64 -0
  267. package/src/site-seo-write.ts +4 -2
  268. package/src/site-seo.ts +55 -6
  269. package/src/source-mtime.ts +50 -0
  270. package/src/static-capture-errors.ts +41 -0
  271. package/src/static-capture.ts +56 -0
  272. package/src/static-cards-serve.ts +39 -0
  273. package/src/static-cards.ts +93 -0
  274. package/src/static-document.ts +14 -13
  275. package/src/static-images.ts +115 -0
  276. package/src/stream-hole-scope.ts +55 -0
  277. package/src/style-bundle.ts +1 -1
  278. package/src/style-routes.ts +3 -2
  279. package/src/sw-precache-plan.ts +2 -2
  280. package/src/sw-routes.ts +2 -2
  281. package/src/templates/action-tests.ts +306 -0
  282. package/src/templates/action.ts +81 -269
  283. package/src/templates/backfill.ts +1 -1
  284. package/src/templates/entity.ts +21 -5
  285. package/src/templates/github/ci.yml.ts +8 -9
  286. package/src/templates/guard-bare-error.ts +2 -2
  287. package/src/templates/guard-error-declared.ts +263 -0
  288. package/src/templates/guard-native-confirm.ts +132 -0
  289. package/src/templates/guard-raw-fetch.ts +151 -0
  290. package/src/templates/guard-raw-interval.ts +121 -0
  291. package/src/templates/guard-repo-raw-sql.ts +71 -2
  292. package/src/templates/job.ts +1 -1
  293. package/src/templates/naming.ts +5 -0
  294. package/src/templates/pinned/docker-compose.yml +6 -0
  295. package/src/templates/pinned-images.ts +8 -0
  296. package/src/templates/policy.ts +85 -2
  297. package/src/templates/query.ts +70 -13
  298. package/src/templates/resource-create.ts +3 -1
  299. package/src/templates/resource-form-island.ts +15 -4
  300. package/src/templates/resource-page-db.ts +83 -0
  301. package/src/templates/resource-page.ts +161 -52
  302. package/src/templates/route.ts +4 -6
  303. package/src/templates/scaffold-app.ts +3 -0
  304. package/src/templates/scaffold-auth.ts +2 -1
  305. package/src/templates/scaffold-bin.ts +5 -52
  306. package/src/templates/scaffold-claude-agents.ts +19 -19
  307. package/src/templates/scaffold-claude-commands.ts +28 -31
  308. package/src/templates/scaffold-claude.ts +26 -23
  309. package/src/templates/scaffold-container-compose.ts +6 -1
  310. package/src/templates/scaffold-container.ts +24 -4
  311. package/src/templates/scaffold-dashboard-bare.ts +3 -3
  312. package/src/templates/scaffold-dashboard-example-tests.ts +49 -9
  313. package/src/templates/scaffold-dashboard-example-view.ts +156 -0
  314. package/src/templates/scaffold-dashboard-example.ts +43 -131
  315. package/src/templates/scaffold-dashboard-shared.ts +3 -7
  316. package/src/templates/scaffold-db-client.ts +20 -6
  317. package/src/templates/scaffold-db-package.ts +5 -14
  318. package/src/templates/scaffold-docs.ts +73 -57
  319. package/src/templates/scaffold-domain-package.ts +18 -14
  320. package/src/templates/scaffold-entries.ts +7 -2
  321. package/src/templates/scaffold-exercise.ts +37 -0
  322. package/src/templates/scaffold-guards.ts +13 -1
  323. package/src/templates/scaffold-helm-alerts.ts +234 -0
  324. package/src/templates/scaffold-helm-templates.ts +7 -5
  325. package/src/templates/scaffold-helm.ts +46 -12
  326. package/src/templates/scaffold-i18n.ts +6 -2
  327. package/src/templates/scaffold-mcp-endpoint.ts +182 -0
  328. package/src/templates/scaffold-mcp-json.ts +31 -0
  329. package/src/templates/scaffold-mcp-package.ts +59 -56
  330. package/src/templates/scaffold-repo.ts +7 -2
  331. package/src/templates/scaffold-shell.ts +45 -79
  332. package/src/templates/scaffold-test-services.ts +13 -5
  333. package/src/templates/shapes/api-keys.ts +170 -0
  334. package/src/templates/shapes/api.ts +101 -0
  335. package/src/templates/shapes/blog-site.ts +340 -0
  336. package/src/templates/shapes/blog-slice.ts +265 -0
  337. package/src/templates/shapes/blog.ts +114 -0
  338. package/src/templates/shapes/dashboard-detail.ts +242 -0
  339. package/src/templates/shapes/dashboard.ts +53 -0
  340. package/src/templates/shapes/index.ts +17 -0
  341. package/src/templates/shapes/overlay.ts +99 -0
  342. package/src/templates/shapes/shared-edits.ts +46 -0
  343. package/src/templates/sign-in-action-tests.ts +237 -0
  344. package/src/templates/sign-in-authenticator.ts +112 -0
  345. package/src/templates/sign-in-oidc.ts +189 -0
  346. package/src/templates/sign-in-pages.ts +148 -0
  347. package/src/templates/sign-in-password.ts +216 -0
  348. package/src/templates/sign-in-shared.ts +268 -0
  349. package/src/templates/slice-foundation.ts +70 -15
  350. package/src/test-batches.ts +1 -1
  351. package/src/test-database.ts +1 -1
  352. package/src/test-shards.ts +7 -1
  353. package/src/test-workers.ts +18 -12
  354. package/src/tool-gate-names.ts +34 -0
  355. package/src/upgrade-agents-link.ts +49 -0
  356. package/src/upgrade-bun-floor.ts +225 -0
  357. package/src/upgrade-gate.ts +228 -0
  358. package/src/upgrade-pins.ts +63 -0
  359. package/src/upgrade-plan.ts +214 -0
  360. package/src/upgrade-registry.ts +53 -0
  361. package/src/upgrade-report.ts +139 -0
  362. package/src/upgrade-root.ts +74 -0
  363. package/src/verify-budgets-build.ts +118 -0
  364. package/src/verify-checks.ts +67 -24
  365. package/src/verify-coverage-run.ts +1 -1
  366. package/src/verify-e2e-lane.ts +41 -0
  367. package/src/verify-exercise.ts +64 -0
  368. package/src/verify-floor.ts +41 -0
  369. package/src/verify-merge.ts +19 -4
  370. package/src/verify-role-load.ts +2 -0
  371. package/src/verify-run.ts +28 -8
  372. package/src/verify-shard.ts +12 -2
  373. package/src/verify-skip-ceiling.ts +87 -0
  374. package/src/verify-step.ts +5 -0
  375. package/src/verify-tests.ts +25 -5
  376. package/src/view-drift.ts +55 -0
  377. package/src/worker-bundle.ts +3 -2
  378. package/src/workspace-graph.ts +38 -19
  379. package/src/write-generated.ts +43 -0
  380. package/src/zone-boot.ts +20 -0
  381. package/wiki/Actions.md +342 -0
  382. package/wiki/Admin-Dashboard.md +432 -0
  383. package/wiki/Agents.md +958 -0
  384. package/wiki/Auth.md +195 -0
  385. package/wiki/Bare-VM.md +111 -0
  386. package/wiki/Batching-And-Preloading.md +136 -0
  387. package/wiki/Building-Your-Own-Base.md +203 -0
  388. package/wiki/CI-Parallel-Gate.md +220 -0
  389. package/wiki/CLI-Reference.md +1894 -0
  390. package/wiki/Caching-And-Invalidation.md +255 -0
  391. package/wiki/Client-Data.md +194 -0
  392. package/wiki/Client-Navigation.md +513 -0
  393. package/wiki/Compared.md +93 -0
  394. package/wiki/Configuration.md +868 -0
  395. package/wiki/Contributing.md +12 -0
  396. package/wiki/Deploy-Recipes.md +122 -0
  397. package/wiki/Deployment.md +508 -0
  398. package/wiki/Entities-And-Migrations.md +1116 -0
  399. package/wiki/FAQ.md +175 -0
  400. package/wiki/Feature-Flags.md +65 -0
  401. package/wiki/Getting-Started.md +221 -0
  402. package/wiki/Home.md +160 -0
  403. package/wiki/I18n.md +239 -0
  404. package/wiki/Installation.md +206 -0
  405. package/wiki/Interface-Rules.md +339 -0
  406. package/wiki/Jobs-And-Workflows.md +783 -0
  407. package/wiki/Known-Gaps.md +185 -0
  408. package/wiki/MCP-And-AI.md +753 -0
  409. package/wiki/Mail.md +138 -0
  410. package/wiki/Migrating-An-Existing-App.md +594 -0
  411. package/wiki/Migrating-From-Django.md +54 -0
  412. package/wiki/Migrating-From-Laravel.md +53 -0
  413. package/wiki/Migrating-From-Node-Drizzle.md +53 -0
  414. package/wiki/Migrating-From-Rails.md +53 -0
  415. package/wiki/Migrations-And-Backfills.md +552 -0
  416. package/wiki/Money.md +338 -0
  417. package/wiki/N-Plus-One-Detection.md +197 -0
  418. package/wiki/Notify.md +208 -0
  419. package/wiki/Observability.md +245 -0
  420. package/wiki/Outbound-HTTP.md +109 -0
  421. package/wiki/PWA-And-Offline.md +343 -0
  422. package/wiki/Policies-And-Authz.md +251 -0
  423. package/wiki/Project-Layout.md +150 -0
  424. package/wiki/Queries-And-Live-Queries.md +429 -0
  425. package/wiki/Realtime.md +734 -0
  426. package/wiki/Resource-Management.md +121 -0
  427. package/wiki/Routes-And-Render-Modes.md +521 -0
  428. package/wiki/SEO.md +288 -0
  429. package/wiki/Scheduled-Tasks.md +175 -0
  430. package/wiki/Scraping.md +493 -0
  431. package/wiki/Shapes.md +63 -0
  432. package/wiki/Stability.md +97 -0
  433. package/wiki/Static-Assets.md +166 -0
  434. package/wiki/Storage-And-Uploads.md +404 -0
  435. package/wiki/Testing.md +1313 -0
  436. package/wiki/The-Eight-Primitives.md +247 -0
  437. package/wiki/Theming.md +362 -0
  438. package/wiki/Timezones-And-Dates.md +194 -0
  439. package/wiki/Troubleshooting.md +163 -0
  440. package/wiki/Tutorial-01-First-App.md +289 -0
  441. package/wiki/Tutorial-02-First-Feature.md +339 -0
  442. package/wiki/Tutorial-03-Auth-And-Admin.md +379 -0
  443. package/wiki/Tutorial-04-Jobs-And-Realtime.md +263 -0
  444. package/wiki/Tutorial-05-Deploy-Free.md +231 -0
  445. package/wiki/Tutorial-06-Growing-Up.md +158 -0
  446. package/wiki/UI-Components.md +156 -0
  447. package/wiki/Upgrading.md +3667 -0
  448. 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. `local-cli.ts` re-executes the app's own `node_modules/@ultimat3/cli` when a global `x` is a different realpath: a second `@ultimat3/entity` instance is an empty registry |
16
- | Registry | `registry.ts`: every declaration static (`cmd-<name>-spec.ts`), every body `await import()`ed when that command runs. A command body is never imported to answer the parser or `x help` — `registry-lazy.test.ts`. A spec's constants live in the spec file or a leaf module, never in the body |
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⟧`). NOT in the catalog: `CommandSpec` summaries and usage, `Finding.cause` / `fix`, fixed-width table headers |
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. Every name there is a semver promise; a name nothing outside this package reads is not exported (22.0.0 pruned 236) |
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` | the step list, the outcome shape, the run order (`BESIDE_SERIAL_SUITES`) |
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. The suite runs as fixed slices, one plain `bun test` each — never `--parallel --coverage`, whose merge moves with the core count. `coverage-lcov.ts` is the ONE lcov reader; `scripts/coverage-gate.ts` reads through it. A shard defers to `verify-merge.ts` (`coverageRiders`), which also holds the shards' `files` to a partition of the corpus they hashed and reads each part step through `verify-part-step.ts`; `doctor-coverage.ts` lists the excludes |
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 (`at`, `meta.inFlight`) and its `fix:` runs that file; any render streams step lines + a heartbeat to stderr. A `fix:` names `ctx.command` — `bun run verify` at the framework root |
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. `app-transport.ts` reuses the files `readAppSources` read (no second walk), resolves through the app's tsconfig `paths` and workspace manifests, reads the app's own `packages/*` lazily, and STOPS at `node_modules`. `browser-transport.ts` is the pure rule — `scripts/browser-transport.ts` calls the same function with this repo's seam FILES. Never a `guards/` file: an app must not be able to delete it |
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). A new one is a `templates/guard-<name>.ts` + a row + `guard-<name>.test.ts`; `scaffold-guards-style.test.ts` holds embedded scales to `@ultimat3/ui`, the framework's own sheets to the rules, and both tracked apps byte-equal to the templates |
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`. A published package's `files` negates `*.test.ts` and `*-fixture.ts`, and no entry point (`exports`, `bin`) may reach a `-fixture.ts` — `X_PACKAGE_SHAPE` names the file to rename; a `src/` module only tests import must be `*-fixture.ts` (`X_PACKAGE_TEST_ONLY_SHIPPED`) |
56
- | `app-permissions.ts` / `permission-grants.ts` / `app-permissions-borrowed.ts` / `app-permissions-site.ts` | `policy`: every permission granted or required is declared, every one required is granted by some role (`X_PERMISSION_UNGRANTED`), and every one an app rule requires is declared by an app module, not only by a package (`X_PERMISSION_BORROWED`, read off `permissionDeclarationSites()`) |
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`, with the `git mv` that mounts it |
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
- | `app-agents-md.ts` / `app-env.ts` / `app-openapi.ts` / `app-manifest.ts` | `manifest` and `contract-diff`. `framework-env.ts` is the ONE list of framework-required deploy secrets `.env.example`, `x env check` and `x doctor` read |
62
- | `schema-drift.ts` / `drift.ts` / `drift-replica-identity.ts` / `db-destructive.ts` / `db-ungeneratable.ts` | `drift`: snapshot vs declarations (`REPLICA IDENTITY FULL` a params channel needs included — never a `subscribes:` table, #518), the source hash (core's `canonicalJson`), the header markers |
63
- | `schema-dump-drift.ts` | `drift`'s fourth rail, the only one that boots a database: committed `packages/db/schema/` vs a scratch replay, and that dump loaded back (`X_SCHEMA_DUMP_DRIFT`) |
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` grants `:read` to `member`, `:write` to `admin` in `apps/web/shared/roles.ts`; a written `entity.ts` declares its table's `<table>:read\|write\|delete` there and grants all three to `admin` — what the admin asks for the screen that entity just became |
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 `const entities = { … }` in `packages/db/src/client.ts` (the typed handle every generated `repo.ts` reads), with the two manifest lines the new imports need; no anchor is `X_DB_HANDLE_UNREGISTERED` carrying the lines. `cmd-generate.ts`'s `nextSteps` prints what the new table owes |
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` lists the override it wrote under `resources:` in `apps/admin/app/admin/admin.ts` (`X_ADMIN_RESOURCE_UNWIRED` when it cannot); every generated entity ships the `admin.<table>.*` labels its screen reads; `source-edit.ts` is the keyed-line and sorted-import edit both registrars share |
82
- | `app-artifacts.ts` | `x.manifest.json` + `openapi.json`, written together by `x g` and `x manifest` |
83
- | `templates/` | every emitted file; `scaffold-*.ts` for `x new`, one file per generator otherwise. `templates/emitted-contract.test.ts` holds every emitted string to the scaffold's own Biome format and lint, its imports to what the scaffold installs, and its `fix:` lines to the error contract — run it after touching a template: `bun test packages/cli/src/templates/emitted-contract.test.ts` |
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`. `serve-boot.ts` (services + roles) is ONE `await import()` in `serveApp`, so `migrate` loads neither |
90
- | `role-load.ts` / `document-graph.ts` / `serve-web.ts` | a role imports what it runs: `ROLE_LOADS` (declared over `Role`) — `worker`/`scheduler` import the API index and every module reaching no `.tsx`/stylesheet, verified against `x.manifest.json`'s jobs and tasks (`X_ROLE_LOAD_INCOMPLETE` imports everything); `serve-web.ts` is the web surface, behind `await import()`. `scanAppModules(root, { track: false })` is the container's scan — no reload graph, no error-code walk. Per-role module pins and `NEVER_AT_BOOT`: `serve-graph.test.ts` |
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`, then stamp the build on `x_jobs`' table comment; a serving role on an external database runs no DDL and VERIFIES the stamp (`X_FRAMEWORK_SCHEMA_UNAPPLIED`, a major skew is a warning). A comment, never a table: a new framework table moves every app's schema dump |
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`. Every boot fact (`app-auth.ts`, `theme-boot.ts`, `site-config.ts`, `pwa-artifacts.ts`, …) reads a section off it, and `startServices` loads it once. An `import(` of the config module anywhere else is `X_CONFIG_IMPORT_OUTSIDE_LOADER` (`scripts/lib/config-import.ts`) |
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 — `stop()`: claim nothing, abort nothing — on SIGUSR2 under `runRole` (armed before boot, then drain + exit 0; none on win32; the chart's `roles.worker.retireSeconds` preStop sends it), and before a supervised `x dev` restart's drain (#677) |
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 (an `isr` hit never runs `load`, and a `load` redirect is answered per request, never stored or shared — `runtime-isr-outcome.ts`; `route-islands.ts` is a render's island collector and realtime boot), `/icons` + `/media`, `/_storage`, authz, the app's API — plus its bearer mounts (`apiMountRoutes`) and pages' bound `POST`s (`pagePostRoutes`), mounted by BOTH boots |
107
- | `stored-object-headers.ts` | how `/_storage` and `/media` present a stored object: inline only for raster images, audio and video; every other type (`text/html`, SVG, XML, PDF) is `content-disposition: attachment` with a `sandbox` CSP, which http's security stage keeps beside the app's |
108
- | `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) |
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`): the allow-list of pure-read pages, the one tag, and its `script-src` hash — composed once for all three writers. An allow-list, never "every link but": a prefetch is a real GET with cookies |
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 the container loads — each chunk's recorded source files (`island-sources.ts`) are rehashed at read, so an edit since the build is a rebuild, never the old chunk. `island-runtime.ts` builds realtime's page runtime ONCE per build as `/islands/page-runtime.<id>.js` (resolved through `@ultimat3/realtime/page-runtime`), which a realtime island awaits where no page boot is rendered. `island-realtime-state.ts`: which realtime islands only FOLLOW the socket (not held, no first-paint wait); the answer rides `IslandChunk.realtime` via the store to the renderer |
115
- | `local-cli.ts` / `local-cli-handoff.ts` | a global `x` hands over to the app's own CLI (`local-cli.ts` decides whether); the hand-off forwards SIGTERM/SIGHUP at once and a SIGINT only if the child is still running after a 1 s grace (a terminal Ctrl-C already reached it), and exits with the child's code |
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
- | `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`. Checked in the route, never left to the app's `csrf` config |
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; routes rendered only to weigh run inside a request as core's `measurementActor()`, with the app's API answered in process (`withInProcessFetch`) |
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-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 (embedded, snapshot-cached under `.x/cache`; a real Postgres only when a migration creates an extension PGlite cannot link), written by `x db gen` and `x db migrate`. `migration-extensions.ts` is also what `runtime-queue.ts` links `x dev`'s database with |
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`: the one-shot that seals plaintext `x_users.mfa_secret` through auth's `sealMfaSecrets` (compare-and-set per row; `{ sealed, alreadySealed, skipped }`), over `startQueue`'s client, `open` injectable. `doctor-auth.ts` is the deploy-time half: unsealed secrets and retired framework tables (`RETIRED_TABLE_FIXES`, a `Map` holding a whole literal per table), asked of an external `DATABASE_URL` only |
136
- | `cmd-mcp.ts` / `mcp-host.ts` / `mcp-errors.ts` / `mcp-db-target.ts` | `x mcp serve`: 18 tools, two transports; a taken port is `X_PORT_IN_USE`. `mcp-test-run.ts` folds `bun test`'s `N errors` line and exit code into `tests.run` |
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** | 20 named steps, each with pass/fail + duration |
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 18 dev tools, over stdio or HTTP | one catalog, one scope set, both transports |
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 docs "<question>"` | the framework docs, offline | answered from the installed packages, never the network |
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 20 steps failed","steps":[...]}
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 drift
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
- Twenty, in cost order, defined once as `VERIFY_STEP_NAMES` (`verify-step.ts`) — the summary
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 seventeen), the blank template otherwise — and
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": "29.4.0",
3
+ "version": "30.0.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": "29.4.0",
43
- "@ultimat3/admin": "29.4.0",
44
- "@ultimat3/ai": "29.4.0",
45
- "@ultimat3/auth": "29.4.0",
46
- "@ultimat3/cache": "29.4.0",
47
- "@ultimat3/core": "29.4.0",
48
- "@ultimat3/db": "29.4.0",
49
- "@ultimat3/entity": "29.4.0",
50
- "@ultimat3/flags": "29.4.0",
51
- "@ultimat3/http": "29.4.0",
52
- "@ultimat3/i18n": "29.4.0",
53
- "@ultimat3/jobs": "29.4.0",
54
- "@ultimat3/mail": "29.4.0",
55
- "@ultimat3/manifest": "29.4.0",
56
- "@ultimat3/mcp": "29.4.0",
57
- "@ultimat3/money": "29.4.0",
58
- "@ultimat3/notify": "29.4.0",
59
- "@ultimat3/policy": "29.4.0",
60
- "@ultimat3/pwa": "29.4.0",
61
- "@ultimat3/query": "29.4.0",
62
- "@ultimat3/realtime": "29.4.0",
63
- "@ultimat3/render": "29.4.0",
64
- "@ultimat3/schema": "29.4.0",
65
- "@ultimat3/seo": "29.4.0",
66
- "@ultimat3/storage": "29.4.0",
67
- "@ultimat3/testing": "29.4.0",
68
- "@ultimat3/time": "29.4.0",
56
+ "@ultimat3/action": "30.0.0",
57
+ "@ultimat3/admin": "30.0.0",
58
+ "@ultimat3/ai": "30.0.0",
59
+ "@ultimat3/auth": "30.0.0",
60
+ "@ultimat3/cache": "30.0.0",
61
+ "@ultimat3/core": "30.0.0",
62
+ "@ultimat3/db": "30.0.0",
63
+ "@ultimat3/entity": "30.0.0",
64
+ "@ultimat3/flags": "30.0.0",
65
+ "@ultimat3/http": "30.0.0",
66
+ "@ultimat3/i18n": "30.0.0",
67
+ "@ultimat3/jobs": "30.0.0",
68
+ "@ultimat3/mail": "30.0.0",
69
+ "@ultimat3/manifest": "30.0.0",
70
+ "@ultimat3/mcp": "30.0.0",
71
+ "@ultimat3/money": "30.0.0",
72
+ "@ultimat3/notify": "30.0.0",
73
+ "@ultimat3/policy": "30.0.0",
74
+ "@ultimat3/pwa": "30.0.0",
75
+ "@ultimat3/query": "30.0.0",
76
+ "@ultimat3/realtime": "30.0.0",
77
+ "@ultimat3/render": "30.0.0",
78
+ "@ultimat3/schema": "30.0.0",
79
+ "@ultimat3/seo": "30.0.0",
80
+ "@ultimat3/storage": "30.0.0",
81
+ "@ultimat3/testing": "30.0.0",
82
+ "@ultimat3/time": "30.0.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
+ }