docs: typography hygiene + 2 in-body H1 removals across 5 pages

Replaced 92 typography characters (curly quotes, apostrophes, em/en
dashes, non-breaking hyphens) with ASCII equivalents per
docs/CLAUDE.md heading and content hygiene rules.

- docs/channels/feishu.md: 19 chars; removed the duplicate
  '# Feishu / Lark' H1 (Mintlify renders title from frontmatter; the
  in-body H1 with a slash produced a brittle anchor).
- docs/gateway/bonjour.md: 18 chars; removed the duplicate
  '# Bonjour / mDNS discovery' H1.
- docs/channels/matrix.md: 19 chars
- docs/tools/browser.md: 18 chars
- docs/automation/standing-orders.md: 18 chars
This commit is contained in:
Vincent Koc
2026-05-05 19:54:53 -07:00
parent 4395f1dd66
commit 7a39551685
5 changed files with 89 additions and 93 deletions

View File

@@ -7,7 +7,7 @@ read_when:
title: "Standing orders"
---
Standing orders grant your agent **permanent operating authority** for defined programs. Instead of giving individual task instructions each time, you define programs with clear scope, triggers, and escalation rules and the agent executes autonomously within those boundaries.
Standing orders grant your agent **permanent operating authority** for defined programs. Instead of giving individual task instructions each time, you define programs with clear scope, triggers, and escalation rules - and the agent executes autonomously within those boundaries.
This is the difference between telling your assistant "send the weekly report" every Friday vs. granting standing authority: "You own the weekly report. Compile it every Friday, send it, and only escalate if something looks wrong."
@@ -33,15 +33,15 @@ Standing orders are defined in your [agent workspace](/concepts/agent-workspace)
Each program specifies:
1. **Scope** what the agent is authorized to do
2. **Triggers** when to execute (schedule, event, or condition)
3. **Approval gates** what requires human sign-off before acting
4. **Escalation rules** when to stop and ask for help
1. **Scope** - what the agent is authorized to do
2. **Triggers** - when to execute (schedule, event, or condition)
3. **Approval gates** - what requires human sign-off before acting
4. **Escalation rules** - when to stop and ask for help
The agent loads these instructions every session via the workspace bootstrap files (see [Agent Workspace](/concepts/agent-workspace) for the full list of auto-injected files) and executes against them, combined with [cron jobs](/automation/cron-jobs) for time-based enforcement.
<Tip>
Put standing orders in `AGENTS.md` to guarantee they're loaded every session. The workspace bootstrap automatically injects `AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`, and `MEMORY.md` but not arbitrary files in subdirectories.
Put standing orders in `AGENTS.md` to guarantee they're loaded every session. The workspace bootstrap automatically injects `AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`, and `MEMORY.md` - but not arbitrary files in subdirectories.
</Tip>
## Anatomy of a standing order
@@ -66,7 +66,7 @@ Put standing orders in `AGENTS.md` to guarantee they're loaded every session. Th
- Do not send reports to external parties
- Do not modify source data
- Do not skip delivery if metrics look bad report accurately
- Do not skip delivery if metrics look bad - report accurately
```
## Standing orders plus cron jobs
@@ -109,7 +109,7 @@ openclaw cron add \
### Weekly cycle
- **Monday:** Review platform metrics and audience engagement
- **TuesdayThursday:** Draft social posts, create blog content
- **Tuesday-Thursday:** Draft social posts, create blog content
- **Friday:** Compile weekly marketing brief → deliver to owner
### Content rules
@@ -176,9 +176,9 @@ openclaw cron add \
Standing orders work best when combined with strict execution discipline. Every task in a standing order should follow this loop:
1. **Execute** Do the actual work (don't just acknowledge the instruction)
2. **Verify** Confirm the result is correct (file exists, message delivered, data parsed)
3. **Report** Tell the owner what was done and what was verified
1. **Execute** - Do the actual work (don't just acknowledge the instruction)
2. **Verify** - Confirm the result is correct (file exists, message delivered, data parsed)
3. **Report** - Tell the owner what was done and what was verified
```markdown
### Execution rules
@@ -188,7 +188,7 @@ Standing orders work best when combined with strict execution discipline. Every
- "Done" without verification is not acceptable. Prove it.
- If execution fails: retry once with adjusted approach.
- If still fails: report failure with diagnosis. Never silently fail.
- Never retry indefinitely 3 attempts max, then escalate.
- Never retry indefinitely - 3 attempts max, then escalate.
```
This pattern prevents the most common agent failure mode: acknowledging a task without completing it.
@@ -228,18 +228,18 @@ Each program should have:
- Start with narrow authority and expand as trust builds
- Define explicit approval gates for high-risk actions
- Include "What NOT to do" sections boundaries matter as much as permissions
- Include "What NOT to do" sections - boundaries matter as much as permissions
- Combine with cron jobs for reliable time-based execution
- Review agent logs weekly to verify standing orders are being followed
- Update standing orders as your needs evolve they're living documents
- Update standing orders as your needs evolve - they're living documents
### Avoid
- Grant broad authority on day one ("do whatever you think is best")
- Skip escalation rules every program needs a "when to stop and ask" clause
- Assume the agent will remember verbal instructions put everything in the file
- Mix concerns in a single program separate programs for separate domains
- Forget to enforce with cron jobs standing orders without triggers become suggestions
- Skip escalation rules - every program needs a "when to stop and ask" clause
- Assume the agent will remember verbal instructions - put everything in the file
- Mix concerns in a single program - separate programs for separate domains
- Forget to enforce with cron jobs - standing orders without triggers become suggestions
## Related

View File

@@ -6,8 +6,6 @@ read_when:
title: Feishu
---
# Feishu / Lark
Feishu/Lark is an all-in-one collaboration platform where teams chat, share documents, manage calendars, and get work done together.
**Status:** production-ready for bot DMs + group chats. WebSocket is the default mode; webhook mode is optional.
@@ -43,10 +41,10 @@ Requires OpenClaw 2026.4.25 or above. Run `openclaw --version` to check. Upgrade
Configure `dmPolicy` to control who can DM the bot:
- `"pairing"` unknown users receive a pairing code; approve via CLI
- `"allowlist"` only users listed in `allowFrom` can chat (default: bot owner only)
- `"open"` allow public DMs only when `allowFrom` includes `"*"`; with restrictive entries, only matching users can chat
- `"disabled"` disable all DMs
- `"pairing"` - unknown users receive a pairing code; approve via CLI
- `"allowlist"` - only users listed in `allowFrom` can chat (default: bot owner only)
- `"open"` - allow public DMs only when `allowFrom` includes `"*"`; with restrictive entries, only matching users can chat
- `"disabled"` - disable all DMs
**Approve a pairing request:**
@@ -69,8 +67,8 @@ Default: `allowlist`
**Mention requirement** (`channels.feishu.requireMention`):
- `true` require @mention (default)
- `false` respond without @mention
- `true` - require @mention (default)
- `false` - respond without @mention
- Per-group override: `channels.feishu.groups.<chat_id>.requireMention`
- Broadcast-only `@all` and `@_all` are not treated as bot mentions. A message that mentions both `@all` and the bot directly still counts as a bot mention.
@@ -261,8 +259,8 @@ per account.
### Message limits
- `textChunkLimit` outbound text chunk size (default: `2000` chars)
- `mediaMaxMb` media upload/download limit (default: `30` MB)
- `textChunkLimit` - outbound text chunk size (default: `2000` chars)
- `mediaMaxMb` - media upload/download limit (default: `30` MB)
### Streaming
@@ -301,7 +299,7 @@ Reduce the number of Feishu/Lark API calls with two optional flags:
### ACP sessions
Feishu/Lark supports ACP for DMs and group thread messages. Feishu/Lark ACP is text-command driven there are no native slash-command menus, so use `/acp ...` messages directly in the conversation.
Feishu/Lark supports ACP for DMs and group thread messages. Feishu/Lark ACP is text-command driven - there are no native slash-command menus, so use `/acp ...` messages directly in the conversation.
#### Persistent ACP binding
@@ -409,19 +407,19 @@ Full configuration: [Gateway configuration](/gateway/configuration)
| `channels.feishu.domain` | API domain (`feishu` or `lark`) | `feishu` |
| `channels.feishu.connectionMode` | Event transport (`websocket` or `webhook`) | `websocket` |
| `channels.feishu.defaultAccount` | Default account for outbound routing | `default` |
| `channels.feishu.verificationToken` | Required for webhook mode | |
| `channels.feishu.encryptKey` | Required for webhook mode | |
| `channels.feishu.verificationToken` | Required for webhook mode | - |
| `channels.feishu.encryptKey` | Required for webhook mode | - |
| `channels.feishu.webhookPath` | Webhook route path | `/feishu/events` |
| `channels.feishu.webhookHost` | Webhook bind host | `127.0.0.1` |
| `channels.feishu.webhookPort` | Webhook bind port | `3000` |
| `channels.feishu.accounts.<id>.appId` | App ID | |
| `channels.feishu.accounts.<id>.appSecret` | App Secret | |
| `channels.feishu.accounts.<id>.appId` | App ID | - |
| `channels.feishu.accounts.<id>.appSecret` | App Secret | - |
| `channels.feishu.accounts.<id>.domain` | Per-account domain override | `feishu` |
| `channels.feishu.accounts.<id>.tts` | Per-account TTS override | `messages.tts` |
| `channels.feishu.dmPolicy` | DM policy | `allowlist` |
| `channels.feishu.allowFrom` | DM allowlist (open_id list) | [BotOwnerId] |
| `channels.feishu.groupPolicy` | Group policy | `allowlist` |
| `channels.feishu.groupAllowFrom` | Group allowlist | |
| `channels.feishu.groupAllowFrom` | Group allowlist | - |
| `channels.feishu.requireMention` | Require @mention in groups | `true` |
| `channels.feishu.groups.<chat_id>.requireMention` | Per-group @mention override; explicit IDs also admit the group in allowlist mode | inherited |
| `channels.feishu.groups.<chat_id>.enabled` | Enable/disable a specific group | `true` |
@@ -489,8 +487,8 @@ stay in the same session.
## Related
- [Channels Overview](/channels) all supported channels
- [Pairing](/channels/pairing) DM authentication and pairing flow
- [Groups](/channels/groups) group chat behavior and mention gating
- [Channel Routing](/channels/channel-routing) session routing for messages
- [Security](/gateway/security) access model and hardening
- [Channels Overview](/channels) - all supported channels
- [Pairing](/channels/pairing) - DM authentication and pairing flow
- [Groups](/channels/groups) - group chat behavior and mention gating
- [Channel Routing](/channels/channel-routing) - session routing for messages
- [Security](/gateway/security) - access model and hardening

View File

@@ -30,7 +30,7 @@ openclaw plugins install ./path/to/local/matrix-plugin
1. Create a Matrix account on your homeserver.
2. Configure `channels.matrix` with either `homeserver` + `accessToken`, or `homeserver` + `userId` + `password`.
3. Restart the gateway.
4. Start a DM with the bot, or invite it to a room (see [auto-join](#auto-join) fresh invites only land when `autoJoin` allows them).
4. Start a DM with the bot, or invite it to a room (see [auto-join](#auto-join) - fresh invites only land when `autoJoin` allows them).
### Interactive setup
@@ -80,7 +80,7 @@ Password-based (the token is cached after first login):
`channels.matrix.autoJoin` defaults to `off`. With the default, the bot will not appear in new rooms or DMs from fresh invites until you join manually.
OpenClaw cannot tell at invite time whether an invited room is a DM or a group, so all invites including DM-style invites go through `autoJoin` first. `dm.policy` only applies later, after the bot has joined and the room has been classified.
OpenClaw cannot tell at invite time whether an invited room is a DM or a group, so all invites - including DM-style invites - go through `autoJoin` first. `dm.policy` only applies later, after the bot has joined and the room has been classified.
<Warning>
Set `autoJoin: "allowlist"` plus `autoJoinAllowlist` to restrict which invites the bot accepts, or `autoJoin: "always"` to accept every invite.
@@ -122,7 +122,7 @@ Matrix stores cached credentials under `~/.openclaw/credentials/matrix/`:
- default account: `credentials.json`
- named accounts: `credentials-<account>.json`
When cached credentials exist there, OpenClaw treats Matrix as configured even if the access token is not in the config file that covers setup, `openclaw doctor`, and channel-status probes.
When cached credentials exist there, OpenClaw treats Matrix as configured even if the access token is not in the config file - that covers setup, `openclaw doctor`, and channel-status probes.
### Environment variables
@@ -237,7 +237,7 @@ When an approval prompt is too long for one Matrix event, OpenClaw chunks the vi
### Self-hosted push rules for quiet finalized previews
`streaming: "quiet"` only notifies recipients once a block or turn is finalized a per-user push rule has to match the finalized preview marker. See [Matrix push rules for quiet previews](/channels/matrix-push-rules) for the full recipe (recipient token, pusher check, rule install, per-homeserver notes).
`streaming: "quiet"` only notifies recipients once a block or turn is finalized - a per-user push rule has to match the finalized preview marker. See [Matrix push rules for quiet previews](/channels/matrix-push-rules) for the full recipe (recipient token, pusher check, rule install, per-homeserver notes).
## Bot-to-bot rooms
@@ -270,7 +270,7 @@ Use strict room allowlists and mention requirements when enabling bot-to-bot tra
## Encryption and verification
In encrypted (E2EE) rooms, outbound image events use `thumbnail_file` so image previews are encrypted alongside the full attachment. Unencrypted rooms still use plain `thumbnail_url`. No configuration is needed the plugin detects E2EE state automatically.
In encrypted (E2EE) rooms, outbound image events use `thumbnail_file` so image previews are encrypted alongside the full attachment. Unencrypted rooms still use plain `thumbnail_url`. No configuration is needed - the plugin detects E2EE state automatically.
All `openclaw matrix` commands accept `--verbose` (full diagnostics), `--json` (machine-readable output), and `--account <id>` (multi-account setups). Output is concise by default with quiet internal SDK logging. The examples below show the canonical form; add the flags as needed.
@@ -331,7 +331,7 @@ openclaw matrix verify status --include-recovery-key --json
### Verify this device with a recovery key
The recovery key is sensitive pipe it via stdin instead of passing it on the command line. Set `MATRIX_RECOVERY_KEY` (or `MATRIX_<ID>_RECOVERY_KEY` for a named account):
The recovery key is sensitive - pipe it via stdin instead of passing it on the command line. Set `MATRIX_RECOVERY_KEY` (or `MATRIX_<ID>_RECOVERY_KEY` for a named account):
```bash
printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin
@@ -405,7 +405,7 @@ openclaw matrix verify request --user-id @ops:example.org --device-id ABCDEF
Sends a verification request from this OpenClaw account. `--own-user` requests self-verification (you accept the prompt in another Matrix client of the same user); `--user-id`/`--device-id`/`--room-id` target someone else. `--own-user` cannot be combined with the other targeting flags.
For lower-level lifecycle handling typically while shadowing inbound requests from another client these commands act on a specific request `<id>` (printed by `verify list` and `verify request`):
For lower-level lifecycle handling - typically while shadowing inbound requests from another client - these commands act on a specific request `<id>` (printed by `verify list` and `verify request`):
| Command | Purpose |
| ------------------------------------------ | ------------------------------------------------------------------- |
@@ -435,7 +435,7 @@ Without `--account <id>`, Matrix CLI commands use the implicit default account.
<Accordion title="Verification notices">
Matrix posts verification lifecycle notices into the strict DM verification room as `m.notice` messages: request, ready (with "Verify by emoji" guidance), start/completion, and SAS (emoji/decimal) details when available.
Incoming requests from another Matrix client are tracked and auto-accepted. For self-verification, OpenClaw starts the SAS flow automatically and confirms its own side once emoji verification is available you still need to compare and confirm "They match" in your Matrix client.
Incoming requests from another Matrix client are tracked and auto-accepted. For self-verification, OpenClaw starts the SAS flow automatically and confirms its own side once emoji verification is available - you still need to compare and confirm "They match" in your Matrix client.
Verification system notices are not forwarded to the agent chat pipeline.
@@ -516,7 +516,7 @@ Explicit conversation bindings always win over `sessionScope`, so bound rooms an
- `"inbound"`: reply inside a thread only when the inbound message was already in that thread.
- `"always"`: reply inside a thread rooted at the triggering message; that conversation is routed through a matching thread-scoped session from the first trigger onward.
`dm.threadReplies` overrides this for DMs only for example, keep room threads isolated while keeping DMs flat.
`dm.threadReplies` overrides this for DMs only - for example, keep room threads isolated while keeping DMs flat.
### Thread inheritance and slash commands
@@ -676,7 +676,7 @@ It does not delete old rooms automatically. It picks the healthy DM and updates
Matrix can act as a native approval client. Configure under `channels.matrix.execApprovals` (or `channels.matrix.accounts.<account>.execApprovals` for a per-account override):
- `enabled`: deliver approvals through Matrix-native prompts. When unset or `"auto"`, Matrix auto-enables once at least one approver can be resolved. Set `false` to disable explicitly.
- `approvers`: Matrix user IDs (`@owner:example.org`) allowed to approve exec requests. Optional falls back to `channels.matrix.dm.allowFrom`.
- `approvers`: Matrix user IDs (`@owner:example.org`) allowed to approve exec requests. Optional - falls back to `channels.matrix.dm.allowFrom`.
- `target`: where prompts go. `"dm"` (default) sends to approver DMs; `"channel"` sends to the originating Matrix room or DM; `"both"` sends to both.
- `agentFilter` / `sessionFilter`: optional allowlists for which agents/sessions trigger Matrix delivery.
@@ -693,7 +693,7 @@ Both kinds share Matrix reaction shortcuts and message updates. Approvers see re
Fallback slash commands: `/approve <id> allow-once`, `/approve <id> allow-always`, `/approve <id> deny`.
Only resolved approvers can approve or deny. Channel delivery for exec approvals includes the command text only enable `channel` or `both` in trusted rooms.
Only resolved approvers can approve or deny. Channel delivery for exec approvals includes the command text - only enable `channel` or `both` in trusted rooms.
Related: [Exec approvals](/tools/exec-approvals).
@@ -742,7 +742,7 @@ Authorization rules still apply: command senders must satisfy the same DM or roo
- Set `defaultAccount` to pick the named account that implicit routing, probing, and CLI commands prefer.
- If you have multiple accounts and one is literally named `default`, OpenClaw uses it implicitly even when `defaultAccount` is unset.
- If you have multiple named accounts and no default is selected, CLI commands refuse to guess set `defaultAccount` or pass `--account <id>`.
- If you have multiple named accounts and no default is selected, CLI commands refuse to guess - set `defaultAccount` or pass `--account <id>`.
- The top-level `channels.matrix.*` block is only treated as the implicit `default` account when its auth is complete (`homeserver` + `accessToken`, or `homeserver` + `userId` + `password`). Named accounts remain discoverable from `homeserver` + `userId` once cached credentials cover auth.
**Promotion:**
@@ -907,8 +907,8 @@ Allowlist-style fields (`groupAllowFrom`, `dm.allowFrom`, `groups.<room>.users`)
## Related
- [Channels Overview](/channels) all supported channels
- [Pairing](/channels/pairing) DM authentication and pairing flow
- [Groups](/channels/groups) group chat behavior and mention gating
- [Channel Routing](/channels/channel-routing) session routing for messages
- [Security](/gateway/security) access model and hardening
- [Channels Overview](/channels) - all supported channels
- [Pairing](/channels/pairing) - DM authentication and pairing flow
- [Groups](/channels/groups) - group chat behavior and mention gating
- [Channel Routing](/channels/channel-routing) - session routing for messages
- [Security](/gateway/security) - access model and hardening

