v0.1.12 · Local-first · MIT
Group chat 「Local Agent」 Whole project
Mention @cc-bot in Slack — Claude Code runs on your laptop, reads the intent, writes the diff itself or dispatches to a specialist. Code, tokens, and shell never leave the machine.
00 — In your workspace
Where cc-bot earns its keep.
Six channels, six jobs. Ask in chat, get an answer, keep working.
-
#bugs
PM drops a screenshot, cc-bot opens a PR.
Maya pastes a 500 screenshot into
#bugs.Bot reads the image, greps the repo, finds a stale migration, opens the PR, replies with the diff.
Why it wins: screenshot, fix, PR — one thread.
-
#deploys
Solo dev ships from the channel.
You type "ship to prod" into
#deploys.deploy_prodisadmin-confirm— bot waits for "yes", deploys, posts the version tag.Why it wins: no SSH, no dashboard, full audit trail.
-
#product
Status without pinging the team.
PM asks "where are we on Feature X?" in
#product.Bot reads the progress doc, cross-refs recent commits, posts a tidy bullet list.
Why it wins: engineer keeps flow, PM gets the answer in 20s.
-
#standup
Standup that writes itself.
At 09:30 a prompt drops in
#standup.Bot diffs 24h of
git log, posts three lines per repo with authors linked.Why it wins: happens whether or not humans show up.
-
#ops-alerts
On-call gets a triage, not just an alert.
Datadog fires a latency alert at 02:14.
Bot queries logs via MCP, threads a probable cause: "p95 spike correlates with the new
ordersreindex."Why it wins: on-call wakes to a starting point, not a mystery.
-
#ship-room
Three devs, three agents — same channel, no clash.
Lin asks for a
rate-limitPR, Maya wants a hero image regen, Kai ships docs to staging — all in#ship-roomwithin a minute.Each request spawns its own Claude Code session under the slot scheduler. Lin's session writes the PR. Maya's dispatches to Nano Banana for the image. Kai's runs the deploy script. HUD lights three lanes side by side.
Why it wins: one project, many hands, zero conflict.
01 — On your machine
Your laptop is the agent.
Slack-native, fully local. cc-bot binds your shell to your IM — every command runs on your own hardware with your own credentials, then writes back to the chat.
-
Yours, end-to-end.
Code, tokens, SSH keys, git remotes — nothing leaves the machine. The IM platform sees the command you typed; everything else stays on disk.
-
Anything you can type, the bot can type.
File system, installed CLIs, the VPN-only Jenkins box, the private mirror behind the firewall. If your terminal reaches it, cc-bot reaches it.
-
Built for the codebases SaaS forgot.
Pre-2020 monorepos, SSH-only build boxes, internal Gerrit, the legacy PHP repo nobody wants to touch. SaaS agents need a clean GitHub repo; cc-bot doesn't.
02 — Capabilities
Seven muscles, one bot.
-
01
Slack-native, IM-agnostic
Socket Mode push — no public webhook, works behind firewalls. The same
IMAdapterpowers Lark. The next adapter is one file.- Slack
- Lark
- Socket Mode
-
02
Defensive delivery
Socket Mode push, dedupe ledger, main-busy queue. Every message delivered exactly once — even when your terminal is mid-edit.
- Socket Mode
- dedupe ledger
- main-busy queue
-
03
Multi-session scheduling
Slots and tags turn parallel Claude Code sessions into a polite queue. Conflicts resolved by config, not chance.
- slot
- tag
- conflict matrix
-
04
HUD status broadcast
The statusline goes live: which agents are busy, which slots are free, last thread. Terminal and Slack agree.
- statusline
- real-time
- shared state
-
05
Three-tier permission matrix
Public reads, admin-auto writes, admin-confirm for the scary ones. Tag the intent once; the bot enforces it forever.
- public
- admin-auto
- admin-confirm
-
06
Main-window priority
A
UserPromptSubmithook lets the dev at the keyboard preempt any background task. Focused — bot waits. Away — it works.- hook
- preempt
- focus-aware
-
07
Claude Code at the helm
Claude Code is the main brain. It reads every intent and either writes the work itself (diffs, PRs) or dispatches to a specialist: Gemini for UI, Nano Banana for design, Seedance for video, DeepSeek for heavy reasoning. Results stitch back into the thread.
- Claude
- Gemini
- Nano Banana
- Seedance
- DeepSeek
03 — Engineering note
One IMAdapter, many group chats.
adapters/base.js defines the contract. Each IM is one file that fulfils it. Slack and Lark ship today; Discord or Teams is a weekend.
Runtime reads profile.im.type, instantiates the adapter, and the rest of the pipeline never knows which IM it's talking to.
// adapters/base.js — the contract every IM implements
class IMAdapter {
listRecentMessages(chat_id, since_ts) { }
sendText(chat_id, text) { }
sendImage(chat_id, file_path) { }
downloadResource(file_id, out_path) { }
getUser(user_id) { }
}
// runtime/poll.js — IM is a config field
const adapter = loadAdapter(profile.im.type)
// → 'slack' loads adapters/slack.js
// → 'lark' loads adapters/lark.js
04 — Architecture
A small idea, drawn carefully.
A thin pipeline. Events in via Socket Mode (Lark polls HTTP). Dedupe ledger guarantees exactly-once. Scheduler hands the message to Claude Code under the right permission tier; Claude Code answers itself or dispatches to a specialist (Gemini · Nano Banana · Seedance · DeepSeek) as the intent demands. Result flows back to channel and HUD together.
Permission matrix
status · tail logsadmin_open_ids (Lark) / admin_user_ids (Slack)compile_preview · run_testsadmin_open_ids (Lark) / admin_user_ids (Slack)deploy_prod · db_migrate05 — Slack setup
Four steps to a chat-driven repo.
/cc-bot:setup runs the whole flow inside Claude Code — idempotent, version-aware, auto-detects what it can.
-
01
Install the cc-bot plugin
# inside Claude Code /plugin marketplace add WaterTian/cc-bot /plugin install cc-bot@cc-botThen run
/cc-bot:setupin any project. When asked "which IM?", pick Slack. -
02
Create the Slack app from the manifest
Open api.slack.com/apps → Create New App → From a manifest. Paste the YAML below.
# templates/slack-manifest.yaml — bot scopes & Socket Mode display_information: name: cc-bot description: Claude Code-powered group project assistant background_color: "#1f3a2a" features: bot_user: display_name: cc-bot always_online: true oauth_config: scopes: bot: - app_mentions:read # listen for @cc-bot - channels:history # read public channels - channels:read - chat:write # post messages - files:read # download images - files:write - groups:history # private channels - groups:read - users:read settings: event_subscriptions: bot_events: - message.channels - message.groups - app_mention interactivity: is_enabled: false org_deploy_enabled: false socket_mode_enabled: true # no public webhook needed token_rotation_enabled: false -
03
Generate the two tokens
In the new app's Basic Information page:
-
App-Level Token — name it
cc-bot-socket, scopeconnections:write. Copy thexapp-1-…value. -
Install to Workspace → Allow. Copy the Bot User OAuth Token (
xoxb-…).
Paste both when
/cc-bot:setupprompts. cc-bot verifies viaauth.testand writes them into.cc-bot/profiles/active.json. -
App-Level Token — name it
-
04
Invite cc-bot to a channel
Paste the channel ID. In Slack, run
/invite @cc-bot— bot sends a probe. Then bring it online:/cc-bot:startAn "online" message lands in your channel. From here, talk to it like a teammate.
Slash commands
/cc-bot:setup— interactive Slack / Lark onboarding/cc-bot:start— bring the bot online/cc-bot:stop— take it offline/cc-bot:new-profile <name>— clone the profile template/cc-bot:switch <name>— swap active profile/cc-bot:doctor— health check & diagnostics
Ship from where the team already talks.
MIT, runtime-free, on GitHub. Slack & Lark adapters both live on main.