Skip to content

Latest commit

 

History

1,069 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Agent Console

Note: Currently only tested on macOS & Claude Code.

Security Note: This tool is designed for local personal use only. It provides terminal access to your system and should not be deployed as a shared server or exposed to untrusted networks. The server binds to localhost by default.

A web application for managing multiple AI coding agent instances running in different git worktrees. Control all your agents through a unified browser interface instead of scattered terminal windows.

Currently supports Claude Code as the default agent, with plans to support additional agents (Gemini CLI, Codex, etc.) in the future.

Features

  • Unified Dashboard: View and manage all repositories, worktrees, and agent sessions in one place
  • Browser-based Terminal: Full terminal access via xterm.js - no need for separate terminal windows
  • Session Persistence: Sessions continue running even when you close the browser tab (tmux-like behavior)
  • Multiple Workers per Session: Run agent and terminal workers side-by-side within a single session
  • Inter-worker Messaging: Send messages between workers in the same session via an embedded message panel
  • Git Worktree Integration: Create and delete git worktrees directly from the UI
  • Real-time Updates: WebSocket-based notifications for session and worker lifecycle changes
  • Orchestration via MCP: Agents can delegate tasks, coordinate workflows, and manage other agents programmatically via MCP tools

Key Concepts

  • Session: A working context tied to a git worktree or arbitrary directory. Each session can have multiple workers.
  • Worker: A PTY process running within a session. Two types:
    • Agent Worker: Runs an AI agent (e.g., Claude Code)
    • Terminal Worker: A plain terminal shell

Architecture

Backend (Bun + Hono)                Frontend (React + Vite)
┌──────────────────────────┐        ┌──────────────────────────┐
│ SessionManager           │        │ Dashboard                │
│ ├── Session1             │        │ ├── SessionList          │
│ │   ├── AgentWorker     │◄──────►│ │   └── WorkerTabs       │
│ │   └── TerminalWorker   │  WS   │ └── Terminal (xterm.js)  │
│ └── Session2             │        │                          │
│     └── AgentWorker      │        │                          │
└──────────────────────────┘        └──────────────────────────┘

Requirements

  • Bun >= 1.3.5

    scripts/check-bun-version.mjs is wired as a preinstall hook and hard-fails on older Bun, so the requirement is enforced rather than advisory. The floor is set by two features: Bun.Terminal (used by the server, 1.3.5+) and minimumReleaseAge (the supply-chain age gate, 1.3.0+); the higher of the two wins. See Supply Chain Security for the age gate details.

Development

Setup

# Install dependencies
bun install

# Start development servers (frontend + backend)
bun dev

The development server runs at:

Environment Configuration

When running multiple development instances (e.g., in different git worktrees), you can use a .env file to avoid port and data conflicts.

# Copy the example file
cp .env.example .env

# Edit .env with your settings

Available variables:

Variable Default Description
PORT 3457 Backend server port
CLIENT_PORT 5173 Frontend dev server port
AGENT_CONSOLE_HOME ~/.agent-console-dev Data directory (DB, outputs)

Bun automatically loads .env files - no additional packages required.

Build

bun run build

This creates a production bundle in the dist/ directory:

dist/
├── package.json    # Standalone package manifest
├── index.js        # Bundled server
└── public/         # Built frontend assets

Production

# From the project root (after build)
bun start

Or run directly:

NODE_ENV=production bun dist/index.js

The server runs at http://localhost:3457

macOS Launch Agent

A deployment script is provided to install Agent Console as a macOS Launch Agent (auto-start on login):

# Deploy with defaults (port 6340)
./scripts/update-and-deploy-for-mac.sh

# Deploy with custom port
PORT=8080 APP_URL=http://localhost:8080 ./scripts/update-and-deploy-for-mac.sh

The script builds the project, copies files to ~/.agent-console/server/, installs a launchd plist, and starts the service.

Environment Configuration via ~/.agent-console/.env

The Launch Agent loads ~/.agent-console/.env on every startup. This is the recommended way to configure the server in production — especially for secrets that should not be embedded in the plist file.

# Example: ~/.agent-console/.env
GITHUB_WEBHOOK_SECRET=your-secret-here
LOG_LEVEL=info

After editing .env, restart the service to apply changes (no redeployment required):

launchctl kickstart -k "gui/$(id -u)/com.agent-console"

Available server environment variables are defined in packages/server/src/lib/server-config.ts.

Note: Variables set in .env override values from the launchd plist. PORT, APP_URL, NODE_ENV, and PATH are set in the plist at deploy time; all other variables should be configured via .env.

Supply Chain Security

This repo uses Bun's minimumReleaseAge install setting to refuse npm package versions younger than 7 days. Compromised packages are usually detected or unpublished within a few days of release, so a short cool-off window catches the common case while letting routine updates through.

