384 lines
17 KiB
Markdown
384 lines
17 KiB
Markdown
# Aetheel — AI Agent Runtime with Mission Control
|
|
|
|
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 ──► 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 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.
|
|
|
|
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+
|
|
- 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
|
|
|
|
```bash
|
|
git clone <your-repo-url>
|
|
cd aetheel-2
|
|
npm install
|
|
cp .env.example .env # Edit with your Discord bot token
|
|
mkdir -p config
|
|
# Create config/CLAUDE.md with your persona (see Setup section)
|
|
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
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
Create a `.env` file in the project root (auto-loaded via dotenv):
|
|
|
|
| Variable | Required | Default | Description |
|
|
|----------|----------|---------|-------------|
|
|
| `DISCORD_BOT_TOKEN` | Yes | — | Discord bot token |
|
|
| `OUTPUT_CHANNEL_ID` | No | — | Discord channel for heartbeat/cron/hook output |
|
|
| `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 |
|
|
| `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 |
|
|
| `MAX_QUEUE_DEPTH` | No | `100` | Max events in the queue |
|
|
| `IDLE_SESSION_TIMEOUT_MS` | No | `1800000` | Session idle timeout (30 min) |
|
|
| `LOG_LEVEL` | No | `info` | Log level: debug, info, warn, error |
|
|
|
|
### Markdown Config Files
|
|
|
|
Place these in `CONFIG_DIR` (default: `./config/`):
|
|
|
|
| File | Purpose | Required |
|
|
|------|---------|----------|
|
|
| `CLAUDE.md` | Persona: identity, personality, user context, tools | Yes |
|
|
| `agents.md` | Operating rules, cron jobs, hooks (parsed at startup) | No |
|
|
| `memory.md` | Long-term memory (agent-writable) | No (auto-created) |
|
|
| `heartbeat.md` | Proactive check definitions (parsed at startup) | No |
|
|
|
|
The gateway reads `CLAUDE.md` and `memory.md` fresh on every event — edit them anytime. `agents.md` and `heartbeat.md` are parsed at startup for timers, so restart after editing those.
|
|
|
|
### Skills
|
|
|
|
Drop skill files into `config/skills/{name}/SKILL.md` and they're automatically loaded into the system prompt:
|
|
|
|
```
|
|
config/skills/
|
|
├── web-research/
|
|
│ └── SKILL.md → "When asked to research, use WebSearch..."
|
|
└── code-review/
|
|
└── 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
|
|
- 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 (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)
|
|
Define in `config/heartbeat.md`:
|
|
```markdown
|
|
## check-email
|
|
Interval: 1800
|
|
Instruction: Check my inbox for anything urgent.
|
|
```
|
|
|
|
### 🕐 Cron Jobs (Scheduled Events)
|
|
Define in `config/agents.md`:
|
|
```markdown
|
|
## Cron Jobs
|
|
|
|
### morning-briefing
|
|
Cron: 0 8 * * *
|
|
Instruction: Good morning! Search for the latest AI news and post a summary.
|
|
```
|
|
|
|
### 🪝 Lifecycle Hooks
|
|
Define in `config/agents.md`:
|
|
```markdown
|
|
## Hooks
|
|
|
|
### startup
|
|
Instruction: Say hello, you just came online.
|
|
|
|
### shutdown
|
|
Instruction: Save important context to memory.md.
|
|
```
|
|
|
|
### 📨 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
|
|
All inbound/outbound messages stored per channel in `config/messages/{channelId}.json`. Max 100 messages per channel, auto-trimmed.
|
|
|
|
### 📝 Conversation Archiving
|
|
Every exchange saved as readable markdown in `config/conversations/{channelId}/{YYYY-MM-DD}.md`.
|
|
|
|
### 🔁 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
|
|
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)
|
|
|
|
```bash
|
|
sudo bash scripts/setup.sh # Creates .env, config/, and systemd service
|
|
```
|
|
|
|
Or manually:
|
|
```bash
|
|
sudo cp scripts/aetheel.service /etc/systemd/system/
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable aetheel
|
|
sudo systemctl start aetheel
|
|
|
|
# View logs
|
|
sudo journalctl -u aetheel -f
|
|
```
|
|
|
|
### PM2
|
|
```bash
|
|
npm run build
|
|
pm2 start dist/index.js --name aetheel
|
|
pm2 save
|
|
```
|
|
|
|
### Dev mode
|
|
```bash
|
|
npm run dev # Full gateway + dashboard
|
|
npm run dashboard # Dashboard only (mock data)
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
src/
|
|
├── index.ts # Entry point (loads .env)
|
|
├── gateway-core.ts # Main orchestrator
|
|
├── config.ts # Environment variable loader
|
|
├── 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, 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
|
|
├── session-manager.ts # Channel → session ID (persisted, idle cleanup)
|
|
├── message-history.ts # Per-channel message storage
|
|
├── conversation-archiver.ts # Markdown conversation logs
|
|
├── ipc-watcher.ts # Polls ipc/outbound/ for proactive messages
|
|
├── response-formatter.ts # Splits long text for Discord's 2000 char limit
|
|
├── error-formatter.ts # Sanitizes errors (strips keys, paths, stacks)
|
|
├── heartbeat-scheduler.ts # Recurring timer events
|
|
├── cron-scheduler.ts # node-cron scheduled events
|
|
├── 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
|
|
├── 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
|
|
├── agents.md # Rules, cron, hooks
|
|
├── 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 (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
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|