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
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
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/), exceptnode_modulesand.git; - a module: the file and the local files it imports (relative
import/requirespecifiers, found once at startup; no bundler).
?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- default3737.--host- default127.0.0.1(localhost only). Pass e.g.--host=0.0.0.0to opt in to LAN access.
lousho chat
<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]:yoryesruns it, anything else rejects it and the model carries on. Anask_questioncall (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
--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
.lousho/ in the current directory. See
Agent Forge for the walkthrough.