### 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"); } } ```