Skip to main content
Installing the package also installs the lousho command. It scaffolds projects, checks your setup, runs an agent locally, serves it over MCP, runs evals, builds a deployable artifact and launches the Agent Forge dashboard. Run it with npx lousho <command> inside a project that has the SDK installed. Every command that takes a <spec> reads an agent spec file (.yaml, .yml or .json, see Configuration).

Usage

Every command parses its flags the same way (Node’s parseArgs, strict): --flag value and --flag=value both work, the last of a repeated flag wins (--tag accumulates), -- ends the flags, and -h / --help prints the command’s usage and exits 0. An unknown flag, a flag without its value (it never takes the next flag as its value) or an extra argument fails with LOUSHO_CONFIG_INVALID and the usage line. A value that starts with - needs the = form: --model=-x. npm create lousho-agent my-agent runs lousho init with the same arguments. To scaffold against an unreleased build of the SDK, pass --sdk-path (see Installing from a local build).

lousho dev

For an agent directory, channels/ are mounted under /channels and schedules/ are started (and both are swapped on reload, the old schedules stopped first); --no-schedules starts none. See Agent directories. Serves a chat UI on GET /, GET /health, GET /dev/status and the chat endpoints below (1MB body limit). What <path> is follows from the path: Any other extension, a missing path, or a module with no agent export fails with a coded error (LOUSHO_SPEC_UNSUPPORTED_FORMAT, LOUSHO_CONFIG_INVALID) and its fix. A .ts module is imported by the running Node (22.19 or later strips types, so relative imports need their file extension); use .js for code that needs a transpiler. Chat sessions. The chat UI keeps one session per browser tab (its id is in sessionStorage; “New session” starts another) and shows the streamed turn: text as it arrives, tool calls with their arguments and results, errors, and tokens and cost from run.done. A tool call that needs approval shows Approve / Reject buttons; an ask_question call shows its options as buttons plus a free-text field. The same endpoints work from curl or your own page: Sessions live in an in-process memoryStore() (gone when lousho dev stops), or in the agent’s own store when a module’s createAgent() options set one. The continuation of an approval is not streamed token by token: the endpoint runs it with agent.approvals.resolve() and sends the turn’s tool results and text as events once it finishes. lousho build servers (node-server, docker) serve these same endpoints from the same code, with sessions in a store chosen by LOUSHO_STORE and optional bearer auth: see Deployment: HTTP API. Hot reload. The agent is rebuilt a moment (100 ms) after a file changes, without restarting the server or dropping the port:
  • a spec: the spec file;
  • a directory: everything under it (instructions.md, the config file, tools/, skills/, subagents/), except node_modules and .git;
  • a module: the file and the local files it imports (relative import / require specifiers, found once at startup; no bundler).
Directory and module files are imported with a ?t=<time> cache-busting query, so an edited tool or agent file is re-evaluated. A file imported by that file (a shared helper) stays cached by Node: restart lousho dev after editing one. The console logs what reloaded. The new agent is built (and ready(), so MCP servers connect) before it replaces the old one, and the old one is then close()d. If the rebuild fails, the last good agent keeps answering, the error is logged and shown in a banner on the chat page (and as error in GET /dev/status); the next good edit clears it. Sessions survive a reload: the store outlives the agent swap, so the next message continues the conversation on the new agent. An approval that was pending on the old agent is not known to the new one (404); start a new session. Directories and modules are your code and run with your permissions; only run lousho dev on ones you trust.
  • --port - default 3737.
  • --host - default 127.0.0.1 (localhost only). Pass e.g. --host=0.0.0.0 to opt in to LAN access.

lousho chat

A terminal REPL: each line you type is one turn of a session. <path> is loaded like lousho dev loads it (spec file, agent directory or .ts/.js module, see lousho dev); a missing path or bad extension fails with the same coded error (LOUSHO_CONFIG_INVALID, LOUSHO_SPEC_UNSUPPORTED_FORMAT), and so does an invalid --session id (LOUSHO_SESSION_ID_INVALID).
  • Text is written as the model produces it. Each tool call is one dim line, [tool_name] {args}, followed by -> result (or -> error: ...).
  • A tool call that needs approval asks Approve <tool>(args)? [y/N]: y or yes runs it, anything else rejects it and the model carries on. An ask_question call (askQuestion: true) prints the question with numbered options; answer with the number or with free text.
  • After each turn [usage] shows the tokens and, when every model used has known pricing, the cost (~ marks estimated tokens).
  • Errors from the SDK print with their [LOUSHO_...] code and fix, and the session continues.
The REPL itself is runChatRepl() in src/cli/chatRepl.ts; it takes the input lines, an output stream and an agent factory, so it can be tested with scripted lines and a mockModel agent and no terminal.

lousho build

Writes the artifact to --out (default .lousho/build/<target>) and prints the command to run or deploy it. Building needs tsup (npm install --save-dev tsup). Targets, the HTTP API they serve and the Workers limits are in Deployment.

lousho studio

Starts one local server for the Agent Forge API and UI. Agents and run state are stored under .lousho/ in the current directory. See Agent Forge for the walkthrough.