com um clique
install
// CCSC lifecycle command center — fresh install walkthrough, health doctor, verify round-trip, auto-repair, Slack app manifest export, reset, tour, and uninstall. One skill for the full install lifecycle.
// CCSC lifecycle command center — fresh install walkthrough, health doctor, verify round-trip, auto-repair, Slack app manifest export, reset, tour, and uninstall. One skill for the full install lifecycle.
Manage Slack channel access control — pairing, allowlist, channel opt-in
Configure Slack channel tokens (bot token + app-level token)
Author MCP tool-call policy rules without hand-editing access.json
| name | install |
| description | CCSC lifecycle command center — fresh install walkthrough, health doctor, verify round-trip, auto-repair, Slack app manifest export, reset, tour, and uninstall. One skill for the full install lifecycle. |
| version | 1.0.0 |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| license | Apache-2.0 |
| user-invocable | true |
| argument-hint | [install | doctor | verify | repair | manifest | reset | tour | uninstall] |
| allowed-tools | ["Read","Write","Edit","Bash","WebFetch"] |
CCSC lifecycle command center. One skill, eight modes — fresh install through teardown. No subcommand defaults to the full install walkthrough.
/slack-channel:install [mode]
Modes:
install full fresh-clone walkthrough (default) ← new user starts here
doctor run a health check against an existing install
verify run the verification round-trip only
repair auto-fix common issues surfaced by doctor
manifest export a Slack app manifest.json (one-click import — saves 10 min of scope clicking)
reset wipe state and restart from Step 3 (keeps Slack app)
tour explain CCSC features without installing (for evaluators)
uninstall clean teardown — remove state dir, optionally guide Slack app deletion
This skill orchestrates. It delegates token configuration to
/slack-channel:configure and pairing to /slack-channel:access pair —
do not re-implement those.
Parse the first word of $ARGUMENTS. If empty or install, run install.
Otherwise dispatch to the matching mode. Unknown modes show the help block
above and exit.
install (default)End-to-end fresh-clone walkthrough.
┌────────────────────────────────────────────────────────┐
│ 0. Prerequisite check (Bun, Claude Code, claude.ai) │
│ 1. Slack app creation (or skip → /install manifest) │
│ 2. Add bot to channel ← THE silent killer step │
│ 3. Configure tokens → /slack-channel:configure │
│ 4. Start MCP server │
│ 5. Pair account → /slack-channel:access pair │
│ 6. Verification round-trip │
│ 7. Offer optional next steps │
└────────────────────────────────────────────────────────┘
See references/prerequisites.md for the
exact commands and recovery paths. Three checks in order:
bun --version. If missing, show install command (Node fallback is fine — see prerequisites doc).claude --version. Older versions cannot load Channels.claude.ai login (NOT API-key-only): Channels is Research Preview and rejects pure API-key auth. If ANTHROPIC_API_KEY is set but no claude.ai session exists, instruct claude login.If any check fails, give the recovery command, wait for the user to fix, then re-check. Don't proceed with broken prerequisites.
Two paths: offer the manifest path (faster) or walk the manual UI:
/slack-channel:install manifest first to download
a slack-app-manifest.json, then at https://api.slack.com/apps click
Create New App → From an app manifest and paste it. All 8 scopes
and 4 event subscriptions are pre-configured. User just clicks
Install to Workspace and copies the two tokens.references/slack-app-setup.md for
the full step-by-step.Tokens stay in a scratch buffer at this point — they're written to disk in Step 3.
Most common silent failure. Slack installs apps to the workspace without joining channels. The pairing DM (Step 5) works because DMs auto-route, but a channel test message (Step 6) hits silence — the bot literally isn't in the channel to see the event.
Walk the user:
Private channels need explicit invitation. If multiple channels, repeat. Wait for confirmation before proceeding.
Delegate:
/slack-channel:configure <xoxb-...> <xapp-...>
That skill validates token prefixes, writes ~/.claude/channels/slack/.env
with 0o600 permissions, never echoes tokens back. Do not re-implement.
bun install # if not already
claude --channels plugin:slack-channel@claude-code-plugins
Node.js or Docker alternatives: see README.md § Quick Start Options B/C.
/slack-channel:access pair <code>.User sends @<bot> hello in the channel from Step 2.
/slack-channel:install doctor to diagnose, then
/slack-channel:install repair to fix.Ask the user if they want any of these:
| Want | Run |
|---|---|
| Author a custom policy rule | /slack-channel:policy |
| Enable signed audit log (Ed25519) | bun scripts/audit-key.ts init — see 000-docs/key-management.md |
| Wire in a second bot (multi-agent) | See 000-docs/multi-agent-channels.md |
| Tighten access (allowlist mode) | /slack-channel:access policy allowlist, then add <user-id> per user |
| Run a health check anytime | /slack-channel:install doctor |
doctorHealth check an existing install. Reports a structured pass/fail per check,
no mutations. Suggests /slack-channel:install repair if fixable issues
are found.
The doctor checks below shell out to curl and jq. curl is preinstalled
on virtually every dev system; jq may not be. Verify before running:
command -v curl >/dev/null && command -v jq >/dev/null || echo "Install jq: brew install jq (macOS) | sudo apt install jq (Debian/Ubuntu)"
The checks also need $SLACK_BOT_TOKEN and $SLACK_APP_TOKEN in the
environment. Load them from the user's .env before running any check
that references them:
set -a; . ~/.claude/channels/slack/.env; set +a
If the user prefers not to export the tokens (some shells leak env to child processes / process listings), substitute the literal token values inline — the doctor commands tolerate either form.
Run all in order:
~/.claude/channels/slack/ is a directory with mode 0700..env exists, is mode 0600, owned by current user..env contains both tokens with valid prefixes (xoxb- and xapp-).curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" https://slack.com/api/auth.test | jq -e '.ok == true'. Reports the bot_id and team if live; "invalid_auth" / "token_revoked" / "account_inactive" if not.connections:write: curl -s -X POST -H "Authorization: Bearer $SLACK_APP_TOKEN" https://slack.com/api/apps.connections.open | jq -e '.ok == true and (.url | startswith("wss://"))'. Expects ok: true and a wss:// URL. Failure modes: "not_authed" (token missing), "missing_scope" (token lacks connections:write), "token_revoked" (regenerate).access.json exists, is mode 0600, parses as valid JSON: [ -f ~/.claude/channels/slack/access.json ] && jq empty ~/.claude/channels/slack/access.json.allowFrom is non-empty: jq -e '.allowFrom | length > 0' ~/.claude/channels/slack/access.json. If empty, user has not completed Step 5.audit.log exists, run bun server.ts --verify-audit-log ~/.claude/channels/slack/audit.log. Report hash-chain status.claude.ai login present: claude --version and claude auth status.access.json.channels: for each opted-in channel, curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" "https://slack.com/api/conversations.members?channel=$CHANNEL_ID" | jq -e --arg bot "$BOT_USER_ID" '.members | index($bot) != null'. THIS catches the silent-killer Step 2 omission.Report format:
✅ State directory /home/.../slack (0700)
✅ Token file .env (0600)
✅ Bot token active — team=acme, bot_id=U0123
✅ App token active — connections:write
✅ Access file access.json (0600, valid JSON)
⚠️ Paired users 0 (run pairing flow — Step 5)
✅ Audit chain verified — 1247 events, no breaks
✅ Claude Code v2.4.1, claude.ai session active
❌ Bot in channel C_OPS opted-in but bot is NOT a member ← silent killer
Fix: open #ops → Integrations → Add an App
Exit code: 0 if all green, 1 if any ⚠️ or ❌. Print
Suggested next: /slack-channel:install repair if any fixable issue.
verifyJust the Step 6 verification round-trip. Useful after repair or after
restarting Claude. Tells the user:
Send
@<bot> helloin any channel where the bot is added. I'll wait up to 30 seconds for a reply event in the journal.
Tail audit.log for the next 30s looking for gate.allowed followed by
reply.sent. Report success or timeout. On timeout, suggest doctor.
repairAuto-fix the issues doctor found that are safely fixable:
| Doctor finding | Repair action |
|---|---|
| State dir missing | mkdir -p ~/.claude/channels/slack && chmod 0700 ~/.claude/channels/slack |
.env perms wrong | chmod 0600 ~/.claude/channels/slack/.env |
access.json perms wrong | chmod 0600 ~/.claude/channels/slack/access.json |
access.json corrupt JSON | TS=$(date +%s); mv ~/.claude/channels/slack/access.json ~/.claude/channels/slack/access.json.broken.$TS && echo '{ "allowFrom": [], "channels": {}, "pending": [] }' > ~/.claude/channels/slack/access.json && chmod 0600 ~/.claude/channels/slack/access.json |
| Audit log hash break | DO NOT repair — surface for incident review (this means tampering or write loss) |
| Bot not in channel | Cannot fix from the terminal — print the exact Slack click-path |
| Token invalid | Cannot fix — instruct user to regenerate at api.slack.com/apps |
NEVER auto-modify access.json content beyond the corrupt-restart case
above. NEVER auto-modify the audit log. Both are append-only / engineer-edit-only.
After repair, re-run doctor and show before/after.
manifestGenerate a Slack app manifest JSON that pre-configures all 8 OAuth scopes and 4 event subscriptions in one import. Saves a fresh user ~10 minutes of UI clicking and eliminates the "did I add the right scopes" failure mode.
Write slack-app-manifest.json to the user's current directory:
{
"display_information": {
"name": "Claude Code Channel",
"description": "Bridge between Claude Code and Slack via Socket Mode + MCP",
"background_color": "#1a1a1a"
},
"features": {
"bot_user": {
"display_name": "Claude Code",
"always_online": true
}
},
"oauth_config": {
"scopes": {
"bot": [
"chat:write",
"channels:history",
"groups:history",
"im:history",
"reactions:write",
"files:read",
"files:write",
"users:read"
]
}
},
"settings": {
"event_subscriptions": {
"bot_events": [
"message.im",
"message.channels",
"message.groups",
"app_mention"
]
},
"interactivity": {
"is_enabled": true
},
"socket_mode_enabled": true,
"org_deploy_enabled": false,
"token_rotation_enabled": false
}
}
Then print:
✅ Wrote slack-app-manifest.json
Next steps:
1. Open https://api.slack.com/apps
2. Click "Create New App" → "From an app manifest"
3. Choose your workspace
4. Paste the contents of slack-app-manifest.json
5. Click "Next" → "Create"
6. On the next screen: "Install to Workspace" → "Allow"
7. Copy the Bot Token (xoxb-...) from "OAuth & Permissions"
8. Copy the App-Level Token (xapp-...) from "Basic Information" → "App-Level Tokens"
(You may need to generate it; required scope: connections:write)
9. Run: /slack-channel:install
(it will pick up from Step 2 — adding the bot to a channel)
resetWipe local state and re-pair, keeping the Slack app intact. Useful when:
access.json (revoked allowlist, etc.)Steps:
~/.claude/channels/slack/access.json
and ~/.claude/channels/slack/sessions/. Tokens (.env) and audit log
stay. Proceed? [y/N]"access.json to access.json.reset.<timestamp> (don't delete — keep one rollback)sessions/ to sessions.reset.<timestamp>/ (archive, never rm -rf — keep one rollback path per the skill's safety invariants)access.json with mode 0600/slack-channel:install from Step 5 (pairing) to re-enroll."NEVER touch audit.log in reset — the journal is permanent record.
NEVER touch .env — Slack tokens are reusable.
tourFor someone evaluating CCSC without installing. No mutations, no prerequisites required. Walk through:
README.md § Security.000-docs/audit-journal-architecture.md.auto_approve / deny / require_approval, two-person integrity, TTL windows. Reference README.md § Policy Engine.allowBotIds, !mute / !unmute. Reference 000-docs/multi-agent-channels.md.ARCHITECTURE.md.End with: "Ready to install? Run /slack-channel:install."
uninstallClean teardown.
~/.claude/channels/slack/ (tokens, access, sessions, audit log)~/.claude/channels/slack.uninstalled.<timestamp>
(don't rm -rf — keep one rollback path)Local state archived to ~/.claude/channels/slack.uninstalled.<timestamp>.
To delete it permanently:
rm -rf ~/.claude/channels/slack.uninstalled.<timestamp>
To revoke the Slack app:
1. Open https://api.slack.com/apps
2. Select your app
3. Settings → Basic Information → scroll down → "Delete App"
OR if you just want to revoke tokens without deleting the app:
- OAuth & Permissions → "Revoke Tokens"
| Mode | Success means |
|---|---|
install | .env exists (0600), user is paired, @bot hello round-trip works |
doctor | All 10 checks reported with pass/warn/fail status; exit code reflects state |
verify | Round-trip succeeds within 30s, journal records gate.allowed + reply.sent |
repair | All fixable findings cleared; doctor re-run shows green or only unfixable issues |
manifest | slack-app-manifest.json written to cwd, instructions printed |
reset | access.json rotated, sessions cleared, .env + audit.log preserved |
tour | User has a mental model of what CCSC does without touching their filesystem |
uninstall | State dir archived, Slack-app deletion instructions printed |
configure handles them; this skill
only orchestrates.~/.claude/channels/slack/.env./slack-channel:access).access.json content beyond the
corrupt-restart case. Never modify audit.log. Both are
append-only / engineer-edit-only.rm -rf. One rollback path
is always preserved.references/prerequisites.md — Bun, Claude Code, claude.ai login check detailsreferences/slack-app-setup.md — Manual Slack app creation step-by-stepreferences/troubleshooting.md — Top silent-failure modes + recovery../configure/SKILL.md — Token configuration (delegated to)../access/SKILL.md — Pairing + allowlist (delegated to)../policy/SKILL.md — Policy authoring (optional next step)../../README.md — Human-readable quick start../../AGENTS.md — Cross-tool agent reference../../ACCESS.md — Full access-control schema../../000-docs/key-management.md — Audit-signing key lifecycle../../000-docs/multi-agent-channels.md — Multi-agent recipe