Configuration lives in bunfig.toml at the repo root. A preinstall hook (scripts/check-bun-version.mjs) enforces the repo's minimum Bun version, which is at or above the 1.3.0 floor required by minimumReleaseAge, so the age gate is never silently ignored.

Emergency override

When you genuinely need a just-published version (e.g., a CVE patch), bypass the gate for that single command rather than editing bunfig.toml:

# CLI flag, scoped to one invocation:
bun add <pkg> --minimum-release-age 0

# Or via environment variable:
BUN_CONFIG_MINIMUM_RELEASE_AGE=0 bun install

Record the reason (CVE number, advisory link, etc.) in the commit message or PR description so the override is auditable. Do not lower minimumReleaseAge in bunfig.toml — keep the gate intact and override per-command.

Standalone Distribution

The dist/ directory can be distributed independently. Users only need to:

cd dist
bun install   # Installs only bun-pty (~few seconds)
bun start     # Starts the server

Template Configuration

When creating a new worktree, Agent Console can automatically copy template files into it. This is useful for setting up consistent configurations (e.g., .claude/settings.local.json for MCP servers) across all worktrees.

Template Locations

Templates are searched in the following order (first found wins):

  1. Repository-local: .agent-console/ directory in the repository root
  2. Global: $AGENT_CONSOLE_HOME/repositories/<owner>/<repo>/templates/

The default $AGENT_CONSOLE_HOME is ~/.agent-console.

Directory Structure

Place files in the templates directory with the same structure you want in the worktree:

~/.agent-console/repositories/<owner>/<repo>/templates/
├── .claude/
│   └── settings.local.json    # → copied to <worktree>/.claude/settings.local.json
├── .env.local                  # → copied to <worktree>/.env.local
└── any/
    └── nested/
        └── file.txt           # → copied to <worktree>/any/nested/file.txt

Placeholders

Template files support variable substitution using {{VARIABLE}} syntax:

Placeholder Description Example
{{WORKTREE_NUM}} Worktree index number (0, 1, 2, ...) 1
{{BRANCH}} Branch name feature/add-login
{{REPO}} Repository name (without owner) agent-console
{{WORKTREE_PATH}} Full path to the worktree /Users/me/.agent-console/.../wt-001-abc

Arithmetic Expressions

{{WORKTREE_NUM}} supports arithmetic operations:

Expression Description Example (WORKTREE_NUM=2)
{{WORKTREE_NUM + 3000}} Addition 3002
{{WORKTREE_NUM - 1}} Subtraction 1
{{WORKTREE_NUM * 10}} Multiplication 20
{{WORKTREE_NUM / 2}} Division (floor) 1

Example: Environment Variables

To configure different ports for each worktree's development server (.env.local):

# Worktree: {{BRANCH}}
DEV_PORT={{WORKTREE_NUM + 3000}}
API_PORT={{WORKTREE_NUM + 4000}}

With this template, worktree 0 uses DEV_PORT=3000, worktree 1 uses DEV_PORT=3001, and so on.

Orchestration via MCP

Agent Console exposes MCP (Model Context Protocol) tools that turn any AI agent into an orchestrator. A single agent can delegate tasks to new worktrees, monitor their progress, coordinate inter-agent communication, run review workflows, and manage timers — all programmatically through a unified tool interface.

Setup

Register the Agent Console MCP server in Claude Code (one-time):

# For production (default port 6340) for user scope
claude mcp add --scope user --transport http agent-console http://localhost:6340/mcp

# For production (default port 6340) for local scope
claude mcp add --transport http agent-console http://localhost:6340/mcp

# For development (if using a different port, match your .env PORT) for local scope
claude mcp add --transport http agent-console-dev http://localhost:3457/mcp

This adds the MCP server to ~/.claude.json. All Claude Code instances (including those spawned by Agent Console) will automatically discover the tools.

Tip: If you change the server port, update the URL accordingly. Multiple Agent Console instances can coexist with different names (e.g., agent-console, agent-console-2).

Available MCP Tools

Session Management

Tool Description
list_sessions List all active sessions with worker activity states
get_session_status Get a specific session's status, workers, and parent info
close_session Close a session and clean up its workers

Worktree Delegation

Tool Description
delegate_to_worktree Create a worktree + session + agent and send a prompt — the primary orchestration tool
remove_worktree Remove a git worktree and its associated session

Communication

Tool Description
send_session_message Send a message to a worker in another session (file-based with PTY notification)
write_memo Write a Markdown memo for a session, visible in the UI

Timer

Tool Description
create_timer Create a periodic timer that sends notifications to a worker at specified intervals
delete_timer Delete a periodic timer
list_timers List active timers, optionally filtered by session

