Skip to main content

npm

Source

Description

A CLI scaffolding tool for creating new WolfStar HTTP Framework bot projects.

Usage

The CLI will guide you through the following prompts:
  • Project name — an npm-compatible name for your bot
  • Package manager — npm, yarn, pnpm, or bun
  • Language — TypeScript or JavaScript
  • Build tool — tsdown, Vite, Vite + Nitro, TypeScript 6, or the TypeScript 7 release candidate (Vite and Vite + Nitro are experimental)
  • Linter and formatter — Oxlint / ESLint and Oxfmt / Prettier
  • Port — the port the HTTP server will listen on (default: 3000)
  • Optional features (multiselect) —
  • Auto-install — install dependencies immediately after scaffolding

Options

Non-interactive / AI agent mode

When the CLI detects an AI agent is running it (via @vercel/detect-agent), it automatically enters non-interactive mode, equivalent to passing --no-interactive. A project name argument is required in this mode:

Generated project structure

  • src/locales/en-US/commands/ping.json and src/@types/i18next.d.ts are only generated when i18n is enabled.
  • src/@types/i18next.d.ts is produced by @wolfstar/i18next-type-generator; the CLI runs it automatically at the end of scaffolding, and it can be re-run any time locale files change (see generate:i18n below).
  • src/commands/math.ts is only generated when Subcommands is enabled.
  • src/lib/cache.ts is only generated with Cache, src/shard.ts with Sharder, and compose.yaml with Redis.
  • tests/ping.test.ts, vitest.config.ts, and vitest.setup.ts are only generated when Testing is enabled.
  • AGENTS.md and llms.txt are always generated. They only describe the features the project was created with. See AI agent files.
  • With a linter, the generated .oxlintrc.json or eslint.config.mjs enables the rules of @wolfstar/eslint-plugin-http-framework. See Framework lint rules.
  • In TypeScript projects built with tsdown or Vite, src/lib/setup/all.ts doesn’t load the environment itself. stars loads .env (the env option in stars.config.ts) before any module of the bot runs. Projects built with tsc, Vite + Nitro, or JavaScript still call setup() from @wolfstar/env-utilities.

TypeScript configuration

TypeScript projects built with tsdown, Vite, or Vite + Nitro are generated for future.compatibilityVersion 6. Their root tsconfig.json is solution-style. It only references the two configs that stars prepare writes to .stars/:
.stars/tsconfig.app.json covers the bot sources, and .stars/tsconfig.node.json covers the config files and scripts Node runs. See Generated TypeScript configuration. The postinstall script runs stars prepare, so both files exist after you install dependencies. These projects also get a typecheck script that runs stars typecheck:
A bare tsc on the root tsconfig.json checks nothing, because it only references .stars/. The generated README.md and AGENTS.md list the typecheck script. Projects built with tsc6 or tsc7 keep their composite tsconfig.json and src/tsconfig.json, without a typecheck script. When you run the CLI again on an existing project, it replaces the root tsconfig.json only when the file is one the generator wrote: the solution-style file, or the older one that extends ./.stars/tsconfig.json. The CLI compares the files as JSON, so formatting changes don’t count as edits. It keeps a hand-edited tsconfig.json and prints a warning. If that file extends ./.stars/tsconfig.json, make it reference the two generated configs instead.

AI agent files

Every project gets two files for AI coding agents:
  • AGENTS.md lists the project’s commands, its layout, and the framework rules that are easy to get wrong.
  • llms.txt links the upstream documentation, grouped by topic.
Both files only cover the features you selected. When you rerun the CLI in an existing project, it replaces these files only if they’re its own unedited output. If you wrote or edited AGENTS.md or llms.txt, the CLI keeps your version and prints a warning. To get the generated version, delete the file and run the CLI again.

Framework lint rules

