/scope
Channel-scope status, opt-in, and audit. Triggers on /agent:scope, "scope status", "scope wizard", "scope enable", "scope disable", "scope audit".
$ npx -y skills add crisandrews/ClawCode --skill scope --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/scope
Context preview
The summary Claude sees to decide when to auto-load this skill.
Channel-scope status, opt-in, and audit. Triggers on /agent:scope, "scope status", "scope wizard", "scope enable", "scope disable", "scope audit".
SKILL.md
scope.SKILL.mdname: scope
description: Channel-scope status, opt-in, and audit. Triggers on /agent:scope, "scope status", "scope wizard", "scope enable", "scope disable", "scope audit".
user-invocable: true
argument-hint: <status|enable|disable|wizard|test|audit> [args...]
Scope
Channel-scope is the per-channel opt-in compatibility layer between ClawCode and messaging plugins that publish their own access governance (today: claude-whatsapp's `historyScope`). When a channel is *armed* (mode != off, governance resolvable), ClawCode's memory surfaces honor the upstream plugin's access rules; when a channel is `mode: off` (the default), behavior is identical to having no scope layer.
This is an OPTIONAL feature — see `docs/channel-scope-compat.md`. Enforcement covers `memory_search`, `memory_get`, `memory_context`, the QMD path, `voice_transcribe`, `dream` promote routing, and `chat_inbox_read`. Per-chat semantics flow through (a) a synthetic per-chat indexer over the upstream `messages.db` which produces per-chat chunks, and (b) a cross-plugin request envelope contract — claude-whatsapp embeds a `requestEnvelopeToken` in each inbound notification, and ClawCode resolves the token to a chat/sender binding for the current MCP call. Owner unlock (declarative `identity = "owner"` + out-of-band trust file) remains the always-available escape hatch; without an envelope (or with an invalid/expired one) under `mode = enforce`, calls fall through to guest `[]`.
Talk to the user in the language they've been using on this turn — never default to a hard-coded language.
When to use
- After installing claude-whatsapp + pairing it: `/agent:scope status` confirms the adapter sees `access.json`.
- To turn enforcement on: `/agent:scope wizard` walks through the choices, or use the one-liner `/agent:scope enable whatsapp shadow` (or `enforce`).
- To turn it off: `/agent:scope disable whatsapp`.
- To inspect existing channel-derived content in shared memory: `/agent:scope audit`.
Steps
Step 1 — Parse the subcommand
The first word in `$ARGS` selects the path:
- `status` → show every configured channel's runtime state
- `enable <channel> [shadow|enforce]` → set `config.scope.<channel>.mode`
- `disable <channel>` → set mode to `off`
- `wizard` → interactive REPL flow via `AskUserQuestion`
- `test <chatId>` → dry-run probe against the adapter (see Step 6)
- `audit` → re-run `mcp__clawcode__agent_doctor` and surface only the `scope-*` rows
If `$ARGS` is empty or the subcommand is unknown, default to `status`.
Step 2 — `status`
1. Call `mcp__clawcode__agent_config(action='get')` and parse the `scope` block. 2. For each channel under `scope`, display:
- `mode` (off / shadow / enforce)
- `identity` (auto / owner / guest)
- `background.identity` (deny / system-owner)
- `execGate.mode` (off / shadow / enforce), `execGate.policy` (denylist / allowlist), and `execGate.tools` count (or "defaults" when omitted)
- WhatsApp only: `accessJsonPath`, `cwdExactMatchOnly`
3. Surface trust file presence (read scope + exec):
- `<channel>-owner` exists? (yes/no) — gates read scope owner unlock
- `<channel>-exec` exists? (yes/no) — gates execGate "trust this machine" path
4. Then call `mcp__clawcode__agent_doctor(action='check')` and surface the scope rows (`scope-pre-enforce-audit`, `scope-bypasses`, `scope-quarantine-pending`, `scope-execgate-status`, `scope-execgate-shadow-events`).
If `scope` is absent in config, say so explicitly and recommend `/agent:scope wizard`.
Step 3 — `enable <channel> [mode]`
**All scope-tree writes are refused by `mcp__clawcode__agent_config(action='set')`** (any key starting with `scope`). The agent cannot silently elevate or relax the policy; every scope key goes through `Bash`, which surfaces a permission prompt to the user.
For `enable <channel> <mode>` the single Bash call covers ALL scope.<channel> keys. Substitute BOTH `<channel>` (validated against the shipped enum `{whatsapp, telegram, discord, imessage, webchat}`) AND `<mode>` ('shadow' or 'enforce'; default 'shadow' when omitted) from `$ARGS`. Refuse any other literal for either parameter — only those values are valid for enable. `cwdExactMatchOnly` preserves the prior value if the user had it `true`:
Bash('node -e "const fs=require(\"fs\"),p=\"agent-config.json\";const c=fs.existsSync(p)?JSON.parse(fs.readFileSync(p,\"utf-8\")):{};c.scope=c.scope||{};const ch=\"<channel>\";const cur=c.scope[ch]||{};c.scope[ch]=Object.assign({},cur,{mode:\"<mode>\",identity:\"auto\",accessJsonPath:cur.accessJsonPath||\"auto\",cwdExactMatchOnly:cur.cwdExactMatchOnly===true,background:Object.assign({},cur.background,{identity:\"deny\"})});fs.writeFileSync(p,JSON.stringify(c,null,2));console.log(\"wrote\",p);"')The `Bash` call surfaces a permission prompt to the user — that's intentional. Default mode when omitted: `shadow`. Confirm by re-running `status`.
Tell the user: "Run `/mcp reconnect clawcode` for changes to take effect."
Step 4 — `disable <channel>`
First validate `<channel>` is one of the shipped channel names (`whatsapp`, `telegram`, `discord`, `imessage`, `webchat`). Reject any other value with an error message — this defends against future channel IDs that might contain shell metacharacters. Currently shipped names are alphanumeric and safe.
`scope.<channel>.mode` AND `scope.<channel>.execGate.mode` are both on the security-sensitive blocklist, so this also goes through `Bash`. A `disable` resets BOTH read scope AND execGate to off (the user expected "turn the channel off" — they don't expect read scope to flip but exec scope to remain active):
Bash('node -e "const fs=require(\"fs\"),p=\"agent-config.json\";const c=fs.existsSync(p)?JSON.parse(fs.readFileSync(p,\"utf-8\")):{};c.scope=c.scope||{};const cur=c.scope.<channel>||{};c.scope.<channel>=Object.assign({},cur,{mode:\"off\",execGate:{mode:\"off\"}});fs.writeFileSync(p,JSON.stringify(c,null,2));console.log(\"disabled\");"')Read more
name: scope description: Channel-scope status, opt-in, and audit. Triggers on /agent:scope, "scope status", "scope wizard", "scope enable", "scope disable", "scope audit". user-invocable: true argument-hint: <status|enable|disable|wizard|test|audit> [args...]
Scope
Channel-scope is the per-channel opt-in compatibility layer between ClawCode and messaging plugins that publish their own access governance (today: claude-whatsapp's `historyScope`). When a channel is *armed* (mode != off, governance resolvable), ClawCode's memory surfaces honor the upstream plugin's access rules; when a channel is `mode: off` (the default), behavior is identical to having no scope layer.
This is an OPTIONAL feature — see `docs/channel-scope-compat.md`. Enforcement covers `memory_search`, `memory_get`, `memory_context`, the QMD path, `voice_transcribe`, `dream` promote routing, and `chat_inbox_read`. Per-chat semantics flow through (a) a synthetic per-chat indexer over the upstream `messages.db` which produces per-chat chunks, and (b) a cross-plugin request envelope contract — claude-whatsapp embeds a `requestEnvelopeToken` in each inbound notification, and ClawCode resolves the token to a chat/sender binding for the current MCP call. Owner unlock (declarative `identity = "owner"` + out-of-band trust file) remains the always-available escape hatch; without an envelope (or with an invalid/expired one) under `mode = enforce`, calls fall through to guest `[]`.
Talk to the user in the language they've been using on this turn — never default to a hard-coded language.
When to use
- After installing claude-whatsapp + pairing it: `/agent:scope status` confirms the adapter sees `access.json`.
- To turn enforcement on: `/agent:scope wizard` walks through the choices, or use the one-liner `/agent:scope enable whatsapp shadow` (or `enforce`).
- To turn it off: `/agent:scope disable whatsapp`.
- To inspect existing channel-derived content in shared memory: `/agent:scope audit`.
Steps
Step 1 — Parse the subcommand
The first word in `$ARGS` selects the path:
- `status` → show every configured channel's runtime state
- `enable <channel> [shadow|enforce]` → set `config.scope.<channel>.mode`
- `disable <channel>` → set mode to `off`
- `wizard` → interactive REPL flow via `AskUserQuestion`
- `test <chatId>` → dry-run probe against the adapter (see Step 6)
- `audit` → re-run `mcp__clawcode__agent_doctor` and surface only the `scope-*` rows
If `$ARGS` is empty or the subcommand is unknown, default to `status`.
Step 2 — `status`
1. Call `mcp__clawcode__agent_config(action='get')` and parse the `scope` block. 2. For each channel under `scope`, display:
- `mode` (off / shadow / enforce)
- `identity` (auto / owner / guest)
- `background.identity` (deny / system-owner)
- `execGate.mode` (off / shadow / enforce), `execGate.policy` (denylist / allowlist), and `execGate.tools` count (or "defaults" when omitted)
- WhatsApp only: `accessJsonPath`, `cwdExactMatchOnly`
3. Surface trust file presence (read scope + exec):
- `<channel>-owner` exists? (yes/no) — gates read scope owner unlock
- `<channel>-exec` exists? (yes/no) — gates execGate "trust this machine" path
4. Then call `mcp__clawcode__agent_doctor(action='check')` and surface the scope rows (`scope-pre-enforce-audit`, `scope-bypasses`, `scope-quarantine-pending`, `scope-execgate-status`, `scope-execgate-shadow-events`).
If `scope` is absent in config, say so explicitly and recommend `/agent:scope wizard`.
Step 3 — `enable <channel> [mode]`
**All scope-tree writes are refused by `mcp__clawcode__agent_config(action='set')`** (any key starting with `scope`). The agent cannot silently elevate or relax the policy; every scope key goes through `Bash`, which surfaces a permission prompt to the user.
For `enable <channel> <mode>` the single Bash call covers ALL scope.<channel> keys. Substitute BOTH `<channel>` (validated against the shipped enum `{whatsapp, telegram, discord, imessage, webchat}`) AND `<mode>` ('shadow' or 'enforce'; default 'shadow' when omitted) from `$ARGS`. Refuse any other literal for either parameter — only those values are valid for enable. `cwdExactMatchOnly` preserves the prior value if the user had it `true`:
Bash('node -e "const fs=require(\"fs\"),p=\"agent-config.json\";const c=fs.existsSync(p)?JSON.parse(fs.readFileSync(p,\"utf-8\")):{};c.scope=c.scope||{};const ch=\"<channel>\";const cur=c.scope[ch]||{};c.scope[ch]=Object.assign({},cur,{mode:\"<mode>\",identity:\"auto\",accessJsonPath:cur.accessJsonPath||\"auto\",cwdExactMatchOnly:cur.cwdExactMatchOnly===true,background:Object.assign({},cur.background,{identity:\"deny\"})});fs.writeFileSync(p,JSON.stringify(c,null,2));console.log(\"wrote\",p);"')The `Bash` call surfaces a permission prompt to the user — that's intentional. Default mode when omitted: `shadow`. Confirm by re-running `status`.
Tell the user: "Run `/mcp reconnect clawcode` for changes to take effect."
Step 4 — `disable <channel>`
First validate `<channel>` is one of the shipped channel names (`whatsapp`, `telegram`, `discord`, `imessage`, `webchat`). Reject any other value with an error message — this defends against future channel IDs that might contain shell metacharacters. Currently shipped names are alphanumeric and safe.
`scope.<channel>.mode` AND `scope.<channel>.execGate.mode` are both on the security-sensitive blocklist, so this also goes through `Bash`. A `disable` resets BOTH read scope AND execGate to off (the user expected "turn the channel off" — they don't expect read scope to flip but exec scope to remain active):
Bash('node -e "const fs=require(\"fs\"),p=\"agent-config.json\";const c=fs.existsSync(p)?JSON.parse(fs.readFileSync(p,\"utf-8\")):{};c.scope=c.scope||{};const cur=c.scope.<channel>||{};c.scope.<channel>=Object.assign({},cur,{mode:\"off\",execGate:{mode:\"off\"}});fs.writeFileSync(p,JSON.stringify(c,null,2));console.log(\"disabled\");"')Showing the first part of this file.
Persistent agents for Claude Code as a plugin, not a harness. Memory, personality, messaging across WhatsApp, Telegram, and Discord, plus a service mode for 24/7 runs. Imports from OpenClaw.
Repo: crisandrews/ClawCode
Other skills on crisandrews-agent.
- /about
Show the plugin source — name, version, and repo URL. Works from CLI or messaging. Triggers on /about, /version, /agent:about, /agent:version, "qué versión", "what version", "about the plugin", "about clawcode".
Open skill - /channels
Show messaging channel status (WhatsApp, Telegram, Discord, iMessage, Slack, Fakechat) and the launch command to load them. Triggers on /agent:channels, /agent:channels list, /agent:channels status, /agent:channels launch, "ver canales", "estado de canales", "cómo lanzo con
Open skill - /compact
Flush important session context to daily log (manual memory flush). Does NOT invoke native /compact. Triggers on /compact, /agent:compact, /flush, "guarda memoria", "flush".
Open skill - /create
Create a new agent in the current directory with personality files and bootstrap ritual. Triggers on /agent:create, "crear agente", "nuevo agente", "new agent", "create agent".
Open skill - /crons
Manage scheduled reminders (crons) — list, add, delete, pause, resume, reconcile, or import from OpenClaw. Triggers on /agent:crons, /agent:reminders; listing ("list reminders", "show crons", "recordatorios", "mis crons", "mis recordatorios"); creating from natural language via
Open skill - /doctor
Run diagnostic checks on the agent workspace. Triggers on /agent:doctor, "diagnóstico", "diagnostico", "doctor", "health check", "agent health", "checkup", "revisar agente", "agent broken", "fix agent", "revisa el agente".
Open skill

