18 files. Bidirectional integration system: **outbound** session event notifications (Discord/Telegram/HTTP webhook/shell command) AND **inbound** reply handling (daemon polls chat apps, injects replies back into tmux session). Named "claw" because it reaches out from OpenCode and pulls replies back in.
## BIDIRECTIONAL FLOW
### Outbound (OpenCode → External)
```
OpenCode session event → dispatchOpenClawEvent()
→ runtime-dispatch.ts: map event to OpenClaw event
→ dispatcher.ts: execute gateway (HTTP POST or shell command)
→ session-registry.ts: record message ID ↔ sessionID ↔ tmux pane
```
### Inbound (External → OpenCode)
```
Discord/Telegram API → reply-listener daemon (separate Bun process)
→ reply-listener-{discord,telegram}.ts: poll every 3s
→ session-registry.ts: look up target tmux session from message ID
→ reply-listener-injection.ts: send-keys into tmux pane (rate limited)
```
## KEY FILES
| File | Purpose |
|------|---------|
| `index.ts` | `wakeOpenClaw()`, `initializeOpenClaw()` — main entry |
- **Authorized users**: Inbound replies filtered by allowed user ID list
- **Token redaction**: Secrets masked in logs and error messages
- **Rate limiting**: Reply injection throttled per pane
## TESTING NOTE
`reply-listener-discord.test.ts` is **always isolated** in CI (listed in `ALWAYS_ISOLATED_TEST_FILES` of `script/run-ci-tests.ts`). Reason: mocks `globalThis.fetch` for Discord API simulation — needs process isolation to avoid interference with shared test batch.