Agent Office is an Electron desktop application for developers who work with several coding CLIs at the same time. It combines a persistent agent registry, real pseudo-terminals, task coordination, project workspaces, and a Pixi.js office floor into one local-first experience.
The application is designed to keep project data and coordination state on the local machine while allowing optional integrations with Git, GitHub CLI, and installed coding-agent providers.
- Detect installed coding CLIs, including Codex, OpenCode, Claude, Gemini, Qwen, and Copilot.
- Create reusable profiles with a role, command, and SOUL/system instructions.
- Start each agent in a real
node-ptypseudo-terminal. - View interactive terminal output through xterm.js.
- Steer, interrupt, pause, resume, or stop running agents.
- Recover agent state after process crashes.
- Enforce profile permissions, execution budgets, and secret redaction.
- Use provider adapters for Codex, OpenCode, Claude, Gemini, Qwen, and Copilot terminal behavior.
- Manage projects and optional per-agent Git worktrees.
- Use a durable task board with assignment, retry, dependency, branch, artifact, result, error, and review metadata.
- Decompose missions deterministically and assign work through the Michael orchestrator.
- Schedule local heartbeats and recurring work with pause/resume controls.
- Route durable messages through an atomic mailbox with retry and dead-letter handling.
- Protect worker branches with a single-committer lock.
- Review potentially destructive, scope-changing, or costly requests through a human approval queue.
- Explore a Pixi.js office floor with animated status-aware avatars.
- See each agent's workstation, including a composite desk, monitor, keyboard, CPU, chair, and desk lamp.
- Observe animated message envelopes and live agent activity.
- Use the office navigation to inspect Live Office, the selected agent, and the terminal.
- Store shared knowledge as Markdown with SQLite FTS5 search.
- Pin and retain important memory entries.
- Optionally use deterministic local vector search.
- Import GitHub issues and prepare or create pull requests through an approval-gated
ghworkflow. - Optionally route OpenAI-compatible and Claude-compatible CLI traffic through a local 9router gateway.
- Maintain an append-only activity log and a redacted settings-diff workflow with backup and atomic replacement.
Agent Office can use 9router as an optional local model gateway. The integration is opt-in and applies to agent CLI sessions running on the same machine or web worker server. Agent Office does not store or expose the gateway API key to the renderer or browser.
- Install and start 9router, then configure its provider and API key.
- Copy
.env.exampleto.envand set the following values:
AGENT_OFFICE_9ROUTER_ENABLED=1
AGENT_OFFICE_9ROUTER_BASE_URL=http://127.0.0.1:20128/v1
AGENT_OFFICE_9ROUTER_API_KEY=your-9router-api-key
AGENT_OFFICE_9ROUTER_MODEL=provider/model- Restart Agent Office or the web worker after changing
.env. In the Settings & Safety screen, you can also save the gateway configuration and test the connection; Electron stores that configuration in its local settings, while the browser server keeps UI changes in memory until restart.
The bridge maps Codex/OpenAI-compatible commands to OPENAI_* variables and Claude commands to ANTHROPIC_*
variables. Keep AGENT_OFFICE_9ROUTER_ENABLED=0 when direct provider routing is preferred. The endpoint must use
http:// or https:// and must not contain credentials in the URL. The health indicator distinguishes authentication,
rate-limit, timeout, routing, and network failures. Agent profiles must allow the secrets permission for the gateway
API key to be passed to a CLI child process; health checks remain available without that permission.
Troubleshooting:
unreachableortimeout: confirm that 9router is running and thatGET http://127.0.0.1:20128/v1/modelsresponds.unauthorized: verify the key in the 9router dashboard and the selected provider credentials.rate-limited: wait for the retry window or select another configured route.routing: verify that the configured model identifier exists in 9router. Usenpm run smoke:9routerto check the active gateway without printing credentials.
- Electron 41
- React 19 and TypeScript
- Pixi.js 8 for the interactive office floor
- xterm.js for terminal rendering
- SQLite through
better-sqlite3 node-ptyfor local pseudo-terminals- Vite and electron-vite for development and bundling
- electron-builder for AppImage, NSIS, and DMG packages
| Layer | Responsibility |
|---|---|
| Main process | SQLite persistence, PTY lifecycle, filesystem and Git operations, scheduling, coordination, and integrations |
| Preload | Typed and restricted IPC bridge between Electron processes |
| Renderer | React interface, navigation, dashboards, terminal views, and Pixi.js office visualization |
| Local storage | Agent registry, task state, mailbox, events, schedules, and Markdown memory |
- Node.js 20 or newer is required for the browser server; Node.js 22 or newer is recommended for the Electron build.
- npm 10 or newer is recommended.
- Git for project and worktree features.
- Optional: GitHub CLI (
gh) authenticated for GitHub workflows. - Linux native build tools for
node-ptyandbetter-sqlite3:
sudo apt install -y build-essential python3git clone git@github.com:yantodev/agent-office.git
cd agent-office
npm install
npm run devThe development command starts the Vite renderer and launches the Electron application.
The browser client uses the same React interface through an authenticated HTTP/WebSocket gateway. The browser never receives direct filesystem or process access; project workspaces and coding CLIs remain on the web server.
For local development, copy .env.example to .env, set a strong token, and run the combined API + Vite development
command. The web:dev and web:server scripts load .env automatically; the file is ignored by Git.
cp .env.example .env
# edit .env and replace the token
npm run web:devOpen http://localhost:5173 and enter the same token. For a production bundle, use:
npm run web:build
npm run web:serverThe web scripts automatically check the native modules and rebuild them for the active Node runtime when needed. The
first rebuild can take a few minutes on Node 20 because a prebuilt binary may not be available; install the native build
tools above. npm run dev automatically runs the Electron rebuild hook before starting. If you switch back to Electron
after using the browser scripts, this prevents the native module ABI from remaining compiled for Node instead of Electron.
The standalone server listens on 127.0.0.1:8787 by default. Restart the web process after changing .env, because the
token is loaded at startup. Set AGENT_OFFICE_WEB_HOST=0.0.0.0 only when it is protected by HTTPS/WSS through a reverse
proxy. AGENT_OFFICE_WEB_DATA selects the SQLite data directory. A production Docker image is available with
docker build -f Dockerfile.web -t agent-office-web .; run it with a strong token and a persistent /data volume.
| Command | Description |
|---|---|
npm run dev |
Start the Electron development environment |
npm run typecheck |
Run the TypeScript compiler without emitting files |
npm run smoke:unit |
Run isolated security, lifecycle, policy, and atomic persistence tests |
npm run smoke:9router |
Check a running 9router gateway (skips when integration is disabled) |
npm run smoke:web |
Verify authenticated web API endpoints and storage transport |
npm run build |
Build the main, preload, and renderer bundles |
npm run web:server |
Start the standalone authenticated web API |
npm run web:dev |
Start the web API and browser client with Vite and API/WebSocket proxy |
npm run web:rebuild-native |
Rebuild native modules for the active Node runtime |
npm run electron:rebuild |
Rebuild native modules for the installed Electron runtime |
npm run web:build |
Build the browser client into dist/web |
npm run web:preview |
Preview the built browser client with Vite |
npm run smoke:native |
Verify native dependencies and runtime behavior |
npm run smoke:main |
Run main-process integration smoke tests |
npm run smoke:migration |
Verify database migration behavior |
npm run dist |
Build and package for the current platform |
npm run dist:linux |
Build a Linux AppImage |
npm run dist:win |
Build a Windows NSIS installer |
npm run dist:mac |
Build a macOS DMG |
npm run release:version |
Prepare a SemVer release commit and annotated tag |
Before opening a pull request, run:
npm run typecheck
npm run smoke:unit
npm run smoke:native
npm run smoke:main
npm run smoke:migration
npm run buildSome Linux installations require Electron's sandbox helper to have the correct owner and setuid permission. If Electron
exits with a chrome-sandbox configuration error, run the following once inside the project:
sudo chown root:root node_modules/electron/dist/chrome-sandbox
sudo chmod 4755 node_modules/electron/dist/chrome-sandboxRun the application as a regular user after applying the fix. In headless CI environments, ELECTRON_DISABLE_GPU=1 may
be useful when no usable GPU is available.
The configured application identifier is com.agentoffice.desktop. The default Electron icon is loaded from
assets/logo/logo.png, while the landscape logo used by the sidebar is stored in assets/logo/logo-landscape.png.
Build artifacts are generated in dist/ and are intentionally ignored by Git.
Use the release script to update the package version, create the release commit, and create an annotated tag. It accepts stable SemVer and prerelease versions such as 0.0.2-beta or 0.0.2-rc.1:
npm run release:version -- 0.0.2-betaReview the generated commit before pushing. To push the current branch and tag and trigger the release workflow, add --push:
npm run release:version -- 0.0.2-beta --pushThe tag must match the version in package.json exactly: 0.0.2-beta becomes v0.0.2-beta.
Agent Office keeps the SQLite registry and execution telemetry in Electron's user-data directory. Project coordination
files are stored in each workspace's .agent-office/ directory. Telemetry records task duration, output size, exit
code, and redacted task results; secrets are removed before persistence. Memory retention policies can prune unpinned
Markdown memories, while task and execution history remains durable until explicitly removed.
To back up a workspace safely, close Agent Office first, then copy the user-data data/ directory together with the
project's .agent-office/ directory. Restore both directories while the application is stopped. Do not commit either
location when it contains local credentials or operational history.
Contributions are welcome. To propose a change:
Because this repository is public, please create a GitHub Issue when you find a bug, unexpected behavior, or have a feature request. Before submitting, search existing issues and include the expected behavior, actual behavior, reproduction steps, environment details, and relevant logs or screenshots. Remove tokens, credentials, and other sensitive data from all reports.
- Fork the repository and create a focused branch.
- Keep changes scoped and update documentation when behavior changes.
- Run the typecheck, smoke tests, and build commands listed above.
- Open a pull request with a concise description, validation steps, and screenshots for UI changes.
Please do not commit credentials, tokens, local settings, generated bundles, or database files. Follow the existing TypeScript conventions and prefer small, reviewable changes.
| Contributor | Role |
|---|---|
| Yanto (@yantodev) | Creator and maintainer |
Additional contributors are welcome through pull requests.
Never place API keys, GitHub PATs, or other credentials in source files, issue reports, commits, or pull requests. Use local environment configuration and revoke any credential that is accidentally exposed.
This project is licensed under the MIT License. See LICENSE for the full license text.
