> ## Documentation Index
> Fetch the complete documentation index at: https://docs.waniwani.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Commands

> The six waniwani commands, the four stages every one of them runs (scan, check, codegen, run), and what the build check catches before a request does.

```bash theme={null}
waniwani init [dir]          # scaffold an app folder, install, ready to dev
waniwani check               # validate the folder
waniwani dev                 # generate + dev server + regenerate on change
waniwani build               # generate + production build
waniwani start               # run the production build
waniwani eject [--out dir]   # hand the plumbing over and step out
```

Running `waniwani` with no command is `dev`. The scaffolded `package.json` maps `check`, `dev`, `build` and `start` to npm scripts, so `npm run dev` and `waniwani dev` are the same thing.

`init` writes files and stops there; its prompts and flags are on the [Quickstart](/kit/quickstart#what-init-asks). Every other command runs the same four stages before doing its own work.

## The four stages

```mermaid theme={null}
flowchart LR
    subgraph app["oney/ (what you own)"]
        cfg["waniwani.config.ts"]
        tools["tools/*.ts"]
        widgets["widgets/&lt;name&gt;/<br/>widget.ts + ui.tsx"]
        flows["flows/*.ts"]
        api["api/**/*.ts"]
        wk["well-known/**/*.ts"]
    end

    subgraph tpl["WaniWani-AI/mcp-distribution-template (public, separate repo)"]
        raw["vite.config.ts · package.json · tsconfig.json<br/>src/index.css (Tailwind)<br/>alpic.json · Dockerfile"]
    end

    subgraph cli["@waniwani/kit (what we own)"]
        scan["scan<br/><i>convention → manifest</i>"]
        check["check<br/><i>fail at build time</i>"]
        gen["codegen<br/><i>emit a real project</i>"]
        runtime["src/server.ts<br/><i>registerApp()</i>"]
    end

    subgraph out[".waniwani/ (build output, disposable)"]
        server["src/server.ts · src/waniwani.ts"]
        views["src/views/*.tsx"]
        appsrc["src/app/ (your source, copied)"]
        deployfiles["Dockerfile · alpic.json"]
    end

    app --> scan --> check --> gen --> out
    runtime -.imported by.-> server
    raw -.fetched at a pinned SHA, copied byte for byte.-> deployfiles
    out --> deploy["dev · build · start"]
    app -.waniwani eject.-> ejected["a plain repo<br/><i>no CLI, no @waniwani/kit</i>"]
```

1. **scan** walks the folder and turns convention into a manifest.
2. **check** validates structure from the filesystem, then imports every server-safe module for real.
3. **codegen** resolves the distribution template at a pinned commit, copies its plumbing byte for byte, generates registration and view entries from the manifest, and copies your source under `src/app/`.
4. **run** hands the result to the framework's `dev`, `build` or `start`, with the output rewritten in Waniwani's voice.

`.waniwani/` is disposable and safe to delete. Keep it out of git, the way `.next/` is; `init` writes that line into `.gitignore` for you.

## dev

`dev` watches the folder, mirrors changes into `.waniwani/`, and leaves nodemon and Vite HMR to do the rest. An edit to a tool reaches the MCP endpoint in about a second. The MCP endpoint is `/mcp` on the dev port, and the dev server's root serves the framework's own page for calling tools without a chat client.

To reach the dev server from ChatGPT or Claude, expose it with a [tunnel](/sdk/guides/tunnel), or bind the repo to a hosted agent with [`@waniwani/cli`](/sdk/cli/overview) and run against the hosted playground.

## What the build check catches

Errors that would otherwise surface as a 500 at request time, or as a widget that silently never renders:

```text theme={null}
✗ Build check failed

  widgets/broken
  └ missing widget.ts
    every widget folder needs a widget.ts with `export default defineWidget({ ... })`

  flows/split-payment.ts
  └ showWidget references the widget "select-plans", which does not exist
    known widgets: broken, select-plan
```

Structure comes from the filesystem. The rest comes from importing every server-safe module, so a flow that fails to compile fails the build, as does a missing default export, a tool with no description, or a runtime configuration mistake:

```text theme={null}
  flows/no-store.ts
  └ failed to load
    [waniwani] createFlow "no_store": no flow store configured. …
```

`check` reads the app's `.env` before importing anything, for the same reason `dev` does: a flow whose store comes from `WANIWANI_API_KEY` would otherwise fail its own check over a variable sitting in the file next to it.

## Environment variables the CLI reads

| Variable                     | Effect                                                                                                                                         |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `WANIWANI_DEBUG=1`           | Print the CLI's own diagnostics: which template was resolved, how many files it copied, stack traces.                                          |
| `WANIWANI_OFFLINE=1`         | Skip the npm lookup `init` and `check` make for the newest SDK; see [Flows](/kit/flows#which-sdk-version-an-app-gets).                         |
| `WANIWANI_TEMPLATE=<source>` | Override the distribution template for one command, with a branch ref or a local checkout. `--template <source>` does the same per invocation. |

Variables for the app itself, such as `WANIWANI_API_KEY`, go in the app's `.env`; see [Deploy](/kit/deploy#secrets-and-environment-variables).
