### Run Milhouse with Custom Settings
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/README.md
Examples of starting the UI with specific configurations.
```bash
# Start with default settings
milhouse ui
# Specify a project directory
milhouse ui --workdir /path/to/project
# Use a custom port
milhouse ui --port 8080
# Don't auto-open browser
milhouse ui --no-open
```
--------------------------------
### Start Web UI
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/AGENTS.md
Builds the project and starts the local web UI server.
```bash
npm run ui
```
--------------------------------
### Install CLI Globally
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/AGENTS.md
Installs the 'milhouse' CLI globally after publishing.
```bash
npm install -g milhouse
```
--------------------------------
### Install Dependencies
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/AGENTS.md
Installs project dependencies using npm.
```bash
npm install
```
--------------------------------
### Development Workflow
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/README.md
Commands for cloning, installing, and running the project in development or production modes.
```bash
# Clone the repository
git clone https://github.com/ordinalOS/Milhouse-Van-Houten.git
cd Milhouse-Van-Houten
# Install dependencies
npm install
# Run in development mode
npm run dev -- ui
# Build for production
npm run build
# Run built version
npm run ui
```
--------------------------------
### Start Run via API
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Handles the click event for the start button. It clears logs, validates the goal input, prepares the request body, and sends a request to start a new run.
```javascript
startBtn.onclick = async () => {
logsEl.textContent = "";
const trimmedGoal = goalEl.value.trim();
if (!trimmedGoal) {
appendLog("Error: goal is required");
setStatus("Error", "error");
return;
}
const body = {
goal: trimmedGoal,
maxIterations: Number(maxEl.value) || 0,
workdir: workdirEl.value.trim() || undefined,
};
setRunning(true);
setStatus("Starting...", "running");
appendLog("[ui] Starting run...");
c
```
--------------------------------
### Run CLI UI
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/AGENTS.md
Launches the 'milhouse' UI from the globally installed CLI.
```bash
milhouse ui
```
--------------------------------
### Programmatic Server Start
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Start the Milhouse server programmatically for integration into other applications. Allows for default or custom configurations.
```APIDOC
## Programmatic Server Start
### Description
Start the Milhouse server programmatically for integration into other applications.
### Method
`startServer` (Function)
### Parameters
#### StartServerOptions
- **host** (string) - Optional - Server bind address (default: "127.0.0.1")
- **port** (number) - Optional - Server port (default: 4173, falls back to random if busy)
- **defaultWorkdir** (string) - Optional - Default working directory for runs
- **stateBaseDir** (string) - Optional - Base directory for state/logs storage
### Request Example
```typescript
import { startServer } from "./ui/server.js";
// Start with default options
const server = await startServer();
console.log(`Server running at ${server.url}`);
// Start with custom configuration
const customServer = await startServer({
host: "0.0.0.0",
port: 8080,
defaultWorkdir: "/home/user/projects",
stateBaseDir: "/var/lib/milhouse",
});
console.log(`Server running at ${customServer.url}`);
console.log(`Host: ${customServer.host}, Port: ${customServer.port}`);
// Gracefully shutdown
await customServer.close();
```
### Response
- **server** (object) - An object representing the running server with properties like `url`, `host`, `port`, and a `close` method.
#### Response Example
```
Server running at http://127.0.0.1:4173
Server running at http://0.0.0.0:8080
Host: 0.0.0.0, Port: 8080
```
```
--------------------------------
### Start Milhouse Server Programmatically
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Use startServer to initialize the server with custom configurations or defaults. Ensure the server is closed gracefully using the close method.
```typescript
import { startServer, type StartServerOptions } from "./ui/server.js";
// Start with default options
const server = await startServer();
console.log(`Server running at ${server.url}`);
// Start with custom configuration
const customServer = await startServer({
host: "0.0.0.0",
port: 8080,
defaultWorkdir: "/home/user/projects",
stateBaseDir: "/var/lib/milhouse",
});
console.log(`Server running at ${customServer.url}`);
console.log(`Host: ${customServer.host}, Port: ${customServer.port}`);
// Gracefully shutdown
await customServer.close();
// StartServerOptions interface
interface StartServerOptions {
host?: string; // Server bind address (default: "127.0.0.1")
port?: number; // Server port (default: 4173, falls back to random if busy)
defaultWorkdir?: string; // Default working directory for runs
stateBaseDir?: string; // Base directory for state/logs storage
}
```
--------------------------------
### Launch Milhouse Web UI Server
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Starts the Milhouse web server. Options include specifying the working directory, host, port, state directory, and whether to auto-open the browser.
```bash
milhouse ui
```
```bash
milhouse ui --workdir /path/to/project
```
```bash
milhouse ui --host 0.0.0.0 --port 8080
```
```bash
milhouse ui --state-dir /tmp/milhouse-state
```
```bash
milhouse ui --no-open
```
```bash
milhouse ui --workdir ~/my-project --port 3000 --state-dir ~/.milhouse --no-open
```
--------------------------------
### GET /api/artifacts - Get Session Artifacts
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Retrieves the current session's output files including plan logs, build logs, and the implementation plan markdown.
```APIDOC
## GET /api/artifacts - Get Session Artifacts
### Description
Retrieves the current session's output files including plan logs, build logs, and the implementation plan markdown.
### Method
GET
### Endpoint
/api/artifacts
### Request Example
```bash
curl http://127.0.0.1:4173/api/artifacts
```
### Response
#### Success Response (200)
- **planLog** (string) - JSON string containing plan log details.
- **buildLog** (string) - JSON string containing build log details.
- **planFile** (string) - Markdown content of the implementation plan.
- **threadId** (string) - The ID of the current thread.
#### Response Example
```json
{
"planLog": "{\"threadId\":\"thread_abc123\",\"finalResponse\":\"Created implementation plan\",\"items\":[...],\"usage\":{...}}",
"buildLog": "{\"threadId\":\"thread_abc123\",\"finalResponse\":\"Completed task: Set up Express server\",\"items\":[...],\"usage\":{...}}",
"planFile": "# Implementation Plan\n\n## Scope\nCreate a REST API with Express that has CRUD operations for users.\n\n## Tasks\n- [x] Initialize package.json and install Express\n- [x] Create server.js with basic Express setup\n- [ ] Add user model and routes\n- [ ] Implement CRUD endpoints\n\nSTATUS: READY",
"threadId": "thread_abc123"
}
```
```
--------------------------------
### Start New Agent Session via API
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Initiates a new Codex agent run using a POST request to the /api/start endpoint. Specify the goal, maximum iterations, and working directory. The `createIfMissing` flag can be used to automatically create the working directory.
```bash
curl -X POST http://127.0.0.1:4173/api/start \
-H "Content-Type: application/json" \
-d '{
"goal": "Create a REST API with Express that has CRUD operations for users",
"maxIterations": 10,
"workdir": "/path/to/project"
}'
```
```json
{
"ok": true,
"session": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"goal": "Create a REST API with Express that has CRUD operations for users",
"maxIterations": 10,
"workdir": "/path/to/project",
"stateDir": "/home/user/.local/share/milhouse/L3BhdGgvdG8vcHJvamVjdA",
"startedAt": "2024-01-15T10:30:00.000Z",
"status": "running"
}
}
```
```bash
curl -X POST http://127.0.0.1:4173/api/start \
-H "Content-Type: application/json" \
-d '{
"goal": "Initialize a new TypeScript project with ESLint and Prettier",
"maxIterations": 5,
"workdir": "/path/to/new-project",
"createIfMissing": true
}'
```
--------------------------------
### GET /api/sessions
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Lists the history of all agent sessions.
```APIDOC
## GET /api/sessions
### Description
Returns the history of all agent sessions including their status, timestamps, and metadata.
### Method
GET
### Endpoint
/api/sessions
### Response
#### Success Response (200)
- **sessions** (array) - List of past and current sessions.
#### Response Example
{
"sessions": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"goal": "Create a REST API with Express",
"status": "succeeded"
}
]
}
```
--------------------------------
### Get Current Run Status via API
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Retrieves the current session state, running status, and associated artifacts by sending a GET request to the /api/status endpoint. The response differs based on whether a session is currently running.
```bash
curl http://127.0.0.1:4173/api/status
```
```json
{
"running": true,
"session": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"goal": "Create a REST API with Express",
"maxIterations": 10,
"workdir": "/path/to/project",
"stateDir": "/home/user/.local/share/milhouse/...",
"startedAt": "2024-01-15T10:30:00.000Z",
"status": "running",
"threadId": "thread_abc123"
},
"artifacts": {
"planLog": "{\"threadId\":\"thread_abc123\",\"finalResponse\":\"...\"}",
"buildLog": "{\"threadId\":\"thread_abc123\",\"finalResponse\":\"...\"}",
"planFile": "# Implementation Plan\n\n## Scope\nCreate REST API...\n\n- [x] Set up Express server\n- [ ] Add user routes\n\nSTATUS: READY",
"threadId": "thread_abc123"
}
}
```
```json
{
"running": false,
"session": null,
"artifacts": {}
}
```
--------------------------------
### GET /api/status
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Retrieves the current session state, running status, and associated artifacts.
```APIDOC
## GET /api/status
### Description
Returns the current session state, running status, and associated artifacts (plan logs, build logs, implementation plan).
### Method
GET
### Endpoint
/api/status
### Response
#### Success Response (200)
- **running** (boolean) - Whether an agent is currently active.
- **session** (object) - Current session details if running.
- **artifacts** (object) - Logs and plan files generated by the agent.
#### Response Example
{
"running": true,
"session": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"goal": "Create a REST API with Express",
"maxIterations": 10,
"workdir": "/path/to/project",
"status": "running",
"threadId": "thread_abc123"
},
"artifacts": {
"planLog": "...",
"buildLog": "...",
"planFile": "# Implementation Plan..."
}
}
```
--------------------------------
### List All Sessions via API
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Retrieves a history of all agent sessions, including their status, timestamps, and metadata, by sending a GET request to the /api/sessions endpoint.
```bash
curl http://127.0.0.1:4173/api/sessions
```
```json
{
"sessions": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"goal": "Create a REST API with Express",
"maxIterations": 10,
"workdir": "/path/to/project",
"stateDir": "/home/user/.local/share/milhouse/...",
"startedAt": "2024-01-15T10:30:00.000Z",
"endedAt": "2024-01-15T10:45:00.000Z",
"status": "succeeded",
"threadId": "thread_abc123"
},
{
"id": "661f9511-f30c-52e5-b827-557766551111",
"goal": "Add authentication middleware",
"maxIterations": 5,
"workdir": "/path/to/project",
"stateDir": "/home/user/.local/share/milhouse/...",
"startedAt": "2024-01-15T11:00:00.000Z",
"status": "running"
}
]
}
```
--------------------------------
### Fetch and Render Sessions List
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Fetches the list of past sessions from the API and renders them in the sessions display element. Sessions are sorted by start time in descending order.
```javascript
async function fetchSessions() {
const res = await fetch("/api/sessions");
const data = await res.json();
const list = (data.sessions || [])
.slice()
.reverse()
.map(
(s) =>
`
${escapeHtml(s.goal || "No goal")} ${s.status} • ${formatDateTime(s.startedAt)}
`,
)
.join("");
sessionsEl.innerHTML = list || 'No sessions yet.
';
}
```
--------------------------------
### Enable/Disable UI Controls
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Enables or disables the start and stop buttons based on the current running state and whether a goal is set.
```javascript
function updateControls() {
const hasGoal = goalEl.value.trim().length > 0;
startBtn.disabled = running || !hasGoal;
stopBtn.disabled = !running;
}
```
--------------------------------
### GET /api/events - Server-Sent Events Stream
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Establishes a persistent connection for real-time log streaming. The server broadcasts all stdout/stderr from the loop runner.
```APIDOC
## GET /api/events - Server-Sent Events Stream
### Description
Establishes a persistent connection for real-time log streaming. The server broadcasts all stdout/stderr from the loop runner.
### Method
GET
### Endpoint
/api/events
### Request Example
```bash
curl -N http://127.0.0.1:4173/api/events
```
### Response Example
```
data: [milhouse] Starting run…
data: [milhouse] workdir: /path/to/project
data: [milhouse] state dir: /home/user/.local/share/milhouse/...
data: thread: thread_abc123
data: ================ LOOP 1 = ================
data: thread: thread_abc123
data: ================ LOOP 2 = ================
data: Plan marked DONE. Exiting.
data: [exit] code=0 signal=null
```
### JavaScript EventSource Usage
```javascript
const eventSource = new EventSource('/api/events');
eventSource.onmessage = (event) => {
console.log('Log:', event.data);
// Check for thread ID
const threadMatch = event.data.match(/thread:\s*([0-9a-zA-Z-]+)/);
if (threadMatch) {
console.log('Thread ID:', threadMatch[1]);
}
// Check for completion
if (event.data.includes('Plan marked DONE')) {
console.log('Run completed successfully');
}
};
eventSource.onerror = () => {
console.log('Connection lost, reconnecting...');
};
```
```
--------------------------------
### POST /api/start
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Initiates a new Codex agent run with a specified goal, creating an implementation plan and executing build tasks.
```APIDOC
## POST /api/start
### Description
Initiates a new Codex agent run with the specified goal. The agent first creates an implementation plan, then iteratively executes tasks until completion.
### Method
POST
### Endpoint
/api/start
### Request Body
- **goal** (string) - Required - The objective for the AI agent.
- **maxIterations** (number) - Required - Maximum number of iterations for the agent loop.
- **workdir** (string) - Required - The directory path where the agent will work.
- **createIfMissing** (boolean) - Optional - Whether to auto-create the workdir if it does not exist.
### Request Example
{
"goal": "Create a REST API with Express that has CRUD operations for users",
"maxIterations": 10,
"workdir": "/path/to/project"
}
### Response
#### Success Response (200)
- **ok** (boolean) - Status of the request.
- **session** (object) - Details of the created session.
#### Response Example
{
"ok": true,
"session": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"goal": "Create a REST API with Express that has CRUD operations for users",
"maxIterations": 10,
"workdir": "/path/to/project",
"stateDir": "/home/user/.local/share/milhouse/L3BhdGgvdG8vcHJvamVjdA",
"startedAt": "2024-01-15T10:30:00.000Z",
"status": "running"
}
}
```
--------------------------------
### View CLI Options
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/README.md
Display available command-line arguments and options for the UI.
```text
milhouse ui [OPTIONS]
Options:
--host Server host (default: 127.0.0.1)
--port , -p Server port (default: 4173)
--workdir , -w Working directory for Codex (default: current directory)
--state-dir State/logs directory (default: OS user data directory)
--no-open Don't auto-open browser
--help, -h Show help
```
--------------------------------
### Build Phase Prompt Template
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Template for executing tasks from the implementation plan. Requires GOAL and PLAN_PATH variables.
```markdown
Build for goal: {{GOAL}}
Plan file: {{PLAN_PATH}}
You are the builder. Follow the plan at {{PLAN_PATH}}:
- Pick the top unchecked item and complete it fully (no placeholders).
- Make direct edits to the repo under `workdir`.
- Run any obvious quick checks for touched stack (skip if none are applicable).
- Update {{PLAN_PATH}}: mark done items `- [x]`, add new `- [ ]` if needed, keep priorities. End with `STATUS: DONE` if nothing remains, else `STATUS: READY`.
Keep `AGENTS.md` operational only; no diaries.
```
--------------------------------
### Planning Phase Prompt Template
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Template for generating an IMPLEMENTATION_PLAN.md file. Requires GOAL and PLAN_PATH variables.
```markdown
Plan for goal: {{GOAL}}
Plan file: {{PLAN_PATH}}
You are the planner. Ignore any existing plan content and write a fresh `IMPLEMENTATION_PLAN.md` with:
- A 1–2 sentence scope summary for the goal.
- A prioritized checklist with `- [ ]` items (or `- [x]` if something is already done).
- Keep tasks concise and concrete (code files or assets to touch).
- End with a status line: `STATUS: READY` if work remains, `STATUS: DONE` if nothing to do.
Do not implement code. Write the plan to {{PLAN_PATH}}. Output only the new plan content.
```
--------------------------------
### Browse and Create Project Directories
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Interacts with the file system API to select or create project paths.
```javascript
openProjectBtn.onclick = () => { fetch("/api/browse", { method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" }) .then((r) => r.text().then((t) => ({ ok: r.ok, text: t }))) .then(({ ok, text }) => { if (!text.trim()) return; try { const data = JSON.parse(text); if (data.path) workdirEl.value = data.path; else if (data.error) { if (String(data.error).toLowerCase().includes("cancel")) return; appendLog("Browse error: " + data.error); } } catch { if (!ok) appendLog("Browse error: " + text.slice(0, 200)); } }) .catch((e) => appendLog("Browse error: " + e.message)); }; newProjectBtn.onclick = () => { fetch("/api/browse", { method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" }) .then((r) => r.text().then((t) => ({ ok: r.ok, text: t }))) .then(({ ok, text }) => { if (!text.trim()) return; let base = ""; try { const data = JSON.parse(text); if (!data.path && data.error) { if (String(data.error).toLowerCase().includes("cancel")) return; appendLog("Browse error: " + data.error); return; } base = data.path || ""; } catch { if (!ok) { appendLog("Browse error: " + text.slice(0, 200)); return; } } const name = prompt("Enter new project folder name", "milhouse-project"); if (name) { const sep = base.endsWith("\\") || base.endsWith("/") ? "" : pathSeparator(base); workdirEl.value = base + sep + name; } }) .catch((e) => appendLog("Browse error: " + e.message)); }; function pathSeparator(p) { return p.includes("\\") ? "\\" : "/"; }
```
--------------------------------
### Open Folder Picker Dialog
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Triggers a native folder selection dialog on the server host.
```bash
# Open folder picker with default path hint
curl -X POST http://127.0.0.1:4173/api/browse \
-H "Content-Type: application/json" \
-d '{"defaultPath": "/home/user/projects"}'
# Response on selection
{
"path": "/home/user/projects/my-app"
}
# Response on cancel (HTTP 204 No Content)
# (empty body)
```
--------------------------------
### Build Project
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/AGENTS.md
Compiles TypeScript code to the 'dist/' directory and copies UI assets.
```bash
npm run build
```
--------------------------------
### Initialize UI Elements and State
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Selects all necessary DOM elements and initializes global state variables for the UI. This code should run once when the page loads.
```javascript
const logsEl = document.getElementById("logs");
const statusEl = document.getElementById("status");
const statusLed = document.getElementById("status-led");
const threadEl = document.getElementById("thread");
const artifactsEl = document.getElementById("artifacts");
const sessionsEl = document.getElementById("sessions");
const milhouseEl = document.getElementById("milhouse-running");
const goalEl = document.getElementById("goal");
const maxEl = document.getElementById("max");
const workdirEl = document.getElementById("workdir");
const openProjectBtn = document.getElementById("open-project");
const newProjectBtn = document.getElementById("new-project");
const startBtn = document.getElementById("start");
const stopBtn = document.getElementById("stop");
const autoScrollEl = document.getElementById("auto-scroll");
const clearLogsBtn = document.getElementById("clear-logs");
const showAdvEl = document.getElementById("show-advanced");
let es;
let running = false;
let streamConnected = false;
```
--------------------------------
### Manage Project Lifecycle and UI Events
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Handles project start/stop requests, log clearing, and UI state updates via fetch API.
```javascript
onst res = await fetch("/api/start", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); if (!res.ok) { const err = await res.json(); appendLog("Error: " + (err.error || res.statusText)); setRunning(false); setStatus("Error", "error"); return; } setStatus("Running", "running"); appendLog("[ui] Run started. Waiting for first logs/artifacts..."); fetchStatus(); fetchSessions(); }; stopBtn.onclick = async () => { await fetch("/api/stop", { method: "POST" }); setStatus("Stopping", "idle"); setRunning(false); }; clearLogsBtn.onclick = () => { logsEl.textContent = ""; }; goalEl.addEventListener("input", updateControls);
```
--------------------------------
### POST /api/browse - Open Folder Picker Dialog
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Opens a native folder selection dialog on the server machine (cross-platform: Windows, macOS, Linux).
```APIDOC
## POST /api/browse - Open Folder Picker Dialog
### Description
Opens a native folder selection dialog on the server machine (cross-platform: Windows, macOS, Linux).
### Method
POST
### Endpoint
/api/browse
### Parameters
#### Request Body
- **defaultPath** (string) - Optional - The default path to pre-fill in the folder picker.
### Request Example
```bash
# Open folder picker with default path hint
curl -X POST http://127.0.0.1:4173/api/browse \
-H "Content-Type: application/json" \
-d '{"defaultPath": "/home/user/projects"}'
```
### Response
#### Success Response (200)
- **path** (string) - The path selected by the user.
#### Response Example
```json
{
"path": "/home/user/projects/my-app"
}
```
#### Success Response (204)
No Content response indicates the user cancelled the dialog.
```
--------------------------------
### Configure Paths via Environment Variables
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Set environment variables to override default state and working directories. Legacy variables are supported for backward compatibility.
```bash
# Set API key (optional if Codex CLI is already authenticated)
export CODEX_API_KEY="sk-..."
# Override state directory (where sessions.json and run artifacts are stored)
export MILHOUSE_STATE_DIR="/custom/state/path"
# Override default working directory
export MILHOUSE_DEFAULT_WORKDIR="/home/user/default-project"
# Legacy environment variables (still supported)
export MILLHOUSE_STATE_DIR="/custom/state/path"
export MILLHOUSE_DEFAULT_WORKDIR="/home/user/default-project"
```
--------------------------------
### Retrieve Session Artifacts
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Fetches current session output files, including logs and the implementation plan.
```bash
curl http://127.0.0.1:4173/api/artifacts
# Response
{
"planLog": "{\"threadId\":\"thread_abc123\",\"finalResponse\":\"Created implementation plan\",\"items\":[...],\"usage\":{...}}",
"buildLog": "{\"threadId\":\"thread_abc123\",\"finalResponse\":\"Completed task: Set up Express server\",\"items\":[...],\"usage\":{...}}",
"planFile": "# Implementation Plan\n\n## Scope\nCreate a REST API with Express that has CRUD operations for users.\n\n## Tasks\n- [x] Initialize package.json and install Express\n- [x] Create server.js with basic Express setup\n- [ ] Add user model and routes\n- [ ] Implement CRUD endpoints\n\nSTATUS: READY",
"threadId": "thread_abc123"
}
```
--------------------------------
### Initialize Periodic Status Updates
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Sets up event listeners and intervals for continuous status and session polling.
```javascript
showAdvEl.addEventListener("change", () => { fetchStatus(); }); updateControls(); startStream(); fetchStatus(); fetchSessions(); setInterval(() => { fetchStatus(); fetchSessions(); }, 5000);
```
--------------------------------
### Prompt Templates
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Details on prompt templates used for planning and building phases.
```APIDOC
## Prompt Templates
### plan.md - Planning Phase Template
#### Description
The planning prompt template generates an `IMPLEMENTATION_PLAN.md` file with prioritized tasks based on a given goal.
#### Template Content
```markdown
Plan for goal: {{GOAL}}
Plan file: {{PLAN_PATH}}
You are the planner. Ignore any existing plan content and write a fresh `IMPLEMENTATION_PLAN.md` with:
- A 1–2 sentence scope summary for the goal.
- A prioritized checklist with `- [ ]` items (or `- [x]` if something is already done).
- Keep tasks concise and concrete (code files or assets to touch).
- End with a status line: `STATUS: READY` if work remains, `STATUS: DONE` if nothing to do.
Do not implement code. Write the plan to {{PLAN_PATH}}. Output only the new plan content.
```
### build.md - Build Phase Template
#### Description
The build prompt template executes tasks from the implementation plan one at a time, updating the plan as tasks are completed.
#### Template Content
```markdown
Build for goal: {{GOAL}}
Plan file: {{PLAN_PATH}}
You are the builder. Follow the plan at {{PLAN_PATH}}:
- Pick the top unchecked item and complete it fully (no placeholders).
- Make direct edits to the repo under `workdir`.
- Run any obvious quick checks for touched stack (skip if none are applicable).
- Update {{PLAN_PATH}}: mark done items `- [x]`, add new `- [ ]` if needed, keep priorities. End with `STATUS: DONE` if nothing remains, else `STATUS: READY`.
Keep `AGENTS.md` operational only; no diaries.
```
```
--------------------------------
### Path Configuration
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Configure Milhouse behavior through environment variables for state directory and default working directory.
```APIDOC
## Path Configuration
### Description
Configure Milhouse behavior through environment variables. These variables can override default paths for state and working directories.
### Environment Variables
- **CODEX_API_KEY** (string) - Optional - API key for Codex CLI authentication.
- **MILHOUSE_STATE_DIR** (string) - Optional - Override the state directory (where sessions.json and run artifacts are stored).
- **MILHOUSE_DEFAULT_WORKDIR** (string) - Optional - Override the default working directory.
- **MILLHOUSE_STATE_DIR** (string) - Optional - Legacy environment variable for state directory.
- **MILLHOUSE_DEFAULT_WORKDIR** (string) - Optional - Legacy environment variable for default working directory.
### Functions
#### `resolveStateBaseDir`
- **Description**: Resolves the state directory, checking environment variables first, then falling back to an OS-specific data directory.
- **Parameters**: `options` (object, optional) - Allows overriding environment variables directly, e.g., `{ MILHOUSE_STATE_DIR: "/tmp/test-state" }`.
- **Returns**: `string` - The resolved state directory path.
#### `resolveDefaultWorkdir`
- **Description**: Resolves the default working directory, checking environment variables first, then falling back to `process.cwd()`.
- **Returns**: `string` - The resolved default working directory path.
### Request Example
```bash
# Set API key (optional if Codex CLI is already authenticated)
export CODEX_API_KEY="sk-..."
# Override state directory
export MILHOUSE_STATE_DIR="/custom/state/path"
# Override default working directory
export MILHOUSE_DEFAULT_WORKDIR="/home/user/default-project"
```
```typescript
import { resolveStateBaseDir, resolveDefaultWorkdir } from "./src/paths.js";
// Resolve state directory
const stateDir = resolveStateBaseDir();
console.log(`State directory: ${stateDir}`);
// Resolve default workdir
const workdir = resolveDefaultWorkdir();
console.log(`Default workdir: ${workdir}`);
// Custom environment override
const customStateDir = resolveStateBaseDir({
MILHOUSE_STATE_DIR: "/tmp/test-state"
});
console.log(`Custom state dir: ${customStateDir}`);
```
```
--------------------------------
### Develop UI with tsx
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/AGENTS.md
Runs the UI directly from TypeScript source files using tsx for development.
```bash
npm run dev -- ui
```
--------------------------------
### Stream Server-Sent Events
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Establishes a persistent connection to receive real-time stdout/stderr logs from the loop runner.
```bash
curl -N http://127.0.0.1:4173/api/events
# Output (streaming)
data: [milhouse] Starting run…
data: [milhouse] workdir: /path/to/project
data: [milhouse] state dir: /home/user/.local/share/milhouse/...
data: thread: thread_abc123
data: ================ LOOP 1 ================
data: thread: thread_abc123
data: ================ LOOP 2 ================
data: Plan marked DONE. Exiting.
data: [exit] code=0 signal=null
```
```javascript
// JavaScript EventSource usage
const eventSource = new EventSource('/api/events');
eventSource.onmessage = (event) => {
console.log('Log:', event.data);
// Check for thread ID
const threadMatch = event.data.match(/thread:\s*([0-9a-zA-Z-]+)/);
if (threadMatch) {
console.log('Thread ID:', threadMatch[1]);
}
// Check for completion
if (event.data.includes('Plan marked DONE')) {
console.log('Run completed successfully');
}
};
eventSource.onerror = () => {
console.log('Connection lost, reconnecting...');
};
```
--------------------------------
### Resolve Paths Programmatically
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Use path resolution utilities to determine state and working directories based on environment variables or OS defaults.
```typescript
import { resolveStateBaseDir, resolveDefaultWorkdir } from "./src/paths.js";
// Resolve state directory (checks env vars, then uses OS-specific data directory)
const stateDir = resolveStateBaseDir();
// Linux: ~/.local/share/milhouse
// macOS: ~/Library/Application Support/milhouse
// Windows: %APPDATA%/milhouse/Data
// Resolve default workdir (checks env vars, then uses process.cwd())
const workdir = resolveDefaultWorkdir();
// Custom environment override
const customStateDir = resolveStateBaseDir({
MILHOUSE_STATE_DIR: "/tmp/test-state"
});
```
--------------------------------
### Configure Codex API Key
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/README.md
Set the Codex API key environment variable in PowerShell.
```powershell
$env:CODEX_API_KEY="..."
```
--------------------------------
### Fetch Current Status from API
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Fetches the current status (running state, thread ID, artifacts) from the backend API and updates the UI accordingly.
```javascript
async function fetchStatus() {
const res = await fetch("/api/status");
const data = await res.json();
setStatus(data.running ? "Running" : "Idle", data.running ? "running" : "idle");
setThread(data.session?.threadId || data.artifacts?.threadId || "");
renderArtifacts(data.artifacts || {});
setRunning(data.running);
}
```
--------------------------------
### Define Session Status and Records
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Types and interfaces for managing session lifecycles and metadata.
```typescript
type SessionStatus = "running" | "succeeded" | "failed" | "stopped";
// Status transitions:
// - "running": Initial state when session starts
// - "succeeded": Exit code 0, all tasks completed (STATUS: DONE in plan)
// - "failed": Non-zero exit code or error during execution
// - "stopped": User manually stopped via POST /api/stop (SIGTERM)
interface SessionRecord {
id: string; // UUID for the session
goal: string; // User-provided goal text
maxIterations: number; // Max build iterations (0 = unlimited)
workdir: string; // Project working directory
stateDir: string; // Session-specific state directory
startedAt: string; // ISO 8601 timestamp
endedAt?: string; // ISO 8601 timestamp (set on completion)
status: SessionStatus; // Current session status
threadId?: string; // Codex thread ID for resumption
}
```
--------------------------------
### Establish Server-Sent Events Stream
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Connects to the '/api/events' endpoint using EventSource to receive live log updates. Handles connection status, errors, and incoming messages.
```javascript
function startStream() {
if (es) es.close();
streamConnected = false;
appendLog("[ui] Connecting to live logs...");
es = new EventSource("/api/events");
es.onopen = () => {
if (streamConnected) return;
streamConnected = true;
appendLog("[ui] Live logs connected.");
};
es.onerror = () => {
if (streamConnected) {
streamConnected = false;
appendLog("[ui] Live logs disconnected (will retry)...");
}
};
es.onmessage = (ev) => {
appendLog(ev.data);
const threadMatch = ev.data.match(/thread:\s*([0-9a-zA-Z-]+)/);
if (threadMatch) setThread(threadMatch[1]);
const loopMatch = ev.data.match(/LOOP\s+(\d+)/i);
if (loopMatch) setStatus("Running (loop " + loopMatch[1] + ")", "running");
if (/\ \[exit\]/i.test(ev.data)) setRunning(false);
};
}
```
--------------------------------
### runTurn - Execute a Single Codex Agent Turn
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
The core function that interfaces with the OpenAI Codex SDK to run a single agent turn within a thread.
```APIDOC
## runTurn - Execute a Single Codex Agent Turn
### Description
The core function that interfaces with the OpenAI Codex SDK to run a single agent turn within a thread.
### Method
Function Call (TypeScript)
### Endpoint
N/A (SDK Function)
### Parameters
#### Request Body (RunTurnOptions interface)
- **promptText** (string) - Required - The prompt to send to Codex.
- **workdir** (string) - Required - Working directory for file operations.
- **threadId** (string) - Optional - Thread ID to resume (undefined for new thread).
- **additionalDirectories** (string[]) - Optional - Extra directories to allow access.
- **sandboxMode** (SandboxMode) - Optional - Sandbox mode: "workspace-write" | "workspace-read" | etc.
- **approvalPolicy** (ApprovalMode) - Optional - Approval policy: "never" | "always" | etc.
- **skipGitRepoCheck** (boolean) - Optional - Skip git repository validation.
- **networkAccessEnabled** (boolean) - Optional - Allow network access.
- **webSearchEnabled** (boolean) - Optional - Allow web search.
### Request Example
```typescript
import { runTurn, type RunTurnOptions, type RunTurnResult } from "./codexRun.js";
// Run a planning turn
const planResult: RunTurnResult = await runTurn({
promptText: "Create an implementation plan for: Build a CLI tool for file renaming",
workdir: "/path/to/project",
threadId: undefined, // Start new thread
additionalDirectories: ["/tmp/milhouse-state"],
sandboxMode: "workspace-write",
approvalPolicy: "never",
skipGitRepoCheck: true,
});
console.log("Thread ID:", planResult.threadId);
console.log("Response:", planResult.finalResponse);
console.log("Items:", planResult.items);
console.log("Usage:", planResult.usage);
// Continue in same thread for build turn
const buildResult = await runTurn({
promptText: "Execute the next task from the implementation plan",
workdir: "/path/to/project",
threadId: planResult.threadId!, // Resume existing thread
additionalDirectories: ["/tmp/milhouse-state"],
sandboxMode: "workspace-write",
approvalPolicy: "never",
skipGitRepoCheck: true,
networkAccessEnabled: false,
webSearchEnabled: false,
});
```
### Response (RunTurnResult interface)
- **threadId** (string | null) - The thread ID for resuming.
- **finalResponse** (string) - The agent's text response.
- **items** (unknown[]) - Structured response items.
- **usage** (unknown) - Token usage statistics.
```
--------------------------------
### Override State Directory
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/AGENTS.md
Specifies a custom directory for state and logs using an environment variable or CLI flag.
```bash
MILHOUSE_STATE_DIR or milhouse ui --state-dir
```
--------------------------------
### Render Artifacts Display
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Renders the artifacts section if advanced view is enabled. Displays thread ID and specific artifact logs/files like 'planLog', 'buildLog', and 'IMPLEMENTATION_PLAN.md'.
```javascript
function renderArtifacts(a) {
if (!showAdvEl.checked) {
artifactsEl.style.display = "none";
return;
}
artifactsEl.style.display = "block";
const parts = [];
if (a.threadId) parts.push(`Thread: ${escapeHtml(a.threadId)}
`);
const artifactDefs = [
{ key: "planLog", title: "Plan log" },
{ key: "buildLog", title: "Build log" },
{ key: "planFile", title: "IMPLEMENTATION_PLAN.md" },
];
artifactDefs.forEach(({ key, title }) => {
const content = a[key];
if (!content) return;
parts.push(
`
${title}: ${escapeHtml(content)}
`,
);
});
if (parts.length === 0) {
artifactsEl.innerHTML = running ? "Waiting for artifacts..." : "No artifacts yet.";
return;
}
artifactsEl.innerHTML = parts.join("");
}
```
--------------------------------
### Date/Time Formatting Utility
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Formats a timestamp into a human-readable locale string. Returns an empty string if the input is invalid or missing.
```javascript
function formatDateTime(value) {
if (!value) return "";
const d = new Date(value);
if (Number.isNaN(d.getTime())) return "";
return d.toLocaleString();
}
```
--------------------------------
### Execute Codex Agent Turn
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Interfaces with the OpenAI Codex SDK to perform agent turns, supporting thread resumption and configuration options.
```typescript
import { runTurn, type RunTurnOptions, type RunTurnResult } from "./codexRun.js";
// Run a planning turn
const planResult: RunTurnResult = await runTurn({
promptText: "Create an implementation plan for: Build a CLI tool for file renaming",
workdir: "/path/to/project",
threadId: undefined, // Start new thread
additionalDirectories: ["/tmp/milhouse-state"],
sandboxMode: "workspace-write",
approvalPolicy: "never",
skipGitRepoCheck: true,
});
console.log("Thread ID:", planResult.threadId);
console.log("Response:", planResult.finalResponse);
console.log("Items:", planResult.items);
console.log("Usage:", planResult.usage);
// Continue in same thread for build turn
const buildResult = await runTurn({
promptText: "Execute the next task from the implementation plan",
workdir: "/path/to/project",
threadId: planResult.threadId!, // Resume existing thread
additionalDirectories: ["/tmp/milhouse-state"],
sandboxMode: "workspace-write",
approvalPolicy: "never",
skipGitRepoCheck: true,
networkAccessEnabled: false,
webSearchEnabled: false,
});
// RunTurnOptions interface
interface RunTurnOptions {
promptText: string; // The prompt to send to Codex
workdir: string; // Working directory for file operations
threadId?: string; // Thread ID to resume (undefined for new thread)
additionalDirectories?: string[]; // Extra directories to allow access
sandboxMode?: SandboxMode; // "workspace-write" | "workspace-read" | etc.
approvalPolicy?: ApprovalMode; // "never" | "always" | etc.
skipGitRepoCheck?: boolean; // Skip git repository validation
networkAccessEnabled?: boolean; // Allow network access
webSearchEnabled?: boolean; // Allow web search
}
// RunTurnResult interface
interface RunTurnResult {
threadId: string | null; // The thread ID for resuming
finalResponse: string; // The agent's text response
items: unknown[]; // Structured response items
usage: unknown; // Token usage statistics
}
```
--------------------------------
### POST /api/stop
Source: https://context7.com/ordinalos/milhouse-van-houten/llms.txt
Terminates the currently running agent session.
```APIDOC
## POST /api/stop
### Description
Terminates the currently running agent session by killing the loop runner process.
### Method
POST
### Endpoint
/api/stop
### Response
#### Success Response (200)
- **ok** (boolean) - Status of the request.
#### Response Example
{
"ok": true
}
```
--------------------------------
### Update Running State and Controls
Source: https://github.com/ordinalos/milhouse-van-houten/blob/main/ui/public/index.html
Updates the global 'running' state and toggles the visibility of the Milhouse animation. It also calls 'updateControls' to enable/disable buttons.
```javascript
function setRunning(value) {
running = Boolean(value);
updateControls();
if (running) {
milhouseEl.classList.add("visible");
} else {
milhouseEl.classList.remove("visible");
}
}
```