Skip to main content
ClaudeWave
Skill30.7k repo starsupdated yesterday

add-slack

The add-slack skill installs Slack channel integration into a NanoClaw project by copying the Slack adapter from a separate branch, registering it with the Chat SDK bridge, installing the `@chat-adapter/slack` dependency, and validating the setup through build and test commands. Use this skill when setting up a new NanoClaw instance that requires Slack workspace connectivity for message routing and channel management.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/nanocoai/nanoclaw /tmp/add-slack && cp -r /tmp/add-slack/.claude/skills/add-slack ~/.claude/skills/add-slack
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Add Slack Channel

Adds Slack support via the Chat SDK bridge. Trunk ships no channels — this skill
copies the Slack channel layer (adapter, shared lib, bot-inbound guard,
provisioning core, container skills) in from the `channels` branch. The **Apply**
steps carry `nc:` directive fences (an agent applies the prose, a parser the
directives); all idempotent.

This is the base Slack experience: one bot, DM and channel chat. The Slack
**agents** feature — child bots provisioned from `create_agent`, shared rooms,
canvases, DM onboarding — ships separately in `/slack-a2a-rooms` +
`/slack-agent-flow`, in-tree under `.claude/skills/` (their canonical home;
the channels branch keeps a compatibility copy for older checkouts). The
setup wizard applies them automatically, and they can be applied on top of
this install at any time.
Existing classic installs that want the Slack agents experience should use
`/migrate-slack-agents` rather than re-running this skill (classic keeps
working; that migration is optional).

## Apply

### 1. Copy the channel payload

Fetch the `channels` branch and copy the payload into place (overwrite — the branch is canonical):
```nc:copy from-branch:channels
src/channels/slack.ts
src/channels/slack-lib.ts
src/channels/slack-lib.test.ts
src/channels/slack-a2a-guard.ts
src/channels/slack-a2a-guard.test.ts
src/channels/slack-raw-text.ts
src/channels/slack-raw-text.test.ts
src/channels/slack-registration.test.ts
src/channels/slack-instances-registration.test.ts
src/provisioning/slack-app.ts
src/provisioning/slack-app.test.ts
container/skills/slack-formatting/SKILL.md
```

- **Adapter + shared lib** (`slack.ts`, `slack-lib.ts`): bridge registration, wiring defaults, conversation resolver, the native `SLACK_INSTANCES` loop — pinned by the two registration tests.
- **Bot-inbound guard** (`slack-a2a-guard.ts`): drops bot-authored inbound at the bridge by default; feature skills register a narrower admission policy on its seam.
- **Raw-text recovery** (`slack-raw-text.ts`): recovers pasted tables, which Slack delivers as attachment blocks in `message.raw` rather than as text — `slack.ts` imports it directly, so it travels with the adapter.
- **Provisioning core** (`src/provisioning/slack-app.ts`): manifest template, scope/event constants, and the broker + manager-token transports for creating a Slack app programmatically. Nothing on the adapter path imports it — the setup wizard's auto-provision pre-step and feature skills do.
- **Container skills**: `slack-formatting/` (mrkdwn syntax; synced to `~/.claude/skills`).

The room/canvas/onboarding host modules, their container files, and the Slack
welcome-tour addendum (it describes rooms, canvases, and the agents access
model) are part of the agents feature and install with `/slack-agent-flow`,
not here.

### 2. Register the payload

Append the self-registration imports (each append is skipped if its first
line is already present). The adapter and the guard, in the channel barrel:
```nc:append to:src/channels/index.ts
import './slack.js';
```
```nc:append to:src/channels/index.ts
import './slack-a2a-guard.js';
```

### 3. Install the adapter package

Pinned exactly — the supply-chain policy rejects ranges and `latest`:
```nc:dep
@chat-adapter/slack@4.29.0
```

### 4. Build and validate

