Slash Commands

Just send these commands directly in a topic, and the daemon intercepts and handles them. Only the allowlisted commands in the passthrough section are forwarded verbatim to the underlying CLI; any other /xxx the daemon doesn't recognize is treated as ordinary conversation text and relayed as a normal message. Send /help anytime to view the full list.

📌 Session Management

CommandDescription
/repoWhen a repository is pending selection, start with the default workingDir; if a session is in progress, pop up the project selection card
/repo <N>Switch to the Nth project from the last scan
/repo <path|project name>Directly specify a path or a top-level project name under workingDir
/cd <path>Switch the working directory and restart the CLI process
/statusView session info (uptime, terminal address, etc.)
/lane statusInspect your isolated principal lane, including its branch, worktree, dirty state, and unpushed commit count (available when the existing bot-level XPI switch enables principal lanes)
/lane closeSafely close your isolated principal lane: refuses while work is running/queued or files are uncommitted, pushes unpublished commits before cleanup, and never auto-merges or deletes the branch
/retryRetry the most recent failed or interrupted turn (10s cooldown)
/stopInterrupt the current turn while keeping the session; same as the streaming card's Stop button
/restartRestart the CLI process (preserving the session context)
/closeClose the session and send a recoverable card (including the CLI's own resume command)
/dismissTop level of a dedicated session group only: after confirmation, closes the session and disbands the whole group (the creator with operator permission only; code and worktrees are kept; not supported in DMs, ordinary groups, subtopics, or adopted sessions). To keep the chat, use /close
/cleanup-wt <ID>Retry a persisted worktree cleanup after a final removal failure; revalidates authorization, active sessions, worktree identity, and safety state before deleting
/fork <task>Fork the current session with full context into a new sub-topic of the same topic group; the source session keeps running untouched (Claude family, Codex terminal, or TraeX terminal mode)
/forklistRe-post the current session's forked-task panel with live/closed status and links to the child topics
/fork --create <group name>Clone the current session into a freshly-created group instead of a sub-topic
/rename <title>Rename this Botmux session and sync the running Codex/Claude native session name
/fork --create <new group name>Clone the current idle session into a newly-created group while leaving the source session untouched (Claude family, Codex terminal, or TraeX terminal mode; Hybrid RPC / external app-server sessions are unsupported; invoke inside the source session)
/cardManually summon the current session's streaming card (can summon and restore live refresh even when streaming is off; in private-card mode, sends a static snapshot visible only to authorized users instead). /card off and /card on toggle streaming cards for this chat; /card pin off, /card pin on, and /card pin status control the per-chat streaming-card Pin override. allowedUsers only (the switch affects the whole chat — Lark has no per-person card view)
/cotCoT switch: /cot off mutes this chat's thinking and tool activity, /cot on restores it, /cot show reveals the current turn once while the switch is off, /cot status reports the state (bot-level master switch cotEnabled, on by default; supports claude-code / codex / traex). allowedUsers only
/mention-mode [always|topic|never|ambient|status]The regular-group mention policy: when the bot answers without an @. Querying needs talk access, changing needs operate rights; regular groups only (rejected in DMs, topic groups, and session groups). The four modes and the 8 no-@ exceptions are explained in Mention Policy
/termGet the operable (write-enabled) terminal link for this session, delivered privately to the owner (visible-to-you in-chat, falling back to DM in topic/p2p — never exposed in the group)
/quotePop a picker of this chat's topics; choosing one reads that topic's transcript into the current session. This fills a gap in Feishu itself — its quote-reply UI can only reference a single message, never a whole topic. The bot replies with a short acknowledgement (how many messages, time span, subject) and waits for your next instruction
/quote <instruction>Same, but runs your instruction as soon as you pick a topic, saving a round trip. The transcript is still injected explicitly labelled as material rather than instructions
/sessionsList this bot's active topic sessions in the current group and jump directly back to a topic (legacy sessions use a safe locate fallback)
/dashboard [module]Open Dashboard control cards in Feishu (sessions/schedules/groups/settings/help, etc.)
@bot /project enable|status|roles|disableEnable, inspect, configure agent roles, or leave project-group mode in the current ordinary group (owner/allowedUsers only; does not consume a session slot)
@bot /context-sharing on|off|statusEnable, disable, or inspect passive context sharing for the current group (off by default; owner/allowedUsers only; creates no session or extra model turn)
/insightowner-only: instantly posts a "session insight summary" card for the current session (aggregate metrics + rule suggestions; action-span detail / per-turn reconciliation / conversation replay live on the Dashboard "Insights" page)
/vc prepare <meeting link or number>Use the current regular group as a meeting-prep chat and reuse the same Agent session during the meeting
/introduceRegister the bots in this chat with each other by open_id, so they can @-mention one another precisely when collaborating
@bot /summaryRead the current topic (or the configured regular-group history range) and generate a summary (default: latest 50 messages / 24 hours). If the bot has summaryMemory enabled, the summary is appended to the configured memory file (summaryMemoryPath, defaults to summary.md), and text following /summary acts as a hard "summarize only from this message" boundary; when memory is off, trailing text is only a focus hint for this summary
[title] /t [/repo <repo> | /repo wt <repo> [branch]] [/model <model>] [/effort <level>] [<first task>] (alias /topic)Force a new topic inside a regular group, declaring the title, repository (or a fresh worktree on it), model, reasoning effort and first task in one message. Newlines are equivalent to spaces; the title goes before /t (Lark shows the raw message in its topic list and a bot cannot rewrite it); quote paths containing spaces; one bad field voids the whole header and replies with a usage error. A bare /t opens topic setup
/th [<first task>], /tw [<first task>] (same as /t here … / /t worktree …)Lifecycle variants: /th opens the topic in the current group session working directory; /tw first creates a deterministically named, multi-bot-shareable worktree from that directory. They combine with a title, /model and /effort, but not with /repo (one says "use the current directory", the other names a repo, so the header is rejected)
/issueOpen the Issue Board card and claim a botmux platform task in place: pick a repo and botmux creates a group, adds you, binds the platform task and starts the agent. Requires this machine to be bound to the platform, and the invoker to be in the bot's allowedUsers; only the invoker can operate the card
/issue statusRun inside the task group to see which platform task it is bound to and where things stand: platform status / claimant / local binding / whether any status write-back is still stuck in the outbox. Read-only, also limited to the bot's allowedUsers
/issue doneRun inside the task group to accept the work and move the task to its terminal state on the platform. An agent can only deliver up to "in review"; marking it done is a human decision. Once done, the platform clears the claim and the task can no longer be released. Also limited to the bot's allowedUsers
/issue releaseRun inside the group created when the task was claimed: hands the task back to the platform's todo pool so someone else can take it. The group and session are not disbanded — the conversation is kept. Also limited to the bot's allowedUsers

/sessions card preview:

Current-group active topic sessions card

See Session & Topic Model for the repository-picker and pinned-directory branches of bare /t.

The header directives:

  • /repo <path|project name> — pin the repository directly, skipping the picker card. Note it takes exactly one token: quote a path containing spaces, as in /repo "~/Code/my project".
  • /repo (no argument) — start right away in the default working directory, the same as the picker card's start-directly button.
  • /repo wt <path|project name> [branch] — create a fresh worktree on that repository (off the remote default branch) and start the session inside it. The branch may be omitted (auto-named from the title / first task); when given, it is only taken from the next word on the same line as the repo that looks like a branch name (ci/temp_split and the like), so a Chinese first task is never swallowed, but start a latin first task on a new line. An invalid branch name or an existing target directory is rejected before the topic is opened; if git itself fails, the topic exists and the session waits in repo selection. Resending while creation is still running is told to wait; after failure, send /repo <path|project name> or /repo wt <repo> [branch] in the topic — the earlier message stays queued.
  • /model <model> — the model to launch with this time. Only available on CLIs that can actually carry a model in their launch arguments; the rest reject it rather than ignoring it silently.
  • /effort <level> — reasoning effort (low/medium/high/xhigh/max/ultra), validated against the model this launch will actually use.

The whole message can be written on one line or split across lines — the result is identical:

botmux ops /t /repo botmux /model sonnet check the restart records in the daemon log
botmux ops
/t
/repo botmux
/model sonnet

check the restart records in the daemon log

With no first task (e.g. /t /repo botmux), the CLI boots idle and waits for your next message instead of answering an empty turn.

A few boundaries:

  • A header only takes effect on the first message of a new topic. To change repository/model/reasoning effort inside a running topic, send /repo, /model or /effort on their own; use /rename to change the title.
  • The header's /repo wt does not accept the numeric form (numbers only mean something on the picker card); the in-session /repo wt <N|project name> [branch] still does.
  • A standalone mid-session /repo still takes the rest of the line, unlike the single-token rule inside the header.

💬 Reply Mode (/reply-mode)

Controls how the bot opens a session when @mentioned. No argument (or status) shows the current mode; changing it needs canOperate, viewing needs canTalk. In group chats you must @ the target bot (in multi-bot groups, @ the specific bot). Only regular groups and 1:1 DMs are supported; topic groups need no setting (they're already topics) and the command is rejected there.

DM (1:1) — the mode applies to all of this bot's DMs (bot-level global config, not per-chat), but different users' DMs with the bot still keep isolated sessions. The modes are chat / topic / group (new-topic is a compat alias of topic):

CommandDescription
/reply-mode /reply-mode statusShow the current DM session mode
/reply-mode chatEach 1:1 DM is one flat continuous session — all messages in that DM share one session (default)
/reply-mode topic /reply-mode new-topicEach top-level DM opens its own session/thread; replies inside an existing thread continue that thread's session
/reply-mode groupEach top-level DM births a dedicated user+bot session group hosting the conversation (AI-generated name; returning to the group resumes the session — see p2pMode=group)

shared / chat-topic rely on native group topics and are rejected in DMs.

Regular groups — how top-level @mentions open sessions (per-chat override, higher priority than the dashboard default):

CommandDescription
/reply-mode /reply-mode statusShow the current group reply mode
/reply-mode chatOne continuous group session (all top-level @mentions share it)
/reply-mode chat-topicFlat at top level, native topics each get their own session
/reply-mode new-topicEach @mention opens a new topic and its own session
/reply-mode topic /reply-mode sharedTopic UI but a shared session (topic is a compat alias of shared)

The group-level setting overrides the dashboard "Bot Config → Regular Group Mode" default.

/substitute [status|on|off] — show or toggle substitute mode for the current group (owner-only to change).

📢 Mention Policy (/mention-mode, regular groups only)

/mention-mode always|topic|never|ambient switches this chat's policy; /mention-mode status (or no argument) reports it. Regular groups only: DMs never need @, and topic groups and /group session groups reject the command. Querying needs only talk access; changing needs operate rights (allowedUsers).

  • always: @ required to get an answer (default); topic: replies inside the bot's own topics skip @; never: no @ required anywhere in the group; ambient: no @ required, but the bot yields when a message explicitly @-mentions someone else.
  • Skipping @ never skips the permission gate, and 8 no-@ exceptions still apply (in-topic replies, substitute triggers, the message listener, and more) — see Mention Policy for the full semantics.

📑 Chat Tabs

CommandDescription
/tabs / /tab / /tabs listList every tab in the current chat and its Tab ID (/tab is a compatibility alias)
/tabs add <url> [name]Add a URL tab (owner or authorized operator required)
/tabs rename <tab_id> <name>Rename an editable URL or document tab
/tabs delete <tab_id>Delete an editable URL or document tab
/tabs sort <tab_id> ...Reorder tabs; the command must include every Tab ID returned by /tabs

Built-in Lark tabs are read-only through OpenAPI, though they must still be included when sorting. If the chat only allows its owner and administrators to manage tabs, the bot also needs that chat-level privilege.

AI agents and background scripts should use the CLI instead of sending a slash command into the chat:

botmux tabs add "https://example.com/project/releases/2026" \
  --name "Project release" --json

The CLI resolves the bot and chat from the current BOTMUX_SESSION_ID. Use --session-id outside the current process tree or --chat-id to override the destination. add is idempotent by URL: an existing page tab is reused and renamed when needed. This works for merge requests, project boards, release pages, and other automation scenarios. Background callers can also use botmux tabs list|update|remove|sort.

🔀 Passthrough to the Underlying CLI

/compact /model /clear /plugin /usage /new /context /cost /mcp /diff /code-review /security-review /review /btw /effort /fast — delivered literally to the underlying CLI and handled by its built-in commands.

/fast is Codex-specific: it toggles Codex's native service tier, and the streaming card shows a read-only ⚡ <tier> badge reflecting whatever tier Codex actually runs. On RPC-input or Riff backends the keystroke can't reach Codex's executor, so /fast fails closed there with a clear notice instead of a silent no-op.

Some CLIs also declare adapter-default passthrough commands: Claude Code and Codex default-allow /goal, so a new topic whose first message is /goal ... will start/select the repository first and then send /goal ... to the CLI literally.

To allow more commands through, configure customPassthroughCommands for that bot (e.g. ["/export"]) to extend beyond the allowlist above as needed. Entries that would shadow a botmux daemon command (such as /status, /help, /cd) are automatically dropped — daemon commands always keep their own semantics and cannot be overridden via passthrough.

Cascading several passthrough commands in one message (inside a running session): put one passthrough command per line, optionally followed by a task body, and botmux sends them in order, waiting for the CLI to become idle between items —

/model opus
/clear
Now go through the review comments on PR #1361

Rules: only a leading run of passthrough lines forms a cascade (a botmux command such as /cd or an unknown /xxx inside that run makes the whole message ordinary text, as today); the body starts at the first line not beginning with /, and any later /xxx is part of the body; a single line such as /model opus then continue is still sent verbatim as one line. The idle wait is capped at 120 s, after which the remaining items are sent immediately with a notice. Remote sandbox backends (riff / mojo) and adopted external sessions do not support cascades and reply "send them one by one"; messages with attachments are not split either.

🧩 View Available Commands

/list-slash-command (alias /slash): lists the currently available slash commands in a card, in four sections —

  1. botmux's fixed passthrough allowlist;
  2. commands default-allowed by the current CLI adapter;
  3. commands this bot custom-allows via customPassthroughCommands in bots.json;
  4. custom commands / skills / plugins auto-discovered from the .claude directory (project-level + ~/.claude + plugin cache), shown in a paginated "command | description" table, with a note of any detected MCP server names.

Permissions are the same as /help, and it doesn't occupy a session slot.

📡 Session Onboarding

CommandDescription
/adoptScan the local tmux and pop up a card to select a running session to adopt
/adopt <tmux_pane>Directly adopt the specified pane (e.g. /adopt 0:2.0)
/detachDisconnect this topic from the adopted session (the original CLI is untouched; /disconnect is an alias)

🔐 User Authorization

CommandDescription
/loginBasic Lark user authorization: read messages, access resources, and renew authorization; does not request docs, contacts, or calendar permissions by default
/login --scope <scope> [more scopes]Add only the requested permissions to the basic scopes, e.g. /login --scope docx:document:readonly
/login statusView authorization status
/login tagsSession-group tag authorization (feed-group scopes); once granted, new session groups auto-join your sidebar feed group (for p2pMode=group with the feed-group tag mode — the default)
/pair <pairing code>Pair a Web/Dashboard-side session with your Lark identity (get the pairing code on the web side, then send /pair <code> in the topic to claim it)

Basic authorization requires the app to enable im:message:readonly, im:resource, and offline_access. If another operation returns missing_scope, request the names reported by the error with /login --scope ...; the app administrator must first enable those user permissions in the developer console. Resource visibility/access errors require access to that resource, not another /login.

🎭 Roles (Personas)

CommandDescription
/roleView the currently effective Role (this-group override > default role > none)
/role set <Markdown>Set this group's Role (overrides the default role)
/role deleteDelete this group's Role
/role team set <Markdown>Set the default role (the cross-group default persona; the command name keeps team, = dashboard "Bot Config → Default Role")
/role cap set <one-liner> / /role cap clearSet/clear the capability tag in the roster
/role profile listList local role profiles
/role profile show <profile> [--all]Show this bot's profile entry, or all local entries known to this daemon
/role profile set <profile> <Markdown>Set this bot's entry in a reusable role profile
/role profile save <profile>Save this bot's current effective role into the profile
/role profile apply <profile> [--preview] [--force] [--quiet]Write this bot's profile entry as this group's Role

See Roles & Teams for details.

🔀 Session Relay (Regular Groups)

CommandDescription
/relayPop up a card in the target group to pull an active session of yours from another group and continue it
@botA @botB /relay --createMove the current session (with its collaborators) into a newly created group

See Session Relay for details.

🛎️ On-Call (Group Chats)

/oncall bind <path> · /oncall unbind · /oncall status

🔑 Usage Authorization (owner / admins)

CommandDescription
@bot /grant (or /grant all)Authorize all members of this group to talk (writes allowedChatGroups; no quota, no expiry; in a topic group keyed by the oc_ group and covers all topics); bare /revoke removes it
@bot /grant @someone [N]Open a grant card authorizing talk in this group for specific members, defaulting to 3 messages / 1 hour each; the card offers 1 hour / 8 hours / 1 day / 7 days / permanent and a quota field (blank = unlimited). The owner-initiated card also offers global talk. @bot /revoke @someone removes the per-group and global guest grants together, and also removes the person from allowedUsers if listed there (revoking the owner themselves, or a revoke that would leave no admin, is refused; the reply names the affected scopes)
/vc-auth @someoneWhile meeting-listening is on, temporarily trust an in-meeting instruction source; /vc-auth revoke @someone revokes; /vc-auth list shows current grants

Layers, quotas, grant request cards, and the block list are documented in Permissions & Access. Note: being added to a group is not authorization — a restricted bot still accepts only listed members.

⚙️ Remote Config & Skills (owner-only)

Written and hot-applied — no restart needed.

CommandDescription
/botconfig getShow this bot's current operational config
/botconfig set <field> <value>Change model/cli/lang/toggles; /botconfig help lists all fields
/skills ...View/manage this bot's skill policy (attach/detach require owner)

🆕 One-Click New Session Group

/group <group name> (alias /g): automatically creates a new Lark group, invites you in, transfers ownership to you, and runs the entire group as a standalone CLI session. @botA @botB /g <group name> can add multiple bots into the new group at once.

Add --role-profile <profile> to bootstrap the new group with reusable per-bot roles:

@botA @botB /g --role-profile collab-main War Room

See One-Click Session Group for details.

📌 Upgrade an Ordinary Group to Project Mode

In the top-level ordinary-group chat, mention the Bot that should coordinate the project:

@bot /project enable

The addressed Bot becomes coordinator and the other bots in this group that are managed by the same Botmux host become workers. The command writes the same source of truth as Dashboard and immediately sends and pins the getting-started card. A settled project goal is not required; discussion can begin first in the top-level chat. Command-based enablement turns on “automatically enroll new bots” by default, so newly joined bots managed by the same host enter the worker allowlist independently of the auto-start-on-join setting.

On every project turn, the coordinator receives Botmux's fixed project-state protocol: read durable state first, then persist material changes to the goal, phase, current work, remaining plan, blockers, or milestones. This protocol is injected separately from custom Roles, so Role wording and once-only Role injection cannot disable it. On first initialization, Botmux sends and pins a fresh formal project card at the current point in the timeline, then unpins the getting-started guide; later progress updates patch the formal card in place.

  • @bot /project status: show the coordinator, workers, and whether a project has started.
  • @bot /project roles: Reply in the current group with a focused role card for this project’s coordinator and workers; only the admin who opened the card can operate it. Saving reuses the per-chat /role files and follows the bot’s existing injection policy: every-turn mode applies on the next message, while once mode applies after a new or rebuilt session.
  • @bot /project disable: leave project-group mode; an unused guide is unpinned, while existing project state is retained for a later re-enable.

The command works only in ordinary groups and only for the Bot's owner/allowedUsers. Repeating enable preserves any worker subset and auto-enrollment policy already curated in Dashboard. Dashboard can disable “automatically enroll new bots”; when disabled, the explicit worker list remains unchanged. Dashboard also lists the same project agents and deep-links to their group-role editors; both entry points share one role source of truth.

🧠 Group Context Sharing

In a real Lark group, mention any bot managed by this deployment:

@bot /context-sharing on
@bot /context-sharing status
@bot /context-sharing off

The switch is group-wide and off by default. Once enabled, bots managed by this deployment passively retain published messages from the group. A bot that was not mentioned stays asleep. On its next activation under the existing mention policy, it receives attributed background it missed. The switch does not change mention routing or create a model turn or session merely to deliver background.

Only a human owner/member of that bot's allowedUsers can inspect or change the switch; ordinary talk grants and other bots do not qualify. DMs and API virtual sessions are unsupported. Sessions configured with promptInjection=none explicitly do not receive automatic background.

By default, injected background is bounded to 24,000 characters per turn, while stored group observations are retained for 30 days or 10,000 messages. Injected background counts toward the activated model's input tokens, but passive observation does not call a model. Scope is limited to published group messages and resource references; it excludes DMs, hidden reasoning, unpublished tool results, and private files. If platform backfill is incomplete because of history limits, permissions, or retention, the background carries an incomplete-range marker instead of presenting the gap as complete history.

status and successful enable responses also show a recall-event subscription diagnostic. Only a subscribed reason means the app configuration was verified to include im.message.recalled_v1; this does not promise 100% push delivery. update_submitted means an update was submitted but still requires publishing a new app version in Lark Developer Console. Unknown, unavailable-login, or stale results mean historical background may temporarily retain recalled messages; inspect that event subscription and retry. Disabling performs no subscription check or setup action.

📄 Feishu Doc Comment Entry

/watch-comment: watch Feishu doc comments, bind them to an AI session, and post replies back into their threads; supports <doc link> [--dir <path>] [--all|--mentions-only] and list/off. /subscribe-lark-doc keeps the original per-file Feishu API subscription flow. See Feishu Doc Comment Entry for details.

🔧 Workflow (orchestration, experimental)

CommandDescription
/workflow <goal> (= /workflow new <goal>)Start an ad-hoc workflow: the bot interrogates the requirement → auto-orchestrates a DAG → runs it concurrently after you confirm, with approval cards on risk nodes at execution time
/workflow run <name> [key=value ...]Run a Saved Workflow
/workflow save last [name] · /workflow list|show|cancelSave / list / inspect / cancel workflows (legacy v2 assets only support offline migrate-v3 / archive-runs)

The old /template run|cancel commands are retired; sending /template now returns a retirement notice.

See Workflow for details.

👥 Multi-Bot Collaboration

@botA @botB /t <prompt> (each opens a new topic) · @botA @botB /introduce (register the bots in this chat with each other by open_id for precise collaboration mentions) · botmux bots list (show bots available in the current group)

⏰ Scheduling & ❓ Help

/schedule ... (see Scheduled Tasks) · /help (shows the full list inside the topic)