mirror of
https://github.com/qwibitai/nanoclaw.git
synced 2026-06-04 10:14:47 +08:00
v2: channel isolation model, manage-channels skill, refactored channel skills
- Add three-level isolation model (shared session, same agent, separate agent) with agent-shared session mode for cross-channel shared sessions - Create /manage-channels skill for wiring channels to agent groups - Refactor all 12 v2 channel skills: lean SKILL.md + VERIFY.md + REMOVE.md with structured Channel Info section for platform-specific metadata - Create /add-discord-v2 skill (was missing) - Add step 5a to setup SKILL.md invoking /manage-channels after channel install - Update setup/verify.ts to check all 12 channel token types - Add docs/v2-isolation-model.md explaining the isolation model - Update v2-checklist.md and v2-setup-wiring.md to reflect completed work Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# Remove Discord
|
||||
|
||||
1. Comment out `import './discord.js'` in `src/channels/index.ts`
|
||||
2. Remove `DISCORD_BOT_TOKEN` from `.env`
|
||||
3. Rebuild and restart
|
||||
|
||||
No package to uninstall — Discord is built in.
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: add-discord-v2
|
||||
description: Add Discord bot channel integration to NanoClaw v2 via Chat SDK.
|
||||
---
|
||||
|
||||
# Add Discord Channel
|
||||
|
||||
Adds Discord bot support to NanoClaw v2. Discord is built in — no adapter package to install.
|
||||
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/discord.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Install
|
||||
|
||||
Discord support is bundled with NanoClaw — there is no separate package to install.
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the Discord import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './discord.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Credentials
|
||||
|
||||
### Create Discord Bot
|
||||
|
||||
1. Go to the [Discord Developer Portal](https://discord.com/developers/applications)
|
||||
2. Click **New Application** and give it a name (e.g., "NanoClaw Assistant")
|
||||
3. Go to the **Bot** tab and click **Add Bot** if needed
|
||||
4. Copy the Bot Token (click **Reset Token** if you need a new one — you can only see it once)
|
||||
5. Under **Privileged Gateway Intents**, enable **Message Content Intent**
|
||||
6. Go to **OAuth2** > **URL Generator**:
|
||||
- Scopes: select `bot`
|
||||
- Bot Permissions: select `Send Messages`, `Read Message History`, `Add Reactions`, `Attach Files`, `Use Slash Commands`
|
||||
7. Copy the generated URL and open it in your browser to invite the bot to your server
|
||||
|
||||
### Configure environment
|
||||
|
||||
Add to `.env`:
|
||||
|
||||
```bash
|
||||
DISCORD_BOT_TOKEN=your-bot-token
|
||||
```
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
## Next Steps
|
||||
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
## Channel Info
|
||||
|
||||
- **type**: `discord`
|
||||
- **terminology**: Discord has "servers" (also called "guilds") containing "channels." Text channels start with #. The bot can also receive direct messages.
|
||||
- **how-to-find-id**: Enable Developer Mode in Discord (Settings > App Settings > Advanced > Developer Mode). Then right-click a server or channel and select "Copy ID."
|
||||
- **supports-threads**: yes
|
||||
- **typical-use**: Interactive chat — server channels or direct messages
|
||||
- **default-isolation**: Same agent group for your personal server. Separate agent group for servers with different communities or where different members have different information boundaries.
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Discord
|
||||
|
||||
Send a message in a channel where the bot has access, or DM the bot directly. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove Google Chat Channel
|
||||
|
||||
1. Comment out `import './gchat.js'` in `src/channels/index.ts`
|
||||
2. Remove `GCHAT_CREDENTIALS` from `.env`
|
||||
3. `npm uninstall @chat-adapter/gchat`
|
||||
4. Rebuild and restart
|
||||
@@ -3,39 +3,31 @@ name: add-gchat-v2
|
||||
description: Add Google Chat channel integration to NanoClaw v2 via Chat SDK.
|
||||
---
|
||||
|
||||
# Add Google Chat Channel (v2)
|
||||
# Add Google Chat Channel
|
||||
|
||||
This skill adds Google Chat support to NanoClaw v2 using the Chat SDK bridge.
|
||||
Adds Google Chat support to NanoClaw v2 using the Chat SDK bridge.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/gchat.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/gchat.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @chat-adapter/gchat
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the Google Chat import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './gchat.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
|
||||
### Create Google Chat App
|
||||
## Credentials
|
||||
|
||||
> 1. Go to [Google Cloud Console](https://console.cloud.google.com)
|
||||
> 2. Create or select a project
|
||||
@@ -58,21 +50,17 @@ GCHAT_CREDENTIALS={"type":"service_account","project_id":"...","private_key":"..
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Add the bot to a Google Chat space, then send a message or @mention the bot.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './gchat.js'` in `src/channels/index.ts`
|
||||
2. Remove `GCHAT_CREDENTIALS` from `.env`
|
||||
3. `npm uninstall @chat-adapter/gchat`
|
||||
4. Rebuild and restart
|
||||
- **type**: `gchat`
|
||||
- **terminology**: Google Chat has "spaces." A space can be a group conversation or a direct message with the bot.
|
||||
- **how-to-find-id**: Open the space in Google Chat, look at the URL — the space ID is the segment after `/space/` (e.g. `spaces/AAAA...`). Or use the Google Chat API to list spaces.
|
||||
- **supports-threads**: yes
|
||||
- **typical-use**: Interactive chat — team spaces or direct messages
|
||||
- **default-isolation**: Same agent group for spaces where you're the primary user. Separate agent group for spaces with different teams or sensitive contexts.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Google Chat Channel
|
||||
|
||||
Add the bot to a Google Chat space, then send a message or @mention the bot. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove GitHub Channel
|
||||
|
||||
1. Comment out `import './github.js'` in `src/channels/index.ts`
|
||||
2. Remove `GITHUB_TOKEN` and `GITHUB_WEBHOOK_SECRET` from `.env`
|
||||
3. `npm uninstall @chat-adapter/github`
|
||||
4. Rebuild and restart
|
||||
@@ -1,41 +1,33 @@
|
||||
---
|
||||
name: add-github-v2
|
||||
description: Add GitHub channel integration to NanoClaw v2 via Chat SDK. PR comment threads as conversations.
|
||||
description: Add GitHub channel integration to NanoClaw v2 via Chat SDK. PR and issue comment threads as conversations.
|
||||
---
|
||||
|
||||
# Add GitHub Channel (v2)
|
||||
# Add GitHub Channel
|
||||
|
||||
This skill adds GitHub support to NanoClaw v2 using the Chat SDK bridge. The agent can participate in PR comment threads.
|
||||
Adds GitHub support to NanoClaw v2 using the Chat SDK bridge. The agent participates in PR and issue comment threads.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/github.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/github.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @chat-adapter/github
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the GitHub import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './github.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
|
||||
### Create GitHub credentials
|
||||
## Credentials
|
||||
|
||||
> 1. Go to [GitHub Settings > Developer Settings > Personal Access Tokens](https://github.com/settings/tokens)
|
||||
> 2. Create a **Fine-grained token** with:
|
||||
@@ -60,21 +52,17 @@ GITHUB_WEBHOOK_SECRET=your-webhook-secret
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> @mention the bot in a PR comment or issue comment. The bot should respond within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './github.js'` in `src/channels/index.ts`
|
||||
2. Remove `GITHUB_TOKEN` and `GITHUB_WEBHOOK_SECRET` from `.env`
|
||||
3. `npm uninstall @chat-adapter/github`
|
||||
4. Rebuild and restart
|
||||
- **type**: `github`
|
||||
- **terminology**: GitHub has "repositories" containing "pull requests" and "issues." Each PR or issue comment thread is a separate conversation.
|
||||
- **how-to-find-id**: The platform ID is `owner/repo` (e.g. `acme/backend`). Each PR/issue becomes its own thread automatically.
|
||||
- **supports-threads**: yes (PR and issue comment threads are native conversations)
|
||||
- **typical-use**: Webhook/notification — the agent receives PR and issue events and responds in comment threads
|
||||
- **default-isolation**: Typically shares a session with a chat channel (e.g. Slack) so the agent can summarize PRs and respond to reviews in the same context. Use a separate agent group if the repo contains sensitive code that other channels shouldn't access.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify GitHub Channel
|
||||
|
||||
@mention the bot in a PR comment or issue comment. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove iMessage Channel
|
||||
|
||||
1. Comment out `import './imessage.js'` in `src/channels/index.ts`
|
||||
2. Remove iMessage env vars (`IMESSAGE_ENABLED`, `IMESSAGE_LOCAL`, `IMESSAGE_SERVER_URL`, `IMESSAGE_API_KEY`) from `.env`
|
||||
3. `npm uninstall chat-adapter-imessage`
|
||||
4. Rebuild and restart
|
||||
@@ -3,61 +3,55 @@ name: add-imessage-v2
|
||||
description: Add iMessage channel integration to NanoClaw v2 via Chat SDK. Local (macOS) or remote (Photon API) mode.
|
||||
---
|
||||
|
||||
# Add iMessage Channel (v2)
|
||||
# Add iMessage Channel
|
||||
|
||||
This skill adds iMessage support to NanoClaw v2 using the Chat SDK bridge. Supports local mode (macOS with Full Disk Access) and remote mode (via Photon API).
|
||||
Adds iMessage support to NanoClaw v2 using the Chat SDK bridge. Two modes: local (macOS with Full Disk Access) or remote (Photon API).
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/imessage.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/imessage.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install chat-adapter-imessage
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the iMessage import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './imessage.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
## Credentials
|
||||
|
||||
### Local Mode (macOS)
|
||||
|
||||
> **Requirements**: macOS with Full Disk Access granted to your terminal/Node.js process.
|
||||
>
|
||||
> 1. Go to **System Settings** > **Privacy & Security** > **Full Disk Access**
|
||||
> 2. Add your terminal app (Terminal, iTerm2, etc.) or the Node.js binary
|
||||
> 3. The adapter reads directly from the iMessage database on disk
|
||||
Requirements: macOS with Full Disk Access granted to your terminal/Node.js process.
|
||||
|
||||
1. Go to **System Settings** > **Privacy & Security** > **Full Disk Access**
|
||||
2. Add your terminal app (Terminal, iTerm2, etc.) or the Node.js binary
|
||||
3. The adapter reads directly from the iMessage database on disk
|
||||
|
||||
### Remote Mode (Photon API)
|
||||
|
||||
> 1. Set up a [Photon](https://photon.im) account
|
||||
> 2. Get your server URL and API key
|
||||
1. Set up a [Photon](https://photon.im) account
|
||||
2. Get your server URL and API key
|
||||
|
||||
### Configure environment
|
||||
|
||||
**Local mode** — add to `.env`:
|
||||
**Local mode** -- add to `.env`:
|
||||
|
||||
```bash
|
||||
IMESSAGE_ENABLED=true
|
||||
IMESSAGE_LOCAL=true
|
||||
```
|
||||
|
||||
**Remote mode** — add to `.env`:
|
||||
**Remote mode** -- add to `.env`:
|
||||
|
||||
```bash
|
||||
IMESSAGE_LOCAL=false
|
||||
@@ -67,20 +61,17 @@ IMESSAGE_API_KEY=your-api-key
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Send an iMessage to the account running NanoClaw. The bot should respond within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './imessage.js'` in `src/channels/index.ts`
|
||||
2. Remove iMessage env vars from `.env`
|
||||
3. `npm uninstall chat-adapter-imessage`
|
||||
4. Rebuild and restart
|
||||
- **type**: `imessage`
|
||||
- **terminology**: iMessage has "conversations." Each conversation is with a contact identified by phone number or email address. Group chats are also supported.
|
||||
- **how-to-find-id**: The platform ID is the contact's phone number (e.g. `+15551234567`) or email address. For group chats, the ID is assigned by iMessage internally.
|
||||
- **supports-threads**: no
|
||||
- **typical-use**: Interactive 1:1 chat — personal messaging
|
||||
- **default-isolation**: Same agent group if you're the only person messaging the bot across iMessage and other channels. Separate agent group if different contacts should have information isolation.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify iMessage Channel
|
||||
|
||||
Send an iMessage to the account running NanoClaw. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove Linear Channel
|
||||
|
||||
1. Comment out `import './linear.js'` in `src/channels/index.ts`
|
||||
2. Remove `LINEAR_API_KEY` and `LINEAR_WEBHOOK_SECRET` from `.env`
|
||||
3. `npm uninstall @chat-adapter/linear`
|
||||
4. Rebuild and restart
|
||||
@@ -3,39 +3,31 @@ name: add-linear-v2
|
||||
description: Add Linear channel integration to NanoClaw v2 via Chat SDK. Issue comment threads as conversations.
|
||||
---
|
||||
|
||||
# Add Linear Channel (v2)
|
||||
# Add Linear Channel
|
||||
|
||||
This skill adds Linear support to NanoClaw v2 using the Chat SDK bridge. The agent can participate in issue comment threads.
|
||||
Adds Linear support to NanoClaw v2 using the Chat SDK bridge. The agent participates in issue comment threads.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/linear.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/linear.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @chat-adapter/linear
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the Linear import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './linear.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
|
||||
### Create Linear credentials
|
||||
## Credentials
|
||||
|
||||
> 1. Go to [Linear Settings > API](https://linear.app/settings/api)
|
||||
> 2. Create a **Personal API Key** (or use an OAuth application for team-wide access)
|
||||
@@ -57,21 +49,17 @@ LINEAR_WEBHOOK_SECRET=your-webhook-secret
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> @mention the bot in a Linear issue comment. The bot should respond within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './linear.js'` in `src/channels/index.ts`
|
||||
2. Remove `LINEAR_API_KEY` and `LINEAR_WEBHOOK_SECRET` from `.env`
|
||||
3. `npm uninstall @chat-adapter/linear`
|
||||
4. Rebuild and restart
|
||||
- **type**: `linear`
|
||||
- **terminology**: Linear has "teams" containing "issues." Each issue's comment thread is a separate conversation.
|
||||
- **how-to-find-id**: The platform ID is your team key (e.g. `ENG`). Find it in Linear under Settings > Teams. Each issue becomes its own thread automatically.
|
||||
- **supports-threads**: yes (issue comment threads are native conversations)
|
||||
- **typical-use**: Webhook/notification — the agent receives issue comment events and responds in threads
|
||||
- **default-isolation**: Typically shares a session with a chat channel (e.g. Slack) so the agent can discuss issues in the same context as team chat. Use a separate agent group if the Linear team tracks sensitive work.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Linear Channel
|
||||
|
||||
@mention the bot in a Linear issue comment. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove Matrix Channel
|
||||
|
||||
1. Comment out `import './matrix.js'` in `src/channels/index.ts`
|
||||
2. Remove `MATRIX_BASE_URL`, `MATRIX_ACCESS_TOKEN`, `MATRIX_USER_ID`, `MATRIX_BOT_USERNAME` from `.env`
|
||||
3. `npm uninstall @beeper/chat-adapter-matrix`
|
||||
4. Rebuild and restart
|
||||
@@ -1,48 +1,40 @@
|
||||
---
|
||||
name: add-matrix-v2
|
||||
description: Add Matrix channel integration to NanoClaw v2 via Chat SDK. Works with any Matrix homeserver (Element, Beeper, etc.).
|
||||
description: Add Matrix channel integration to NanoClaw v2 via Chat SDK. Works with any Matrix homeserver.
|
||||
---
|
||||
|
||||
# Add Matrix Channel (v2)
|
||||
# Add Matrix Channel
|
||||
|
||||
This skill adds Matrix support to NanoClaw v2 using the Chat SDK bridge. Works with any Matrix homeserver.
|
||||
Adds Matrix support to NanoClaw v2 using the Chat SDK bridge.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/matrix.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/matrix.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @beeper/chat-adapter-matrix
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the Matrix import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './matrix.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
## Credentials
|
||||
|
||||
### Create Matrix bot account
|
||||
|
||||
> 1. Register a bot account on your Matrix homeserver (e.g., via Element)
|
||||
> 2. Get the homeserver URL (e.g., `https://matrix.org` or your self-hosted URL)
|
||||
> 3. Get an access token:
|
||||
> - In Element: **Settings** > **Help & About** > **Access Token** (advanced)
|
||||
> - Or via API: `curl -XPOST 'https://matrix.org/_matrix/client/r0/login' -d '{"type":"m.login.password","user":"botuser","password":"..."}'`
|
||||
> 4. Note the bot's user ID (e.g., `@botuser:matrix.org`)
|
||||
1. Register a bot account on your Matrix homeserver (e.g., via Element)
|
||||
2. Get the homeserver URL (e.g., `https://matrix.org` or your self-hosted URL)
|
||||
3. Get an access token:
|
||||
- In Element: **Settings** > **Help & About** > **Access Token** (advanced)
|
||||
- Or via API: `curl -XPOST 'https://matrix.org/_matrix/client/r0/login' -d '{"type":"m.login.password","user":"botuser","password":"..."}'`
|
||||
4. Note the bot's user ID (e.g., `@botuser:matrix.org`)
|
||||
|
||||
### Configure environment
|
||||
|
||||
@@ -57,21 +49,17 @@ MATRIX_BOT_USERNAME=botuser
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Invite the bot to a Matrix room and send a message. The bot should respond within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './matrix.js'` in `src/channels/index.ts`
|
||||
2. Remove `MATRIX_BASE_URL`, `MATRIX_ACCESS_TOKEN`, `MATRIX_USER_ID`, `MATRIX_BOT_USERNAME` from `.env`
|
||||
3. `npm uninstall @beeper/chat-adapter-matrix`
|
||||
4. Rebuild and restart
|
||||
- **type**: `matrix`
|
||||
- **terminology**: Matrix has "rooms." A room can be a group chat or a direct message. Rooms have internal IDs (like `!abc123:matrix.org`) and optional aliases (like `#general:matrix.org`).
|
||||
- **how-to-find-id**: In Element, click the room name > Settings > Advanced — the "Internal room ID" is the platform ID (starts with `!`). Or use a room alias like `#general:matrix.org`.
|
||||
- **supports-threads**: partial (some clients support threads, but not all — treat as no for reliability)
|
||||
- **typical-use**: Interactive chat — rooms or direct messages
|
||||
- **default-isolation**: Same agent group for rooms where you're the primary user. Separate agent group for rooms with different communities or sensitive contexts.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Matrix Channel
|
||||
|
||||
Invite the bot to a Matrix room and send a message. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove Resend Email Channel
|
||||
|
||||
1. Comment out `import './resend.js'` in `src/channels/index.ts`
|
||||
2. Remove `RESEND_API_KEY`, `RESEND_FROM_ADDRESS`, `RESEND_FROM_NAME`, `RESEND_WEBHOOK_SECRET` from `.env`
|
||||
3. `npm uninstall @resend/chat-sdk-adapter`
|
||||
4. Rebuild and restart
|
||||
@@ -3,48 +3,42 @@ name: add-resend-v2
|
||||
description: Add Resend (email) channel integration to NanoClaw v2 via Chat SDK.
|
||||
---
|
||||
|
||||
# Add Resend Email Channel (v2)
|
||||
# Add Resend Email Channel
|
||||
|
||||
This skill adds email support via Resend to NanoClaw v2 using the Chat SDK bridge.
|
||||
Connect NanoClaw to email via Resend for async email conversations.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/resend.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/resend.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @resend/chat-sdk-adapter
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the Resend import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './resend.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
Build:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
## Credentials
|
||||
|
||||
### Create Resend credentials
|
||||
|
||||
> 1. Go to [resend.com](https://resend.com) and create an account
|
||||
> 2. Add and verify your sending domain
|
||||
> 3. Go to **API Keys** and create a new key
|
||||
> 4. Set up a webhook:
|
||||
> - Go to **Webhooks** > **Add webhook**
|
||||
> - URL: `https://your-domain/webhook/resend`
|
||||
> - Events: select **email.received** (for inbound email)
|
||||
> - Copy the signing secret
|
||||
1. Go to [resend.com](https://resend.com) and create an account.
|
||||
2. Add and verify your sending domain.
|
||||
3. Go to **API Keys** and create a new key.
|
||||
4. Set up a webhook:
|
||||
- Go to **Webhooks** > **Add webhook**.
|
||||
- URL: `https://your-domain/webhook/resend`.
|
||||
- Events: select **email.received**.
|
||||
- Copy the signing secret.
|
||||
|
||||
### Configure environment
|
||||
|
||||
@@ -59,21 +53,17 @@ RESEND_WEBHOOK_SECRET=your-webhook-secret
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Send an email to the configured from address. The bot should respond via email within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './resend.js'` in `src/channels/index.ts`
|
||||
2. Remove `RESEND_API_KEY`, `RESEND_FROM_ADDRESS`, `RESEND_FROM_NAME`, `RESEND_WEBHOOK_SECRET` from `.env`
|
||||
3. `npm uninstall @resend/chat-sdk-adapter`
|
||||
4. Rebuild and restart
|
||||
- **type**: `resend`
|
||||
- **terminology**: Resend handles email. Each email thread (identified by subject/In-Reply-To headers) is a separate conversation. The "from address" is the bot's identity.
|
||||
- **how-to-find-id**: The platform ID is the from email address (e.g. `bot@yourdomain.com`). Each sender's email thread becomes its own conversation.
|
||||
- **supports-threads**: yes (via email threading headers -- replies to the same thread stay together)
|
||||
- **typical-use**: Async communication -- email conversations with longer response expectations
|
||||
- **default-isolation**: Same agent group if you want your agent to handle email alongside other channels. Separate agent group if email contains sensitive correspondence that shouldn't be accessible from other channels.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Resend Email Channel
|
||||
|
||||
Send an email to the configured from address. The bot should respond via email within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove Slack
|
||||
|
||||
1. Comment out `import './slack.js'` in `src/channels/index.ts`
|
||||
2. Remove `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET` from `.env`
|
||||
3. `npm uninstall @chat-adapter/slack`
|
||||
4. Rebuild and restart
|
||||
@@ -3,15 +3,15 @@ name: add-slack-v2
|
||||
description: Add Slack channel integration to NanoClaw v2 via Chat SDK.
|
||||
---
|
||||
|
||||
# Add Slack Channel (v2)
|
||||
# Add Slack Channel
|
||||
|
||||
This skill adds Slack support to NanoClaw v2 using the Chat SDK bridge.
|
||||
Adds Slack support to NanoClaw v2 using the Chat SDK bridge.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/slack.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/slack.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
## Install
|
||||
|
||||
### Install the adapter package
|
||||
|
||||
@@ -33,21 +33,19 @@ import './slack.js';
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
## Credentials
|
||||
|
||||
### Create Slack App (if needed)
|
||||
### Create Slack App
|
||||
|
||||
If the user doesn't have a Slack app:
|
||||
|
||||
> 1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App** > **From scratch**
|
||||
> 2. Name it (e.g., "NanoClaw") and select your workspace
|
||||
> 3. Go to **OAuth & Permissions** and add Bot Token Scopes:
|
||||
> - `chat:write`, `channels:history`, `groups:history`, `im:history`, `channels:read`, `groups:read`, `users:read`, `reactions:write`
|
||||
> 4. Click **Install to Workspace** and copy the **Bot User OAuth Token** (`xoxb-...`)
|
||||
> 5. Go to **Basic Information** and copy the **Signing Secret**
|
||||
> 6. Go to **Event Subscriptions**, enable events, and subscribe to:
|
||||
> - `message.channels`, `message.groups`, `message.im`, `app_mention`
|
||||
> 7. Set the Request URL to your webhook endpoint (e.g., `https://your-domain/webhook/slack`)
|
||||
1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App** > **From scratch**
|
||||
2. Name it (e.g., "NanoClaw") and select your workspace
|
||||
3. Go to **OAuth & Permissions** and add Bot Token Scopes:
|
||||
- `chat:write`, `channels:history`, `groups:history`, `im:history`, `channels:read`, `groups:read`, `users:read`, `reactions:write`
|
||||
4. Click **Install to Workspace** and copy the **Bot User OAuth Token** (`xoxb-...`)
|
||||
5. Go to **Basic Information** and copy the **Signing Secret**
|
||||
6. Go to **Event Subscriptions**, enable events, and subscribe to:
|
||||
- `message.channels`, `message.groups`, `message.im`, `app_mention`
|
||||
7. Set the Request URL to your webhook endpoint (e.g., `https://your-domain/webhook/slack`)
|
||||
|
||||
### Configure environment
|
||||
|
||||
@@ -60,22 +58,17 @@ SLACK_SIGNING_SECRET=your-signing-secret
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Add the bot to a Slack channel, then send a message or @mention the bot.
|
||||
> The bot should respond within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './slack.js'` in `src/channels/index.ts`
|
||||
2. Remove `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET` from `.env`
|
||||
3. `npm uninstall @chat-adapter/slack`
|
||||
4. Rebuild and restart
|
||||
- **type**: `slack`
|
||||
- **terminology**: Slack has "workspaces" containing "channels." Channels can be public (#general) or private. The bot can also receive direct messages.
|
||||
- **how-to-find-id**: Right-click a channel name > "View channel details" — the Channel ID is at the bottom (starts with C). Or copy the channel link — the ID is the last segment of the URL.
|
||||
- **supports-threads**: yes
|
||||
- **typical-use**: Interactive chat — team channels or direct messages
|
||||
- **default-isolation**: Same agent group for channels where you're the primary user. Separate agent group for channels with different teams or sensitive contexts.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Slack
|
||||
|
||||
Add the bot to a Slack channel, then send a message or @mention the bot. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove Microsoft Teams Channel
|
||||
|
||||
1. Comment out `import './teams.js'` in `src/channels/index.ts`
|
||||
2. Remove `TEAMS_APP_ID` and `TEAMS_APP_PASSWORD` from `.env`
|
||||
3. `npm uninstall @chat-adapter/teams`
|
||||
4. Rebuild and restart
|
||||
@@ -3,46 +3,38 @@ name: add-teams-v2
|
||||
description: Add Microsoft Teams channel integration to NanoClaw v2 via Chat SDK.
|
||||
---
|
||||
|
||||
# Add Microsoft Teams Channel (v2)
|
||||
# Add Microsoft Teams Channel
|
||||
|
||||
This skill adds Microsoft Teams support to NanoClaw v2 using the Chat SDK bridge.
|
||||
Connect NanoClaw to Microsoft Teams for interactive chat in team channels and direct messages.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/teams.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/teams.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @chat-adapter/teams
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the Teams import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './teams.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
Build:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
## Credentials
|
||||
|
||||
### Create Teams Bot
|
||||
|
||||
> 1. Go to [Azure Portal](https://portal.azure.com) > **Azure Bot** > **Create**
|
||||
> 2. Fill in the bot details and create
|
||||
> 3. Go to **Configuration**:
|
||||
> - Messaging endpoint: `https://your-domain/webhook/teams`
|
||||
> 4. Go to **Channels** > add **Microsoft Teams**
|
||||
> 5. Note the **Microsoft App ID** and **Password** (from the bot's Azure AD app registration)
|
||||
1. Go to [Azure Portal](https://portal.azure.com) > **Azure Bot** > **Create**.
|
||||
2. Configure the messaging endpoint: `https://your-domain/webhook/teams`.
|
||||
3. Add the **Microsoft Teams** channel.
|
||||
4. Note the **App ID** and **Password** from the Azure AD app registration.
|
||||
|
||||
### Configure environment
|
||||
|
||||
@@ -55,21 +47,17 @@ TEAMS_APP_PASSWORD=your-app-password
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Add the bot to a Teams channel or send it a direct message. The bot should respond within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './teams.js'` in `src/channels/index.ts`
|
||||
2. Remove `TEAMS_APP_ID` and `TEAMS_APP_PASSWORD` from `.env`
|
||||
3. `npm uninstall @chat-adapter/teams`
|
||||
4. Rebuild and restart
|
||||
- **type**: `teams`
|
||||
- **terminology**: Teams has "teams" containing "channels." The bot can also receive direct messages. Teams channels can have threaded replies.
|
||||
- **how-to-find-id**: Right-click a channel in Teams > "Get link to channel" -- the channel ID is in the URL. Or use the Microsoft Graph API to list channels.
|
||||
- **supports-threads**: yes
|
||||
- **typical-use**: Interactive chat -- team channels or direct messages
|
||||
- **default-isolation**: Same agent group for channels where you're the primary user. Separate agent group for channels with different teams or where different members have different information boundaries.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Microsoft Teams Channel
|
||||
|
||||
Add the bot to a Teams channel or send it a direct message. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove Telegram
|
||||
|
||||
1. Comment out `import './telegram.js'` in `src/channels/index.ts`
|
||||
2. Remove `TELEGRAM_BOT_TOKEN` from `.env`
|
||||
3. `npm uninstall @chat-adapter/telegram`
|
||||
4. Rebuild and restart
|
||||
@@ -3,15 +3,15 @@ name: add-telegram-v2
|
||||
description: Add Telegram channel integration to NanoClaw v2 via Chat SDK.
|
||||
---
|
||||
|
||||
# Add Telegram Channel (v2)
|
||||
# Add Telegram Channel
|
||||
|
||||
This skill adds Telegram support to NanoClaw v2 using the Chat SDK bridge.
|
||||
Adds Telegram bot support to NanoClaw v2 using the Chat SDK bridge.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/telegram.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/telegram.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
## Install
|
||||
|
||||
### Install the adapter package
|
||||
|
||||
@@ -33,22 +33,20 @@ import './telegram.js';
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
## Credentials
|
||||
|
||||
### Create Telegram Bot (if needed)
|
||||
### Create Telegram Bot
|
||||
|
||||
> 1. Open Telegram and search for `@BotFather`
|
||||
> 2. Send `/newbot` and follow the prompts:
|
||||
> - Bot name: Something friendly (e.g., "NanoClaw Assistant")
|
||||
> - Bot username: Must end with "bot" (e.g., "nanoclaw_bot")
|
||||
> 3. Copy the bot token (looks like `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`)
|
||||
1. Open Telegram and search for `@BotFather`
|
||||
2. Send `/newbot` and follow the prompts:
|
||||
- Bot name: Something friendly (e.g., "NanoClaw Assistant")
|
||||
- Bot username: Must end with "bot" (e.g., "nanoclaw_bot")
|
||||
3. Copy the bot token (looks like `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`)
|
||||
|
||||
### Disable Group Privacy (for group chats)
|
||||
**Important for group chats**: By default, Telegram bots only see @mentions and commands in groups. To let the bot see all messages:
|
||||
|
||||
> **Important for group chats**: By default, Telegram bots only see @mentions and commands in groups. To let the bot see all messages:
|
||||
>
|
||||
> 1. Open `@BotFather` > `/mybots` > select your bot
|
||||
> 2. **Bot Settings** > **Group Privacy** > **Turn off**
|
||||
1. Open `@BotFather` > `/mybots` > select your bot
|
||||
2. **Bot Settings** > **Group Privacy** > **Turn off**
|
||||
|
||||
### Configure environment
|
||||
|
||||
@@ -60,23 +58,17 @@ TELEGRAM_BOT_TOKEN=your-bot-token
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Send a message to your bot in Telegram (search for its username).
|
||||
> For groups: add the bot to a group and send a message.
|
||||
> The bot should respond within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './telegram.js'` in `src/channels/index.ts`
|
||||
2. Remove `TELEGRAM_BOT_TOKEN` from `.env`
|
||||
3. `npm uninstall @chat-adapter/telegram`
|
||||
4. Rebuild and restart
|
||||
- **type**: `telegram`
|
||||
- **terminology**: Telegram calls them "groups" and "chats." A "group" has multiple members; a "chat" is a 1:1 conversation with the bot.
|
||||
- **how-to-find-id**: Send a message in the group/chat, then visit `https://api.telegram.org/bot<TOKEN>/getUpdates` — the `chat.id` field is the platform ID. Group IDs are negative numbers.
|
||||
- **supports-threads**: no
|
||||
- **typical-use**: Interactive chat — direct messages or small groups
|
||||
- **default-isolation**: Same agent group if you're the only participant across multiple chats. Separate agent group if different people are in different groups.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Telegram
|
||||
|
||||
Send a message to your bot in Telegram (search for its username), or add the bot to a group and send a message there. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove Webex Channel
|
||||
|
||||
1. Comment out `import './webex.js'` in `src/channels/index.ts`
|
||||
2. Remove `WEBEX_BOT_TOKEN` and `WEBEX_WEBHOOK_SECRET` from `.env`
|
||||
3. `npm uninstall @bitbasti/chat-adapter-webex`
|
||||
4. Rebuild and restart
|
||||
@@ -3,46 +3,37 @@ name: add-webex-v2
|
||||
description: Add Webex channel integration to NanoClaw v2 via Chat SDK.
|
||||
---
|
||||
|
||||
# Add Webex Channel (v2)
|
||||
# Add Webex Channel
|
||||
|
||||
This skill adds Cisco Webex support to NanoClaw v2 using the Chat SDK bridge.
|
||||
Adds Cisco Webex support to NanoClaw v2 using the Chat SDK bridge.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/webex.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/webex.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @bitbasti/chat-adapter-webex
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the Webex import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './webex.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
## Credentials
|
||||
|
||||
### Create Webex Bot
|
||||
|
||||
> 1. Go to [developer.webex.com](https://developer.webex.com/my-apps/new/bot)
|
||||
> 2. Create a new bot and copy the **Bot Access Token**
|
||||
> 3. Set up a webhook:
|
||||
> - Use the Webex API to create a webhook pointing to `https://your-domain/webhook/webex`
|
||||
> - Or use the Webex Developer Portal
|
||||
> - Set a webhook secret for signature verification
|
||||
1. Go to [developer.webex.com](https://developer.webex.com/my-apps/new/bot) and create a new bot
|
||||
2. Copy the **Bot Access Token**
|
||||
3. Set up a webhook:
|
||||
- Use the Webex API or Developer Portal to create a webhook pointing to `https://your-domain/webhook/webex`
|
||||
- Set a webhook secret for signature verification
|
||||
|
||||
### Configure environment
|
||||
|
||||
@@ -55,21 +46,17 @@ WEBEX_WEBHOOK_SECRET=your-webhook-secret
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Add the bot to a Webex space or send it a direct message. The bot should respond within a few seconds.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './webex.js'` in `src/channels/index.ts`
|
||||
2. Remove `WEBEX_BOT_TOKEN` and `WEBEX_WEBHOOK_SECRET` from `.env`
|
||||
3. `npm uninstall @bitbasti/chat-adapter-webex`
|
||||
4. Rebuild and restart
|
||||
- **type**: `webex`
|
||||
- **terminology**: Webex has "spaces." A space can be a group conversation or a 1:1 direct message with the bot.
|
||||
- **how-to-find-id**: Open the space in Webex, click the space name > Settings — the Space ID is listed there. Or use the Webex API (`GET /rooms`) to list spaces and their IDs.
|
||||
- **supports-threads**: yes
|
||||
- **typical-use**: Interactive chat — team spaces or direct messages
|
||||
- **default-isolation**: Same agent group for spaces where you're the primary user. Separate agent group for spaces with different teams or sensitive information.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify Webex Channel
|
||||
|
||||
Add the bot to a Webex space or send it a direct message. The bot should respond within a few seconds.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Remove WhatsApp Cloud API Channel
|
||||
|
||||
1. Comment out `import './whatsapp-cloud.js'` in `src/channels/index.ts`
|
||||
2. Remove `WHATSAPP_ACCESS_TOKEN`, `WHATSAPP_PHONE_NUMBER_ID`, `WHATSAPP_APP_SECRET`, `WHATSAPP_VERIFY_TOKEN` from `.env`
|
||||
3. `npm uninstall @chat-adapter/whatsapp`
|
||||
4. Rebuild and restart
|
||||
@@ -1,52 +1,46 @@
|
||||
---
|
||||
name: add-whatsapp-cloud-v2
|
||||
description: Add WhatsApp Business Cloud API channel to NanoClaw v2 via Chat SDK. Official Meta API (not Baileys).
|
||||
description: Add WhatsApp Business Cloud API channel to NanoClaw v2 via Chat SDK. Official Meta API.
|
||||
---
|
||||
|
||||
# Add WhatsApp Cloud API Channel (v2)
|
||||
# Add WhatsApp Cloud API Channel
|
||||
|
||||
This skill adds WhatsApp support via the official Meta WhatsApp Business Cloud API. This is different from the Baileys-based WhatsApp adapter (which uses WhatsApp Web protocol).
|
||||
Connect NanoClaw to WhatsApp via the official Meta WhatsApp Business Cloud API.
|
||||
|
||||
## Phase 1: Pre-flight
|
||||
## Pre-flight
|
||||
|
||||
Check if `src/channels/whatsapp-cloud.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Phase 3.
|
||||
Check if `src/channels/whatsapp-cloud.ts` exists and the import is uncommented in `src/channels/index.ts`. If both are in place, skip to Credentials.
|
||||
|
||||
## Phase 2: Apply Code Changes
|
||||
|
||||
### Install the adapter package
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @chat-adapter/whatsapp
|
||||
```
|
||||
|
||||
### Enable the channel
|
||||
|
||||
Uncomment the WhatsApp Cloud API import in `src/channels/index.ts`:
|
||||
|
||||
```typescript
|
||||
import './whatsapp-cloud.js';
|
||||
```
|
||||
|
||||
### Build
|
||||
Build:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Phase 3: Setup
|
||||
## Credentials
|
||||
|
||||
### Create WhatsApp Business App
|
||||
|
||||
> 1. Go to [Meta for Developers](https://developers.facebook.com/apps/) and create an app (type: Business)
|
||||
> 2. Add the **WhatsApp** product
|
||||
> 3. Go to **WhatsApp** > **API Setup**:
|
||||
> - Note the **Phone Number ID** (not the phone number itself)
|
||||
> - Generate a **permanent System User access token** with `whatsapp_business_messaging` permission
|
||||
> 4. Go to **WhatsApp** > **Configuration**:
|
||||
> - Set webhook URL: `https://your-domain/webhook/whatsapp`
|
||||
> - Set a **Verify Token** (any random string you choose)
|
||||
> - Subscribe to webhook fields: `messages`
|
||||
> 5. Copy the **App Secret** from **Settings** > **Basic**
|
||||
1. Go to [Meta for Developers](https://developers.facebook.com/apps/) and create an app (type: Business).
|
||||
2. Add the **WhatsApp** product.
|
||||
3. Go to **WhatsApp** > **API Setup**:
|
||||
- Note the **Phone Number ID** (not the phone number itself).
|
||||
- Generate a **permanent System User access token** with `whatsapp_business_messaging` permission.
|
||||
4. Go to **WhatsApp** > **Configuration**:
|
||||
- Set webhook URL: `https://your-domain/webhook/whatsapp`.
|
||||
- Set a **Verify Token** (any random string you choose).
|
||||
- Subscribe to webhook fields: `messages`.
|
||||
5. Copy the **App Secret** from **Settings** > **Basic**.
|
||||
|
||||
### Configure environment
|
||||
|
||||
@@ -61,22 +55,17 @@ WHATSAPP_VERIFY_TOKEN=your-verify-token
|
||||
|
||||
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
||||
|
||||
### Build and restart
|
||||
## Next Steps
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
If you're in the middle of `/setup`, return to the setup flow now.
|
||||
|
||||
## Phase 4: Verify
|
||||
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
||||
|
||||
> Send a message to your WhatsApp Business number. The bot should respond within a few seconds.
|
||||
> Note: WhatsApp Cloud API only supports 1:1 DMs, not group chats.
|
||||
## Channel Info
|
||||
|
||||
## Removal
|
||||
|
||||
1. Comment out `import './whatsapp-cloud.js'` in `src/channels/index.ts`
|
||||
2. Remove `WHATSAPP_ACCESS_TOKEN`, `WHATSAPP_PHONE_NUMBER_ID`, `WHATSAPP_APP_SECRET`, `WHATSAPP_VERIFY_TOKEN` from `.env`
|
||||
3. `npm uninstall @chat-adapter/whatsapp`
|
||||
4. Rebuild and restart
|
||||
- **type**: `whatsapp-cloud`
|
||||
- **terminology**: WhatsApp Cloud API supports 1:1 conversations only (no group chats). Each conversation is with a phone number.
|
||||
- **how-to-find-id**: The platform ID is the Phone Number ID from the Meta Business dashboard (not the phone number itself). Find it under WhatsApp > API Setup.
|
||||
- **supports-threads**: no
|
||||
- **typical-use**: Interactive 1:1 chat -- direct messages only
|
||||
- **default-isolation**: Same agent group if you're the only person messaging the bot. Each additional person who messages gets their own conversation automatically, but they share the agent's workspace and memory -- use a separate agent group if you need information isolation between different contacts.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Verify WhatsApp Cloud API Channel
|
||||
|
||||
Send a message to your WhatsApp Business number. The bot should respond within a few seconds. Note: WhatsApp Cloud API only supports 1:1 DMs, not group chats.
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
name: manage-channels
|
||||
description: Wire channels to agent groups, manage isolation levels, add new channel groups. Use after adding a channel, during setup, or standalone to reconfigure.
|
||||
---
|
||||
|
||||
# Manage Channels
|
||||
|
||||
Wire messaging channels to agent groups. See `docs/v2-isolation-model.md` for the full isolation model.
|
||||
|
||||
## Assess Current State
|
||||
|
||||
Read the v2 central DB (`data/v2.db`) — query `agent_groups`, `messaging_groups`, and `messaging_group_agents` tables. Also check `.env` for channel tokens and `src/channels/index.ts` for uncommented imports.
|
||||
|
||||
Categorize channels as: **wired** (has DB entities), **configured but unwired** (has credentials + barrel import, no DB entities), or **not configured**.
|
||||
|
||||
## First Channel (No Agent Groups Exist)
|
||||
|
||||
1. Ask the assistant name (default: project name or "Andy")
|
||||
2. Ask which channel is the primary/admin channel
|
||||
3. Ask for the platform ID — read the channel's SKILL.md `## Channel Info` > `how-to-find-id` to guide them
|
||||
4. Register:
|
||||
|
||||
```bash
|
||||
npx tsx setup/index.ts --step register -- \
|
||||
--platform-id "<id>" --name "<name>" --folder "main" \
|
||||
--channel "<type>" --is-main --no-trigger-required \
|
||||
--assistant-name "<name>" --session-mode "shared"
|
||||
```
|
||||
|
||||
5. Continue to "Wire New Channel" for any remaining configured channels.
|
||||
|
||||
## Wire New Channel
|
||||
|
||||
For each unwired channel:
|
||||
|
||||
1. Read its SKILL.md `## Channel Info` for terminology, how-to-find-id, typical-use, and default-isolation
|
||||
2. Ask for the platform ID using the platform's terminology
|
||||
3. Ask the isolation question (see below)
|
||||
4. Register with the appropriate flags
|
||||
|
||||
### Isolation Question
|
||||
|
||||
Present a multiple-choice with a contextual recommendation. The three options:
|
||||
|
||||
- **Same conversation** (`--session-mode "agent-shared"` + existing folder) — all messages land in one session. Recommend for webhook + chat combos (GitHub + Slack).
|
||||
- **Same agent, separate conversations** (`--session-mode "shared"` + existing folder) — shared workspace/memory, independent threads. Recommend for same user across platforms.
|
||||
- **Separate agent** (new `--folder`) — full isolation. Recommend when different people are involved.
|
||||
|
||||
Use the channel's `typical-use` and `default-isolation` fields to pick the recommendation. Offer to explain more if the user is unsure — reference `docs/v2-isolation-model.md` for the detailed explanation.
|
||||
|
||||
### Register Command
|
||||
|
||||
```bash
|
||||
npx tsx setup/index.ts --step register -- \
|
||||
--platform-id "<id>" --name "<name>" \
|
||||
--folder "<folder>" --channel "<type>" \
|
||||
--session-mode "<shared|agent-shared>" \
|
||||
--assistant-name "<name>"
|
||||
```
|
||||
|
||||
For separate agents, also ask for a folder name and optionally a different assistant name.
|
||||
|
||||
## Add Channel Group
|
||||
|
||||
When adding another group/chat on an already-configured platform (e.g. a second Telegram group):
|
||||
|
||||
1. Read the channel's SKILL.md `## Channel Info` for terminology and how-to-find-id
|
||||
2. Ask for the new group/chat ID
|
||||
3. Ask the isolation question
|
||||
4. Register — no package or credential changes needed
|
||||
|
||||
## Change Wiring
|
||||
|
||||
1. Show current wiring
|
||||
2. Ask which channel to move and to which agent group
|
||||
3. Delete the old `messaging_group_agents` entry, create a new one
|
||||
4. Note: existing sessions stay with the old agent group; new messages route to the new one
|
||||
|
||||
## Show Configuration
|
||||
|
||||
Display a readable summary showing agent groups with their wired channels, configured-but-unwired channels, and unconfigured channels.
|
||||
@@ -260,7 +260,7 @@ AskUserQuestion (multiSelect): Which messaging channels do you want to enable?
|
||||
|
||||
For each selected channel, invoke its skill:
|
||||
|
||||
- **Discord:** Invoke `/add-discord`
|
||||
- **Discord:** Invoke `/add-discord-v2`
|
||||
- **Slack:** Invoke `/add-slack-v2`
|
||||
- **Telegram:** Invoke `/add-telegram-v2`
|
||||
- **GitHub:** Invoke `/add-github-v2`
|
||||
@@ -286,7 +286,18 @@ Each skill will:
|
||||
npm install && npm run build
|
||||
```
|
||||
|
||||
If the build fails, read the error output and fix it (usually a missing dependency). Then continue to step 6.
|
||||
If the build fails, read the error output and fix it (usually a missing dependency). Then continue to step 5a.
|
||||
|
||||
## 5a. Wire Channels to Agent Groups
|
||||
|
||||
Invoke `/manage-channels` to wire the installed channels to agent groups. This step:
|
||||
1. Creates the agent group(s) and assigns a name to the assistant
|
||||
2. Asks for each channel's platform-specific ID (guided by channel-specific instructions)
|
||||
3. Decides the isolation level — whether channels share an agent, session, or are fully separate
|
||||
|
||||
The `/manage-channels` skill reads each channel's `## Channel Info` section from its SKILL.md for platform-specific guidance (terminology, how to find IDs, recommended isolation).
|
||||
|
||||
**This step is required.** Without it, channels are installed but not wired — messages will be silently dropped because the router has no agent group to route to.
|
||||
|
||||
## 6. Mount Allowlist
|
||||
|
||||
@@ -334,7 +345,7 @@ Run `npx tsx setup/index.ts --step verify` and parse the status block.
|
||||
- SERVICE=not_found → re-run step 7
|
||||
- CREDENTIALS=missing → re-run step 4 (Docker: check `onecli secrets list`; Apple Container: check `.env` for credentials)
|
||||
- CHANNEL_AUTH shows `not_found` for any channel → re-invoke that channel's skill (e.g. `/add-telegram`)
|
||||
- REGISTERED_GROUPS=0 → re-invoke the channel skills from step 5
|
||||
- REGISTERED_GROUPS=0 → re-invoke `/manage-channels` from step 5a
|
||||
- MOUNT_ALLOWLIST=missing → `npx tsx setup/index.ts --step mounts -- --empty`
|
||||
|
||||
Tell user to test: send a message in their registered chat. Show: `tail -f logs/nanoclaw.log`
|
||||
|
||||
@@ -55,8 +55,10 @@ Status: [x] done, [~] partial, [ ] not started
|
||||
- [~] iMessage via Chat SDK (adapter + skill written, not tested)
|
||||
- [x] Backward compatibility with native channels (old adapters still work)
|
||||
- [x] Channel barrel wired (src/index.ts imports barrel, skills uncomment)
|
||||
- [~] Setup flow wired to v2 channels (register.ts + verify.ts updated, but channel skills don't call register yet — see docs/v2-setup-wiring.md)
|
||||
- [ ] Setup communicates each group is a different agent, distinct names
|
||||
- [x] Setup flow wired to v2 channels (channel skills + /manage-channels for registration + verify.ts checks all tokens)
|
||||
- [x] Channel Info metadata in each channel skill (type, terminology, how-to-find-id, isolation defaults)
|
||||
- [x] /manage-channels skill (wire channels to agent groups with three isolation levels)
|
||||
- [x] Agent-shared session mode (cross-channel shared sessions, e.g. GitHub + Slack)
|
||||
- [ ] Setup vs production channel separation
|
||||
- [ ] Generate visual diagram of customized instance at end of setup
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# Channel Isolation Model
|
||||
|
||||
NanoClaw v2 decouples messaging channels from agent groups. When you connect a channel (Discord, Telegram, Slack, GitHub, etc.), you decide how it relates to your existing agents. There are three isolation levels.
|
||||
|
||||
## The Three Levels
|
||||
|
||||
### 1. Shared Session
|
||||
|
||||
Multiple channels feed into the same conversation. The agent sees all messages from all channels in one thread.
|
||||
|
||||
**What's shared:** Everything — workspace, memory, CLAUDE.md, and the conversation itself. A GitHub PR comment and a Slack message appear side by side in the agent's context.
|
||||
|
||||
**Example:** A Slack channel paired with GitHub webhooks. The agent receives PR review requests via GitHub and discusses them in Slack — all in one session. When someone comments on a PR, the agent can reference the earlier Slack discussion about that feature.
|
||||
|
||||
**When to use:** When one channel feeds context into another. Webhook/notification channels (GitHub, Linear) paired with a chat channel (Slack, Discord) are the classic case.
|
||||
|
||||
**Technical:** Both messaging groups are wired to the same agent group with `session_mode: 'agent-shared'`. Session resolution looks up by agent group ID only, ignoring the messaging group — so all channels converge on one session.
|
||||
|
||||
---
|
||||
|
||||
### 2. Same Agent, Separate Sessions
|
||||
|
||||
Multiple channels share the same agent (same workspace, memory, personality) but have independent conversations.
|
||||
|
||||
**What's shared:** Workspace, memory, CLAUDE.md, and all persistent state. If you tell the agent something in one session, it can save that to memory and recall it in another. The agent's personality, knowledge, and tools are identical across sessions.
|
||||
|
||||
**What's separate:** The conversation thread. Messages from one channel don't appear in the other channel's session. Each channel has its own context window and conversation history.
|
||||
|
||||
**Example:** You have three Telegram chats with your agent — one for a side project, one for personal tasks, one for work. All three share the same agent workspace. If you ask it to remember your API key naming convention in the project chat, it may recall that convention in the work chat too. But the conversations themselves are independent.
|
||||
|
||||
**When to use:** When you're the primary (or sole) participant across channels and you want a unified agent identity. This is the most common setup for personal use across multiple platforms or multiple groups within one platform.
|
||||
|
||||
**Technical:** Multiple messaging groups are wired to the same agent group with `session_mode: 'shared'` (or `'per-thread'`). Each messaging group gets its own session, but they all run in the same agent group folder.
|
||||
|
||||
---
|
||||
|
||||
### 3. Separate Agent Groups
|
||||
|
||||
Each channel gets its own agent with its own workspace, memory, and personality. Nothing is shared.
|
||||
|
||||
**What's shared:** Nothing. The agents don't know about each other. Different CLAUDE.md, different memory, different workspace, different conversation history.
|
||||
|
||||
**Example:** You have a Telegram group with a friend and a Discord server for a team project. The friend shouldn't know what you discuss with your team, and vice versa. Each gets its own agent with its own memory and personality.
|
||||
|
||||
**When to use:** When different people are involved, or when the information in one channel should never leak to another. This is the right choice whenever there's a privacy or confidentiality boundary between channels.
|
||||
|
||||
**Technical:** Each channel is wired to a different agent group, each with its own folder under `groups/`. Separate containers, separate session databases, separate everything.
|
||||
|
||||
---
|
||||
|
||||
## How to Decide
|
||||
|
||||
The key question: **Are you okay with any and every piece of information from one channel being available in the other?**
|
||||
|
||||
- **No** → Separate agent groups (level 3)
|
||||
- **Yes, and the channels should see each other's messages** → Shared session (level 1)
|
||||
- **Yes, but the conversations should be independent** → Same agent, separate sessions (level 2)
|
||||
|
||||
### Rules of Thumb
|
||||
|
||||
| Scenario | Recommended Level |
|
||||
|----------|------------------|
|
||||
| Just you, multiple platforms (Telegram + Discord + Slack) | Same agent, separate sessions |
|
||||
| Just you, multiple groups on one platform (3 Telegram chats) | Same agent, separate sessions |
|
||||
| Webhook channel + chat channel (GitHub + Slack) | Shared session |
|
||||
| Channel with friend A and channel with friend B | Separate agent groups |
|
||||
| Personal channel and work channel | Separate agent groups |
|
||||
| Team channel with different access levels | Separate agent groups |
|
||||
|
||||
### When in Doubt
|
||||
|
||||
If the participants are the same across channels → same agent group is usually fine.
|
||||
|
||||
If different people are involved → separate agent groups. Information will cross-pollinate through agent memory if you don't.
|
||||
|
||||
## Entity Model
|
||||
|
||||
```
|
||||
agent_groups (workspace, memory, CLAUDE.md, personality)
|
||||
↕ many-to-many
|
||||
messaging_groups (a specific channel/chat/group on a platform)
|
||||
via
|
||||
messaging_group_agents (session_mode, trigger_rules, priority)
|
||||
```
|
||||
|
||||
- **Shared session:** multiple messaging_groups → same agent_group, `session_mode = 'agent-shared'`
|
||||
- **Same agent, separate sessions:** multiple messaging_groups → same agent_group, `session_mode = 'shared'`
|
||||
- **Separate agents:** each messaging_group → different agent_group
|
||||
+13
-58
@@ -37,76 +37,31 @@ Last updated: 2026-04-09, branch `v2`, commit `1dc5750`
|
||||
|
||||
---
|
||||
|
||||
## What's NOT Done — Remaining Work for Fresh Install
|
||||
## Previously Open — Now Resolved
|
||||
|
||||
### 1. v2 Channel Skills Don't Register Groups
|
||||
### 1. ~~v2 Channel Skills Don't Register Groups~~ ✅
|
||||
|
||||
**Problem:** The v2 channel skills (`.claude/skills/add-telegram-v2/SKILL.md`, `add-slack-v2`, `add-linear-v2`, etc.) only do:
|
||||
- Install npm package
|
||||
- Uncomment barrel import
|
||||
- Collect credentials → write to `.env`
|
||||
- Build and verify
|
||||
Channel skills now point to `/manage-channels` in their "Next Steps" section. Registration is handled by the `/manage-channels` skill, which reads each channel's `## Channel Info` section for platform-specific guidance. Channel skills stay lean (credentials only).
|
||||
|
||||
They do NOT create agent groups, messaging groups, or wiring in the v2 central DB. Without these DB entities, the router auto-creates a `messaging_group` on first message but finds no `messaging_group_agents` → message is silently dropped (now logged as WARN).
|
||||
### 2. ~~v1 add-discord Skill is Incompatible~~ ✅
|
||||
|
||||
**Fix needed:** Each v2 channel skill needs a registration phase that calls:
|
||||
```bash
|
||||
npx tsx setup/index.ts --step register -- \
|
||||
--platform-id "<channel-id>" \
|
||||
--name "<group-name>" \
|
||||
--folder "<agent-folder>" \
|
||||
--trigger "@BotName" \
|
||||
--channel <channel-type> \
|
||||
--is-main # (if this is the primary group)
|
||||
```
|
||||
Created `/add-discord-v2` skill matching the v2 pattern. Setup SKILL.md updated to reference `/add-discord-v2`.
|
||||
|
||||
Or alternatively, add a dedicated "register groups" step to `setup/SKILL.md` between step 5 (channels) and step 6 (mounts). This step would:
|
||||
1. Ask the user how many agent groups they want
|
||||
2. For each group: name, folder, which channels it handles, trigger pattern, session mode
|
||||
3. Call `setup/register.ts` for each
|
||||
### 3. ~~Setup SKILL.md Missing Group Registration Step~~ ✅
|
||||
|
||||
### 2. v1 add-discord Skill is Incompatible
|
||||
Added step 5a "Wire Channels to Agent Groups" between channel installation (step 5) and mount allowlist (step 6). This step invokes `/manage-channels` which handles agent group creation, isolation level decisions, and wiring.
|
||||
|
||||
**Problem:** Setup SKILL.md line 263 references `/add-discord` (v1 skill). This skill:
|
||||
- Tries to merge a branch (`feat/discord`)
|
||||
- Uses `--jid "dc:<id>"` format
|
||||
- References `store/messages.db` for verification
|
||||
- Creates a v1 DiscordChannel class (we now use Chat SDK)
|
||||
### 4. ~~Channel Skills Should Know Channel Type~~ ✅
|
||||
|
||||
**Fix needed:** Either:
|
||||
- Create a `/add-discord-v2` skill matching the pattern of other v2 skills
|
||||
- Or update the existing `/add-discord` skill for v2
|
||||
- Update `setup/SKILL.md` line 263 to reference the correct skill
|
||||
Each v2 channel skill now has a `## Channel Info` structured section with: type, terminology, how-to-find-id, supports-threads, typical-use, default-isolation. The `/manage-channels` skill reads this for contextual recommendations.
|
||||
|
||||
### 3. Setup SKILL.md Missing Group Registration Step
|
||||
### 5. ~~Verify Step Channel Auth Check~~ ✅
|
||||
|
||||
**Problem:** The setup flow (steps 0-9) has no step for creating agent groups. Channels get configured (step 5) but nobody creates the v2 entities needed for routing.
|
||||
`setup/verify.ts` now checks all v2 channel tokens: DISCORD_BOT_TOKEN, TELEGRAM_BOT_TOKEN, SLACK_BOT_TOKEN+SLACK_APP_TOKEN, GITHUB_TOKEN, LINEAR_API_KEY, GCHAT_CREDENTIALS, TEAMS_APP_ID+TEAMS_APP_PASSWORD, WEBEX_BOT_TOKEN, MATRIX_ACCESS_TOKEN, RESEND_API_KEY, WHATSAPP_ACCESS_TOKEN, IMESSAGE_ENABLED, plus WhatsApp Baileys auth dir.
|
||||
|
||||
**Fix needed:** Add a step (probably between current step 5 and 6, or as part of step 5) that:
|
||||
1. Asks "What do you want to name your assistant?" (already partially handled by `--assistant-name`)
|
||||
2. Asks which channel+platform-id is the primary/admin channel
|
||||
3. Creates the agent_group with `is_admin=1`
|
||||
4. Creates messaging_group + messaging_group_agents wiring
|
||||
5. Optionally creates additional non-admin agent groups
|
||||
### 6. Agent-Shared Session Mode ✅
|
||||
|
||||
The v1 flow embedded this in each channel skill's "Register" phase. The v2 flow should either do the same (add register calls to each v2 channel skill) or centralize it.
|
||||
|
||||
### 4. Setup Groups Step (`setup/groups.ts`)
|
||||
|
||||
Check if `setup/groups.ts` exists and what it does. It may need updating for v2 or may need to be created.
|
||||
|
||||
### 5. Channel Skills Should Know Channel Type
|
||||
|
||||
Each v2 channel skill knows its channel type (discord, telegram, slack, etc.) but the registration args need the platform-specific channel/group ID which the user must provide. The skill should ask for this during Phase 3 (Setup) and then call register.
|
||||
|
||||
### 6. Verify Step Channel Auth Check
|
||||
|
||||
`setup/verify.ts` currently checks for a limited set of channel tokens:
|
||||
- TELEGRAM_BOT_TOKEN, SLACK_BOT_TOKEN, SLACK_APP_TOKEN, DISCORD_BOT_TOKEN
|
||||
- WhatsApp auth dir
|
||||
|
||||
It should also check for v2 channel tokens:
|
||||
- GITHUB_TOKEN, LINEAR_API_KEY, GCHAT_CREDENTIALS, TEAMS_APP_PASSWORD, etc.
|
||||
Added `session_mode: 'agent-shared'` for cross-channel shared sessions (e.g. GitHub + Slack in one conversation). Session resolution looks up by agent_group_id instead of messaging_group_id when this mode is set.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+25
-14
@@ -112,29 +112,40 @@ export async function run(_args: string[]): Promise<void> {
|
||||
'SLACK_BOT_TOKEN',
|
||||
'SLACK_APP_TOKEN',
|
||||
'DISCORD_BOT_TOKEN',
|
||||
'GITHUB_TOKEN',
|
||||
'LINEAR_API_KEY',
|
||||
'GCHAT_CREDENTIALS',
|
||||
'TEAMS_APP_ID',
|
||||
'TEAMS_APP_PASSWORD',
|
||||
'WEBEX_BOT_TOKEN',
|
||||
'MATRIX_ACCESS_TOKEN',
|
||||
'RESEND_API_KEY',
|
||||
'WHATSAPP_ACCESS_TOKEN',
|
||||
'IMESSAGE_ENABLED',
|
||||
]);
|
||||
|
||||
const has = (key: string) => !!(process.env[key] || envVars[key]);
|
||||
const channelAuth: Record<string, string> = {};
|
||||
|
||||
// WhatsApp: check for auth credentials on disk
|
||||
// WhatsApp Baileys: check for auth credentials on disk
|
||||
const authDir = path.join(projectRoot, 'store', 'auth');
|
||||
if (fs.existsSync(authDir) && fs.readdirSync(authDir).length > 0) {
|
||||
channelAuth.whatsapp = 'authenticated';
|
||||
}
|
||||
|
||||
// Token-based channels: check .env
|
||||
if (process.env.TELEGRAM_BOT_TOKEN || envVars.TELEGRAM_BOT_TOKEN) {
|
||||
channelAuth.telegram = 'configured';
|
||||
}
|
||||
if (
|
||||
(process.env.SLACK_BOT_TOKEN || envVars.SLACK_BOT_TOKEN) &&
|
||||
(process.env.SLACK_APP_TOKEN || envVars.SLACK_APP_TOKEN)
|
||||
) {
|
||||
channelAuth.slack = 'configured';
|
||||
}
|
||||
if (process.env.DISCORD_BOT_TOKEN || envVars.DISCORD_BOT_TOKEN) {
|
||||
channelAuth.discord = 'configured';
|
||||
}
|
||||
// Token-based channels
|
||||
if (has('DISCORD_BOT_TOKEN')) channelAuth.discord = 'configured';
|
||||
if (has('TELEGRAM_BOT_TOKEN')) channelAuth.telegram = 'configured';
|
||||
if (has('SLACK_BOT_TOKEN') && has('SLACK_APP_TOKEN')) channelAuth.slack = 'configured';
|
||||
if (has('GITHUB_TOKEN')) channelAuth.github = 'configured';
|
||||
if (has('LINEAR_API_KEY')) channelAuth.linear = 'configured';
|
||||
if (has('GCHAT_CREDENTIALS')) channelAuth.gchat = 'configured';
|
||||
if (has('TEAMS_APP_ID') && has('TEAMS_APP_PASSWORD')) channelAuth.teams = 'configured';
|
||||
if (has('WEBEX_BOT_TOKEN')) channelAuth.webex = 'configured';
|
||||
if (has('MATRIX_ACCESS_TOKEN')) channelAuth.matrix = 'configured';
|
||||
if (has('RESEND_API_KEY')) channelAuth.resend = 'configured';
|
||||
if (has('WHATSAPP_ACCESS_TOKEN')) channelAuth['whatsapp-cloud'] = 'configured';
|
||||
if (has('IMESSAGE_ENABLED')) channelAuth.imessage = 'configured';
|
||||
|
||||
const configuredChannels = Object.keys(channelAuth);
|
||||
const anyChannelConfigured = configuredChannels.length > 0;
|
||||
|
||||
@@ -11,7 +11,7 @@ export interface ConversationConfig {
|
||||
agentGroupId: string;
|
||||
triggerPattern?: string; // regex string (for native channels)
|
||||
requiresTrigger: boolean;
|
||||
sessionMode: 'shared' | 'per-thread';
|
||||
sessionMode: 'shared' | 'per-thread' | 'agent-shared';
|
||||
}
|
||||
|
||||
/** Passed to the adapter at setup time. */
|
||||
|
||||
@@ -27,6 +27,13 @@ export function findSession(messagingGroupId: string, threadId: string | null):
|
||||
.get(messagingGroupId, 'active') as Session | undefined;
|
||||
}
|
||||
|
||||
/** Find an active session scoped to an agent group (ignoring messaging group). */
|
||||
export function findSessionByAgentGroup(agentGroupId: string): Session | undefined {
|
||||
return getDb()
|
||||
.prepare("SELECT * FROM sessions WHERE agent_group_id = ? AND status = 'active' ORDER BY created_at DESC LIMIT 1")
|
||||
.get(agentGroupId) as Session | undefined;
|
||||
}
|
||||
|
||||
export function getSessionsByAgentGroup(agentGroupId: string): Session[] {
|
||||
return getDb().prepare('SELECT * FROM sessions WHERE agent_group_id = ?').all(agentGroupId) as Session[];
|
||||
}
|
||||
|
||||
+22
-9
@@ -11,7 +11,7 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { DATA_DIR } from './config.js';
|
||||
import { createSession, findSession, getSession, updateSession } from './db/sessions.js';
|
||||
import { createSession, findSession, findSessionByAgentGroup, getSession, updateSession } from './db/sessions.js';
|
||||
import { log } from './log.js';
|
||||
import { INBOUND_SCHEMA, OUTBOUND_SCHEMA } from './db/schema.js';
|
||||
import type { Session } from './types.js';
|
||||
@@ -55,22 +55,35 @@ function generateId(): string {
|
||||
|
||||
/**
|
||||
* Find or create a session for a messaging group + thread.
|
||||
* Returns the session and whether it was newly created.
|
||||
*
|
||||
* Session modes:
|
||||
* - 'shared': one session per messaging group (ignores threadId)
|
||||
* - 'per-thread': one session per (messaging group, thread)
|
||||
* - 'agent-shared': one session per agent group — all messaging groups
|
||||
* wired with this mode share a single session (e.g. GitHub + Slack)
|
||||
*/
|
||||
export function resolveSession(
|
||||
agentGroupId: string,
|
||||
messagingGroupId: string,
|
||||
threadId: string | null,
|
||||
sessionMode: 'shared' | 'per-thread',
|
||||
sessionMode: 'shared' | 'per-thread' | 'agent-shared',
|
||||
): { session: Session; created: boolean } {
|
||||
const lookupThreadId = sessionMode === 'shared' ? null : threadId;
|
||||
const existing = findSession(messagingGroupId, lookupThreadId);
|
||||
|
||||
if (existing) {
|
||||
return { session: existing, created: false };
|
||||
// agent-shared: single session per agent group, regardless of messaging group
|
||||
if (sessionMode === 'agent-shared') {
|
||||
const existing = findSessionByAgentGroup(agentGroupId);
|
||||
if (existing) {
|
||||
return { session: existing, created: false };
|
||||
}
|
||||
} else {
|
||||
const lookupThreadId = sessionMode === 'shared' ? null : threadId;
|
||||
const existing = findSession(messagingGroupId, lookupThreadId);
|
||||
if (existing) {
|
||||
return { session: existing, created: false };
|
||||
}
|
||||
}
|
||||
|
||||
const id = generateId();
|
||||
const lookupThreadId = sessionMode === 'per-thread' ? threadId : null;
|
||||
const session: Session = {
|
||||
id,
|
||||
agent_group_id: agentGroupId,
|
||||
@@ -85,7 +98,7 @@ export function resolveSession(
|
||||
|
||||
createSession(session);
|
||||
initSessionFolder(agentGroupId, id);
|
||||
log.info('Session created', { id, agentGroupId, messagingGroupId, threadId: lookupThreadId });
|
||||
log.info('Session created', { id, agentGroupId, messagingGroupId, threadId: lookupThreadId, sessionMode });
|
||||
|
||||
return { session, created: true };
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ export interface MessagingGroupAgent {
|
||||
agent_group_id: string;
|
||||
trigger_rules: string | null; // JSON: { pattern, mentionOnly, excludeSenders, includeSenders }
|
||||
response_scope: 'all' | 'triggered' | 'allowlisted';
|
||||
session_mode: 'shared' | 'per-thread';
|
||||
session_mode: 'shared' | 'per-thread' | 'agent-shared';
|
||||
priority: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user