feat: add Pi Coding Agent backend runtime, update dashboard UI

This commit is contained in:
Tanmay Karande
2026-03-03 00:24:19 -05:00
parent 453389f55c
commit 4c3a58b680
21 changed files with 4955 additions and 192 deletions

212
README.md
View File

@@ -1,27 +1,35 @@
# Aetheel — Discord-Claude Gateway
# Aetheel — AI Agent Runtime with Mission Control
An event-driven AI agent runtime that connects Discord to Claude Code CLI. Inspired by [OpenClaw](https://github.com/nichochar/open-claw)'s architecture — a gateway in front of an agent runtime with markdown-based personality, memory, scheduled behaviors, and proactive messaging.
An event-driven AI agent runtime that connects Discord to your choice of coding agent CLI — **Claude Code**, **Codex**, **Gemini CLI**, **OpenCode**, or **Pi** — with an embedded **Mission Control dashboard** for real-time monitoring, second brain knowledge management, task tracking, and content curation. Inspired by [OpenClaw](https://github.com/nichochar/open-claw)'s architecture — a gateway in front of an agent runtime with markdown-based personality, memory, scheduled behaviors, and proactive messaging.
## How It Works
```
Discord Users ──► Discord Bot ──► Event Queue ──► Agent Runtime ──► Claude Code CLI
Heartbeats ─────────
Cron Jobs ──────────┌─────────────────────┘
Hooks ──────────────
IPC Watcher ───────────── Markdown Config Files
(CLAUDE.md, memory.md, etc.)
Discord Users ──► Discord Bot ──► Event Queue ──► Agent Runtime ──► Backend Adapter
▲ │
Heartbeats ─────────┤ ┌────────────────┘
Cron Jobs ──────────┤
Hooks ──────────────┘ Claude | Codex | Gemini
IPC Watcher ────────── OpenCode | Pi (CLI)
Markdown Config Files
(CLAUDE.md, memory.md, etc.)
Mission Control Dashboard ◄───────────┘
(http://localhost:3100) JSON Stores
(brain, tasks, content)
```
All inputs — Discord messages, heartbeat timers, cron jobs, lifecycle hooks — enter a unified event queue. The agent runtime reads your markdown config files fresh on each event, assembles a dynamic system prompt, and calls the Claude Code CLI. The agent can write back to `memory.md` to persist facts across sessions, and send proactive messages via the IPC system.
All inputs — Discord messages, heartbeat timers, cron jobs, lifecycle hooks — enter a unified event queue. The agent runtime reads your markdown config files fresh on each event, assembles a dynamic system prompt, and calls your configured backend CLI (Claude Code, Codex, Gemini, OpenCode, or Pi). The agent can write back to `memory.md` to persist facts across sessions, and send proactive messages via the IPC system.
Uses your existing Claude Code subscription — no API key needed.
The **Mission Control dashboard** runs on an embedded HTTP server, providing real-time visibility into agent activity, a knowledge store (Second Brain), productivity task tracking, content curation, and full configuration management — all backed by local JSON files with zero external dependencies.
Uses your existing subscription or API key for whichever backend you choose — no extra configuration needed.
## Prerequisites
- Node.js 18+
- Claude Code CLI installed and signed in (`npm install -g @anthropic-ai/claude-code && claude`)
- At least one supported coding agent CLI installed and signed in (see [Multi-Backend Support](#multi-backend-support))
- A Discord bot token ([create one here](https://discord.com/developers/applications)) with Message Content Intent enabled
## Quick Start
@@ -36,6 +44,8 @@ mkdir -p config
npm run dev
```
The dashboard will be available at **http://localhost:3100** once the gateway starts.
Or run the interactive setup:
```bash
bash scripts/setup.sh
@@ -51,9 +61,14 @@ Create a `.env` file in the project root (auto-loaded via dotenv):
|----------|----------|---------|-------------|
| `DISCORD_BOT_TOKEN` | Yes | — | Discord bot token |
| `OUTPUT_CHANNEL_ID` | No | — | Discord channel for heartbeat/cron/hook output |
| `CLAUDE_CLI_PATH` | No | `claude` | Path to the Claude Code CLI binary |
| `AGENT_BACKEND` | No | `claude` | Backend runtime: `claude`, `codex`, `gemini`, `opencode`, or `pi` |
| `BACKEND_CLI_PATH` | No | *(backend name)* | Path to the backend CLI binary |
| `BACKEND_MODEL` | No | — | Model override for the active backend |
| `BACKEND_MAX_TURNS` | No | `25` | Max agentic turns per query |
| `CLAUDE_CLI_PATH` | No | `claude` | *(Deprecated)* Use `BACKEND_CLI_PATH` instead |
| `CONFIG_DIR` | No | `./config` | Path to markdown config directory |
| `ALLOWED_TOOLS` | No | `Read,Write,Edit,Glob,Grep,WebSearch,WebFetch` | Comma-separated tools the agent can use |
| `DASHBOARD_PORT` | No | `3100` | Port for the Mission Control dashboard |
| `ALLOWED_TOOLS` | No | `Read,Write,Edit,Glob,Grep,WebSearch,WebFetch` | Comma-separated tools (Claude only) |
| `PERMISSION_MODE` | No | `bypassPermissions` | Claude Code permission mode |
| `QUERY_TIMEOUT_MS` | No | `120000` | Max time per query (ms) |
| `MAX_CONCURRENT_QUERIES` | No | `5` | Max simultaneous queries |
@@ -86,20 +101,53 @@ config/skills/
└── SKILL.md → "When reviewing code, focus on..."
```
## Multi-Backend Support
Aetheel supports five coding agent CLI backends. Switch between them via the `AGENT_BACKEND` environment variable — no code changes required.
| Backend | `AGENT_BACKEND` | CLI | Install | Session Resume | Tool Filtering |
|---------|-----------------|-----|---------|----------------|----------------|
| **Claude Code** | `claude` *(default)* | `claude` | `npm i -g @anthropic-ai/claude-code` | `--resume <id>` | ✅ `--allowedTools` |
| **Codex** | `codex` | `codex` | `npm i -g @openai/codex` | `exec resume <id>` | ❌ |
| **Gemini CLI** | `gemini` | `gemini` | `npm i -g @anthropic-ai/gemini-cli` | `--resume <id>` | ❌ |
| **OpenCode** | `opencode` | `opencode` | See [OpenCode docs](https://github.com/opencode-ai/opencode) | `--session <id> --continue` | ❌ |
| **Pi** | `pi` | `pi` | `npm i -g @mariozechner/pi-coding-agent` | `--session <id> --continue` | ❌ |
### Switching Backends
Edit your `.env` file:
```bash
# Use Pi as the backend
AGENT_BACKEND=pi
BACKEND_CLI_PATH=pi
# BACKEND_MODEL=anthropic/sonnet # Optional model override
```
```bash
# Use Codex as the backend
AGENT_BACKEND=codex
BACKEND_CLI_PATH=codex
```
Each backend adapter normalizes the CLI's output into the same internal format (`BackendEventResult`), so all features — sessions, streaming, retries, error handling — work identically regardless of which CLI you use.
> **Note:** `ALLOWED_TOOLS` only works with the Claude backend (it's the only CLI that supports `--allowedTools` flags). Other backends will log a warning if `ALLOWED_TOOLS` is configured.
## Features
### Discord Integration
### 🎮 Discord Integration
- Mention the bot (`@Aetheel hi`) or use `/claude` slash command
- `/claude-reset` to start a fresh conversation
- Responses auto-split at 2000 chars with code block preservation
- Typing indicators while processing
### Session Management
- Per-channel conversation sessions with Claude Code CLI `--resume`
### 💬 Session Management
- Per-channel conversation sessions (each backend uses its own resume mechanism)
- Sessions persist to `config/sessions.json` (survive restarts)
- Auto-cleanup of idle sessions after 30 minutes (configurable)
### Heartbeats (Timer Events)
### 💚 Heartbeats (Timer Events)
Define in `config/heartbeat.md`:
```markdown
## check-email
@@ -107,7 +155,7 @@ Interval: 1800
Instruction: Check my inbox for anything urgent.
```
### Cron Jobs (Scheduled Events)
### 🕐 Cron Jobs (Scheduled Events)
Define in `config/agents.md`:
```markdown
## Cron Jobs
@@ -117,7 +165,7 @@ Cron: 0 8 * * *
Instruction: Good morning! Search for the latest AI news and post a summary.
```
### Lifecycle Hooks
### 🪝 Lifecycle Hooks
Define in `config/agents.md`:
```markdown
## Hooks
@@ -129,25 +177,98 @@ Instruction: Say hello, you just came online.
Instruction: Save important context to memory.md.
```
### Proactive Messaging (IPC)
### 📨 Proactive Messaging (IPC)
The agent can send messages to any Discord channel by writing JSON files to `config/ipc/outbound/`:
```json
{"channelId": "123456789", "text": "Hey, found something interesting!"}
```
The gateway polls every 2 seconds and delivers the message.
### Message History
### 📊 Message History
All inbound/outbound messages stored per channel in `config/messages/{channelId}.json`. Max 100 messages per channel, auto-trimmed.
### Conversation Archiving
### 📝 Conversation Archiving
Every exchange saved as readable markdown in `config/conversations/{channelId}/{YYYY-MM-DD}.md`.
### Retry with Backoff
Claude CLI calls retry 3 times with exponential backoff (5s, 10s, 20s) on transient errors. Session corruption errors fail immediately.
### 🔁 Retry with Backoff
Backend CLI calls retry 3 times with exponential backoff (5s, 10s, 20s) on transient errors. Session corruption errors fail immediately.
### Structured Logging
### 📋 Structured Logging
Pino-based structured JSON logging. Set `LOG_LEVEL=debug` for verbose output. Pretty-printed in dev, JSON in production (`NODE_ENV=production`).
---
## Mission Control Dashboard
An embedded web dashboard for real-time agent monitoring and data management. Accessible at `http://localhost:3100` when the gateway is running.
### Pages
| Page | Description |
|------|-------------|
| **Command Center** | Real-time stats (messages, heartbeats, cron runs, uptime), live activity feed, agent configuration |
| **Activity** | Full event history with real-time SSE updates |
| **Sessions** | Active Discord channel sessions and message history viewer |
| **🧠 Second Brain** | Knowledge store with facts, notes, URLs, and file references — searchable with categories and tags. Also includes memory and persona editors, and a skills viewer |
| **📋 Productivity** | Kanban-style task board (To Do → In Progress → Done) with priorities, projects, and due dates |
| **📰 Content Intel** | Content curation and tracking — save articles, videos, papers, repos with status workflow (queued → read → archived) |
| **⏱️ Scheduler** | View all active cron jobs, heartbeat checks, and lifecycle hooks |
| **🔌 Connections** | Status of all integrations (Discord, Claude, heartbeat, cron, IPC, skills) |
| **⚙️ Settings** | Agent configuration overview and quick todos |
### Local Storage
All dashboard data is persisted as JSON files in the `config/` directory — zero external dependencies:
| Store | File | Description |
|-------|------|-------------|
| Brain facts | `config/brain.json` | Notes, URLs, file references with categories and tags |
| Tasks | `config/tasks.json` | Productivity tasks with status, priority, project, due dates |
| Content items | `config/content-items.json` | Curated articles, videos, papers with read-status tracking |
| Activity log | `config/activity-log.json` | Last 2000 events — survives restarts |
| Bot config | `config/bot-config.json` | Dashboard-editable settings |
Data is flushed on shutdown and debounced during writes for performance.
### Dashboard Development
You can run the dashboard standalone with mock data (no Discord bot or Claude CLI needed):
```bash
npm run dashboard
```
This starts a dev server at http://localhost:3100 with simulated activity events and sample data.
### Dashboard API
All dashboard APIs are available at the same port:
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/stats` | GET | Agent statistics (uptime, messages, heartbeats, cron runs) |
| `/api/activity` | GET | Recent activity log entries |
| `/api/config` | GET | Agent configuration |
| `/api/sessions` | GET | Active sessions |
| `/api/messages` | GET | Message history (per channel) |
| `/api/cron` | GET | Cron job definitions |
| `/api/heartbeats` | GET | Heartbeat definitions |
| `/api/hooks` | GET | Lifecycle hook definitions |
| `/api/connections` | GET | Integration statuses |
| `/api/skills` | GET | Loaded skills |
| `/api/memory` | GET/POST | Read/write memory.md |
| `/api/persona` | GET/POST | Read/write CLAUDE.md |
| `/api/brain` | GET/POST/DELETE | CRUD for brain facts |
| `/api/brain?q=...` | GET | Search brain facts |
| `/api/tasks` | GET/POST/DELETE | CRUD for productivity tasks |
| `/api/tasks/update` | POST | Update task fields (e.g. status) |
| `/api/content` | GET/POST/DELETE | CRUD for content items |
| `/api/content/update` | POST | Update content fields (e.g. status) |
| `/api/bot-config` | GET/POST | Read/write bot configuration |
| `/events` | SSE | Real-time event stream |
---
## Deployment
### systemd (recommended for Linux servers)
@@ -176,7 +297,8 @@ pm2 save
### Dev mode
```bash
npm run dev
npm run dev # Full gateway + dashboard
npm run dashboard # Dashboard only (mock data)
```
## Project Structure
@@ -189,7 +311,16 @@ src/
├── logger.ts # Pino structured logger
├── discord-bot.ts # Discord.js wrapper
├── event-queue.ts # Unified FIFO event queue
├── agent-runtime.ts # Core engine: reads configs, spawns CLI, streams output
├── agent-runtime.ts # Core engine: reads configs, delegates to backend
├── backends/ # Pluggable CLI backend adapters
│ ├── types.ts # BackendAdapter interface & BackendName type
│ ├── registry.ts # resolveBackendName() & createBackend() factory
│ ├── index.ts # Barrel exports
│ ├── claude-backend.ts # Claude Code CLI adapter
│ ├── codex-backend.ts # OpenAI Codex CLI adapter
│ ├── gemini-backend.ts # Google Gemini CLI adapter
│ ├── opencode-backend.ts # OpenCode CLI adapter
│ └── pi-backend.ts # Pi Coding Agent CLI adapter
├── markdown-config-loader.ts # Reads CLAUDE.md, agents.md, memory.md
├── system-prompt-assembler.ts # Assembles system prompt with sections
├── skills-loader.ts # Loads skills from config/skills/*/SKILL.md
@@ -204,7 +335,16 @@ src/
├── hook-manager.ts # Lifecycle hooks
├── bootstrap-manager.ts # First-run file validation/creation
├── channel-queue.ts # Per-channel sequential processing
── shutdown-handler.ts # Graceful SIGTERM/SIGINT handling
── shutdown-handler.ts # Graceful SIGTERM/SIGINT handling
├── dashboard-server.ts # Embedded HTTP server for Mission Control
├── dashboard-dev.ts # Standalone dashboard dev server (mock data)
├── activity-log.ts # In-memory + persisted activity event log
└── local-store.ts # JSON file persistence layer (brain, tasks, content)
dashboard/ # Mission Control frontend
├── index.html # SPA shell with sidebar navigation
├── styles.css # Dark-theme design system (~1700 lines)
└── app.js # Client-side SPA (routing, API, rendering)
config/ # Agent workspace (gitignored)
├── CLAUDE.md # Persona
@@ -212,18 +352,28 @@ config/ # Agent workspace (gitignored)
├── memory.md # Long-term memory (agent-writable)
├── heartbeat.md # Heartbeat checks
├── sessions.json # Session persistence (auto)
├── brain.json # Second Brain facts (auto)
├── tasks.json # Productivity tasks (auto)
├── content-items.json # Content Intel items (auto)
├── activity-log.json # Persisted activity log (auto)
├── bot-config.json # Dashboard bot config (auto)
├── messages/ # Message history (auto)
├── conversations/ # Conversation archives (auto)
├── ipc/outbound/ # Proactive message queue (auto)
├── skills/ # Skill definitions
└── news/ # Example: agent-created content
docs/
├── PROCESS-FLOW.md # Step-by-step event processing walkthrough
└── FUTURE-FEATURES.md # Feature roadmap and ideas
```
## Development
```bash
npm test # Run tests (85 passing)
npm run dev # Dev mode with tsx
npm test # Run tests (vitest)
npm run dev # Full gateway + embedded dashboard
npm run dashboard # Dashboard only with mock data
npm run build # Compile TypeScript
npm start # Run compiled JS
```