View File

@@ -6,8 +6,6 @@ read_when:
title: "Bonjour discovery"
---
# Bonjour / mDNS discovery
OpenClaw can use Bonjour (mDNS / DNS-SD) to discover an active Gateway (WebSocket endpoint).
Multicast `local.` browsing is a **LAN-only convenience**. The bundled `bonjour`
plugin owns LAN advertising. It auto-starts on macOS hosts and is opt-in on
@@ -17,20 +15,20 @@ is still best-effort and does **not** replace SSH or Tailnet-based connectivity.
## Wide-area Bonjour (Unicast DNS-SD) over Tailscale
If the node and gateway are on different networks, multicast mDNS wont cross the
boundary. You can keep the same discovery UX by switching to **unicast DNSSD**
("WideArea Bonjour") over Tailscale.
If the node and gateway are on different networks, multicast mDNS won't cross the
boundary. You can keep the same discovery UX by switching to **unicast DNS-SD**
("Wide-Area Bonjour") over Tailscale.
Highlevel steps:
High-level steps:
1. Run a DNS server on the gateway host (reachable over Tailnet).
2. Publish DNSSD records for `_openclaw-gw._tcp` under a dedicated zone
2. Publish DNS-SD records for `_openclaw-gw._tcp` under a dedicated zone
(example: `openclaw.internal.`).
3. Configure Tailscale **split DNS** so your chosen domain resolves via that
DNS server for clients (including iOS).
OpenClaw supports any discovery domain; `openclaw.internal.` is just an example.
iOS/Android nodes browse both `local.` and your configured widearea domain.
iOS/Android nodes browse both `local.` and your configured wide-area domain.
### Gateway config (recommended)
@@ -49,10 +47,10 @@ openclaw dns setup --apply
This installs CoreDNS and configures it to:
- listen on port 53 only on the gateways Tailscale interfaces
- listen on port 53 only on the gateway's Tailscale interfaces
- serve your chosen domain (example: `openclaw.internal.`) from `~/.openclaw/dns/<domain>.db`
Validate from a tailnetconnected machine:
Validate from a tailnet-connected machine:
```bash
dns-sd -B _openclaw-gw._tcp openclaw.internal.
@@ -63,7 +61,7 @@ dig @<TAILNET_IPV4> -p 53 _openclaw-gw._tcp.openclaw.internal PTR +short
In the Tailscale admin console:
- Add a nameserver pointing at the gateways tailnet IP (UDP/TCP 53).
- Add a nameserver pointing at the gateway's tailnet IP (UDP/TCP 53).
- Add split DNS so your discovery domain uses that nameserver.
Once clients accept tailnet DNS, iOS nodes and CLI discovery can browse
@@ -74,7 +72,7 @@ Once clients accept tailnet DNS, iOS nodes and CLI discovery can browse
The Gateway WS port (default `18789`) binds to loopback by default. For LAN/tailnet
access, bind explicitly and keep auth enabled.
For tailnetonly setups:
For tailnet-only setups:
- Set `gateway.bind: "tailnet"` in `~/.openclaw/openclaw.json`.
- Restart the Gateway (or restart the macOS menubar app).
@@ -87,11 +85,11 @@ DNS-SD publishing remains Gateway-owned.
## Service types
- `_openclaw-gw._tcp` gateway transport beacon (used by macOS/iOS/Android nodes).
- `_openclaw-gw._tcp` - gateway transport beacon (used by macOS/iOS/Android nodes).
## TXT keys (non-secret hints)
The Gateway advertises small nonsecret hints to make UI flows convenient:
The Gateway advertises small non-secret hints to make UI flows convenient:
- `role=gateway`
- `displayName=<friendly name>`
@@ -115,7 +113,7 @@ Security notes:
## Debugging on macOS
Useful builtin tools:
Useful built-in tools:
- Browse instances:
@@ -129,7 +127,7 @@ Useful builtin tools:
dns-sd -L "<instance>" _openclaw-gw._tcp local.
```
If browsing works but resolving fails, youre usually hitting a LAN policy or
If browsing works but resolving fails, you're usually hitting a LAN policy or
mDNS resolver issue.
## Debugging in Gateway logs
@@ -158,7 +156,7 @@ To capture logs:
- Settings → Gateway → Advanced → **Discovery Debug Logs**
- Settings → Gateway → Advanced → **Discovery Logs** → reproduce → **Copy**
The log includes browser state transitions and resultset changes.
The log includes browser state transitions and result-set changes.
## When to enable Bonjour
@@ -257,8 +255,8 @@ If a node no longer auto-discovers the Gateway after Docker setup:
## Common failure modes
- **Bonjour doesnt cross networks**: use Tailnet or SSH.
- **Multicast blocked**: some WiFi networks disable mDNS.
- **Bonjour doesn't cross networks**: use Tailnet or SSH.
- **Multicast blocked**: some Wi-Fi networks disable mDNS.
- **Advertiser stuck in probing/announcing**: hosts with blocked multicast,
container bridges, WSL, or interface churn can leave the ciao advertiser in a
non-announced state. OpenClaw retries a few times and then disables Bonjour
@@ -273,7 +271,7 @@ If a node no longer auto-discovers the Gateway after Docker setup:
## Escaped instance names (`\032`)
Bonjour/DNSSD often escapes bytes in service instance names as decimal `\DDD`
Bonjour/DNS-SD often escapes bytes in service instance names as decimal `\DDD`
sequences (e.g. spaces become `\032`).
- This is normal at the protocol level.

