--- title: Server & CLI icon: terminal description: Daemon + CLI for managing workspaces from the shell. --- ## Overview Two companion packages to the core SDK: - **[`@struktoai/mirage-server`](https://github.com/strukto-ai/mirage/tree/main/typescript/packages/server)**, a Fastify daemon that owns workspaces in-process and exposes them over HTTP (`/v1/workspaces`, `/v1/jobs`, ...). - **[`@struktoai/mirage-cli`](https://github.com/strukto-ai/mirage/tree/main/typescript/packages/cli)**, a `commander` CLI that speaks to the daemon. Mirrors Python's `mirage` CLI 1:1. The CLI is stateless. Long-running state lives in the daemon; the CLI auto-spawns one on the first `mirage workspace create` if none is running. ## Install ```bash npm install -g @struktoai/mirage-cli ``` This pulls in `@struktoai/mirage-server` transitively (the CLI spawns the daemon from the server package's installed `bin/daemon.js`). ## Create a workspace Write a YAML config: ```yaml # config.yaml mounts: /: resource: ram mode: write ``` Then: ```bash mirage workspace create config.yaml ``` The CLI: 1. Validates the YAML + interpolates `${VAR}` env references (fails fast if any are missing). 2. Auto-spawns a daemon on `127.0.0.1:8765` if none is reachable. 3. Sends `POST /v1/workspaces` and prints the returned detail as JSON. ## Run commands in a workspace ```bash # synchronous, blocks until the command finishes mirage execute -w -c "ls /" # background, returns a job id immediately; poll/wait later mirage execute --bg -w -c "wc -l /large.csv" mirage job wait ``` ## Workspace lifecycle | Command | Purpose | |---|---| | `mirage workspace create ` | Create; auto-spawns daemon if needed. | | `mirage workspace list` | List active workspaces. | | `mirage workspace get [--verbose]` | Show one workspace's detail. | | `mirage workspace delete ` | Stop and remove. | | `mirage workspace clone [--id NEW] [--at REF]` | New workspace from the source; `--at REF` clones a past version, else the live state. | | `mirage workspace snapshot ` | Snapshot to tar. | ## Versioning Each workspace has a git-backed history kept by the daemon (under `~/.mirage/repos/`; set `MIRAGE_VERSION_ROOT` to relocate). Same verbs and semantics as the [Python CLI](/home/cli#versioning). ```bash mirage workspace commit -m "first" # commit live state mirage workspace log [-b branch] # versions, newest first mirage workspace diff [a] [b] # changed paths; no refs = live vs HEAD mirage workspace branch [--from b] # fork a branch mirage workspace checkout # restore in place (version id or branch) mirage workspace clone --at --id new # new workspace from a past version ``` | Command | Purpose | |---|---| | `mirage workspace commit [-m MSG] [-b BRANCH]` | Commit the live state as a version. | | `mirage workspace log [-b BRANCH]` | List versions on a branch, newest first. | | `mirage workspace diff [a] [b] [-b BRANCH]` | Changed paths (added/modified/deleted). | | `mirage workspace branch [--from BRANCH]` | Fork a branch at a branch's current version. | | `mirage workspace checkout ` | Restore the live state in place to a version or branch. | ## Sessions ```bash mirage session create --id agent_a mirage session list mirage session delete ``` ## Daemon lifecycle ```bash mirage daemon status # health + PID + uptime mirage daemon stop # graceful shutdown (POST /v1/shutdown + SIGTERM fallback) mirage daemon restart # stop; next CLI command auto-spawns fresh mirage daemon kill # SIGKILL; last resort ``` ## Configuration Precedence (highest first): 1. **`MIRAGE_DAEMON_URL`** env var, e.g. `http://127.0.0.1:9000`. 2. **`MIRAGE_TOKEN`** env var, bearer token passed as `Authorization: Bearer `. 3. **`~/.mirage/config.toml`** `[daemon]` table, managed with `mirage config list|get|set|unset` (per key: env var > `config.toml` > default; `mirage config list --resolved` shows the effective values and origins): ```toml [daemon] url = "http://127.0.0.1:8765" auth_token = "" idle_grace_seconds = 30 port = 8765 version_root = "/data/repos" ``` The daemon validates the table at startup and refuses to start on unknown keys or malformed TOML. The full key list and semantics match the Python CLI docs. ## Python parity The daemon speaks the same `/v1/...` protocol as Python's `mirage` CLI. A Python CLI client can talk to a Node daemon and vice versa. The CLI subcommand tree matches Python's `mirage/cli/*.py` file-for-file. ## Where things live | File | Purpose | |---|---| | [`packages/server/src/app.ts`](https://github.com/strukto-ai/mirage/blob/main/typescript/packages/server/src/app.ts) | Fastify app factory. | | [`packages/server/src/routers/`](https://github.com/strukto-ai/mirage/tree/main/typescript/packages/server/src/routers) | health / workspaces / sessions / execute / jobs. | | [`packages/server/src/bin/daemon.ts`](https://github.com/strukto-ai/mirage/blob/main/typescript/packages/server/src/bin/daemon.ts) | `mirage-daemon` bin. | | [`packages/cli/src/main.ts`](https://github.com/strukto-ai/mirage/blob/main/typescript/packages/cli/src/main.ts) | CLI program wiring. | | [`packages/cli/src/{workspace,session,execute,provision,job,daemon}.ts`](https://github.com/strukto-ai/mirage/tree/main/typescript/packages/cli/src) | Per-subcommand modules. | | [`packages/cli/src/client.ts`](https://github.com/strukto-ai/mirage/blob/main/typescript/packages/cli/src/client.ts) | HTTP client + auto-spawn. |