@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.
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 +1314 -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
@@ -12,13 +12,15 @@ export const DB_SUBCOMMANDS = [
12
12
  'studio',
13
13
  'branch',
14
14
  'backfill',
15
+ 'diagnostics',
16
+ 'recount',
15
17
  ] as const;
16
18
 
17
19
  export const dbSpec: CommandSpec = {
18
20
  name: 'db',
19
- summary: 'gen, migrate, reset, seed, studio, branch, backfill',
21
+ summary: 'gen, migrate, reset, seed, studio, branch, backfill, diagnostics, recount',
20
22
  usage:
21
- 'x db gen "add publish_at" | migrate | reset | seed [<name>] [--tier reference|dev] [--dry-run] | studio | branch list | branch create <name> | branch delete <name> | backfill [<name>|--all] [--write] [--force] | backfill --pending | backfill --list [--name n] [--status s] [--limit n]',
23
+ 'x db gen "add publish_at" | migrate | reset | seed [<name>] [--tier reference|dev] [--dry-run] | seed --generate [--rows n] [--seed n] [--dry-run] | studio | branch list | branch create <name> | branch delete <name> | backfill [<name>|--all] [--write] [--force] | backfill --pending | backfill --list [--name n] [--status s] [--limit n] | diagnostics [--limit n] | recount <entity>.<column> [--write]',
22
24
  requiresApp: true,
23
25
  subcommands: DB_SUBCOMMANDS,
24
26
  // Declared from the constant `runBranchCommand` validates against, never a second literal: it
@@ -46,6 +48,26 @@ export const dbSpec: CommandSpec = {
46
48
  summary: 'seed: report what each seed would write, and write nothing',
47
49
  subcommands: ['seed'],
48
50
  },
51
+ // Rows for every table off the entity declarations, with no seed written: the seed graph
52
+ // `x exercise` runs on. Fixture data, so `dev` only; production is refused whatever the tier.
53
+ {
54
+ name: 'generate',
55
+ type: 'boolean',
56
+ summary: 'seed: generated dev rows for every entity, parents first; never in production',
57
+ subcommands: ['seed'],
58
+ },
59
+ {
60
+ name: 'rows',
61
+ type: 'string',
62
+ summary: 'seed: with --generate, rows per table (per tenant when tenant-scoped; default 3)',
63
+ subcommands: ['seed'],
64
+ },
65
+ {
66
+ name: 'seed',
67
+ type: 'string',
68
+ summary: 'seed: with --generate, the integer the graph is drawn from — same seed, same rows',
69
+ subcommands: ['seed'],
70
+ },
49
71
  {
50
72
  name: 'list',
51
73
  type: 'boolean',
@@ -67,8 +89,8 @@ export const dbSpec: CommandSpec = {
67
89
  {
68
90
  name: 'write',
69
91
  type: 'boolean',
70
- summary: 'backfill: enqueue the pass; dry run without it',
71
- subcommands: ['backfill'],
92
+ summary: 'backfill, recount: enqueue the pass, or set drifted counters; dry run without it',
93
+ subcommands: ['backfill', 'recount'],
72
94
  },
73
95
  {
74
96
  name: 'force',
@@ -85,8 +107,9 @@ export const dbSpec: CommandSpec = {
85
107
  {
86
108
  name: 'limit',
87
109
  type: 'string',
88
- summary: 'backfill: max ledger rows to return',
89
- subcommands: ['backfill'],
110
+ summary:
111
+ 'backfill, diagnostics: max ledger rows, or rows per diagnostics section (default 20)',
112
+ subcommands: ['backfill', 'diagnostics'],
90
113
  },
91
114
  // Declared because `X_MIGRATION_IRREVERSIBLE`'s own fix line names it. A `fix:` is copied
92
115
  // and run verbatim, so a flag the parser refuses would make the error unfollowable.
@@ -95,5 +118,12 @@ export const dbSpec: CommandSpec = {
95
118
  type: 'boolean',
96
119
  summary: 'let x db gen emit a drop whose down cannot restore the rows',
97
120
  },
121
+ // Declared because `X_MIGRATION_ROLLING_UNSAFE`'s own fix line names it.
122
+ {
123
+ name: 'rolling-unsafe',
124
+ type: 'boolean',
125
+ summary:
126
+ 'let x db gen drop a column never retired, for an app that stops before it starts: one instance, or strategy: Recreate',
127
+ },
98
128
  ],
99
129
  };
package/src/cmd-db.ts CHANGED
@@ -1,6 +1,7 @@
1
- // `x db gen|migrate|reset|seed|studio|branch|backfill` — everything that touches the database. One
2
- // subcommand per line and no fall-through: a word this file does not know is refused, never
3
- // re-read as an argument to the last branch. `branch` itself is `cmd-db-branch.ts`.
1
+ // `x db gen|migrate|reset|seed|studio|branch|backfill|diagnostics|recount` — everything that touches the
2
+ // database. One subcommand per line and no fall-through: a word this file does not know is refused,
3
+ // never re-read as an argument to the last branch. `branch` is `cmd-db-branch.ts`, `diagnostics`
4
+ // is `db-diagnostics.ts`.
4
5
  //
5
6
  // Every subcommand here runs `@ultimat3/db`'s own engine, which is the engine `ROLE=migrate` runs
6
7
  // (`serve.ts`): one `x_migrations` ledger, one checksum rule, one advisory lock, from a laptop to
@@ -17,9 +18,11 @@ import { postgresDriver } from '@ultimat3/entity';
17
18
  import { requireAppRoot } from './app-root';
18
19
  import { runBackfillCommand } from './cmd-db-backfill';
19
20
  import { runBranchCommand } from './cmd-db-branch';
21
+ import { runRecountCommand } from './cmd-db-recount';
20
22
  import { DB_SUBCOMMANDS, dbSpec } from './cmd-db-spec';
21
23
  import { plannedSubcommand } from './cmd-planned';
22
24
  import type { CliCommand, CommandContext } from './command';
25
+ import { runDiagnostics } from './db-diagnostics';
23
26
  import { stepFinding } from './db-finding';
24
27
  import { generateAppMigration, unrenderedJson, unrenderedLines } from './db-generate';
25
28
  import { liveObjectDrift } from './db-object-drift';
@@ -40,6 +43,7 @@ import {
40
43
  seedTotals,
41
44
  selectSeeds,
42
45
  } from './db-seed';
46
+ import { runGeneratedSeed } from './db-seed-generate';
43
47
  import { DevAlreadyRunningError, liveDevLock } from './dev-lock';
44
48
  import { MissingSubcommandError, UnknownCommandError } from './errors';
45
49
  import { withJobDriver } from './jobs-driver';
@@ -71,6 +75,8 @@ export const dbCommand: CliCommand = {
71
75
  if (sub === 'studio') throw plannedSubcommand('db', 'studio');
72
76
  if (sub === 'backfill') return runBackfillCommand(ctx, root);
73
77
  if (sub === 'branch') return runBranchCommand(ctx, root);
78
+ if (sub === 'diagnostics') return runDiagnostics(ctx, root);
79
+ if (sub === 'recount') return runRecountCommand(ctx, root);
74
80
 
75
81
  // Never a fall-through. This used to end `return runBranch(ctx, root, argument ?? 'preview')`,
76
82
  // so ANY subcommand the parser had not already refused was reinterpreted as a branch NAME and
@@ -102,6 +108,7 @@ async function runGen(ctx: CommandContext, root: string, name: string): Promise<
102
108
  generated = await generateAppMigration(root, {
103
109
  name,
104
110
  allowDestructive: flagBool(ctx.args, 'allow-destructive'),
111
+ rollingUnsafe: flagBool(ctx.args, 'rolling-unsafe'),
105
112
  });
106
113
  } catch (error) {
107
114
  return {
@@ -297,6 +304,7 @@ async function runReset(ctx: CommandContext, root: string): Promise<CommandResul
297
304
  * `handle.enqueue()` a seeded write triggers. A second boot path would be a second answer.
298
305
  */
299
306
  async function runSeed(ctx: CommandContext, root: string): Promise<CommandResult> {
307
+ if (flagBool(ctx.args, 'generate')) return runGeneratedSeed(ctx, root);
300
308
  const environment = resolveEnvironment({ env: ctx.env });
301
309
  const requested = parseSeedTierFlag(
302
310
  flagString(ctx.args, 'tier') ?? ctx.env['ULTIMATE_SEED_TIER'],
@@ -1,6 +1,6 @@
1
- // The compose half of `x deploy`'s rollout: which serving roles can start their new container
2
- // BEFORE the old one stops, read off the app's compose file. The sequence that does it is
3
- // `cmd-deploy-start-first.ts`.
1
+ // The compose half of `x deploy`, read off the app's compose file: which serving roles can start
2
+ // their new container BEFORE the old one stops (the sequence is `cmd-deploy-start-first.ts`), and
3
+ // what the file demands of `.env.production` — read by the deploy's pre-flight and `x env init`.
4
4
  // `docker compose up -d <role>` alone is stop-first — it recreates, so the role serves nothing
5
5
  // between the old container's exit and the new one's healthcheck.
6
6
 
@@ -101,3 +101,61 @@ export async function readComposeFile(path: string): Promise<string | undefined>
101
101
  const file = Bun.file(path);
102
102
  return (await file.exists()) ? file.text() : undefined;
103
103
  }
104
+
105
+ /**
106
+ * The reference `x build --target docker` tags and `x deploy` deploys when neither is given one
107
+ * (`cmd-build.ts` spells the same literal). `x env init` writes it as `IMAGE`, so a compose command
108
+ * run by hand reaches the image the build made rather than the compose file's own default.
109
+ */
110
+ export const DEFAULT_IMAGE = 'ultimate-app:dev';
111
+
112
+ /**
113
+ * Every variable the file interpolates with `${VAR:?…}` or `${VAR?…}`, in first-use order — the
114
+ * ones compose refuses to parse without. Read off the text, not the parse: YAML keeps the
115
+ * interpolation inside a string, wherever in the document it sits. Comment lines are skipped.
116
+ */
117
+ export function composeRequiredVars(text: string): readonly string[] {
118
+ // A comment line is never interpolated, and the scaffold's header spells `${VAR:?…}` in prose.
119
+ const live = text
120
+ .split('\n')
121
+ .filter((line) => !line.trimStart().startsWith('#'))
122
+ .join('\n');
123
+ const names = [...live.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*):?\?/g)].map((m) => m[1] ?? '');
124
+ return [...new Set(names)];
125
+ }
126
+
127
+ /** The `db` service's role and database, which a `DATABASE_URL` for this file must name. */
128
+ export interface ComposeDatabase {
129
+ readonly user: string;
130
+ readonly database: string;
131
+ }
132
+
133
+ /** One `environment:` entry, from either of compose's two spellings (map or `KEY=value` list). */
134
+ function environmentValue(environment: unknown, key: string): string | undefined {
135
+ if (isRecord(environment)) {
136
+ const value = environment[key];
137
+ return typeof value === 'string' || typeof value === 'number' ? String(value) : undefined;
138
+ }
139
+ if (!Array.isArray(environment)) return undefined;
140
+ const entry = environment.find((e) => typeof e === 'string' && e.startsWith(`${key}=`));
141
+ return typeof entry === 'string' ? entry.slice(key.length + 1) : undefined;
142
+ }
143
+
144
+ /**
145
+ * The `db` service's Postgres role and database: the image's defaults (`postgres`, and a database
146
+ * named after the role) unless `POSTGRES_USER` / `POSTGRES_DB` say otherwise. `undefined` when the
147
+ * file runs no `db` service, so the database is the operator's and no URL can be derived.
148
+ */
149
+ export function composeDatabase(text: string | undefined): ComposeDatabase | undefined {
150
+ let parsed: unknown;
151
+ try {
152
+ parsed = text === undefined ? undefined : Bun.YAML.parse(text);
153
+ } catch {
154
+ return undefined;
155
+ }
156
+ const services = isRecord(parsed) ? parsed['services'] : undefined;
157
+ const db = isRecord(services) ? services['db'] : undefined;
158
+ if (!isRecord(db)) return undefined;
159
+ const user = environmentValue(db['environment'], 'POSTGRES_USER') ?? 'postgres';
160
+ return { user, database: environmentValue(db['environment'], 'POSTGRES_DB') ?? user };
161
+ }
@@ -1,10 +1,12 @@
1
1
  // What a helm deploy tells the chart about the drain: `app.config.ts`'s `drain` section — the ONE
2
2
  // drain budget since 25.0.0 deleted `http.drainTimeoutMs` — in the seconds `docker/helm` derives
3
3
  // each role's terminationGracePeriodSeconds from. Passed on every upgrade, so a raised
4
- // budget can never ship against a grace period sized for 25 s.
4
+ // budget can never ship against a grace period sized for 25 s, and nor can the retire beside it.
5
5
 
6
6
  import type { DrainConfig } from '@ultimat3/core';
7
7
  import { isUltimateError, READINESS_GRACE_DEFAULT_MS } from '@ultimat3/core';
8
+ import { loadAppConfig } from './app-config-load';
9
+ import { helmWorkerTargetOverrides } from './cmd-deploy-helm';
8
10
  import { loadDrainConfig } from './serve-drain';
9
11
 
10
12
  const seconds = (ms: number): number => Math.ceil(ms / 1000);
@@ -29,6 +31,10 @@ export function helmDrainOverrides(drain: Partial<DrainConfig> | undefined): rea
29
31
  if (drain?.workerDeadlineMs !== undefined) {
30
32
  out.push('--set', `drain.workerDeadlineSeconds=${seconds(drain.workerDeadlineMs)}`);
31
33
  }
34
+ // Sent at 0 as well: `workerRetireMs: 0` must reach a chart whose default is on.
35
+ if (drain?.workerRetireMs !== undefined) {
36
+ out.push('--set', `roles.worker.retireSeconds=${seconds(drain.workerRetireMs)}`);
37
+ }
32
38
  if (drain === undefined) return out;
33
39
  const grace = Math.max(drain.readinessGraceMs ?? 0, READINESS_GRACE_DEFAULT_MS);
34
40
  out.push('--set', `drain.readinessGraceSeconds=${seconds(grace)}`);
@@ -43,11 +49,13 @@ export function helmDrainOverrides(drain: Partial<DrainConfig> | undefined): rea
43
49
  */
44
50
  export async function readHelmDrainOverrides(root: string): Promise<readonly string[]> {
45
51
  let drain: Partial<DrainConfig> | undefined;
52
+ let maxInFlight: number | undefined;
46
53
  try {
47
54
  drain = await loadDrainConfig(root);
55
+ maxInFlight = (await loadAppConfig(root))?.jobs?.maxInFlight;
48
56
  } catch (error) {
49
57
  if (!isUltimateError(error) || error.code !== 'X_CONFIG_INVALID') throw error;
50
58
  return [];
51
59
  }
52
- return helmDrainOverrides(drain);
60
+ return [...helmDrainOverrides(drain), ...helmWorkerTargetOverrides(maxInFlight)];
53
61
  }
@@ -104,6 +104,17 @@ export function helmUpgradeArgs(
104
104
  ];
105
105
  }
106
106
 
107
+ /**
108
+ * One worker pod's capacity is what an AverageValue target on `queue_demand` must be: the HPA asks
109
+ * for `ceil(demand / target)` pods, so a target above `jobs.maxInFlight` leaves demand no pod can
110
+ * hold. Undeclared, the chart's value stands: nothing here knows the size of a pod.
111
+ */
112
+ export function helmWorkerTargetOverrides(maxInFlight: number | undefined): readonly string[] {
113
+ return maxInFlight === undefined
114
+ ? []
115
+ : ['--set', `roles.worker.autoscaling.targetAverageValue=${maxInFlight}`];
116
+ }
117
+
107
118
  /** What `--json` reports about the rollout helm waited on. */
108
119
  export interface Rollout {
109
120
  readonly release: string;
@@ -0,0 +1,118 @@
1
+ // What `x deploy --method compose` checks before its first step, and what it reads after a failed
2
+ // one. Before: `.env.production` exists and sets every `${VAR:?}` the compose file demands —
3
+ // without it each step died as `role "migrate" step exited 1`. After: the role's last log line.
4
+
5
+ // why: Bun ships no path-join primitive; the env file is app-root-relative.
6
+ import { join } from 'node:path';
7
+ import type { EnvSchema } from '@ultimat3/core';
8
+ import { ERROR_DOCS_URL } from '@ultimat3/core';
9
+ import { composeRequiredVars } from './cmd-deploy-compose';
10
+ import { requiredAtBoot } from './env-production';
11
+ import type { ExecOptions, Runner } from './exec';
12
+ import type { Finding } from './output';
13
+ import { parseDotenv } from './root-env';
14
+ import { PROD_ENV_FILE } from './templates/scaffold-container-compose';
15
+
16
+ type EnvTable = Readonly<Record<string, string | undefined>>;
17
+
18
+ const missingFinding = (cause: string): Finding => ({
19
+ code: 'X_DEPLOY_ENV_MISSING',
20
+ cause,
21
+ fix: 'x env init --production --json',
22
+ docs: ERROR_DOCS_URL,
23
+ at: PROD_ENV_FILE,
24
+ });
25
+
26
+ /**
27
+ * The refusal, or `undefined` when every step can parse the compose file and every role can boot.
28
+ * A compose variable counts as set from the shell too — compose reads it there first; a key the
29
+ * app's `envSchema` requires reaches the containers through `env_file:` alone, so only the file
30
+ * counts for it. Empty is as absent as none: `${VAR:?}` and the boot's env check refuse both.
31
+ */
32
+ export async function composeEnvPreflight(
33
+ root: string,
34
+ compose: string | undefined,
35
+ shell: EnvTable,
36
+ schema: EnvSchema = {},
37
+ ): Promise<Finding | undefined> {
38
+ const file = Bun.file(join(root, PROD_ENV_FILE));
39
+ if (!(await file.exists())) {
40
+ return missingFinding(
41
+ `${PROD_ENV_FILE} does not exist, and every compose step reads it (--env-file and env_file:)`,
42
+ );
43
+ }
44
+ const values = parseDotenv(await file.text());
45
+ const interpolated = (compose === undefined ? [] : composeRequiredVars(compose)).filter(
46
+ (key) => (shell[key] ?? values.get(key) ?? '') === '',
47
+ );
48
+ const declared = Object.entries(schema)
49
+ .filter(([key, decl]) => requiredAtBoot(decl) && (values.get(key) ?? '') === '')
50
+ .map(([key]) => key)
51
+ .filter((key) => !interpolated.includes(key));
52
+ const missing = [...interpolated, ...declared];
53
+ if (missing.length === 0) return undefined;
54
+ return {
55
+ ...missingFinding(
56
+ `${PROD_ENV_FILE} leaves ${missing.join(', ')} unset or empty, and ${missing.length === 1 ? 'it is' : 'each is'} required: by docker/docker-compose.prod.yml (\${VAR:?}) or by app.config.ts's envSchema, which every role checks at boot`,
57
+ ),
58
+ // The file exists, so the generator would refuse it: the edit is the fix.
59
+ fix: `NODE_ENV=production x env check --json # after setting ${missing.join(', ')} in ${PROD_ENV_FILE}`,
60
+ };
61
+ }
62
+
63
+ /** A rendered `UltimateError`: `X_CODE: title — cause`. A JSON log's `"code":"X_…"` is not one. */
64
+ const RENDERED_CODE = /\bX_[A-Z][A-Z0-9_]*: /;
65
+
66
+ /** Bun's trailer after an uncaught error, the last line of every crash and never its reason. */
67
+ const BUN_TRAILER = /^Bun v\d+\.\d+/;
68
+
69
+ /** The longest line a finding carries: the reason fits, a stack-sized blob does not. */
70
+ const LINE_CEILING = 500;
71
+
72
+ /**
73
+ * The line that says why a process failed: the last rendered `X_*` refusal, else the last
74
+ * non-empty line that is not Bun's version trailer. stderr first, where a refusal is written.
75
+ */
76
+ export function lastLine(output: { readonly stdout: string; readonly stderr: string }): string {
77
+ for (const text of [output.stderr, output.stdout]) {
78
+ const lines = text
79
+ .split(/\r?\n/)
80
+ .map((entry) => entry.trim())
81
+ .filter((entry) => entry !== '');
82
+ const line =
83
+ lines.findLast((entry) => RENDERED_CODE.test(entry)) ??
84
+ lines.findLast((entry) => !BUN_TRAILER.test(entry));
85
+ if (line !== undefined) return line.slice(0, LINE_CEILING);
86
+ }
87
+ return '';
88
+ }
89
+
90
+ /**
91
+ * A serving role's last log line, read after its step failed: a crash-looping container says why
92
+ * in its log, and `up -d` itself only says that it did not become healthy. Empty when compose
93
+ * cannot read the log either; the finding then carries the rerun command alone.
94
+ */
95
+ export async function roleLastLogLine(input: {
96
+ readonly base: readonly string[];
97
+ readonly role: string;
98
+ readonly runner: Runner;
99
+ readonly options: ExecOptions;
100
+ }): Promise<string> {
101
+ const command = [
102
+ ...input.base,
103
+ 'logs',
104
+ '--no-color',
105
+ '--no-log-prefix',
106
+ '--tail',
107
+ '50',
108
+ input.role,
109
+ ];
110
+ try {
111
+ const result = await input.runner(command, input.options);
112
+ return result.ok ? lastLine(result) : '';
113
+ } catch {
114
+ // The log is a courtesy on a failure already being reported; a runner that cannot spawn
115
+ // compose here must not replace that report with its own.
116
+ return '';
117
+ }
118
+ }
@@ -7,24 +7,76 @@ export const deploySpec: CommandSpec = {
7
7
  name: 'deploy',
8
8
  summary: 'run the container deploy plan: migrate first, then the serving roles',
9
9
  usage:
10
- 'x deploy --image repo/app:tag [--method compose|helm] [--release name] [--namespace ns] [--timeout 15m] [--dry-run] [--json]',
10
+ 'x deploy --image repo/app:tag [--method compose|helm] [--release name] [--namespace ns] [--timeout 15m] [--dry-run] [--json] | x deploy verify --url <origin> [--build <id>] [--window 60s] [--interval 5s] [--timeout 10m] [--idle-ok <queue,…>] [--json]',
11
11
  requiresApp: true,
12
+ // `up` is the parser's name for the bare form, so `x deploy --image …` stays the deploy. The usage
13
+ // and every doc keep that one spelling.
14
+ subcommands: ['up', 'verify'],
15
+ defaultSubcommand: 'up',
12
16
  flags: [
13
- { name: 'image', type: 'string', summary: 'image reference to deploy' },
14
- { name: 'method', type: 'string', summary: 'compose | helm', default: 'compose' },
15
- { name: 'dry-run', type: 'boolean', summary: 'print the plan, run nothing' },
17
+ { name: 'image', type: 'string', summary: 'image reference to deploy', subcommands: ['up'] },
18
+ {
19
+ name: 'method',
20
+ type: 'string',
21
+ summary: 'compose | helm',
22
+ default: 'compose',
23
+ subcommands: ['up'],
24
+ },
25
+ {
26
+ name: 'dry-run',
27
+ type: 'boolean',
28
+ summary: 'print the plan, run nothing',
29
+ subcommands: ['up'],
30
+ },
16
31
  {
17
32
  name: 'release',
18
33
  type: 'string',
19
34
  summary: 'helm release name (default: app.config.ts name)',
35
+ subcommands: ['up'],
36
+ },
37
+ {
38
+ name: 'namespace',
39
+ type: 'string',
40
+ summary: 'helm namespace (default: the kube context)',
41
+ subcommands: ['up'],
20
42
  },
21
- { name: 'namespace', type: 'string', summary: 'helm namespace (default: the kube context)' },
22
43
  {
23
44
  name: 'timeout',
24
45
  type: 'string',
25
46
  // No `default:` — the parser would then fill it on every compose deploy too, and the refusal
26
47
  // of a helm-only flag there could not tell an operator's value from its own.
27
- summary: 'how long helm waits for the migrate hook and the rollout (default 15m)',
48
+ summary:
49
+ 'how long helm waits for the migrate hook and the rollout (default 15m); verify: the whole wait (default 10m)',
50
+ },
51
+ {
52
+ name: 'url',
53
+ type: 'string',
54
+ summary: 'the origin to sample: /readyz behind the load balancer',
55
+ subcommands: ['verify'],
56
+ },
57
+ {
58
+ name: 'build',
59
+ type: 'string',
60
+ summary: "the build that must answer (default: x.manifest.json's buildId)",
61
+ subcommands: ['verify'],
62
+ },
63
+ {
64
+ name: 'window',
65
+ type: 'string',
66
+ summary: 'how long consecutive good samples must span (default 60s); 0: answered once',
67
+ subcommands: ['verify'],
68
+ },
69
+ {
70
+ name: 'interval',
71
+ type: 'string',
72
+ summary: 'the gap between samples (default 5s)',
73
+ subcommands: ['verify'],
74
+ },
75
+ {
76
+ name: 'idle-ok',
77
+ type: 'string',
78
+ summary: 'queues a scale-to-zero pool may leave unserved while their depth is 0',
79
+ subcommands: ['verify'],
28
80
  },
29
81
  // `--critical` was here and is gone. It parsed, it was echoed into the plan JSON as
30
82
  // `critical: <bool>`, and no file in `packages/` read that field — so the flag changed