View File

@@ -42,7 +42,7 @@ openclaw browser --browser-profile openclaw open https://example.com
openclaw browser --browser-profile openclaw snapshot
```
If you get Browser disabled, enable it in config (see below) and restart the
If you get "Browser disabled", enable it in config (see below) and restart the
Gateway.
If `openclaw browser` is missing entirely, or the agent says the browser tool
@@ -342,10 +342,10 @@ This is the default path for remote gateways.
Notes:
- The node host exposes its local browser control server via a **proxy command**.
- Profiles come from the nodes own `browser.profiles` config (same as local).
- Profiles come from the node's own `browser.profiles` config (same as local).
- `nodeHost.browserProxy.allowProfiles` is optional. Leave it empty for the legacy/default behavior: all configured profiles remain reachable through the proxy, including profile create/delete routes.
- If you set `nodeHost.browserProxy.allowProfiles`, OpenClaw treats it as a least-privilege boundary: only allowlisted profiles can be targeted, and persistent profile create/delete routes are blocked on the proxy surface.
- Disable if you dont want it:
- Disable if you don't want it:
- On the node: `nodeHost.browserProxy.enabled=false`
- On the gateway: `gateway.nodes.browser.mode="off"`
@@ -422,14 +422,14 @@ Some hosted browser services expose a **direct WebSocket** endpoint rather than
the standard HTTP-based CDP discovery (`/json/version`). OpenClaw accepts three
CDP URL shapes and picks the right connection strategy automatically:
- **HTTP(S) discovery** `http://host[:port]` or `https://host[:port]`.
- **HTTP(S) discovery** - `http://host[:port]` or `https://host[:port]`.
OpenClaw calls `/json/version` to discover the WebSocket debugger URL, then
connects. No WebSocket fallback.
- **Direct WebSocket endpoints** `ws://host[:port]/devtools/<kind>/<id>` or
- **Direct WebSocket endpoints** - `ws://host[:port]/devtools/<kind>/<id>` or
`wss://...` with a `/devtools/browser|page|worker|shared_worker|service_worker/<id>`
path. OpenClaw connects directly via a WebSocket handshake and skips
`/json/version` entirely.
- **Bare WebSocket roots** `ws://host[:port]` or `wss://host[:port]` with no
- **Bare WebSocket roots** - `ws://host[:port]` or `wss://host[:port]` with no
`/devtools/...` path (e.g. [Browserless](https://browserless.io),
[Browserbase](https://www.browserbase.com)). OpenClaw tries HTTP
`/json/version` discovery first (normalising the scheme to `http`/`https`);
@@ -481,7 +481,7 @@ Notes:
Key ideas:
- Browser control is loopback-only; access flows through the Gateways auth or node pairing.
- Browser control is loopback-only; access flows through the Gateway's auth or node pairing.
- The standalone loopback browser HTTP API uses **shared-secret auth only**:
gateway token bearer auth, `x-openclaw-password`, or HTTP Basic auth with the
configured gateway password.
@@ -512,7 +512,7 @@ Defaults:
- The `openclaw` profile is auto-created if missing.
- The `user` profile is built-in for Chrome MCP existing-session attach.
- Existing-session profiles are opt-in beyond `user`; create them with `--driver existing-session`.
- Local CDP ports allocate from **1880018899** by default.
- Local CDP ports allocate from **18800-18899** by default.
- Deleting a profile moves its local data directory to Trash.
All control endpoints accept `?profile=<name>`; the CLI uses `--browser-profile`.
@@ -598,7 +598,7 @@ What to check if attach does not work:
Agent use:
- Use `profile="user"` when you need the users logged-in browser state.
- Use `profile="user"` when you need the user's logged-in browser state.
- If you use a custom existing-session profile, pass that explicit profile name.
- Only choose this mode when the user is at the computer to approve the attach
prompt.
@@ -641,10 +641,10 @@ directory.
Compared to the managed `openclaw` profile, existing-session drivers are more constrained:
- **Screenshots** page captures and `--ref` element captures work; CSS `--element` selectors do not. `--full-page` cannot combine with `--ref` or `--element`. Playwright is not required for page or ref-based element screenshots.
- **Actions** `click`, `type`, `hover`, `scrollIntoView`, `drag`, and `select` require snapshot refs (no CSS selectors). `click-coords` clicks visible viewport coordinates and does not require a snapshot ref. `click` is left-button only. `type` does not support `slowly=true`; use `fill` or `press`. `press` does not support `delayMs`. `type`, `hover`, `scrollIntoView`, `drag`, `select`, `fill`, and `evaluate` do not support per-call timeouts. `select` accepts a single value.
- **Wait / upload / dialog** `wait --url` supports exact, substring, and glob patterns; `wait --load networkidle` is not supported. Upload hooks require `ref` or `inputRef`, one file at a time, no CSS `element`. Dialog hooks do not support timeout overrides.
- **Managed-only features** batch actions, PDF export, download interception, and `responsebody` still require the managed browser path.
- **Screenshots** - page captures and `--ref` element captures work; CSS `--element` selectors do not. `--full-page` cannot combine with `--ref` or `--element`. Playwright is not required for page or ref-based element screenshots.
- **Actions** - `click`, `type`, `hover`, `scrollIntoView`, `drag`, and `select` require snapshot refs (no CSS selectors). `click-coords` clicks visible viewport coordinates and does not require a snapshot ref. `click` is left-button only. `type` does not support `slowly=true`; use `fill` or `press`. `press` does not support `delayMs`. `type`, `hover`, `scrollIntoView`, `drag`, `select`, `fill`, and `evaluate` do not support per-call timeouts. `select` accepts a single value.
- **Wait / upload / dialog** - `wait --url` supports exact, substring, and glob patterns; `wait --load networkidle` is not supported. Upload hooks require `ref` or `inputRef`, one file at a time, no CSS `element`. Dialog hooks do not support timeout overrides.
- **Managed-only features** - batch actions, PDF export, download interception, and `responsebody` still require the managed browser path.
</Accordion>
@@ -740,7 +740,7 @@ Security guidance:
The agent gets **one tool** for browser automation:
- `browser` doctor/status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act
- `browser` - doctor/status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act
How it maps:
@@ -759,6 +759,6 @@ This keeps the agent deterministic and avoids brittle selectors.
## Related
- [Tools Overview](/tools) all available agent tools
- [Sandboxing](/gateway/sandboxing) browser control in sandboxed environments
- [Security](/gateway/security) browser control risks and hardening
- [Tools Overview](/tools) - all available agent tools
- [Sandboxing](/gateway/sandboxing) - browser control in sandboxed environments
- [Security](/gateway/security) - browser control risks and hardening