Interactive Process

Tool Description
run_process Start an interactive script that communicates via STDOUT/STDIN
write_process_response Send a response to a waiting interactive process
kill_process Terminate a running interactive process
list_processes List all interactive processes (useful after agent restart)

Review

Tool Description
write_review_annotations Write review annotations for a git-diff worker, pushed to the client in real-time
clear_review_annotations Clear all review annotations for a git-diff worker

Agent & Repository Registry

Tool Description
list_agents Discover available agents (built-in + custom) with capabilities
list_repositories Discover available repositories with IDs and remote URLs

Patterns in Practice

Parallel Delegation

An orchestrator splits work across multiple worktrees and monitors progress:

Orchestrator (wt-000)
    ├── delegate_to_worktree → Agent A (wt-001): "implement feature X"
    ├── delegate_to_worktree → Agent B (wt-002): "write tests for module Y"
    └── delegate_to_worktree → Agent C (wt-003): "fix bug Z"
    
    ... later ...
    ├── get_session_status(wt-001) → "active, working"
    ├── get_session_status(wt-002) → "idle, waiting for input"
    └── get_session_status(wt-003) → "idle, task complete"

With parentSessionId and parentWorkerId, delegated agents automatically report results back via send_session_message.

Timer-Based Monitoring

Set up periodic check-ins to monitor long-running tasks:

create_timer(sessionId, workerId, intervalSeconds: 300, action: "check CI status and report")
    → Timer fires every 5 minutes with [internal:timer] PTY notification
    → Agent wakes up, checks status, takes action
    
delete_timer(timerId)  # Clean up when done

Interactive Process Workflow

Drive scripts that require back-and-forth communication:

run_process(command: "node acceptance-check.js 526", sessionId, workerId)
    → Process starts, sends STDOUT as [internal:process] PTY notifications
    → Agent reads output, decides next action
    
write_process_response(processId, content: "approve")
    → Process receives response, continues execution
    
kill_process(processId)  # Terminate if needed

Review and Memo

Annotate diffs for human review and leave persistent notes:

write_review_annotations(workerId, sessionId, annotations: [...], summary: {...})
    → Annotations appear in the git-diff viewer in real-time

write_memo(sessionId, content: "## Status\n- Feature complete\n- Tests passing\n- Ready for review")
    → Memo visible in the session UI panel

See docs/design/self-worktree-delegation.md for the full design document.

GitHub Webhook Integration (Inbound Events)

Agent Console can receive GitHub webhooks and route them to active sessions. When a webhook arrives (e.g., CI failure, PR merged), Agent Console:

  • Matches the event to sessions working on the same repository
  • Notifies agent workers by writing a structured message to the agent's PTY input
  • Sends UI notifications via WebSocket to connected browsers

Setup

  1. Set the webhook secret environment variable:

    GITHUB_WEBHOOK_SECRET=your-secret-here

    For the macOS Launch Agent, add it to ~/.agent-console/.env.

  2. Expose the webhook endpoint to the internet:

    GitHub sends webhooks from its servers, so your local Agent Console must be reachable via a public URL. Use a tunnel service such as ngrok, Cloudflare Tunnel, or similar:

    # Example with ngrok (forward to the Agent Console server port)
    ngrok http 3457
    # → https://xxxx-xxxx.ngrok-free.app
  3. Configure the webhook in GitHub:

    • Go to Settings > Webhooks > Add webhook in your repository (or organization)
    • Payload URL: https://<your-tunnel-domain>/webhooks/github
    • Content type: application/json
    • Secret: Same value as GITHUB_WEBHOOK_SECRET
    • Events: Select individual events: Workflow runs, Issues, Pull requests

Multi-user mode (Ubuntu / systemd) recipe

Place the secret in a file outside the deploy target so that the rsync --delete in scripts/update-and-deploy-for-multiuser-ubuntu.sh does not wipe it on the next redeploy. The recommended path is /home/<service-user>/.config/agent-console/secrets.env, owned by the service user with mode 0600. Then point the systemd unit at it via EnvironmentFile=-.

# 1. Secret file outside the deploy target
sudo mkdir -p /home/agentconsole/.config/agent-console
echo "GITHUB_WEBHOOK_SECRET=$(openssl rand -hex 32)" | \
  sudo tee /home/agentconsole/.config/agent-console/secrets.env
sudo chown -R agentconsole:agentconsole /home/agentconsole/.config/agent-console
sudo chmod 600 /home/agentconsole/.config/agent-console/secrets.env

# 2. Reference from the systemd unit
sudo systemctl edit --full agent-console.service
# In [Service], add:
#   EnvironmentFile=-/home/agentconsole/.config/agent-console/secrets.env
# The leading `-` makes the unit start even if the file is absent.

