fix: explain /bash enablement when disabled (#722) (thanks @vrknetha)

This commit is contained in:
Peter Steinberger 2026-01-13 07:18:15 +00:00
parent b0d0914ca0
commit 07cc816969
5 changed files with 62 additions and 5 deletions

View File

@ -28,6 +28,7 @@
- Anthropic: merge consecutive user turns (preserve newest metadata) before validation to avoid incorrect role errors.
- Messaging: enforce context isolation for message tool sends; keep typing indicators alive during tool execution.
- Auto-reply: `/status` allowlist behavior, reasoning-tag enforcement on fallback, and system-event enqueueing for elevated/reasoning toggles.
- Auto-reply: explain how to enable `/bash` when its disabled; add security notes + FAQ. (#722) — thanks @vrknetha.
- Auto-reply: resolve ambiguous `/model` matches; fix streaming block reply media handling; keep >300 char heartbeat replies instead of dropping.
- Discord/Slack: centralize reply-thread planning; fix autoThread routing + add per-channel autoThread; avoid duplicate listeners; keep reasoning italics intact; allow clearing channel parents via message tool.
- Telegram: preserve forum topic thread ids, persist polling offsets, respect account bindings in webhook mode, and show typing indicator in General topics.

View File

@ -99,8 +99,9 @@ Quick answers plus deeper troubleshooting for real-world setups (local dev, VPS,
- [Is it safe to expose Clawdbot to inbound DMs?](#is-it-safe-to-expose-clawdbot-to-inbound-dms)
- [WhatsApp: will it message my contacts? How does pairing work?](#whatsapp-will-it-message-my-contacts-how-does-pairing-work)
- [Chat commands, aborting tasks, and “it wont stop”](#chat-commands-aborting-tasks-and-it-wont-stop)
- [How do I stop/cancel a running task?](#how-do-i-stopcancel-a-running-task)
- [Why does it feel like the bot “ignores” rapidfire messages?](#why-does-it-feel-like-the-bot-ignores-rapidfire-messages)
- [How do I stop/cancel a running task?](#how-do-i-stopcancel-a-running-task)
- [Why does `/bash` say its disabled?](#why-does-bash-say-its-disabled)
- [Why does it feel like the bot “ignores” rapidfire messages?](#why-does-it-feel-like-the-bot-ignores-rapidfire-messages)
- [Common troubleshooting](#common-troubleshooting)
- [“All models failed” — what should I check first?](#all-models-failed-what-should-i-check-first)
- [Im running on my personal WhatsApp number — why is self-chat weird?](#im-running-on-my-personal-whatsapp-number-why-is-self-chat-weird)
@ -1063,6 +1064,26 @@ Slash commands overview: see [Slash commands](/tools/slash-commands).
Most commands must be sent as a **standalone** message that starts with `/`, but a few shortcuts (like `/status`) also work inline for allowlisted senders.
### Why does `/bash` say its disabled?
The host shell command (`! <cmd>` or `/bash <cmd>`) is **disabled by default** because it runs directly on the gateway host. To enable it, update your config and restart the Gateway:
```json5
{
commands: { bash: true },
tools: {
elevated: {
enabled: true,
allowFrom: {
"<provider>": ["<sender-id>"]
}
}
}
}
```
Keep the allowlist tight and avoid enabling it in public rooms. See [Slash commands](/tools/slash-commands) and [Security](/gateway/security).
### Why does it feel like the bot “ignores” rapidfire messages?
Queue mode controls how new messages interact with an inflight run. Use `/queue` to change modes:

View File

@ -12,6 +12,8 @@ read_when:
- Directive forms: `/elevated on`, `/elevated off`, `/elev on`, `/elev off`.
- Only `on|off` are accepted; anything else returns a hint and does not change state.
Security note: enabling elevated access or `/bash` effectively grants host shell access. Keep allowlists tight and avoid enabling it in public rooms.
## What it controls (and what it doesnt)
- **Availability gates**: `tools.elevated` is the global baseline. `agents.list[].tools.elevated` can further restrict elevated per agent (both must allow).
- **Per-session state**: `/elevated on|off` sets the elevated level for the current session key.

View File

@ -44,6 +44,7 @@ They run immediately, are stripped before the model sees the message, and the re
- Set `discord.commands.native`, `telegram.commands.native`, or `slack.commands.native` to override per provider (bool or `"auto"`).
- `false` clears previously registered commands on Discord/Telegram at startup. Slack commands are managed in the Slack app and are not removed automatically.
- `commands.bash` (default `false`) enables `! <cmd>` to run host shell commands (`/bash <cmd>` is an alias; requires `tools.elevated` allowlists).
- When `commands.bash` is `false`, `/bash` replies with a short enablement hint (config keys + allowlist).
- `commands.bashForegroundMs` (default `2000`) controls how long bash waits before switching to background mode (`0` backgrounds immediately).
- `commands.config` (default `false`) enables `/config` (reads/writes `clawdbot.json`).
- `commands.debug` (default `false`) enables `/debug` (runtime-only overrides).
@ -90,6 +91,10 @@ Notes:
- **Inline shortcuts (allowlisted senders only):** `/help`, `/commands`, `/status` (`/usage`), `/whoami` (`/id`) also work when embedded in text.
- Unauthorized command-only messages are silently ignored, and inline `/...` tokens are treated as plain text.
## Security note: `!` / `/bash`
`! <cmd>` and `/bash <cmd>` run **directly on the gateway host** as the gateway user. Keep this disabled unless you fully trust the sender and have locked down allowlists. Treat it like giving someone SSH access to the host.
## Usage vs cost (what shows where)
- **Provider usage/quota** (example: “Claude 80% left”) shows up in `/status` when provider usage tracking is enabled.

View File

@ -155,6 +155,30 @@ function buildUsageReply(): ReplyPayload {
};
}
function buildBashDisabledReply(provider?: string): ReplyPayload {
const providerKey = provider?.trim().toLowerCase() || "<provider>";
return {
text: [
"⚠️ /bash is disabled (default).",
"Enable it in your config (host-only; trusted senders only):",
"```json5",
"{",
" commands: {",
" bash: true",
" },",
" tools: {",
" elevated: {",
" enabled: true,",
` allowFrom: { "${providerKey}": ["<sender-id>"] }`,
" }",
" }",
"}",
"```",
"Restart the Gateway after updating config.",
].join("\n"),
};
}
function formatElevatedUnavailableMessage(params: {
runtimeSandboxed: boolean;
failures: Array<{ gate: string; key: string }>;
@ -199,9 +223,13 @@ export async function handleBashChatCommand(params: {
};
}): Promise<ReplyPayload> {
if (params.cfg.commands?.bash !== true) {
return {
text: "⚠️ bash is disabled. Set commands.bash=true to enable.",
};
logVerbose("Blocked /bash: commands.bash is disabled.");
const provider =
params.ctx.Provider ??
params.ctx.Surface ??
params.ctx.OriginatingChannel ??
undefined;
return buildBashDisabledReply(provider ?? undefined);
}
const agentId =