Files
aetheel-2/README.md

209 lines
7.2 KiB
Markdown

# Discord-Claude Gateway
An event-driven agent runtime that connects Discord to Claude via the [Claude Agent SDK](https://docs.anthropic.com/en/docs/agent-sdk/overview). Inspired by [OpenClaw](https://github.com/nichochar/open-claw)'s architecture — a gateway in front of an agent runtime with markdown-based personality, memory, and scheduled behaviors.
## How It Works
```
Discord Users ──► Discord Bot ──► Event Queue ──► Agent Runtime ──► Claude Agent SDK
▲ │
Heartbeats ──────────┤ │
Cron Jobs ───────────┤ ┌─────────────────────┘
Hooks ───────────────┘ ▼
Markdown Config Files
(soul, identity, memory, etc.)
```
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 Agent SDK. The agent can write back to `memory.md` to persist facts across sessions.
## Prerequisites
- **Node.js** 18+
- **Claude Code CLI** — [Install Claude Code](https://docs.anthropic.com/en/docs/claude-code/getting-started) and sign in with your subscription
- **Discord Bot Token** — [Create a bot](https://discord.com/developers/applications) with Message Content Intent enabled
## Quick Start
```bash
# Install dependencies
npm install
# Make sure Claude Code CLI is installed and you're signed in
claude --version
# Set required environment variables
export DISCORD_BOT_TOKEN=your-discord-bot-token
# Create config directory with persona files
mkdir config
```
Create at minimum `config/soul.md` and `config/identity.md`:
```bash
# config/identity.md
echo "# Identity
- **Name:** Aetheel
- **Vibe:** Helpful, sharp, slightly witty
- **Emoji:** ⚡" > config/identity.md
# config/soul.md
echo "# Soul
Be genuinely helpful. Have opinions. Be resourceful before asking.
Earn trust through competence." > config/soul.md
```
```bash
# Start the gateway
npm run dev
```
## Configuration
All settings are via environment variables:
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `DISCORD_BOT_TOKEN` | Yes | — | Discord bot token |
| `CLAUDE_CLI_PATH` | No | `claude` | Path to the Claude Code CLI binary |
| `ALLOWED_TOOLS` | No | `Read,Write,Edit,Glob,Grep,WebSearch,WebFetch` | Comma-separated Claude Code tools |
| `PERMISSION_MODE` | No | `bypassPermissions` | Claude Code permission mode |
| `QUERY_TIMEOUT_MS` | No | `120000` | Query timeout in milliseconds |
| `MAX_CONCURRENT_QUERIES` | No | `5` | Max simultaneous Claude queries |
| `CONFIG_DIR` | No | `./config` | Path to markdown config directory |
| `MAX_QUEUE_DEPTH` | No | `100` | Max events in the queue |
| `OUTPUT_CHANNEL_ID` | No | — | Discord channel for heartbeat/cron output |
## Markdown Config Files
Place these in your `CONFIG_DIR` (default: `./config/`). The gateway reads them fresh on every event — edit them anytime, no restart needed (except `agents.md` and `heartbeat.md` which are parsed at startup for cron/heartbeat timers).
| File | Purpose | Required |
|------|---------|----------|
| `CLAUDE.md` | Persona: identity, personality, user context, tools — all in one | Yes |
| `agents.md` | Operating rules, cron jobs, hooks (parsed by gateway) | No |
| `memory.md` | Long-term memory (agent can write to this) | No (auto-created) |
| `heartbeat.md` | Proactive check definitions (parsed by gateway) | No |
Missing optional files are created with default headers on first run.
### Heartbeat Config (`heartbeat.md`)
Define proactive checks the agent runs on a timer:
```markdown
## check-email
Interval: 1800
Instruction: Check my inbox for anything urgent. If nothing, reply HEARTBEAT_OK.
## check-calendar
Interval: 3600
Instruction: Review upcoming calendar events in the next 24 hours.
```
Interval is in seconds (minimum 60).
### Cron Jobs (in `agents.md`)
Define scheduled tasks with cron expressions:
```markdown
## Cron Jobs
### morning-briefing
Cron: 0 9 * * *
Instruction: Good morning! Check email, review today's calendar, and give me a brief summary.
### weekly-review
Cron: 0 15 * * 1
Instruction: Review the week's calendar and flag any conflicts.
```
### Hooks (in `agents.md`)
Define lifecycle hook instructions:
```markdown
## Hooks
### startup
Instruction: Read memory.md and greet the user.
### shutdown
Instruction: Save any important context to memory.md before shutting down.
```
## Discord Commands
| Command | Description |
|---------|-------------|
| `@bot <message>` | Send a prompt by mentioning the bot |
| `/claude <prompt>` | Send a prompt via slash command |
| `/claude-reset` | Reset the conversation session in the current channel |
## Architecture
The system has 5 input types (inspired by OpenClaw):
1. **Messages** — Discord mentions and slash commands
2. **Heartbeats** — Timer-based proactive checks
3. **Cron Jobs** — Scheduled events with cron expressions
4. **Hooks** — Internal lifecycle triggers (startup, shutdown, agent_begin, agent_stop)
5. **Webhooks** — External system events (planned)
All inputs enter a unified FIFO event queue → processed sequentially by the agent runtime → state persists to markdown files → loop continues.
## Project Structure
```
src/
├── index.ts # Entry point
├── gateway-core.ts # Main orchestrator
├── config.ts # Environment variable loader
├── discord-bot.ts # Discord.js wrapper
├── event-queue.ts # Unified FIFO event queue
├── agent-runtime.ts # Core processing engine
├── markdown-config-loader.ts # Reads config files from disk
├── system-prompt-assembler.ts# Assembles system prompt from configs
├── session-manager.ts # Channel-to-session bindings
├── channel-queue.ts # Per-channel sequential processing
├── response-formatter.ts # Message splitting for Discord's 2000 char limit
├── error-formatter.ts # Safe error formatting
├── heartbeat-scheduler.ts # Recurring timer events
├── cron-scheduler.ts # Cron-expression scheduled events
├── hook-manager.ts # Lifecycle hook events
├── bootstrap-manager.ts # First-run file validation/creation
└── shutdown-handler.ts # Graceful SIGTERM/SIGINT handling
```
## Development
```bash
# Run tests
npm test
# Run in dev mode
npm run dev
# Build
npm run build
# Start production
npm start
```
## Claude Code CLI vs API Key
This gateway uses the **Claude Code CLI** (`claude -p`) instead of the Anthropic API directly. This means:
- You use your existing **Claude Code subscription** — no separate API key needed
- Just sign in with `claude` in your terminal and you're good to go
- The gateway shells out to `claude -p "prompt" --output-format json` for each query
- Set `CLAUDE_CLI_PATH` if `claude` isn't in your PATH
## License
MIT