# 3. Reload + restart
sudo systemctl daemon-reload
sudo systemctl restart agent-console.service

# 4. Verify (see "Verifying webhook configuration" below for the auth-cookie variant)
# From a logged-in browser DevTools console:
#   fetch('/api/system/health').then(r => r.json()).then(console.log)
# → { webhookSecretConfigured: true, ... }

Why outside the deploy target. scripts/update-and-deploy-for-multiuser-ubuntu.sh syncs the source-repo into the deploy target with rsync -a --delete, excluding only node_modules and .git. A secret file placed at <deploy-target>/.env would work on the first deploy (Bun auto-loads env files at WorkingDirectory) but would be deleted on the next update-and-deploy-for-multiuser-ubuntu.sh invocation, because env files are excluded from the source-repo by .gitignore. Placing the secret under /home/<service-user>/.config/agent-console/ and referencing it via EnvironmentFile=- keeps deploys and secret management on independent lifecycles.

Tunneling for inbound webhooks (Cloudflare Tunnel, ngrok, etc.) works the same as in the single-user instructions above — point the public URL at the server's HOST:PORT (e.g. 127.0.0.1:8080 for the bootstrap default).

Supported Events

GitHub Event Condition Inbound Event Actions
Workflow runs Completed successfully ci:completed Notify agent, refresh diff view
Workflow runs Completed with failure ci:failed Notify agent, show UI alert
Issues Closed issue:closed Show UI alert
Pull requests Merged pr:merged Refresh diff view, show UI alert

How Events Are Routed

  • Events are matched to sessions by comparing the webhook's repository name with each session's git remote URL
  • If the event includes a branch name, only sessions working on that branch are notified
  • Events without a branch (e.g., issue closed) are delivered to all sessions for that repository

Environment Variables

Variable Required Default Description
GITHUB_WEBHOOK_SECRET Yes (empty) Shared secret for HMAC-SHA256 signature verification. If unset, incoming webhooks are accepted but not processed (the endpoint still returns 200 OK). Check server logs or GET /api/system/health to verify configuration.

Verifying webhook configuration via /api/system/health

GET /api/system/health returns { webhookSecretConfigured: boolean, appUrl: string | null } for the running server. This endpoint requires authentication — unauthenticated requests return 401 Unauthorized. Two reliable ways to call it:

  • From a logged-in browser DevTools console:
    fetch('/api/system/health').then(r => r.json()).then(console.log)
  • With curl, providing the auth cookie: Copy the auth_token=... cookie value from your browser's DevTools (Application → Cookies) and pass it via --cookie. The cookie name is auth_token (defined in packages/server/src/lib/auth-constants.ts):
    curl -s --cookie "auth_token=<your-auth-cookie-value>" http://localhost:8080/api/system/health | jq

A simple unauthenticated curl -sf http://localhost:8080/api/system/health returns an empty body (silent failure on 401), which is easy to misread as "the webhook is unconfigured." Use one of the authenticated paths above.

Project Structure

agent-console/
├── packages/
│   ├── client/          # React frontend
│   ├── server/          # Hono backend
│   └── shared/          # Shared TypeScript types
├── docs/                # Documentation
├── scripts/             # Deployment scripts
└── dist/                # Production build output (generated)

Contributing

See AGENTS.md for repository guidelines, commands, and testing expectations.

Tech Stack

AI-Driven Development

This project serves as a testbed for exploring the boundaries of AI-assisted software development. The goal is to minimize human involvement throughout the entire development lifecycle:

  • Code generation: All code is written by Claude Code, not by humans
  • Code review: Reviews are performed by Claude subagents (code-quality-reviewer, test-reviewer, ux-architecture-reviewer)
  • Testing: Test code is also generated and reviewed by AI

The human role is limited to:

  • Providing high-level requirements and direction
  • Final approval of pull requests
  • Resolving issues that AI cannot handle autonomously

This approach allows us to dogfood Agent Console while simultaneously validating how far AI can go in autonomous software development. The codebase you see here is the result of this experiment.

Special Thanks

This project is built on the shoulders of amazing open-source projects:

  • Claude Code - The AI coding agent that wrote most of this codebase with remarkable speed and quality. This project literally couldn't exist without it.
  • Bun - Blazing fast runtime that makes development a joy
  • Hono - Ultrafast web framework with excellent DX
  • TypeScript - Type safety that saves countless debugging hours
  • xterm.js - The terminal emulator that makes browser-based CLI possible

Inspiration

  • Vibe Kanban - A fantastic project for managing AI coding agents. Exploring this project sparked the idea for Agent Console. Highly recommended!

Thank you to all the maintainers and contributors!

License

MIT

About

Web console for managing multiple AI coding agents across git worktrees

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages