Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/nanocoai/nanoclaw-opencode --skill add-slack명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | add-slack |
| description | Add Slack channel integration via Chat SDK. |
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; 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).
Fetch the channels branch and copy the payload into place (overwrite — the branch is canonical):
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-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
slack.ts, slack-lib.ts): bridge registration, wiring defaults, conversation resolver, the native SLACK_INSTANCES loop — pinned by the two registration tests.slack-a2a-guard.ts): drops bot-authored inbound at the bridge by default; feature skills register a narrower admission policy on its seam.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.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.
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:
import './slack.js';
import './slack-a2a-guard.js';
Pinned exactly — the supply-chain policy rejects ranges and latest:
@chat-adapter/slack@4.29.0
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.
pnpm run build
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
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.
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:
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:
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). 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. Install to Workspace, then copy the Bot User OAuth Token (starts with xoxb-).
5. Basic Information → copy the Signing Secret.
Store the secrets in .env (the app-level token doubles as the Socket Mode switch, the signing secret authenticates webhook requests):
Paste the Bot User OAuth Token — OAuth & Permissions, starts with `xoxb-`.
Paste the App-Level Token — Basic Information → App-Level Tokens, starts with `xapp-`.
Paste the App-Level Token of the provisioned app (starts with `xapp-`).
Paste the Signing Secret — Basic Information.
SLACK_BOT_TOKEN={{bot_token}}
SLACK_APP_TOKEN={{app_token}}
SLACK_APP_TOKEN={{app_token}}
SLACK_SIGNING_SECRET={{signing_secret}}
Additional bot identities (optional). The adapter natively reads
SLACK_INSTANCES=<name>[,…] from .env, registering one slack-<name> instance per
name from suffixed keys (SLACK_BOT_TOKEN_<NAME> etc.) — see /slack-multi-instance.
With webhook delivery, the bridge serves port 3000 at /webhook/slack; that
URL must be publicly reachable and registered with Slack. Tell the user:
Set up event delivery (needs a public HTTPS URL for port 3000 — ngrok, a Cloudflare Tunnel, or a reverse proxy on a VPS):
1. Event Subscriptions → Enable Events. Set the Request URL to https://<your-public-host>/webhook/slack and wait for the challenge to pass.
2. Subscribe to bot events: message.channels, message.groups, message.im, app_mention. Save Changes.
3. Interactivity & Shortcuts → toggle Interactivity on, set the same Request URL, Save Changes, then reinstall the app when Slack prompts.
Resolve the owner DM address the owner-wiring step needs; validating the token here, before the restart, fast-fails a bad credential.
Your Slack member ID (Profile → ⋮ → "Copy member ID"; starts with U).
auth.test confirms the bot token works and captures the bot identity:
curl -sf -X POST https://slack.com/api/auth.test -H "Authorization: Bearer {{bot_token}}" | jq -er '"@" + .user + " in " + .team'
conversations.open yields the DM address slack:<channelId> (no channel back = the im:write scope is missing — add it and reinstall):
curl -s -X POST https://slack.com/api/conversations.open -H "Authorization: Bearer {{bot_token}}" -H "Content-Type: application/json" -d '{"users":"{{owner_handle}}"}' | jq -er '"slack:" + .channel.id'
owner_handle and platform_id feed the owner-wiring step. Sending works immediately;
receiving needs the event path (Socket Mode: live after the restart below; webhook: the steps above first).
Restart so the service loads the adapter and secrets; wait for its CLI socket before wiring:
bash setup/lib/restart.sh
Mid-/setup: return to the setup flow. Otherwise wire the channel with /init-first-agent
(or /manage-channels). For the Slack agents feature (child bots from
create_agent, shared rooms, canvases), apply /slack-a2a-rooms then
/slack-agent-flow — the setup wizard does both automatically by default.
slackslack:{channelId} for channels (e.g., slack:C0123ABC), slack:{dmId} for DMs (e.g., slack:D0ARWEBLV63)xoxb- (OAuth & Permissions, after Install to Workspace), the App-Level Token starts xapp- (Basic Information → App-Level Tokens), and the Signing Secret is a hex string (Basic Information). The classic mix-up is pasting a user token (xoxp-) instead of the bot token, or the app's Client Secret instead of the Signing Secret.auth.test fails, or conversations.open returns no channel. A failing auth.test means the bot token is wrong or the app was never installed to the workspace. An empty conversations.open means the im:write scope is missing — add it and reinstall the app; scope changes only take effect after reinstall, which also mints a new xoxb- token to store.SLACK_APP_TOKEN set with connections:write, and the bot events (message.im, message.channels, message.groups, app_mention) subscribed. Webhook: the Request URL must have passed Slack's challenge and the same events subscribed. Either way, App Home's Messages Tab must be enabled or Slack refuses DMs to the app.pnpm exec vitest run src/channels/slack-registration.test.ts — red means the barrel import or the @chat-adapter/slack install drifted, so re-run the Apply steps. If green, restart the service (bash setup/lib/restart.sh) and check logs/nanoclaw.error.log./slack-a2a-rooms + /slack-agent-flow (setup applies both by default). If those skills were applied, check src/modules/index.ts carries their module imports, then restart.