slack-agent-flow
Let an existing Slack agent create new agents that arrive as their own Slack bots — provisioned app, operator DM, and a shared three-way room, hot-started without a host restart.
git clone --depth 1 https://github.com/nanocoai/nanoclaw /tmp/slack-agent-flow && cp -r /tmp/slack-agent-flow/.claude/skills/slack-agent-flow ~/.claude/skills/slack-agent-flowSKILL.md
# Slack agent flow (create_agent → provisioned Slack bot) Composes the Slack extension skills into one conversational flow: a user tells an existing Slack-wired agent "create an agent called Research", and the new agent doesn't just exist as a `send_message` destination — it arrives in Slack as **its own bot**. The host provisions a Slack app for it (managed broker, or a workspace manager token), registers it as a `slack-<name>` instance, hot-starts the adapter in the running host, opens a DM between the new bot and the operator, opens a three-way MPIM (operator + originating bot + new bot) registered as an agent-to-agent room, and wires everything so both agents hear the room. The flow also adds two agent-facing room actions — `create_room` (one shared room with N agents at once, the team primitive) and `add_to_room` (grow a room by one agent) — and extends the base `create_agent` tool with the flow's `purpose` / `allow_guests` / `room` parameters. Non-Slack sessions are untouched: `create_agent` from any other channel behaves exactly as upstream. **Canonical home.** This directory on `main` is the skill's canonical source — the setup wizard and any direct apply read it from the checkout. The copy on the `channels` branch is a compatibility mirror for older checkouts whose setup fetches companions from there; edits land here, never there. The payload the Apply steps fetch with `from-branch:channels` stays on the channels branch, exactly like `/add-slack`'s own. ## Prerequisites All prose below assumes these are already in place, in this order: 1. **`add-slack`** — the Slack channel install (`src/channels/slack.ts` and the shared channel-layer lib `src/channels/slack-lib.ts` present, with `slack.ts` exporting its `SLACK_DEFAULTS` declaration and the multi-instance factory `slackInstanceBridgeFactory` — the adapter owns `SLACK_INSTANCES` registration natively, and the flow writes each new agent's tokens under that env-key scheme). 2. **`slack-a2a-rooms`** — the bot-sender room policy (`src/channels/slack-a2a.ts` present), so shared rooms admit the sibling bots' posts. 3. **A provisioning credential in `.env`** — `NANOCLAW_INSTALL_TOKEN` (managed broker) or `SLACK_MANAGER_TOKEN` (direct workspace-level app creation). Without one, agent creation still works but the Slack leg reports `no-credentials` and points at the finish script. 4. **At least one Slack owner/admin in `user_roles`** — the flow resolves "the operator" from the approver chain (scoped admins → global admins → owners) and needs a `slack:U…` identity there to open the DM and the room. ## Apply ### 1. Check the Slack payloads are installed The flow imports the skill-installed Slack channel modules; verify they are in the tree before copying anything. If `slack-lib.ts`, the `SLACK_DEFAULTS` export, or the `slackInstanceBridgeFactory` export is missing, the installed Slack channel payload predates this flow — re-apply the two skills above (or `/update-skills`) first: ```nc:run effect:check test -f src/channels/slack.ts && test -f src/channels/slack-lib.ts && test -f src/channels/slack-a2a.ts && grep -q "export const SLACK_DEFAULTS" src/channels/slack.ts && grep -q "export function slackInstanceBridgeFactory" src/channels/slack.ts ``` ### 2. Check the trunk extension seams Everything this flow plugs into is standard trunk API — the adapter hot-start entry, the delivery batch preview, the mailbox delivery/session helpers, the create-agent notify option, the decline-and-notify overrides, the container tool-extension hook, and the setup wizard's channel registries. This is a trunk **version requirement, not an edit**: if the check below fails, the NanoClaw trunk is too old for this skill — bring the install up to date (`/update-nanoclaw`) instead of patching any of these files by hand: ```nc:run effect:check grep -q "export async function startChannelAdapter" src/channels/channel-registry.ts && grep -q "export function registerDeliveryBatchPreview" src/delivery.ts && grep -q "session: Session) => Promise<void>" src/delivery.ts && grep -q "trigger?: boolean" src/session-manager.ts && grep -q "findCliResponse" container/agent-runner/src/db/messages-in.ts && grep -q "Promise<number>" container/agent-runner/src/db/messages-out.ts && grep -q "suppressCreatedNotify" src/modules/agent-to-agent/create-agent.ts && grep -q "dedupeKey?: string" src/modules/permissions/sender-approval.ts && grep -q "declineText?: string" src/modules/permissions/sender-approval.ts && grep -q "fyiText?: string" src/modules/permissions/sender-approval.ts && grep -q "export function extendTool" container/agent-runner/src/mcp-tools/server.ts && grep -q "export function registerChannelPreStep" setup/channels/companions.ts && grep -q "instructions.md" src/project-doc-compose.ts && grep -q "await action.decide" src/guard/guard.ts ``` The last term requires an async-capable guard seam: the flow's `create_agent` and room-action guards read container config asynchronously, and on a trunk whose `guard()` does not await `decide` a returned Promise would be treated as an allow — the check turns that silent fail-open into a fail-fast here. ### 3. Copy the shared feature payload from the channels branch The agents experience needs more than the base adapter: the room-membership module (invite-to-room adoption, group-DM fork carry-over, detach on removal, owner-presence access rule), canvas actions + the container `canvas` tool + the `canvas-work` skill (section-scoped canvas edits/reads via the session's own bot identity), DM onboarding (get-started prompts, per-thread DM titles), and their `env-file.ts` dotenv plumbing. They live on the `channels` branch; fetch and copy them into place (overwrite — the branch is canonical): ```nc:copy from-branch:channels src/env-file.ts src/env-file.test.ts src/modules/slack-room-membership/index.ts src/modules/slack-room-membership/membership.ts src/modules/slack-room-membership/membership
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.
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 a monitoring dashboard to NanoClaw. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.
Add DeltaChat channel integration via @deltachat/stdio-rpc-server. Native adapter — no Chat SDK bridge. Email-based messaging with end-to-end encryption.
Add Discord bot channel integration via Chat SDK.
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 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 Google Chat channel integration via Chat SDK.