@wolfstar/cli 2.1.0-next-20261001111011 → 2.2.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 (74) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +304 -304
  3. package/dist/{_shared-B-hRZDRS.js → _shared-DJrpalNQ.js} +12 -5
  4. package/dist/_shared-DJrpalNQ.js.map +1 -0
  5. package/dist/{build-CPnSLYME.js → build-CluOR8dJ.js} +5 -5
  6. package/dist/build-CluOR8dJ.js.map +1 -0
  7. package/dist/cli.js +1 -1
  8. package/dist/cli.js.map +1 -1
  9. package/dist/{codegen-BqpLGLLs.js → codegen-D6V1i_fa.js} +4 -4
  10. package/dist/codegen-D6V1i_fa.js.map +1 -0
  11. package/dist/{commands-ExM8HILu.js → commands-BJ589_AC.js} +4 -4
  12. package/dist/commands-BJ589_AC.js.map +1 -0
  13. package/dist/{dev-4wpEQC7l.js → dev-DJJZN4NJ.js} +11 -30
  14. package/dist/dev-DJJZN4NJ.js.map +1 -0
  15. package/dist/{diagnostics-CZBVxlpj.js → diagnostics-3JRAy8Xj.js} +17 -1
  16. package/dist/diagnostics-3JRAy8Xj.js.map +1 -0
  17. package/dist/{errors-Crt4hu0b.js → errors-COFWKKKw.js} +5 -2
  18. package/dist/errors-COFWKKKw.js.map +1 -0
  19. package/dist/external-CxFKxwi3.js.map +1 -1
  20. package/dist/framework-auto-imports-Gu_PXSyr.js.map +1 -1
  21. package/dist/hooks-BfDFM38k.js +316 -0
  22. package/dist/hooks-BfDFM38k.js.map +1 -0
  23. package/dist/index.d.ts +22 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +3 -3
  26. package/dist/{info-CdiQajgn.js → info-C1Kx_4Og.js} +4 -4
  27. package/dist/info-C1Kx_4Og.js.map +1 -0
  28. package/dist/{locales-C7X8VNmK.js → locales-BzOLRBVg.js} +5 -5
  29. package/dist/locales-BzOLRBVg.js.map +1 -0
  30. package/dist/log-buffer-CY82aqnb.js.map +1 -1
  31. package/dist/{nitro-sP2F3SQu.js → nitro-yjqZBh5L.js} +2 -2
  32. package/dist/nitro-yjqZBh5L.js.map +1 -0
  33. package/dist/none-uC_wi_l4.js.map +1 -1
  34. package/dist/output-mode-Bp7Da8vJ.js.map +1 -1
  35. package/dist/plain-B6z85uQP.js.map +1 -1
  36. package/dist/{prepare-B4ysyG6H.js → prepare-Cb45Z4re.js} +9 -5
  37. package/dist/prepare-Cb45Z4re.js.map +1 -0
  38. package/dist/{project-MD4dIo2X.js → project-D-8VIcyF.js} +2 -2
  39. package/dist/project-D-8VIcyF.js.map +1 -0
  40. package/dist/{run-Ddwrxe1O.js → run-BiLZqib3.js} +8 -8
  41. package/dist/run-BiLZqib3.js.map +1 -0
  42. package/dist/theme-3Fc_LI-2.js.map +1 -1
  43. package/dist/tsc-B931Ezh7.js +3 -0
  44. package/dist/{tsc-DO7D_uCl.js → tsc-DEBcwIO0.js} +3 -3
  45. package/dist/tsc-DEBcwIO0.js.map +1 -0
  46. package/dist/{tsdown-CD68G8_U.js → tsdown-DrWXld54.js} +2 -2
  47. package/dist/tsdown-DrWXld54.js.map +1 -0
  48. package/dist/tui-BRddrLQP.js.map +1 -1
  49. package/dist/{tunnel-DT1FH6oA.js → tunnel-DHSxOZKr.js} +2 -2
  50. package/dist/tunnel-DHSxOZKr.js.map +1 -0
  51. package/dist/version-BzclCE19.js.map +1 -1
  52. package/dist/{vite-CLyB6wl7.js → vite-Bf7nrJx7.js} +2 -2
  53. package/dist/vite-Bf7nrJx7.js.map +1 -0
  54. package/package.json +5 -4
  55. package/dist/_shared-B-hRZDRS.js.map +0 -1
  56. package/dist/build-CPnSLYME.js.map +0 -1
  57. package/dist/codegen-BqpLGLLs.js.map +0 -1
  58. package/dist/commands-ExM8HILu.js.map +0 -1
  59. package/dist/dev-4wpEQC7l.js.map +0 -1
  60. package/dist/diagnostics-CZBVxlpj.js.map +0 -1
  61. package/dist/errors-Crt4hu0b.js.map +0 -1
  62. package/dist/hooks-H9kjLCMk.js +0 -148
  63. package/dist/hooks-H9kjLCMk.js.map +0 -1
  64. package/dist/info-CdiQajgn.js.map +0 -1
  65. package/dist/locales-C7X8VNmK.js.map +0 -1
  66. package/dist/nitro-sP2F3SQu.js.map +0 -1
  67. package/dist/prepare-B4ysyG6H.js.map +0 -1
  68. package/dist/project-MD4dIo2X.js.map +0 -1
  69. package/dist/run-Ddwrxe1O.js.map +0 -1
  70. package/dist/tsc-DO7D_uCl.js.map +0 -1
  71. package/dist/tsc-YnAWKn3n.js +0 -3
  72. package/dist/tsdown-CD68G8_U.js.map +0 -1
  73. package/dist/tunnel-DT1FH6oA.js.map +0 -1
  74. package/dist/vite-CLyB6wl7.js.map +0 -1
