@zerotal/arch 1.7.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 (160) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +67 -0
  4. package/api-surface.md +283 -0
  5. package/docs/about.md +676 -0
  6. package/docs/admin/actions.md +183 -0
  7. package/docs/admin/auth.md +89 -0
  8. package/docs/admin/dashboard.md +155 -0
  9. package/docs/admin/extending-ui.md +229 -0
  10. package/docs/admin/extending.md +205 -0
  11. package/docs/admin/forms.md +155 -0
  12. package/docs/admin/index.md +144 -0
  13. package/docs/admin/operations.md +224 -0
  14. package/docs/admin/references.md +174 -0
  15. package/docs/admin/resources.md +132 -0
  16. package/docs/admin/structure.md +158 -0
  17. package/docs/admin/tables.md +185 -0
  18. package/docs/admin/testing.md +138 -0
  19. package/docs/ai.md +373 -0
  20. package/docs/application.md +435 -0
  21. package/docs/arch.md +263 -0
  22. package/docs/assets.md +755 -0
  23. package/docs/audit.md +367 -0
  24. package/docs/authentication.md +1000 -0
  25. package/docs/authorization.md +529 -0
  26. package/docs/broadcasting/channels.md +170 -0
  27. package/docs/broadcasting/client.md +108 -0
  28. package/docs/broadcasting/events.md +190 -0
  29. package/docs/broadcasting/index.md +163 -0
  30. package/docs/broadcasting/references.md +84 -0
  31. package/docs/broadcasting/testing.md +132 -0
  32. package/docs/cache.md +387 -0
  33. package/docs/carbon.md +830 -0
  34. package/docs/changelog.md +465 -0
  35. package/docs/client/auth.md +113 -0
  36. package/docs/client/errors.md +139 -0
  37. package/docs/client/files.md +118 -0
  38. package/docs/client/index.md +128 -0
  39. package/docs/client/references.md +58 -0
  40. package/docs/client/requests.md +131 -0
  41. package/docs/client/resilience.md +141 -0
  42. package/docs/client/testing.md +146 -0
  43. package/docs/commands.md +450 -0
  44. package/docs/components.md +2427 -0
  45. package/docs/config-system.md +258 -0
  46. package/docs/container.md +596 -0
  47. package/docs/context.md +579 -0
  48. package/docs/contributing.md +164 -0
  49. package/docs/controllers.md +354 -0
  50. package/docs/conventions.md +466 -0
  51. package/docs/cookies.md +101 -0
  52. package/docs/csrf.md +206 -0
  53. package/docs/database.md +476 -0
  54. package/docs/deployment.md +434 -0
  55. package/docs/devtools.md +1013 -0
  56. package/docs/email-verification.md +320 -0
  57. package/docs/encryption.md +380 -0
  58. package/docs/errors.md +317 -0
  59. package/docs/events.md +420 -0
  60. package/docs/flow/components.md +846 -0
  61. package/docs/flow/decorators.md +458 -0
  62. package/docs/flow/events.md +420 -0
  63. package/docs/flow/forms.md +551 -0
  64. package/docs/flow/index.md +568 -0
  65. package/docs/flow/layouts.md +793 -0
  66. package/docs/flow/lifecycle.md +336 -0
  67. package/docs/flow/pagination.md +402 -0
  68. package/docs/flow/performance.md +262 -0
  69. package/docs/flow/references.md +317 -0
  70. package/docs/flow/routing.md +550 -0
  71. package/docs/flow/testing.md +447 -0
  72. package/docs/getting-started.md +286 -0
  73. package/docs/health.md +269 -0
  74. package/docs/helpers.md +423 -0
  75. package/docs/i18n.md +414 -0
  76. package/docs/index.md +65 -0
  77. package/docs/inertia/build.md +95 -0
  78. package/docs/inertia/devtools.md +197 -0
  79. package/docs/inertia/index.md +267 -0
  80. package/docs/inertia/middleware.md +81 -0
  81. package/docs/inertia/props.md +507 -0
  82. package/docs/inertia/references.md +144 -0
  83. package/docs/inertia/rendering.md +189 -0
  84. package/docs/inertia/ssr.md +102 -0
  85. package/docs/inspirations.md +257 -0
  86. package/docs/lifecycle.md +331 -0
  87. package/docs/lock.md +454 -0
  88. package/docs/logger.md +517 -0
  89. package/docs/media.md +582 -0
  90. package/docs/middleware.md +509 -0
  91. package/docs/migrations.md +529 -0
  92. package/docs/monitor.md +377 -0
  93. package/docs/notifications.md +848 -0
  94. package/docs/orm/casts.md +365 -0
  95. package/docs/orm/factories.md +231 -0
  96. package/docs/orm/index.md +663 -0
  97. package/docs/orm/lifecycle.md +421 -0
  98. package/docs/orm/queries.md +692 -0
  99. package/docs/orm/relationships.md +440 -0
  100. package/docs/orm/serialization.md +251 -0
  101. package/docs/package-development.md +536 -0
  102. package/docs/pagination.md +340 -0
  103. package/docs/password-reset.md +335 -0
  104. package/docs/providers.md +447 -0
  105. package/docs/query-builder.md +465 -0
  106. package/docs/queue.md +549 -0
  107. package/docs/rate-limiting.md +253 -0
  108. package/docs/responses.md +336 -0
  109. package/docs/roles-and-2fa.md +418 -0
  110. package/docs/routing.md +1008 -0
  111. package/docs/scaffolding.md +335 -0
  112. package/docs/scheduler.md +533 -0
  113. package/docs/seeding.md +229 -0
  114. package/docs/session.md +451 -0
  115. package/docs/social.md +524 -0
  116. package/docs/storage.md +622 -0
  117. package/docs/structure.md +230 -0
  118. package/docs/support-policy.md +114 -0
  119. package/docs/telemetry.md +505 -0
  120. package/docs/tenancy.md +608 -0
  121. package/docs/testing/browser.md +153 -0
  122. package/docs/testing/console.md +130 -0
  123. package/docs/testing/database.md +238 -0
  124. package/docs/testing/flow-browser.md +216 -0
  125. package/docs/testing/http.md +441 -0
  126. package/docs/testing/index.md +240 -0
  127. package/docs/testing/mocking.md +410 -0
  128. package/docs/upgrade.md +192 -0
  129. package/docs/validator.md +549 -0
  130. package/docs/view.md +453 -0
  131. package/package.json +60 -0
  132. package/src/bin/mcp.ts +73 -0
  133. package/src/config.ts +63 -0
  134. package/src/errors.ts +27 -0
  135. package/src/index.ts +56 -0
  136. package/src/install/ArchInstallCommand.ts +189 -0
  137. package/src/install/detect.ts +98 -0
  138. package/src/install/guidelines.ts +290 -0
  139. package/src/install/markers.ts +77 -0
  140. package/src/install/mcpConfig.ts +81 -0
  141. package/src/mcp/index.ts +27 -0
  142. package/src/mcp/jsonrpc.ts +133 -0
  143. package/src/mcp/server.ts +307 -0
  144. package/src/mcp/stdio.ts +111 -0
  145. package/src/mcp/types.ts +146 -0
  146. package/src/probe/ArchProbeCommand.ts +48 -0
  147. package/src/probe/sentinel.ts +13 -0
  148. package/src/probe/topics.ts +291 -0
  149. package/src/provider/ArchProvider.ts +101 -0
  150. package/src/tools/_probe.ts +164 -0
  151. package/src/tools/apiSurface.ts +241 -0
  152. package/src/tools/appInfo.ts +88 -0
  153. package/src/tools/baselines.ts +210 -0
  154. package/src/tools/context.ts +37 -0
  155. package/src/tools/doctor.ts +93 -0
  156. package/src/tools/index.ts +50 -0
  157. package/src/tools/logs.ts +265 -0
  158. package/src/tools/routes.ts +133 -0
  159. package/src/tools/schema.ts +119 -0
  160. package/src/tools/searchDocs.ts +345 -0