When you pick a linter, the CLI adds @wolfstar/eslint-plugin-http-framework to devDependencies and enables its rules. They catch mistakes TypeScript can’t, such as decorator order, raw Discord fetches, and dynamic translation keys. With ESLint, eslint.config.mjs registers the plugin with its recommended rules:
eslint.config.mjs
With Oxlint, .oxlintrc.json loads the plugin through jsPlugins and sets each wolfstar/* rule to error:
.oxlintrc.json

Dev tunnel

Discord sends interactions to a public URL, so a bot running on your machine needs a tunnel while you develop. --tunnel (or the Dev tunnel feature in the prompt) writes dev: { tunnel: true } to stars.config.ts. stars dev then opens a cloudflared quick tunnel at startup.
stars.config.ts
Without the flag, press t in stars dev to open a tunnel on demand. See Type checking, tunnel and logs for the other dev.tunnel options.

varlock

--env varlock (or the Environment schema feature in the prompt) sets the project up with varlock, which validates the environment and types it:
  • .env.schema declares DISCORD_TOKEN, DISCORD_PUBLIC_KEY, DISCORD_CLIENT_ID, the HTTP port, HTTP_POST_PATH, and what the other features need (REDIS_URL, SHARDER_CLUSTERS). The values stay in .env.
  • varlock is added as a dependency. @wolfstar/env-utilities loads the schema by itself, because it picks varlock when it finds a .env.schema and an installed varlock.
  • src/lib/types/augments.ts derives Env from src/@types/env.d.ts with EnvFromVarlock from @wolfstar/env-utilities/varlock, instead of declaring each variable by hand. The scaffold ships a stand-in src/@types/env.d.ts so the project type-checks right away. The schema’s @generateTsTypes directive makes varlock replace it, with the same shape, whenever it loads the schema (npm run dev, or npx varlock load).
  • For tsdown and vite projects, stars.config.ts also gets env: { loader: 'varlock' }, so stars dev and stars doctor read the variables the way the bot does. tsc, JavaScript, and Nitro projects load the environment themselves, so they get the schema and the dependency but no env entry.
src/lib/types/augments.ts
The generator detects an existing varlock project when you run it against a directory with --ignore, without the flag:
  • With a .env.schema (in src/, the project root, or at varlock.loadPath), the schema is kept as it is, varlock stays a dependency, and stars.config.ts sets env.loader.
  • With only a varlock dependency, varlock stays a dependency.
  • A varlock.loadPath in package.json is kept.
The generator never replaces an existing .env.schema it did not write, with or without --env varlock. With the flag, it keeps the schema, reports it, and leaves Env hand-written, because that schema may not generate types. Rerunning without the flag over a project the generator scaffolded with varlock keeps varlock on. Delete .env.schema to turn it off.

Vite and Nitro

--build vite bundles the bot with Vite into a single dist/main.js. --build vite-nitro hands the bundle to Nitro, which writes a deployable .output/ directory using the node-server preset, pinned in stars.config.ts. Both options are TypeScript only and experimental. They turn on experimental.enableVite (and experimental.enableNitro for vite-nitro) in the generated stars.config.ts.
  • A bundle has no commands directory to scan, so src/main.ts imports and loads the example commands explicitly. Add your own commands there.
  • With Nitro, src/main.ts default-exports the client instead of calling listen(). The port comes from PORT in .env instead of HTTP_PORT.
  • The main field and start script point to the node-server preset’s output, .output/server/index.mjs. If you change nitro.preset to target another platform, deploy that platform’s .output/ instead of running npm start. With --gateway, only a preset that keeps a server alive can hold the gateway connection open.
  • Nitro can’t be combined with --sharder. The sharder’s manager process has no client for Nitro to forward requests to, so the CLI exits with an error.

Gateway, cache, and sharder

Use the gateway plugins when your bot also needs gateway events in addition to HTTP interactions. They require a long-lived process.
  • --gateway makes src/main.* create a GatewayClient. The bot still answers HTTP interactions.
  • --cache adds src/lib/cache.*, an in-memory cache by default.
  • --redis (or the follow-up prompt) swaps the in-memory cache for ioredis. It adds a compose.yaml that starts a local Redis server, and adds REDIS_URL=redis://localhost:6379 to .env.
  • --sharder turns src/main.* into the shard manager and adds src/shard.*, which runs in every cluster worker. Set the number of workers with SHARDER_CLUSTERS in .env (default: 2).
  • Each flag turns on the flags it depends on: --redis turns on --cache, and --cache and --sharder both turn on --gateway.
  • When the gateway is enabled, the generated package.json sets engines.node to >=24.17.0.
To start the local Redis server for a --redis project:

i18n type generation

When i18n is enabled, the generated package.json includes a generate:i18n script that (re)generates src/@types/i18next.d.ts from the JSON files under src/locales/:
The CLI runs this script automatically once at the end of scaffolding; re-run it manually whenever you add or edit locale keys so the generated types stay in sync.

Requirements

  • Node.js >=20 (>=24.17.0 for projects using the gateway)