package/README.md CHANGED
@@ -1,304 +1,304 @@
1
- <div align="center">
2
-
3
- # @wolfstar/cli
4
-
5
- **The `stars` command line interface for [`@wolfstar/http-framework`](../http-framework) projects.**
6
-
7
- [![GitHub](https://img.shields.io/github/license/wolfstar-project/stars-components)](https://github.com/wolfstar-project/stars-components/blob/main/LICENSE)
8
- [![npm](https://img.shields.io/npm/v/@wolfstar/cli?color=crimson&logo=npm&style=flat-square)](https://www.npmjs.com/package/@wolfstar/cli)
9
-
10
- </div>
11
-
12
- ## Description
13
-
14
- `stars` is a small, fast CLI that owns the developer workflow of a bot built with `@wolfstar/http-framework`. Like
15
- Nuxt splits `nuxt.config`/`defineNuxtConfig` (owned by `@nuxt/schema`, which both `nuxt` and the separate `@nuxt/cli`
16
- package depend on) from `nuxi`, the typed `stars.config.*` schema and loader live in their own package,
17
- [`@wolfstar/schema`](../schema), which both [`@wolfstar/http-framework`](../http-framework) (re-exported
18
- as `@wolfstar/http-framework/config`) and this package depend on — this package only consumes it to drive its
19
- commands. `@wolfstar/http-framework` also depends on this package and exposes it as its own `stars` binary (the way
20
- `nuxt` exposes `nuxi`'s), so installing it is enough to get `stars` without a separate `@wolfstar/cli` install; this
21
- package has no install-time dependency on `@wolfstar/http-framework` in return, the same way `@nuxt/cli` has none on
22
- `nuxt` — its own commands:
23
-
24
- - `stars dev` builds the project, starts the bot, restarts it on changes and shows what is happening in an interactive terminal UI (or plain logs).
25
- - `stars build` runs the configured build tool once.
26
- - `stars info` prints the resolved configuration and environment (`--json` for scripts).
27
- - `stars codegen` runs the configured code generators (`--check` for CI).
28
- - `stars prepare` generates `.stars/tsconfig.json` and the auto imports declaration file (`--check` for CI).
29
- - `stars commands` inspects and cleans the application commands Discord has deployed.
30
-
31
- Everything is driven by a typed `stars.config.ts` file.
32
-
33
- ## Installation
34
-
35
- ```sh
36
- pnpm add -D @wolfstar/cli
37
- ```
38
-
39
- Installing [`@wolfstar/http-framework`](../http-framework) already gives a project the `stars` binary, so this
40
- explicit install is only needed to depend on this package directly — for its programmatic exports (`loadStarsConfig`,
41
- diagnostics), or to pin its version independently of the framework's.
42
-
43
- Projects scaffolded with [`@wolfstar/create-http-framework`](../create-http-framework) come with `@wolfstar/cli`, a `stars.config.ts` file and `dev`/`build` scripts already wired up.
44
-
45
- ## Configuration
46
-
47
- `stars.config.{ts,mts,cts,js,mjs,cjs}` is defined and loaded by [`@wolfstar/http-framework`](../http-framework#project-configuration-starsconfig), not by this package — see its README for the full option reference (`root`, `entry`, `build`, `dev`, `codegen`) and the `defineConfig` helper. `stars` looks for it in the working directory (`--config <file>` overrides it, `--cwd <dir>` changes the working directory) and passes `ConfigError`s from the framework through as exit code `2`, with the offending option path and a hint printed to the terminal.
48
-
49
- ```ts
50
- // stars.config.ts
51
- import { defineConfig } from '@wolfstar/http-framework/config';
52
-
53
- export default defineConfig({});
54
- ```
55
-
56
- `stars dev`'s URL needs no configuration either — it is detected from `HTTP_PORT` (env var, `src/.env*`/`.env*`, or `dev.env`) or `3000`, the same way Vite's and Nuxt's dev servers do, and `localhost` is swapped for `127.0.0.1` at runtime if that is what is actually reachable. Set `dev.url` only to override it.
57
-
58
- The resolved configuration is also available programmatically, exactly as the commands see it (re-exported from this package for convenience, or import it directly from `@wolfstar/http-framework/config`):
59
-
60
- ```ts
61
- import { loadStarsConfig } from '@wolfstar/cli';
62
-
63
- const config = await loadStarsConfig({ cwd: process.cwd() });
64
- console.log(config.entry, config.build.output);
65
- ```
66
-
67
- ## Commands
68
-
69
- ```sh
70
- stars dev [--no-tui] [--config <file>] [--cwd <dir>]
71
- stars build [--config <file>] [--cwd <dir>]
72
- stars info [--json] [--config <file>] [--cwd <dir>]
73
- stars codegen [--check] [--json] [--config <file>] [--cwd <dir>]
74
- stars prepare [--check] [--json] [--config <file>] [--cwd <dir>]
75
- stars commands [list|clean] [--guild <id>] [--name <name>] [--yes] [--json]
76
- stars --help | --version
77
- ```
78
-
79
- ### `stars dev`
80
-
81
- Watches the sources through the configured build tool (`tsdown` programmatically, configured from your `stars.config`, `tsc -b --watch`, or a plain file watcher for JavaScript projects), starts the bot after the first successful build and restarts it after every following one. Failed builds keep the previous process running and wait for the next change; a crashed bot waits for the next change or a manual restart.
82
-
83
- The bot runs as a child `node` process with `STARS_DEV=1` and `NODE_ENV=development` in its environment. Because `stars dev` already restarts the whole process, leave the framework's own `hmr` option disabled while using it.
84
-
85
- **Interactive UI** (default on a TTY): a bottom-aligned panel following the layout and keyboard conventions of
86
- [Nuxt CLI's dev TUI](https://github.com/nuxt/cli/tree/b4b366eafdd9ac4d5b81b6ae7dadda35364252c9/packages/nuxt-cli/src/dev/tui).
87
- The normal screen shows a Stars wordmark, aligned URLs, a 20-cell progress bar with elapsed time, status and
88
- shortcuts. The percentage follows actual build milestones, not a timer: it can stay still while a compiler phase
89
- runs. Once ready, the bar gives way to diagnostics and the header reports the load time.
90
-
91
- Application output (including its banner), build-plugin output and diagnostics stay in the bounded log history and
92
- `.stars/dev.log`. tsdown's entry list and output-size table are suppressed. Only log/help/info overlays enter the
93
- alternate screen; closing them restores the panel without duplicating output in scrollback. Error stack frames do
94
- not count as individual errors. `READY` reports process state unless `dev.health` is configured; it does not certify
95
- that every application plugin loaded successfully. Logged errors switch the badge to `ERROR`.
96
-
97
- | Key | Action |
98
- | -------------- | ------------------------------------------------------------ |
99
- | `r` / `Ctrl+R` | restart the bot |
100
- | `o` | open the local URL in a browser |
101
- | `t` | toggle a public `cloudflared` tunnel |
102
- | `i` | show project, versions, URLs, health, types and session info |
103
- | `T` | pick a colour theme (see **Themes** below) |
104
- | `l` | browse logs |
105
- | `e` | select the last error with its surrounding context |
106
- | `c` / `Ctrl+L` | clear log history |
107
- | `h` / `?` | show keyboard shortcuts |
108
- | `q` / `Ctrl+D` | quit; confirm with `y` while a build/restart is in flight |
109
- | `Ctrl+C` | quit immediately from any view |
110
-
111
- In the log view: arrows or `j/k` select, `PgUp/PgDn` move a page, `g/G` go to the beginning/follow the tail,
112
- `e/w/a` filter errors/warnings/all, `c/b/r` toggle CLI/build/runtime sources, `/` searches, `x` clears, and
113
- `Enter`/`y` copies the selected line on terminals supporting OSC 52 clipboard writes. `q`, `Esc` or the view's
114
- own shortcut closes an overlay rather than quitting the session. Nuxt-specific request and page-route inspectors
115
- are not exposed: the bot supervisor does not receive those runtime events.
116
-
117
- Replace the default wordmark in `stars.config.ts` (up to four lines are displayed, clipped to the terminal width):
118
-
119
- ```ts
120
- export default defineConfig({
121
- dev: { banner: ['★ STARYL', 'Twitch notifications'] }
122
- });
123
- ```
124
-
125
- `dev.banner` also accepts a string containing newlines, or `false` to hide the wordmark. Omit it for Stars branding.
126
- For the application's standalone banner outside the TUI, use `createStarsBanner` from `@wolfstar/start-banner`.
127
-
128
- **Themes.** Press `T` to pick a colour theme, like Claude Code's `/theme`: arrows preview it live, `Enter` keeps and saves
129
- it, `Esc` restores the previous one. Available themes are `auto` (follows the terminal background through
130
- `COLORFGBG`, dark when unknown), `dark`, `light`, `dark-daltonized` and `light-daltonized` (blue/orange instead of
131
- green/red, for colour-blind users), and `dark-ansi` and `light-ansi` (only the 16 ANSI colours, so your terminal
132
- palette decides). The theme resolves as `--theme <name>` › `STARS_THEME` › the saved choice › `auto`. It is saved in
133
- `preferences.json` under `$STARS_CONFIG_DIR`, `$XDG_CONFIG_HOME/stars`, `%APPDATA%\stars` or `~/.config/stars`.
134
- `NO_COLOR` still disables colour altogether.
135
-
136
- **Plain mode** prints prefixed lines instead and is selected by `--no-tui`, `STARS_TUI=plain`, redirected input/output,
137
- CI, `TERM=dumb`, or terminals smaller than 40×10. `STARS_TUI=1` overrides CI/size checks, never redirected streams or
138
- a dumb terminal. Both modes honour `NO_COLOR`/`FORCE_COLOR`; `STARS_REDUCED_MOTION=1` freezes the logo/spinner but
139
- keeps the elapsed clock. Both stop the bot cleanly on `SIGINT`/`SIGTERM`. `SIGUSR2` restarts the bot (not on Windows).
140
-
141
- ### `stars commands`
142
-
143
- Lists what Discord currently has deployed, which is not necessarily what the project registers today: renamed and
144
- removed commands stay until something deletes them.
145
-
146
- ```sh
147
- stars commands list # global commands
148
- stars commands list --guild 1234 # a guild's commands
149
- stars commands clean # wizard: pick from a checklist, then confirm
150
- stars commands clean --name ping # delete one, asking first
151
- stars commands clean --guild 1234 --yes
152
- ```
153
-
154
- It reads `DISCORD_TOKEN` and `DISCORD_APPLICATION_ID` (or `APPLICATION_ID`) from the environment or the project's
155
- `.env`, the same place the bot reads them from. `clean` deletes deployed commands, so on a terminal it opens a wizard —
156
- a checklist of what is deployed, then a confirmation — and refuses to run without `--yes` (or `--name`) anywhere
157
- else.
158
-
159
- ### Type checking, tunnel and logs
160
-
161
- Three `dev` options round out the dev loop (all documented in
162
- [`@wolfstar/http-framework`](../http-framework#project-configuration-starsconfig)):
163
-
164
- - `dev.typecheck: true` runs a type checker next to the bot and reports type errors on the UI's `tsc` channel,
165
- without ever blocking a build or a restart — useful when building with `tsdown`, which does not type-check.
166
- `dev.typecheck.checker` picks which one: `tsc` (the project's TypeScript, watch mode), `golar` (`golar tsc`, watch
167
- mode), `tsz` (the tsc-compatible checker, re-run after every build since it has no watch mode), or `auto` — the
168
- default, which uses `golar` when the project depends on it and `tsc` otherwise.
169
- - Pressing `t` opens and closes a `cloudflared` quick tunnel without configuration. `dev.tunnel: true` opens it at startup so Discord can reach the bot's interactions endpoint from the
170
- internet; a string is an https URL you already serve, which the CLI only probes. `dev.tunnel.updateEndpoint` writes
171
- the URL to the Discord application, and is opt-in because it edits a live application.
172
- - `dev.logFile` (default `.stars/dev.log`) mirrors the session's logs to disk, so a run can be read back after the
173
- terminal UI is gone. Set it to `false` to disable it.
174
-
175
- ### The build
176
-
177
- `tsdown` is configured from `stars.config`, and a base project configures nothing: the entry's directory, one output
178
- file per source file, ESM on Node, `build.outDir`, the tsconfig (`src/tsconfig.json` or `tsconfig.json`), the
179
- extension `build.output` implies, sourcemaps, unbundled dependencies, Nuxt's `~`/`@`/`~~`/`@@` alias prefixes and
180
- the auto imports plugin, and copying `src/locales` to `dist/locales` are all filled in
181
- (the [framework README](../http-framework#the-build-tsdown) lists every default). The `tsdown` block is for what they
182
- cannot know:
183
-
184
- Every `@wolfstar/plugin-*` package listed in the project's `dependencies` or `optionalDependencies` is activated
185
- automatically in bundler builds. `stars` injects its `/register` side-effect entrypoint before the application entry,
186
- so projects do not need to maintain bare imports such as `import '@wolfstar/plugin-i18next/register'`. Packages used
187
- only for development are intentionally not activated from `devDependencies`.
188
-
189
- ```typescript
190
- export default defineConfig({
191
- tsdown: { dts: true }
192
- });
193
- ```
194
-
195
- With `future.compatibilityVersion: 3` (end-of-life) an existing `tsdown.config.*` still drives the build and the block
196
- is merged over it (values from `stars.config` win, `plugins` are appended); from `4` on the block is the whole
197
- configuration. The
198
- `vite` block works the same way for `build.tool: 'vite'`. `stars info` shows which file the build is configured from
199
- and which options the block sets.
200
-
201
- ### Compatibility version
202
-
203
- `future.compatibilityVersion` selects the legacy or current defaults, the way Nuxt's own compatibility setting does (see the
204
- [framework README](../http-framework#compatibility-version) for the full reference):
205
-
206
- | Version | What it changes |
207
- | ------------- | ----------------------------------------------------------------------------------------------------------------------------- |
208
- | `3` (EOL) | Legacy behaviour: a `tsdown.config.*` drives the build, auto imports off unless asked for; prints `COMPATIBILITY_VERSION_EOL` |
209
- | `4` | `tsdown` configured from `stars.config` alone, auto imports on and wired in, `'auto'` picks `tsdown` for TypeScript |
210
- | `5` (default) | Everything in `4`, plus `env` registered automatically when the project depends on `@wolfstar/env-utilities` |
211
-
212
- ### Environment and hooks
213
-
214
- `env` mirrors the options of `setup()` from `@wolfstar/env-utilities`: `stars` calls it with them as the first import
215
- of the built entry, before plugin registrations and the bot's own modules. tsdown, Vite and Nitro builds get it
216
- through the entry transform; with `build.tool: 'tsc'` or `'none'` only `stars dev` preloads it (`node --import`).
217
- Nitro leaves it off unless `env` is set explicitly.
218
-
219
- ```typescript
220
- export default defineConfig({
221
- env: { prefix: 'BOT_' },
222
- hooks: {
223
- 'env:options'(options) {
224
- if (process.env.CI) options.path = '.env.ci';
225
- },
226
- build: { done: (outcome) => void (outcome.ok || console.error(outcome.message)) }
227
- }
228
- });
229
- ```
230
-
231
- `hooks` are CLI lifecycle hooks run with [`hookable`](https://github.com/unjs/hookable): `config:resolved`,
232
- `env:options`, `prepare:before`/`prepare:done`, `builder:created`, `tsdown:options`, `build:before`/`build:done`,
233
- `dev:start`/`dev:restart`/`dev:close`. They run in the CLI process, never in the bot, in the same order in `stars build` and
234
- `stars dev` (see the framework README for how `stars dev` awaits them). `stars info` lists the env
235
- options and the registered hooks. See the [framework README](../http-framework#environment-env) for the full
236
- reference.
237
-
238
- ### Experimental flags
239
-
240
- `experimental` in `stars.config.*` turns on work that is still landing (see the
241
- [framework README](../http-framework#experimental-flags) for the full reference):
242
-
243
- | Flag | What it changes |
244
- | -------------------- | ------------------------------------------------------------------------------------------------------------------------- |
245
- | `enableVite` | Builds through the project's own `vite` (and allows `build.tool: 'vite'`) instead of `tsdown` |
246
- | `enableExternalVite` | The project runs Vite itself; `stars dev` only watches the build output and restarts the bot |
247
- | `enableNitro` | Builds through [Nitro](https://nitro.build) (itself a Vite plugin) instead of `node:http`, deployable to any Nitro preset |
248
-
249
- `stars info` prints which flags are on.
250
-
251
- ### Exit codes
252
-
253
- | Code | Meaning |
254
- | ----- | ---------------------------------------------------- |
255
- | `0` | success |
256
- | `1` | generic error (including `codegen --check` failures) |
257
- | `2` | invalid or missing configuration |
258
- | `3` | build failed |
259
- | `130` | interrupted with `SIGINT` |
260
- | `143` | terminated with `SIGTERM`/`SIGHUP` |
261
-
262
- ### Generated TypeScript configuration
263
-
264
- The generated compiler options combine `@sapphire/ts-config`, `@sapphire/ts-config/extra-strict`, and
265
- `@sapphire/ts-config/decorators`. The CLI loads these presets and writes their options directly into the file,
266
- so consumers do not need to install Sapphire. This enables strict checks, explicit overrides, and legacy decorators
267
- with metadata. Stars targets ES2022, skips dependency declaration checks, and stores incremental build information
268
- inside `.stars/`. Tsdown and Vite use `ESNext`/`Bundler` with `noEmit`; tsc retains Sapphire's Node16 emit settings.
269
- Project compiler options can override these defaults.
270
-
271
- Bundler builds also follow [Nitro's TypeScript configuration](https://github.com/nitrojs/nitro/blob/main/lib/tsconfig.json):
272
- forced module detection, isolated modules, verbatim module syntax, JavaScript sources, `.ts` import extensions,
273
- package.json imports, and ESNext/DOM libraries. Use `import type` and `export type` for type-only dependencies.
274
- These options apply to tsdown and Vite; tsc keeps its emit-compatible settings. Sapphire's decorator options and
275
- the ES2022 target remain in effect. This does not enable Stars' experimental Nitro runtime integration.
276
-
277
- Run `stars prepare` and extend the generated config from your project's `tsconfig.json`:
278
-
279
- ```json
280
- {
281
- "extends": "./.stars/tsconfig.json"
282
- }
283
- ```
284
-
285
- New tsdown projects already extend this file and run `stars prepare` through `postinstall`.
286
- Keep your existing compiler options alongside `extends`. `stars dev` and `stars build` also regenerate this file.
287
- For tsdown builds, `@/` and `~/` resolve to the entry file's directory (normally `src/`), while `@@/` and `~~/`
288
- resolve to the project root. Filesystem aliases in `stars.config.ts`'s `tsdown.alias` are included too, with custom
289
- values taking precedence. Legacy builds using a separate tsdown config only include aliases declared in
290
- `stars.config.ts`. Other build tools do not get tsdown aliases, since TypeScript alone does not rewrite imports.
291
-
292
- The generated config includes source files and the auto imports declaration, including a custom `imports.dts`
293
- location. Explicit `include` or `compilerOptions.paths` in your own tsconfig replace the inherited values;
294
- remove manually duplicated paths to use the generated aliases. Generation works with `imports: false` too.
295
- Use `stars prepare --check` to check both generated files without writing them. Do not edit `.stars/tsconfig.json`
296
- by hand; keep `.stars/` ignored by Git and run `stars prepare` after installing dependencies on a fresh checkout.
297
-
298
- ## Server integrations
299
-
300
- `@wolfstar/vite-server` and `@wolfstar/nitro-server` provide the Vite and Nitro builders. The CLI loads the
301
- selected integration lazily, passes the resolved `stars.config` and supplies project dependency loading and
302
- plugin registration through `BuilderContext` from `@wolfstar/schema`. Neither server package depends on the CLI
303
- or framework. Existing experimental flags, presets, output directories and `stars dev`/`stars build` commands
304
- are unchanged; install Vite/Nitro in the consuming project as before.
1
+ <div align="center">
2
+
3
+ # @wolfstar/cli
4
+
5
+ **The `stars` command line interface for [`@wolfstar/http-framework`](../http-framework) projects.**
6
+
7
+ [![GitHub](https://img.shields.io/github/license/wolfstar-project/stars-components)](https://github.com/wolfstar-project/stars-components/blob/main/LICENSE)
8
+ [![npm](https://img.shields.io/npm/v/@wolfstar/cli?color=crimson&logo=npm&style=flat-square)](https://www.npmjs.com/package/@wolfstar/cli)
9
+
10
+ </div>
11
+
12
+ ## Description
13
+
14
+ `stars` is a small, fast CLI that owns the developer workflow of a bot built with `@wolfstar/http-framework`. Like
15
+ Nuxt splits `nuxt.config`/`defineNuxtConfig` (owned by `@nuxt/schema`, which both `nuxt` and the separate `@nuxt/cli`
16
+ package depend on) from `nuxi`, the typed `stars.config.*` schema and loader live in their own package,
17
+ [`@wolfstar/schema`](../schema), which both [`@wolfstar/http-framework`](../http-framework) (re-exported
18
+ as `@wolfstar/http-framework/config`) and this package depend on — this package only consumes it to drive its
19
+ commands. `@wolfstar/http-framework` also depends on this package and exposes it as its own `stars` binary (the way
20
+ `nuxt` exposes `nuxi`'s), so installing it is enough to get `stars` without a separate `@wolfstar/cli` install; this
21
+ package has no install-time dependency on `@wolfstar/http-framework` in return, the same way `@nuxt/cli` has none on
22
+ `nuxt` — its own commands:
23
+
24
+ - `stars dev` builds the project, starts the bot, restarts it on changes and shows what is happening in an interactive terminal UI (or plain logs).
25
+ - `stars build` runs the configured build tool once.
26
+ - `stars info` prints the resolved configuration and environment (`--json` for scripts).
27
+ - `stars codegen` runs the configured code generators (`--check` for CI).
28
+ - `stars prepare` generates `.stars/tsconfig.json` and the auto imports declaration file (`--check` for CI).
29
+ - `stars commands` inspects and cleans the application commands Discord has deployed.
30
+
31
+ Everything is driven by a typed `stars.config.ts` file.
32
+
33
+ ## Installation
34
+
35
+ ```sh
36
+ pnpm add -D @wolfstar/cli
37
+ ```
38
+
39
+ Installing [`@wolfstar/http-framework`](../http-framework) already gives a project the `stars` binary, so this
40
+ explicit install is only needed to depend on this package directly — for its programmatic exports (`loadStarsConfig`,
41
+ diagnostics), or to pin its version independently of the framework's.
42
+
43
+ Projects scaffolded with [`@wolfstar/create-http-framework`](../create-http-framework) come with `@wolfstar/cli`, a `stars.config.ts` file and `dev`/`build` scripts already wired up.
44
+
45
+ ## Configuration
46
+
47
+ `stars.config.{ts,mts,cts,js,mjs,cjs}` is defined and loaded by [`@wolfstar/http-framework`](../http-framework#project-configuration-starsconfig), not by this package — see its README for the full option reference (`root`, `entry`, `build`, `dev`, `codegen`) and the `defineConfig` helper. `stars` looks for it in the working directory (`--config <file>` overrides it, `--cwd <dir>` changes the working directory) and passes `ConfigError`s from the framework through as exit code `2`, with the offending option path and a hint printed to the terminal.
48
+
49
+ ```ts
50
+ // stars.config.ts
51
+ import { defineConfig } from '@wolfstar/http-framework/config';
52
+
53
+ export default defineConfig({});
54
+ ```
55
+
56
+ `stars dev`'s URL needs no configuration either — it is detected from `HTTP_PORT` (env var, `src/.env*`/`.env*`, or `dev.env`) or `3000`, the same way Vite's and Nuxt's dev servers do, and `localhost` is swapped for `127.0.0.1` at runtime if that is what is actually reachable. Set `dev.url` only to override it.
57
+
58
+ The resolved configuration is also available programmatically, exactly as the commands see it (re-exported from this package for convenience, or import it directly from `@wolfstar/http-framework/config`):
59
+
60
+ ```ts
61
+ import { loadStarsConfig } from '@wolfstar/cli';
62
+
63
+ const config = await loadStarsConfig({ cwd: process.cwd() });
64
+ console.log(config.entry, config.build.output);
65
+ ```
66
+
67
+ ## Commands
68
+
69
+ ```sh
70
+ stars dev [--no-tui] [--config <file>] [--cwd <dir>]
71
+ stars build [--config <file>] [--cwd <dir>]
72
+ stars info [--json] [--config <file>] [--cwd <dir>]
73
+ stars codegen [--check] [--json] [--config <file>] [--cwd <dir>]
74
+ stars prepare [--check] [--json] [--config <file>] [--cwd <dir>]
75
+ stars commands [list|clean] [--guild <id>] [--name <name>] [--yes] [--json]
76
+ stars --help | --version
77
+ ```
78
+
79
+ ### `stars dev`
80
+
81
+ Watches the sources through the configured build tool (`tsdown` programmatically, configured from your `stars.config`, `tsc -b --watch`, or a plain file watcher for JavaScript projects), starts the bot after the first successful build and restarts it after every following one. Failed builds keep the previous process running and wait for the next change; a crashed bot waits for the next change or a manual restart.
82
+
83
+ The bot runs as a child `node` process with `STARS_DEV=1` and `NODE_ENV=development` in its environment. Because `stars dev` already restarts the whole process, leave the framework's own `hmr` option disabled while using it.
84
+
85
+ **Interactive UI** (default on a TTY): a bottom-aligned panel following the layout and keyboard conventions of
86
+ [Nuxt CLI's dev TUI](https://github.com/nuxt/cli/tree/b4b366eafdd9ac4d5b81b6ae7dadda35364252c9/packages/nuxt-cli/src/dev/tui).
87
+ The normal screen shows a Stars wordmark, aligned URLs, a 20-cell progress bar with elapsed time, status and
88
+ shortcuts. The percentage follows actual build milestones, not a timer: it can stay still while a compiler phase
89
+ runs. Once ready, the bar gives way to diagnostics and the header reports the load time.
90
+
91
+ Application output (including its banner), build-plugin output and diagnostics stay in the bounded log history and
92
+ `.stars/dev.log`. tsdown's entry list and output-size table are suppressed. Only log/help/info overlays enter the
93
+ alternate screen; closing them restores the panel without duplicating output in scrollback. Error stack frames do
94
+ not count as individual errors. `READY` reports process state unless `dev.health` is configured; it does not certify
95
+ that every application plugin loaded successfully. Logged errors switch the badge to `ERROR`.
96
+
97
+ | Key | Action |
98
+ | -------------- | ------------------------------------------------------------ |
99
+ | `r` / `Ctrl+R` | restart the bot |
100
+ | `o` | open the local URL in a browser |
101
+ | `t` | toggle a public `cloudflared` tunnel |
102
+ | `i` | show project, versions, URLs, health, types and session info |
103
+ | `T` | pick a colour theme (see **Themes** below) |
104
+ | `l` | browse logs |
105
+ | `e` | select the last error with its surrounding context |
106
+ | `c` / `Ctrl+L` | clear log history |
107
+ | `h` / `?` | show keyboard shortcuts |
108
+ | `q` / `Ctrl+D` | quit; confirm with `y` while a build/restart is in flight |
109
+ | `Ctrl+C` | quit immediately from any view |
110
+
111
+ In the log view: arrows or `j/k` select, `PgUp/PgDn` move a page, `g/G` go to the beginning/follow the tail,
112
+ `e/w/a` filter errors/warnings/all, `c/b/r` toggle CLI/build/runtime sources, `/` searches, `x` clears, and
113
+ `Enter`/`y` copies the selected line on terminals supporting OSC 52 clipboard writes. `q`, `Esc` or the view's
114
+ own shortcut closes an overlay rather than quitting the session. Nuxt-specific request and page-route inspectors
115
+ are not exposed: the bot supervisor does not receive those runtime events.
116
+
117
+ Replace the default wordmark in `stars.config.ts` (up to four lines are displayed, clipped to the terminal width):
118
+
119
+ ```ts
120
+ export default defineConfig({
121
+ dev: { banner: ['★ STARYL', 'Twitch notifications'] }
122
+ });
123
+ ```
124
+
125
+ `dev.banner` also accepts a string containing newlines, or `false` to hide the wordmark. Omit it for Stars branding.
126
+ For the application's standalone banner outside the TUI, use `createStarsBanner` from `@wolfstar/start-banner`.
127
+
128
+ **Themes.** Press `T` to pick a colour theme, like Claude Code's `/theme`: arrows preview it live, `Enter` keeps and saves
129
+ it, `Esc` restores the previous one. Available themes are `auto` (follows the terminal background through
130
+ `COLORFGBG`, dark when unknown), `dark`, `light`, `dark-daltonized` and `light-daltonized` (blue/orange instead of
131
+ green/red, for colour-blind users), and `dark-ansi` and `light-ansi` (only the 16 ANSI colours, so your terminal
132
+ palette decides). The theme resolves as `--theme <name>` › `STARS_THEME` › the saved choice › `auto`. It is saved in
133
+ `preferences.json` under `$STARS_CONFIG_DIR`, `$XDG_CONFIG_HOME/stars`, `%APPDATA%\stars` or `~/.config/stars`.
134
+ `NO_COLOR` still disables colour altogether.
135
+
136
+ **Plain mode** prints prefixed lines instead and is selected by `--no-tui`, `STARS_TUI=plain`, redirected input/output,
137
+ CI, `TERM=dumb`, or terminals smaller than 40×10. `STARS_TUI=1` overrides CI/size checks, never redirected streams or
138
+ a dumb terminal. Both modes honour `NO_COLOR`/`FORCE_COLOR`; `STARS_REDUCED_MOTION=1` freezes the logo/spinner but
139
+ keeps the elapsed clock. Both stop the bot cleanly on `SIGINT`/`SIGTERM`. `SIGUSR2` restarts the bot (not on Windows).
140
+
141
+ ### `stars commands`
142
+
143
+ Lists what Discord currently has deployed, which is not necessarily what the project registers today: renamed and
144
+ removed commands stay until something deletes them.
145
+
146
+ ```sh
147
+ stars commands list # global commands
148
+ stars commands list --guild 1234 # a guild's commands
149
+ stars commands clean # wizard: pick from a checklist, then confirm
150
+ stars commands clean --name ping # delete one, asking first
151
+ stars commands clean --guild 1234 --yes
152
+ ```
153
+
154
+ It reads `DISCORD_TOKEN` and `DISCORD_APPLICATION_ID` (or `APPLICATION_ID`) from the environment or the project's
155
+ `.env`, the same place the bot reads them from. `clean` deletes deployed commands, so on a terminal it opens a wizard —
156
+ a checklist of what is deployed, then a confirmation — and refuses to run without `--yes` (or `--name`) anywhere
157
+ else.
158
+
159
+ ### Type checking, tunnel and logs
160
+
161
+ Three `dev` options round out the dev loop (all documented in
162
+ [`@wolfstar/http-framework`](../http-framework#project-configuration-starsconfig)):
163
+
164
+ - `dev.typecheck: true` runs a type checker next to the bot and reports type errors on the UI's `tsc` channel,
165
+ without ever blocking a build or a restart — useful when building with `tsdown`, which does not type-check.
166
+ `dev.typecheck.checker` picks which one: `tsc` (the project's TypeScript, watch mode), `golar` (`golar tsc`, watch
167
+ mode), `tsz` (the tsc-compatible checker, re-run after every build since it has no watch mode), or `auto` — the
168
+ default, which uses `golar` when the project depends on it and `tsc` otherwise.
169
+ - Pressing `t` opens and closes a `cloudflared` quick tunnel without configuration. `dev.tunnel: true` opens it at startup so Discord can reach the bot's interactions endpoint from the
170
+ internet; a string is an https URL you already serve, which the CLI only probes. `dev.tunnel.updateEndpoint` writes
171
+ the URL to the Discord application, and is opt-in because it edits a live application.
172
+ - `dev.logFile` (default `.stars/dev.log`) mirrors the session's logs to disk, so a run can be read back after the
173
+ terminal UI is gone. Set it to `false` to disable it.
174
+
175
+ ### The build
176
+
177
+ `tsdown` is configured from `stars.config`, and a base project configures nothing: the entry's directory, one output
178
+ file per source file, ESM on Node, `build.outDir`, the tsconfig (`src/tsconfig.json` or `tsconfig.json`), the
179
+ extension `build.output` implies, sourcemaps, unbundled dependencies, Nuxt's `~`/`@`/`~~`/`@@` alias prefixes and
180
+ the auto imports plugin, and copying `src/locales` to `dist/locales` are all filled in
181
+ (the [framework README](../http-framework#the-build-tsdown) lists every default). The `tsdown` block is for what they
182
+ cannot know:
183
+
184
+ Every `@wolfstar/plugin-*` package listed in the project's `dependencies` or `optionalDependencies` is activated
185
+ automatically in bundler builds. `stars` injects its `/register` side-effect entrypoint before the application entry,
186
+ so projects do not need to maintain bare imports such as `import '@wolfstar/plugin-i18next/register'`. Packages used
187
+ only for development are intentionally not activated from `devDependencies`.
188
+
189
+ ```typescript
190
+ export default defineConfig({
191
+ tsdown: { dts: true }
192
+ });
193
+ ```
194
+
195
+ With `future.compatibilityVersion: 3` (end-of-life) an existing `tsdown.config.*` still drives the build and the block
196
+ is merged over it (values from `stars.config` win, `plugins` are appended); from `4` on the block is the whole
197
+ configuration. The
198
+ `vite` block works the same way for `build.tool: 'vite'`. `stars info` shows which file the build is configured from
199
+ and which options the block sets.
200
+
201
+ ### Compatibility version
202
+
203
+ `future.compatibilityVersion` selects the legacy or current defaults, the way Nuxt's own compatibility setting does (see the
204
+ [framework README](../http-framework#compatibility-version) for the full reference):
205
+
206
+ | Version | What it changes |
207
+ | ------------- | ----------------------------------------------------------------------------------------------------------------------------- |
208
+ | `3` (EOL) | Legacy behaviour: a `tsdown.config.*` drives the build, auto imports off unless asked for; prints `COMPATIBILITY_VERSION_EOL` |
209
+ | `4` | `tsdown` configured from `stars.config` alone, auto imports on and wired in, `'auto'` picks `tsdown` for TypeScript |
210
+ | `5` (default) | Everything in `4`, plus `env` registered automatically when the project depends on `@wolfstar/env-utilities` |
211
+
212
+ ### Environment and hooks
213
+
214
+ `env` mirrors the options of `setup()` from `@wolfstar/env-utilities`: `stars` calls it with them as the first import
215
+ of the built entry, before plugin registrations and the bot's own modules. tsdown, Vite and Nitro builds get it
216
+ through the entry transform; with `build.tool: 'tsc'` or `'none'` only `stars dev` preloads it (`node --import`).
217
+ Nitro leaves it off unless `env` is set explicitly.
218
+
219
+ ```typescript
220
+ export default defineConfig({
221
+ env: { prefix: 'BOT_' },
222
+ hooks: {
223
+ 'env:options'(options) {
224
+ if (process.env.CI) options.path = '.env.ci';
225
+ },
226
+ build: { done: (outcome) => void (outcome.ok || console.error(outcome.message)) }
227
+ }
228
+ });
229
+ ```
230
+
231
+ `hooks` are CLI lifecycle hooks run with [`hookable`](https://github.com/unjs/hookable): `config:resolved`,
232
+ `env:options`, `prepare:before`/`prepare:done`, `builder:created`, `tsdown:options`, `build:before`/`build:done`,
233
+ `dev:start`/`dev:restart`/`dev:close`. They run in the CLI process, never in the bot, in the same order in `stars build` and
234
+ `stars dev` (see the framework README for how `stars dev` awaits them). `stars info` lists the env
235
+ options and the registered hooks. See the [framework README](../http-framework#environment-env) for the full
236
+ reference.
237
+
238
+ ### Experimental flags
239
+
240
+ `experimental` in `stars.config.*` turns on work that is still landing (see the
241
+ [framework README](../http-framework#experimental-flags) for the full reference):
242
+
243
+ | Flag | What it changes |
244
+ | -------------------- | ------------------------------------------------------------------------------------------------------------------------- |
245
+ | `enableVite` | Builds through the project's own `vite` (and allows `build.tool: 'vite'`) instead of `tsdown` |
246
+ | `enableExternalVite` | The project runs Vite itself; `stars dev` only watches the build output and restarts the bot |
247
+ | `enableNitro` | Builds through [Nitro](https://nitro.build) (itself a Vite plugin) instead of `node:http`, deployable to any Nitro preset |
248
+
249
+ `stars info` prints which flags are on.
250
+
251
+ ### Exit codes
252
+
253
+ | Code | Meaning |
254
+ | ----- | ---------------------------------------------------- |
255
+ | `0` | success |
256
+ | `1` | generic error (including `codegen --check` failures) |
257
+ | `2` | invalid or missing configuration |
258
+ | `3` | build failed |
259
+ | `130` | interrupted with `SIGINT` |
260
+ | `143` | terminated with `SIGTERM`/`SIGHUP` |
261
+
262
+ ### Generated TypeScript configuration
263
+
264
+ The generated compiler options combine `@sapphire/ts-config`, `@sapphire/ts-config/extra-strict`, and
265
+ `@sapphire/ts-config/decorators`. The CLI loads these presets and writes their options directly into the file,
266
+ so consumers do not need to install Sapphire. This enables strict checks, explicit overrides, and legacy decorators
267
+ with metadata. Stars targets ES2022, skips dependency declaration checks, and stores incremental build information
268
+ inside `.stars/`. Tsdown and Vite use `ESNext`/`Bundler` with `noEmit`; tsc retains Sapphire's Node16 emit settings.
269
+ Project compiler options can override these defaults.
270
+
271
+ Bundler builds also follow [Nitro's TypeScript configuration](https://github.com/nitrojs/nitro/blob/main/lib/tsconfig.json):
272
+ forced module detection, isolated modules, verbatim module syntax, JavaScript sources, `.ts` import extensions,
273
+ package.json imports, and ESNext/DOM libraries. Use `import type` and `export type` for type-only dependencies.
274
+ These options apply to tsdown and Vite; tsc keeps its emit-compatible settings. Sapphire's decorator options and
275
+ the ES2022 target remain in effect. This does not enable Stars' experimental Nitro runtime integration.
276
+
277
+ Run `stars prepare` and extend the generated config from your project's `tsconfig.json`:
278
+
279
+ ```json
280
+ {
281
+ "extends": "./.stars/tsconfig.json"
282
+ }
283
+ ```
284
+
285
+ New tsdown projects already extend this file and run `stars prepare` through `postinstall`.
286
+ Keep your existing compiler options alongside `extends`. `stars dev` and `stars build` also regenerate this file.
287
+ For tsdown builds, `@/` and `~/` resolve to the entry file's directory (normally `src/`), while `@@/` and `~~/`
288
+ resolve to the project root. Filesystem aliases in `stars.config.ts`'s `tsdown.alias` are included too, with custom
289
+ values taking precedence. Legacy builds using a separate tsdown config only include aliases declared in
290
+ `stars.config.ts`. Other build tools do not get tsdown aliases, since TypeScript alone does not rewrite imports.
291
+
292
+ The generated config includes source files and the auto imports declaration, including a custom `imports.dts`
293
+ location. Explicit `include` or `compilerOptions.paths` in your own tsconfig replace the inherited values;
294
+ remove manually duplicated paths to use the generated aliases. Generation works with `imports: false` too.
295
+ Use `stars prepare --check` to check both generated files without writing them. Do not edit `.stars/tsconfig.json`
296
+ by hand; keep `.stars/` ignored by Git and run `stars prepare` after installing dependencies on a fresh checkout.
297
+
298
+ ## Server integrations
299
+
300
+ `@wolfstar/vite-server` and `@wolfstar/nitro-server` provide the Vite and Nitro builders. The CLI loads the
301
+ selected integration lazily, passes the resolved `stars.config` and supplies project dependency loading and
302
+ plugin registration through `BuilderContext` from `@wolfstar/schema`. Neither server package depends on the CLI
303
+ or framework. Existing experimental flags, presets, output directories and `stars dev`/`stars build` commands
304
+ are unchanged; install Vite/Nitro in the consuming project as before.