@@ -0,0 +1,450 @@
1
+ ---
2
+ title: Commands
3
+ description: Build and run CLI commands with bun zt, from generators to your own class- or closure-based commands.
4
+ ---
5
+
6
+ # Commands
7
+
8
+ Zerotal ships a class-based CLI for running framework tasks and your own
9
+ scripts. Every command is invoked with `bun zt <name>`, and you can add new
10
+ ones as classes or one-line closures.
11
+
12
+ ```bash
13
+ # in your project root
14
+ bun zt list # list all commands with descriptions
15
+ bun zt help <command> # detailed usage for one command
16
+ bun zt make:controller PostController
17
+ ```
18
+
19
+ The command system is built into `@zerotal/core` — there is no package to
20
+ install and no provider to register. The CLI bootstraps your application, then
21
+ dispatches the matched command.
22
+
23
+ ## Listing & help
24
+
25
+ `bun zt list` prints every registered command, its description, and any
26
+ aliases. `bun zt help <command>` prints the usage line, description,
27
+ arguments, and options for a single command.
28
+
29
+ ```bash
30
+ # in your project root
31
+ bun zt list
32
+ bun zt help migrate
33
+ ```
34
+
35
+ ## Class-based commands
36
+
37
+ Extend `Command`, declare static metadata, and implement `run()`. Inside `run()`
38
+ you read parsed positional arguments from `this.args` and flags from
39
+ `this.flags`:
40
+
41
+ ```typescript
42
+ // app/commands/SendDigestCommand.ts
43
+ import { Command } from "zerotal";
44
+
45
+ export class SendDigestCommand extends Command {
46
+ static commandName = "digest:send";
47
+ static description = "Send the weekly digest email";
48
+ static args = [{ name: "segment", required: false, default: "all" }];
49
+ static flags = [{ name: "dry", type: "boolean" as const, default: false }];
50
+
51
+ async run(): Promise<void> {
52
+ const segment = this.args["segment"];
53
+ if (this.flags["dry"]) {
54
+ this.warn("Dry run — nothing sent");
55
+ return;
56
+ }
57
+ this.info(`Sending digest to ${segment}…`);
58
+ }
59
+ }
60
+ ```
61
+
62
+ A `FlagDef`'s `type` is `"string" | "boolean" | "number"`; the `as const`
63
+ keeps the literal type so the field stays type-checked.
64
+
65
+ > **Tip** — Run `bun zt make:command SendDigest` to scaffold a ready-to-edit
66
+ > command class at `app/commands/SendDigestCommand.ts`.
67
+
68
+ ## Closure commands
69
+
70
+ For one-liners, register a plain definition with a signature string. The
71
+ signature's first token is the name; `{arg}` is required, `{arg?}` optional,
72
+ `{arg=default}` has a default, `{--flag}` is a boolean flag, and `{--flag=}` /
73
+ `{--flag=default}` is a string flag.
74
+
75
+ ```typescript
76
+ // in a service provider or bootstrap script
77
+ const runner = app.container.tryMake("commands");
78
+
79
+ runner.command({
80
+ signature: "greet {name} {--loud}",
81
+ description: "Say hello",
82
+ handle: ({ name, loud }, cmd) => {
83
+ cmd.info(loud ? `HELLO ${name}!` : `Hello, ${name}`);
84
+ },
85
+ });
86
+ ```
87
+
88
+ The `handle` callback receives a single object merging the parsed arguments and
89
+ flags, plus the `Command` instance so you can use its output helpers.
90
+
91
+ > **Note** — `registerCommand()` is an alias for `command()`; both build a
92
+ > synthetic `Command` subclass from the definition and register it.
93
+
94
+ ### Which should I use?
95
+
96
+ | You have… | Use |
97
+ | ------------------------------------------------------ | -------------------- |
98
+ | A quick task with little logic, defined inline | Closure |
99
+ | Logic worth testing, multiple methods, or its own file | Class |
100
+ | A folder of commands to register together | Class + `discover()` |
101
+
102
+ ## Auto-discovery
103
+
104
+ `app/commands/` is discovered automatically: any command class dropped there —
105
+ including everything `make:command` generates — is registered when the CLI boots,
106
+ with no imports or provider wiring. An app command registers after the built-ins,
107
+ so it wins a name collision. The directory is configurable via
108
+ `conventions.paths.commands` in `config/app.ts`, and discovery honours the
109
+ `conventions.enabled` master switch.
110
+
111
+ To register a folder from somewhere else, call `discover()` yourself:
112
+
113
+ ```typescript
114
+ // in a service provider or bootstrap script
115
+ await runner.discover("./vendor/acme/commands");
116
+ ```
117
+
118
+ Every non-test `.ts`/`.js` file under the directory is imported, and any exported
119
+ `Command` subclass with a non-empty `commandName` is registered. `discover()`
120
+ returns the list of registered names.
121
+
122
+ ## Styled output & prompts
123
+
124
+ The `Command` base class provides coloured output helpers and interactive
125
+ prompts. The prompts read from stdin and only work on a real TTY:
126
+
127
+ ```typescript
128
+ // inside a command's run()
129
+ this.info("Success"); // green
130
+ this.warn("Heads up"); // yellow
131
+ this.error("Failed"); // red (written to stderr)
132
+ this.line("Plain"); // cyan
133
+ this.dim("subtle"); // dim
134
+ this.section("Title"); // bold heading
135
+ this.table([["Key", "Value"]]); // aligned two-column rows
136
+ this.newLine();
137
+
138
+ const name = await this.ask("Your name?", "guest");
139
+ const ok = await this.confirm("Proceed?", true);
140
+ const env = await this.choice("Environment:", ["local", "staging", "production"]);
141
+ const token = await this.secret("API token:"); // input hidden on a Unix TTY
142
+ ```
143
+
144
+ > **Warning** — `secret()` only hides input on a Unix TTY with raw mode; on
145
+ > Windows and in non-interactive contexts it falls back to a visible prompt.
146
+
147
+ ## Built-in Commands
148
+
149
+ ### Server & Development
150
+
151
+ | Command | Description |
152
+ | ----------------------------- | --------------------------------------------------------------- |
153
+ | `bun zt dev` | Dev mode: the server plus every registered process (alias: `d`) |
154
+ | `bun zt dev --only=server` | Run only the named processes, comma-separated |
155
+ | `bun zt dev --without=queue` | Run everything except the named processes |
156
+ | `bun zt dev --list` | Print what would run, and which provider registered it |
157
+ | `bun zt dev --stream` | Interleave prefixed output instead of drawing tabs |
158
+ | `bun zt dev --force-build` | Rebuild assets even when the build cache says they're current |
159
+ | `bun zt serve` | Start the HTTP server on port 3000 |
160
+ | `bun zt serve --port 8080` | Start on a custom port |
161
+ | `bun zt serve --force` | If the port is busy, stop whatever holds it |
162
+ | `bun zt serve --auto-port` | If the port is busy, start on the next free port |
163
+ | `bun zt reload` | Hot-reload routes in the running server (sends SIGUSR2) |
164
+ | `bun zt status` | Show live metrics from the running server |
165
+ | `bun zt repl` | Start an interactive REPL with the bootstrapped app in scope |
166
+ | `bun zt worker` | Start the background job worker process |
167
+ | `bun zt worker --queue email` | Process a specific queue |
168
+ | `bun zt worker --once` | Process one job then exit |
169
+ | `bun zt test` | Run the test suite in the `test` environment |
170
+ | `bun zt compile` | Compile the app to a self-contained binary (alias: `build`) |
171
+ | `bun zt css:build` | Build the Tailwind CSS bundle for production |
172
+
173
+ #### When the port is already taken
174
+
175
+ `serve` checks the port before it binds, so a busy one is a question rather than
176
+ a crash. It tells you which process is holding it — usually a server you forgot
177
+ was running — and offers to stop that process and take the port, or to start on
178
+ the next free one instead. Pressing Enter takes the next free port, the answer
179
+ that cannot cost you anything.
180
+
181
+ Nothing prompts when there is no terminal to answer, which covers CI, containers,
182
+ and anything reading `serve`'s output from a pipe. There it fails with the same
183
+ explanation, so use `--force` or `--auto-port` to say up front which way you want
184
+ it decided. Both flags work with a plain `serve` and with `serve --dev`.
185
+
186
+ The dev server is a special case worth knowing about: on every restart it waits a
187
+ few seconds for its own previous process to let go of the socket rather than
188
+ asking you about it. A prompt on each file save would be unbearable, and the port
189
+ is about to free itself anyway.
190
+
191
+ #### Dev mode and the deck
192
+
193
+ `bun zt dev` starts the server, the file watcher, and every process a provider or
194
+ your app registered — a queue worker, a type-checker, a Stripe listener — in one
195
+ terminal, each in its own tab. It is `serve --dev` with those extra tabs and the
196
+ keys to drive them, so anything true of one is true of the other.
197
+
198
+ An app with a queue no longer needs a second terminal:
199
+
200
+ ```bash
201
+ # in your project root
202
+ bun zt dev
203
+ ```
204
+
205
+ The deck draws one tab per process, colour-coded, showing whether each is
206
+ running, restarting, or has given up:
207
+
208
+ ```text
209
+ 1 server ●│ 2 queue ●│ 3 types ◌
210
+ ─────────────────────────────────────────────────
211
+ GET / 200 4ms
212
+ GET /posts 200 11ms
213
+ 1-9 tab · ←/→ cycle · r restart · c clear · / search · t time · s stream · q quit
214
+ ```
215
+
216
+ | Key | Does |
217
+ | ------------- | ---------------------------------------------------------------- |
218
+ | `1`–`9` | Select that tab |
219
+ | `←` `→` `Tab` | Cycle through tabs |
220
+ | `r` | Restart the focused process |
221
+ | `c` | Clear the focused tab's output |
222
+ | `/` | Search within the focused tab (`Enter` keeps it, `Esc` drops it) |
223
+ | `t` | Toggle per-line timestamps |
224
+ | `s` | Switch to stream mode |
225
+ | `PgUp` `PgDn` | Scroll the focused tab |
226
+ | `q` | Quit — stops every process and restores your shell |
227
+
228
+ Scrollback belongs to the deck rather than to your terminal, which is what makes
229
+ per-tab history and search possible. It keeps the last 5,000 lines per process.
230
+
231
+ **A process that dies never takes the server with it.** It restarts on its own —
232
+ three times, backing off between attempts — and if it still will not start, that
233
+ one tab parks with a message telling you how to retry. Everything else keeps
234
+ running. This is the opposite of the asset build, where a failure deliberately
235
+ aborts the reload.
236
+
237
+ #### Stream mode
238
+
239
+ Not everything watching `zt dev` is a person at a terminal. When stdout is not a
240
+ TTY — CI, a pipe, a log file — the deck writes prefixed lines instead, with no
241
+ escape codes at all:
242
+
243
+ ```text
244
+ [server] GET / 200 4ms
245
+ [queue ] processing SendWelcomeEmail
246
+ [server] GET /posts 200 11ms
247
+ ```
248
+
249
+ That happens automatically; `--stream` forces it, and `s` switches to it
250
+ mid-session. It is the same information, and it is what you want in a file.
251
+
252
+ #### Choosing what runs
253
+
254
+ `--only` and `--without` take comma-separated names, and the server is an
255
+ ordinary name among them:
256
+
257
+ ```bash
258
+ # in your project root
259
+ bun zt dev --only=server,queue # just these two
260
+ bun zt dev --without=queue # everything else
261
+ bun zt dev --only=queue # no server at all
262
+ ```
263
+
264
+ When you are not sure what a tab is or who asked for it, `--list` answers both
265
+ without starting anything:
266
+
267
+ ```bash
268
+ # in your project root
269
+ bun zt dev --list
270
+ ```
271
+
272
+ ```text
273
+ Dev processes
274
+ server
275
+ command managed by the orchestrator
276
+ registered by @zerotal/core
277
+ queue
278
+ command bun zt queue:work
279
+ registered by QueueProvider
280
+ ```
281
+
282
+ Your app has the last word. `app.dev.disable` removes a process by name, and
283
+ registering the same name again replaces it rather than adding a second tab:
284
+
285
+ ```ts
286
+ // config/app.ts
287
+ export default AppConfig({
288
+ dev: {
289
+ processes: [
290
+ { name: "stripe", command: ["stripe", "listen", "--forward-to", "localhost:3000"] },
291
+ ],
292
+ disable: ["queue"],
293
+ },
294
+ });
295
+ ```
296
+
297
+ Packages register their own — see
298
+ [Registering a dev process](/docs/package-development#registering-a-dev-process).
299
+
300
+ ### Inspection
301
+
302
+ | Command | Description |
303
+ | ---------------------- | ------------------------------------------------------ |
304
+ | `bun zt route:list` | List all registered routes with methods and middleware |
305
+ | `bun zt route:types` | Write `types/routes.generated.ts` (`--check` in CI) |
306
+ | `bun zt doctor` | Check the app for silent misconfigurations |
307
+ | `bun zt key:generate` | Generate a new `APP_KEY` and write it to `.env` |
308
+ | `bun zt lint:packages` | Check every workspace package against convention rules |
309
+
310
+ `doctor` runs every static sanity check against the booted app and prints each
311
+ finding with its fix: APP_KEY strength, `database.synchronize` colliding with
312
+ migration files, a `routes/` directory nothing loads, and class directories
313
+ (`app/schedules`, `app/jobs`, `config/storage.ts`) whose consuming provider is
314
+ not registered. These failures otherwise fail by _doing nothing_, which is the
315
+ most expensive kind to find. Packages can contribute checks via
316
+ `app.registerDoctorCheck()`. Exits non-zero when a check fails outright, so it
317
+ can gate a deploy.
318
+
319
+ ### Database
320
+
321
+ | Command | Description |
322
+ | ----------------------------- | -------------------------------------------------------------- |
323
+ | `bun zt migrate` | Run all pending migrations |
324
+ | `bun zt migrate --fresh` | Drop all tables, then re-run everything from scratch |
325
+ | `bun zt migrate --seed` | Run migrations, then run the seeders |
326
+ | `bun zt migrate:rollback` | Roll back the most recent migration batch |
327
+ | `bun zt migrate:fresh` | Alias: drop all tables and re-run all migrations |
328
+ | `bun zt migrate:fresh --seed` | Rebuild the schema from scratch, then run the seeders |
329
+ | `bun zt migrate:status` | Show the status (run / pending / batch) of each migration file |
330
+ | `bun zt migrate:generate` | Auto-generate a migration from model schema changes |
331
+ | `bun zt db:seed` | Run all seeders from `database/seeders/` |
332
+
333
+ > **Danger** — `migrate --fresh` and `migrate:fresh` drop every table before
334
+ > re-running migrations. Never run them against a production database.
335
+
336
+ ### Generators
337
+
338
+ | Command | Creates |
339
+ | ---------------------------------------------------- | -------------------------------------------------------------------------- |
340
+ | `bun zt make:model Post` | `app/models/Post.ts` |
341
+ | `bun zt make:controller PostController [--resource]` | `app/controllers/PostController.ts` |
342
+ | `bun zt make:middleware RequireAdmin` | `app/middleware/RequireAdminMiddleware.ts` |
343
+ | `bun zt make:command SendDigest` | `app/commands/SendDigestCommand.ts` |
344
+ | `bun zt make:request StorePost` | `app/requests/StorePostRequest.ts` |
345
+ | `bun zt make:notification OrderShipped` | `app/notifications/OrderShippedNotification.ts` |
346
+ | `bun zt make:job ProcessPayment` | `app/jobs/ProcessPaymentJob.ts` |
347
+ | `bun zt make:event UserRegistered` | `app/events/UserRegisteredEvent.ts` |
348
+ | `bun zt make:listener SendWelcome` | `app/listeners/SendWelcomeListener.ts` |
349
+ | `bun zt make:observer UserObserver [--model User]` | `app/observers/UserObserver.ts` |
350
+ | `bun zt make:policy PostPolicy [--model Post]` | `app/policies/PostPolicy.ts` |
351
+ | `bun zt make:resource UserResource` | `app/resources/UserResource.ts` |
352
+ | `bun zt make:migration create_posts_table` | `database/migrations/{timestamp}_create_posts_table.ts` |
353
+ | `bun zt make:factory PostFactory` | `database/factories/PostFactory.ts` |
354
+ | `bun zt make:seeder PostSeeder` | `database/seeders/PostSeeder.ts` |
355
+ | `bun zt make:provider Payment [--no-register]` | `app/providers/PaymentProvider.ts` + registers in `bootstrap/providers.ts` |
356
+ | `bun zt make:package billing` | Full `packages/billing/` package skeleton |
357
+
358
+ ### Queue
359
+
360
+ | Command | Description |
361
+ | ---------------------------------------------- | ---------------------------------------------------- |
362
+ | `bun zt queue:work [--queue default] [--once]` | Process jobs. Daemon in production; `--once` for CI. |
363
+ | `bun zt queue:failed` | List all failed jobs |
364
+ | `bun zt queue:retry <id\|all>` | Retry one failed job or all failed jobs |
365
+ | `bun zt queue:flush [--queue name] [--force]` | Delete all failed jobs from the database |
366
+
367
+ ### Cache
368
+
369
+ | Command | Description |
370
+ | -------------------- | ------------------------------------------------------- |
371
+ | `bun zt cache:clear` | Clear all cached values from the configured cache store |
372
+
373
+ ### Scheduler
374
+
375
+ | Command | Description |
376
+ | ---------------------- | ------------------------------------------------------------ |
377
+ | `bun zt schedule:list` | List all registered scheduled tasks with their next run time |
378
+
379
+ ## References
380
+
381
+ The command surface lives in `@zerotal/core`. The base `Command` class is what
382
+ you extend; `CommandRunner` (resolved from the container as `"commands"`) is the
383
+ registry and dispatcher.
384
+
385
+ ### Command static metadata
386
+
387
+ | Field | Type | Description |
388
+ | ------------- | ----------- | ----------------------------------------- |
389
+ | `commandName` | `string` | The name invoked on the CLI. |
390
+ | `description` | `string` | Shown in `list` and `help`. |
391
+ | `args` | `ArgDef[]` | Positional arguments the command accepts. |
392
+ | `flags` | `FlagDef[]` | Named flags the command accepts. |
393
+ | `needsApp` | `boolean` | Whether the bootstrapped app is injected. |
394
+
395
+ `ArgDef` is `{ name: string; required?: boolean; default?: string }`. `FlagDef`
396
+ is `{ name: string; short?: string; type: "string" | "boolean" | "number"; description?: string; default?: unknown }`.
397
+
398
+ ### Command instance members
399
+
400
+ | Member | Signature | Description |
401
+ | ------- | --------------------------------------------- | ------------------------------------------------ |
402
+ | `run` | `run(): Promise<void>` | The work the command performs (abstract). |
403
+ | `args` | `Record<string, string>` | Parsed positional arguments, set before `run()`. |
404
+ | `flags` | `Record<string, string \| boolean \| number>` | Parsed flags, set before `run()`. |
405
+ | `app` | `unknown` | The application instance, set before `run()`. |
406
+
407
+ ### Output helpers
408
+
409
+ | Method | Signature | Description |
410
+ | --------- | ------------------------------------------------ | ---------------------------- |
411
+ | `info` | `info(msg: string): void` | Green success line. |
412
+ | `warn` | `warn(msg: string): void` | Yellow warning line. |
413
+ | `error` | `error(msg: string): void` | Red line, written to stderr. |
414
+ | `line` | `line(msg: string): void` | Cyan line. |
415
+ | `dim` | `dim(msg: string): void` | Dimmed line. |
416
+ | `write` | `write(msg: string): void` | Raw write, no newline. |
417
+ | `newLine` | `newLine(): void` | Blank line. |
418
+ | `section` | `section(title: string): void` | Bold heading. |
419
+ | `table` | `table(rows: [string, string][], indent?): void` | Aligned two-column rows. |
420
+
421
+ ### Prompts
422
+
423
+ | Method | Signature | Description |
424
+ | --------- | --------------------------------------------------------------------- | --------------------------------- |
425
+ | `ask` | `ask(question: string, defaultValue?: string): Promise<string>` | Text input with optional default. |
426
+ | `confirm` | `confirm(question: string, defaultValue?: boolean): Promise<boolean>` | Yes/no confirmation. |
427
+ | `choice` | `choice(question: string, options: string[]): Promise<string>` | Pick one from a numbered list. |
428
+ | `secret` | `secret(question: string): Promise<string>` | Hidden input on a Unix TTY. |
429
+
430
+ ### CommandRunner
431
+
432
+ | Method | Signature | Description |
433
+ | ----------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------ |
434
+ | `register` | `register(Cmd: CommandClass, aliases?: string[]): void` | Register a command class under its name and aliases. |
435
+ | `registerAll` | `registerAll(commandClasses: CommandClass[]): void` | Register several classes at once. |
436
+ | `command` | `command(definition: CommandDefinition, aliases?: string[]): CommandClass` | Build and register a closure command. |
437
+ | `registerCommand` | `registerCommand(definition: CommandDefinition, aliases?: string[]): CommandClass` | Alias for `command()`. |
438
+ | `registerLazy` | `registerLazy(name: string, thunk: CommandThunk, aliases?: string[]): void` | Register a command imported lazily on first call. |
439
+ | `discover` | `discover(dir: string): Promise<string[]>` | Import a directory and register found command classes. |
440
+ | `run` | `run(argv: string[]): Promise<void>` | Parse argv, run the command, and `process.exit()`. |
441
+ | `callInProcess` | `callInProcess(argv: string[], parameters?): Promise<{ code: number; output: string }>` | Run in-process, capture output, no exit. |
442
+
443
+ ## Next steps
444
+
445
+ - [Scaffolding](/docs/scaffolding) — what the `make:` generators produce.
446
+ - [Scheduler](/docs/scheduler) — register tasks that `schedule:list` reports.
447
+ - [Queue](/docs/queue) — the worker and queue commands in context.
448
+ - [Container](/docs/container) — how commands resolve their dependencies.
449
+ </content>
450
+ </invoke>