The build guards the typed `createChatSdkBridge(...)` call and proves the dependency
installed; the tests pin registration (barrel import, dependency, the `SLACK_INSTANCES`
loop), the guard, the shared lib, and the provisioning core.
```nc:run effect:build
pnpm run build
```
```nc:run effect:test
pnpm exec vitest run src/channels/slack-registration.test.ts src/channels/slack-instances-registration.test.ts src/channels/slack-lib.test.ts src/channels/slack-a2a-guard.test.ts src/provisioning/slack-app.test.ts
```

## Credentials

Socket Mode (an outbound WebSocket — no public URL, the right default behind NAT)
vs webhook delivery (needs a public HTTPS Request URL); the adapter picks Socket
Mode automatically whenever `SLACK_APP_TOKEN` is set.
```nc:prompt connection validate:^(socket|webhook|provisioned)$ choices:socket|webhook
How should Slack deliver events? `socket` (Socket Mode — no public URL, recommended for local or behind-NAT installs) or `webhook` (needs a public HTTPS Request URL).
```

`provisioned` is never offered interactively (`choices:` limits the select;
`validate:` stays wider because pre-bound inputs may exceed the offered set) —
it arrives only via pre-bound `inputs` (a programmatically created app) and
behaves like Socket Mode minus the walkthrough below.

For Socket Mode, tell the user:
```nc:operator when:connection=socket
Create the Slack app (Socket Mode):
1. Go to api.slack.com/apps and create a new app using whichever creation flow is currently available (e.g. starting from scratch or from a manifest). Name it (e.g. "NanoClaw") and pick your workspace.
2. OAuth & Permissions → add these Bot Token Scopes: chat:write, im:write, channels:history, groups:history, im:history, channels:read, groups:read, mpim:read, users:read, reactions:write, files:read, files:write.
3. App Home → enable the Messages Tab, and check "Allow users to send Slash commands and messages from the messages tab."
4. Basic Information → App-Level Tokens → "Generate Token and Scopes" → add the connections:write scope → copy the token (starts with xapp-).
5. Socket Mode → toggle "Enable Socket Mode" on.
6. Event Subscriptions → toggle "Enable Events" on, then under "Subscribe to bot events" add: message.channels, message.groups, message.im, app_mention. Save Changes. (No Request URL is needed in Socket Mode.)
7. Install to Workspace, then copy the Bot User OAuth Token (starts with xoxb-).
```

For webhook delivery, tell the user:
```nc:operator when:connection=webhook
Create the Slack app (webhook delivery):
1. Go to api.slack.com/apps and create a new app using whichever creation flow is currently available (e.g. starting from scratch or from a manifest). Na
add-atomic-chat-toolSkill

Add Atomic Chat MCP server so the container agent can call local models served by the Atomic Chat desktop app via its OpenAI-compatible API.

add-codexSkill

Use Codex (OpenAI's codex app-server) as a full agent provider — planning, tool orchestration, MCP tools, server-side history, session resume — alongside or instead of Claude. ChatGPT subscription or OpenAI API key, vault-only via OneCLI. Per-group via `ncl groups config update --provider codex`. Distinct from using OpenAI as an MCP tool (where Claude remains the planner).

add-dashboardSkill

Add a monitoring dashboard to NanoClaw. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.

add-deltachatSkill

Add DeltaChat channel integration via @deltachat/stdio-rpc-server. Native adapter — no Chat SDK bridge. Email-based messaging with end-to-end encryption.

add-discordSkill

Add Discord bot channel integration via Chat SDK.

add-emacsSkill

Add Emacs as a channel. Opens an interactive chat buffer and org-mode integration so you can talk to NanoClaw from within Emacs (Doom, Spacemacs, or vanilla). Local HTTP bridge — no bot token or external service needed.

add-gcal-toolSkill

Add Google Calendar as an MCP tool (list calendars, list/search/create events, free/busy queries) using OneCLI-managed OAuth. Multi-calendar and multi-account supported. Mirrors /add-gmail-tool's stub pattern — no raw credentials ever reach the container; OneCLI injects real tokens at request time.

add-gchatSkill

Add Google Chat channel integration via Chat SDK.